#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
}
}