using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Globalization;
namespace DotNetOpenId.Extensions {
class AliasManager {
readonly string aliasFormat = "alias{0}";
///
/// Tracks extension Type URIs and aliases assigned to them.
///
Dictionary typeUriToAliasMap = new Dictionary();
///
/// Tracks extension aliases and Type URIs assigned to them.
///
Dictionary aliasToTypeUriMap = new Dictionary();
///
/// Gets an alias assigned for a given Type URI. A new alias is assigned if necessary.
///
public string GetAlias(string typeUri) {
if (string.IsNullOrEmpty(typeUri)) throw new ArgumentNullException("typeUri");
string alias;
if (typeUriToAliasMap.TryGetValue(typeUri, out alias))
return alias;
else
return assignNewAlias(typeUri);
}
///
/// Sets an alias and the value that will be returned by .
///
public void SetAlias(string alias, string typeUri) {
if (string.IsNullOrEmpty(alias)) throw new ArgumentNullException("alias");
if (string.IsNullOrEmpty(typeUri)) throw new ArgumentNullException("typeUri");
aliasToTypeUriMap.Add(alias, typeUri);
typeUriToAliasMap.Add(typeUri, alias);
}
///
/// Takes a sequence of type URIs and assigns aliases for all of them.
///
/// The type URIs to create aliases for.
/// An optional dictionary of URI/alias pairs that suggest preferred aliases to use if available for certain type URIs.
public void AssignAliases(IEnumerable typeUris, IDictionary preferredTypeUriToAliases) {
// First go through the actually used type URIs and see which ones have matching preferred aliases.
if (preferredTypeUriToAliases != null) {
foreach (string typeUri in typeUris) {
if (typeUriToAliasMap.ContainsKey(typeUri)) {
// this Type URI is already mapped to an alias.
continue;
}
string preferredAlias;
if (preferredTypeUriToAliases.TryGetValue(typeUri, out preferredAlias) && !IsAliasUsed(preferredAlias)) {
SetAlias(preferredAlias, typeUri);
}
}
}
// Now go through the whole list again and assign whatever is left now that the preferred ones
// have gotten their picks where available.
foreach (string typeUri in typeUris) {
if (typeUriToAliasMap.ContainsKey(typeUri)) {
// this Type URI is already mapped to an alias.
continue;
}
assignNewAlias(typeUri);
}
}
///
/// Sets up aliases for any Type URIs in a dictionary that do not yet have aliases defined,
/// and where the given preferred alias is still available.
///
/// A dictionary of type URI keys and alias values.
public void SetPreferredAliasesWhereNotSet(IDictionary preferredTypeUriToAliases) {
if (preferredTypeUriToAliases == null) throw new ArgumentNullException("preferredTypeUriToAliases");
foreach (var pair in preferredTypeUriToAliases) {
if (typeUriToAliasMap.ContainsKey(pair.Key)) {
// type URI is already mapped
continue;
}
if (aliasToTypeUriMap.ContainsKey(pair.Value)) {
// alias is already mapped
continue;
}
// The type URI and alias are as yet unset, so go ahead and assign them.
SetAlias(pair.Value, pair.Key);
}
}
///
/// Gets the Type Uri encoded by a given alias.
///
public string ResolveAlias(string alias) {
string typeUri = TryResolveAlias(alias);
if (typeUri == null)
throw new ArgumentOutOfRangeException("alias");
return typeUri;
}
public string TryResolveAlias(string alias) {
if (string.IsNullOrEmpty(alias)) throw new ArgumentNullException("alias");
string typeUri = null;
aliasToTypeUriMap.TryGetValue(alias, out typeUri);
return typeUri;
}
public IEnumerable Aliases {
get { return aliasToTypeUriMap.Keys; }
}
///
/// Returns a value indicating whether an alias has already been assigned to a type URI.
///
/// The alias in question.
/// True if the alias has already been assigned. False otherwise.
public bool IsAliasUsed(string alias) {
if (string.IsNullOrEmpty(alias)) throw new ArgumentNullException("alias");
return aliasToTypeUriMap.ContainsKey(alias);
}
public bool IsAliasAssignedTo(string typeUri) {
if (string.IsNullOrEmpty("typeUri")) throw new ArgumentNullException("typeUri");
return typeUriToAliasMap.ContainsKey(typeUri);
}
string assignNewAlias(string typeUri) {
Debug.Assert(!string.IsNullOrEmpty(typeUri));
Debug.Assert(!typeUriToAliasMap.ContainsKey(typeUri));
string alias = string.Format(CultureInfo.InvariantCulture, aliasFormat, typeUriToAliasMap.Count + 1);
typeUriToAliasMap.Add(typeUri, alias);
aliasToTypeUriMap.Add(alias, typeUri);
return alias;
}
}
}