#region Disclaimer / License // Copyright (C) 2009, Kenneth Skovhede // http://www.hexad.dk, opensource@hexad.dk // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // #endregion using System; using System.Collections.Generic; using System.Text; namespace OSGeo.MapGuide.MaestroAPI { /// /// This class contains all the required code for maintaining resource identifiers. /// It has implicit conversions to and from a string, which makes it much easier to use. /// It has both static methods that operate on strings, as well as a class that can be manipulated. /// public class ResourceIdentifier { /// /// The actual ResourceID /// private string m_id; /// /// Constructs a new ResourceIdentifier with the given full path /// /// The path of the resource to refence public ResourceIdentifier(string resourceId) { m_id = resourceId; } /// /// Constructs a new ResourceIdentifier, based on an existing one. /// /// The resource identifier to copy public ResourceIdentifier(ResourceIdentifier id) { m_id = id.m_id; } /// /// Constructs a new library based resource identifier /// /// The name of the resource, may include path information with the \"/\" character /// The type of resource the identifier names public ResourceIdentifier(string name, ResourceTypes type) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); if (name.IndexOf(".") > 0 || name.IndexOf("//") > 0 || name.IndexOf(":") > 0) throw new ArgumentException("The resource name must not contain ':', \"//\" or '.'", "name"); if (!Enum.IsDefined(typeof(ResourceTypes), type)) throw new ArgumentException("The type given was not a valid ResourceType", "type"); m_id = "Library://" + name + EnumHelper.ResourceName(type, true); } /// /// Constructs a new session based resource identifier /// /// The name of the resource, may include path information with the \"/\" character /// The type of resource the identifier names /// The session id to use public ResourceIdentifier(string name, ResourceTypes type, string sessionId) : this(name, type) { this.ConvertToSession(sessionId); } /// /// Gets a value indicating if the resource is blank /// public bool IsEmpty { get { return string.IsNullOrEmpty(m_id); } } /// /// Gets or sets the name of the resource /// public string Name { get { return GetName(m_id); } set { m_id = SetName(m_id, value); } } /// /// Gets or sets the name and extension of the resource /// public string Fullname { get { return GetFullname(m_id); } set { m_id = SetName(m_id, value); } } /// /// Gets or sets the extension of the resourceId /// public string Extension { get { return GetExtension(m_id); } set { m_id = SetExtension(m_id, value); } } /// /// Gets the full path of the resource, that is the path without repository information /// public string Fullpath { get { return GetFullpath(m_id); } set { m_id = SetPath(m_id, value); } } /// /// Gets the path of the resource, that is the path without repository information and no extension /// public string Path { get { return GetPath(m_id); } set { m_id = SetPath(m_id, value); } } /// /// Gets or sets the path to the resource, including the repository /// public string RepositoryPath { get { return GetRepositoryPath(m_id); } set { m_id = SetRepositoryPath(m_id, value); } } /// /// Gets a value indicating if the resource is in the library repository /// public bool IsInLibrary { get { return GetRepository(m_id) == "Library://"; } } /// /// Gets a value indicating if the resource is in the session repository /// public bool IsInSessionRepository { get { return !this.IsInLibrary; } } /// /// Converts this instance to be in the library repository /// public void ConvertToLibrary() { m_id = ResourceIdentifier.ConvertToLibrary(m_id); } /// /// Converts this instance to be in the session repository /// /// The sessionid public void ConvertToSession(string sessionId) { m_id = ResourceIdentifier.ConvertToSession(m_id, sessionId); } /// /// Helper operator that makes using the resource identifiers easier /// /// The id to convert to a string /// The converted string public static implicit operator string(ResourceIdentifier id) { return id == null ? null : id.m_id; } /// /// Helper operator that makes using the resource identifiers easier /// /// The id to convert into a resource indetifier class /// The resource identifier public static implicit operator ResourceIdentifier(string id) { return new ResourceIdentifier(id); } /// /// Returns the full resource id as a string /// /// The full resource id as a string public override string ToString() { return m_id; } /// /// Gets the length of the resource identifier as a string /// public int Length { get { return m_id == null ? 0 : m_id.Length; } } /// /// Gets or sets the full resource identifier /// public string ResourceId { get { return m_id; } set { m_id = value; } } /// /// Gets a value indicating if the resource identifier points to a folder /// public bool IsFolder { get { return ResourceIdentifier.IsFolderResource(m_id); } } /// /// Gets a value indicating if the resource identifier is valid /// public bool IsValid { get { return ResourceIdentifier.Validate(m_id); } } /// /// Normalizes the identifier, that is prepends a slash if the identifier points to a folder /// public void Normalize() { m_id = ResourceIdentifier.Normalize(m_id); } /// /// Gets the containing folder path for the resource, including the repository /// public string ParentFolder { get { return ResourceIdentifier.GetParentFolder(m_id); } } #region Static handlers /// /// Gets the name of a resource, given its identifier /// /// The identifier to look for /// The name of the resource public static string GetName(string identifier) { if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier"); string temp = GetPath(identifier); if (string.IsNullOrEmpty(temp)) throw new ArgumentException("The value must be a resource identifier", "identifier"); return temp.Substring(temp.LastIndexOf("/") + 1); } /// /// Sets the name of the resource, with or without the extension /// /// The identifier to give a new name /// The new name to assign /// The renamed identifier public static string SetName(string identifier, string newname) { string temp = GetPath(identifier); if (identifier.EndsWith("/")) { if (!newname.EndsWith("/")) newname += "/"; } else newname += "." + GetExtension(identifier); if (newname.IndexOf("/") > 0) throw new ArgumentException("The new name must not contain the \"/\" character", "newname"); temp = temp.Substring(0, temp.Length - GetName(identifier).Length) + newname; return GetRepository(identifier) + temp; } /// /// Sets the path of the identifier, with or without the extension /// /// The identifier to update /// The new path to user, with or without the extension /// The new identifier public static string SetPath(string identifier, string newpath) { string temp = GetPath(identifier); if (!identifier.EndsWith("/")) newpath += "." + GetExtension(identifier); return GetRepository(identifier) + newpath + (identifier.EndsWith("/") ? "/" : ""); } /// /// Changes the extension of the given resource /// /// The identifier to change the extension for /// The new extension to use /// The renmaed identifier public static string SetExtension(string identifier, string newextension) { if (identifier.EndsWith("/")) throw new Exception("Cannot change extension for a folder"); if (!newextension.StartsWith(".")) newextension = "." + newextension; if (newextension.LastIndexOf(".") > 0) throw new ArgumentException("The supplied extension is invalid", "newextension"); return identifier.Substring(0, identifier.Length - GetExtension(identifier).Length - 1) + newextension; } /// /// Gets the repository part of a resource identifier, eg.: "Library://" or "Session:xxxx//" /// /// /// public static string GetRepository(string identifier) { if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier"); int ix = identifier.IndexOf("//"); if (ix <= 0) throw new ArgumentException("The value must be a resource identifier", "identifier"); string repo = identifier.Substring(0, ix); if (repo != "Library:" && !repo.StartsWith("Session:")) throw new ArgumentException("The value must be a resource identifier", "identifier"); return repo + "//"; } /// /// Returns the full path of the resource, that is the resourceId without the repository information /// /// The identifier to get the path from /// The path of the identifier public static string GetFullpath(string identifier) { if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier"); return identifier.Substring(GetRepository(identifier).Length); } /// /// Returns the path of the resource, that is the resourceId without the repository information and extension /// /// The identifier to get the path from /// The path of the identifier public static string GetPath(string identifier) { if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier"); return identifier.Substring(GetRepository(identifier).Length, identifier.Length - GetExtension(identifier).Length - GetRepository(identifier).Length - 1); } /// /// Returns the extension of a resource identifier /// /// The identifier to get the extension from /// The extension of the identifier public static string GetExtension(string identifier) { if (string.IsNullOrEmpty(identifier)) throw new ArgumentNullException("identifier"); if (identifier.EndsWith("/")) return ""; int ix = identifier.LastIndexOf("."); if (ix <= 0) throw new ArgumentException("The value must be a resource identifier", "identifier"); return identifier.Substring(ix + 1); } /// /// Converts a resource id to be placed in the library /// /// The identifier to convert /// The converted identifier public static string ConvertToLibrary(string identifier) { return "Library://" + identifier.Substring(GetRepository(identifier).Length); } /// /// Converts a resource id to be placed in the library /// /// The identifier to convert /// The session id of the repository it should be placed in /// The converted identifier public static string ConvertToSession(string identifier, string sessionId) { return "Session:" + sessionId + "//" + identifier.Substring(GetRepository(identifier).Length); } /// /// Gets the name and extension of the identifier /// /// The identifier to extract the information from /// The full name of the identifier public static string GetFullname(string identifier) { if (identifier.EndsWith("/")) return GetName(identifier); else return GetName(identifier) + "." + GetExtension(identifier); } /// /// Determines if a resource identifier is valid /// /// The identifier to validate /// A value indicating if the identifier is valid public static bool Validate(string identifier) { try { GetRepository(identifier); if (identifier.IndexOf(".") < 0 && !identifier.EndsWith("/")) return false; } catch { return false; } return true; } /// /// Returns a value indicating if the resource points to a folder /// /// The identifier to evaluate /// A value indicating if the resource points to a folder public static bool IsFolderResource(string identifier) { return identifier.EndsWith("/"); } /// /// Normalizes a identifier, that is prepends a slash if it is a folder resource /// /// The identifier to normalize /// The normalized identifier public static string Normalize(string identifier) { if (identifier.LastIndexOf(".") <= identifier.LastIndexOf("/") && !identifier.EndsWith("/")) return identifier + "/"; else return identifier; } /// /// Determines if a resource identifier is valid and of the desired type /// /// The identifier to validate /// The type the resource identifer must be /// A value indicating if the identifier is valid public static bool Validate(string identifier, ResourceTypes type) { if (!Validate(identifier)) return false; if (type == ResourceTypes.Folder) return IsFolderResource(identifier); else return EnumHelper.ResourceName(type) == GetExtension(identifier); } /// /// Returns the path that contains the resource, including the repository /// /// The resource identifier to use /// The folder for the identifier public static string GetRepositoryPath(string identifier) { if (!Validate(identifier)) throw new Exception("Invalid resource id: " + identifier); identifier = Normalize(identifier); return identifier.Substring(0, identifier.LastIndexOf("/", identifier.Length)) + "/"; } /// /// Sets the path including the repository to the given value /// /// The identifier to change the folder for /// The new folder /// An identifier in the new folder public static string SetRepositoryPath(string identifier, string folder) { if (!folder.StartsWith("Library:") && !folder.StartsWith("Session:")) { string res = identifier.EndsWith("/") ? "" : GetFullname(identifier); string repo = GetRepository(identifier); if (!folder.EndsWith("/") && !string.IsNullOrEmpty(folder)) folder += "/"; return repo + folder + res; } else if (GetExtension(identifier) == "") { if (!folder.EndsWith("/")) folder += "/"; return folder; } else { if (!folder.EndsWith("/")) folder += "/"; return folder + GetFullname(identifier); } } public static string GetParentFolder(string identifier) { if (!Validate(identifier)) throw new Exception("Invalid resource id: " + identifier); identifier = Normalize(identifier); if (identifier == GetRepository(identifier)) return identifier; if (identifier.EndsWith("/")) identifier = identifier.Remove(identifier.Length - 1); identifier = identifier.Remove(identifier.LastIndexOf("/") + 1); return identifier; } #endregion } }