Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

Sorted usings and removed unused usings in entire solution (#1094)

File size: 9.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Linq;
25using System.Text;
26using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
27
28namespace HeuristicLab.Persistence.Auxiliary {
29
30  /// <summary>
31  /// Contains a more modular representation of type names that can
32  /// be used to compare versions and ignore extended assembly
33  /// attributes.
34  /// </summary>
35  [StorableClass]
36  public class TypeName {
37
38    /// <summary>
39    /// Gets or sets the namespace.
40    /// </summary>
41    /// <value>The namespace.</value>
42    [Storable]
43    public string Namespace { get; private set; }
44
45    /// <summary>
46    /// Gets or sets the name of the class.
47    /// </summary>
48    /// <value>The name of the class.</value>
49    [Storable]
50    public string ClassName { get; private set; }
51
52    /// <summary>
53    /// Gets or sets the generic args.
54    /// </summary>
55    /// <value>The generic args.</value>
56    [Storable]
57    public List<TypeName> GenericArgs { get; internal set; }
58
59    /// <summary>
60    /// Gets a value indicating whether this instance is generic.
61    /// </summary>
62    /// <value>
63    ///   <c>true</c> if this instance is generic; otherwise, <c>false</c>.
64    /// </value>
65    public bool IsGeneric { get { return GenericArgs.Count > 0; } }
66
67    /// <summary>
68    /// Gets or sets the memory magic (point or array declaration).
69    /// </summary>
70    /// <value>The memory magic.</value>
71    [Storable]
72    public string MemoryMagic { get; internal set; }
73
74    /// <summary>
75    /// Gets or sets the name of the assembly.
76    /// </summary>
77    /// <value>The name of the assembly.</value>
78    [Storable]
79    public string AssemblyName { get; internal set; }
80
81    /// <summary>
82    /// Gets or sets the assembly attribues.
83    /// </summary>
84    /// <value>The assembly attribues.</value>
85    [Storable]
86    public Dictionary<string, string> AssemblyAttribues { get; internal set; }
87
88    /// <summary>
89    /// Gets or sets a value indicating whether this instance is reference.
90    /// </summary>
91    /// <value>
92    ///   <c>true</c> if this instance is reference; otherwise, <c>false</c>.
93    /// </value>
94    [Storable]
95    public bool IsReference { get; internal set; }
96
97
98
99    /// <summary>
100    /// Initializes a new instance of the <see cref="TypeName"/> class.
101    /// </summary>
102    /// <param name="nameSpace">The namespace.</param>
103    /// <param name="className">Name of the class.</param>
104    internal TypeName(string nameSpace, string className) {
105      Namespace = nameSpace;
106      ClassName = className;
107      GenericArgs = new List<TypeName>();
108      MemoryMagic = "";
109      AssemblyAttribues = new Dictionary<string, string>();
110    }
111
112
113    /// <summary>
114    /// Returns a <see cref="System.String"/> that represents this instance.
115    /// </summary>
116    /// <param name="full">if set to <c>true</c> includes full information
117    /// about generic parameters and assembly properties.</param>
118    /// <returns>
119    /// A <see cref="System.String"/> that represents this instance.
120    /// </returns>
121    public string ToString(bool full) {
122      return ToString(full, true);
123    }
124
125
126    /// <summary>
127    /// Returns a <see cref="System.String"/> that represents this instance.
128    /// </summary>
129    /// <param name="full">if set to <c>true</c> includes full information
130    /// about generic parameters and assembly properties.</param>
131    /// <param name="includeAssembly">if set to <c>true</c> include assembly properties and generic parameters.</param>
132    /// <returns>
133    /// A <see cref="System.String"/> that represents this instance.
134    /// </returns>
135    public string ToString(bool full, bool includeAssembly) {
136      StringBuilder sb = new StringBuilder();
137      if (!string.IsNullOrEmpty(Namespace))
138        sb.Append(Namespace).Append('.');
139      sb.Append(ClassName);
140      if (IsGeneric) {
141        sb.Append('`').Append(GenericArgs.Count).Append('[');
142        bool first = true;
143        foreach (TypeName t in GenericArgs) {
144          if (first)
145            first = false;
146          else
147            sb.Append(',');
148          sb.Append('[').Append(t.ToString(full)).Append(']');
149        }
150        sb.Append(']');
151      }
152      sb.Append(MemoryMagic);
153      if (includeAssembly && AssemblyName != null) {
154        sb.Append(", ").Append(AssemblyName);
155        if (full)
156          foreach (var property in AssemblyAttribues)
157            sb.Append(", ").Append(property.Key).Append('=').Append(property.Value);
158      }
159      return sb.ToString();
160    }
161
162    public string GetTypeNameInCode(HashSet<string> omitNamespaces) {
163      StringBuilder sb = new StringBuilder();
164      if (!string.IsNullOrEmpty(Namespace) && omitNamespaces == null || !omitNamespaces.Contains(Namespace))
165        sb.Append(Namespace).Append('.');
166      sb.Append(ClassName);
167      if (IsGeneric) {
168        sb.Append("<");
169        sb.Append(
170          string.Join(", ",
171            GenericArgs
172              .Select(a => a.GetTypeNameInCode(omitNamespaces))
173              .ToArray()));
174        sb.Append(">");
175      }
176      sb.Append(MemoryMagic);
177      return sb.ToString();
178    }
179
180    public string GetTypeNameInCode(bool includeAllNamespaces) {
181      StringBuilder sb = new StringBuilder();
182      if (includeAllNamespaces)
183        sb.Append(Namespace).Append('.');
184      sb.Append(ClassName);
185      if (IsGeneric) {
186        sb.Append("<");
187        sb.Append(
188          string.Join(", ",
189            GenericArgs
190              .Select(a => a.GetTypeNameInCode(includeAllNamespaces))
191              .ToArray()));
192        sb.Append(">");
193      }
194      sb.Append(MemoryMagic);
195      return sb.ToString();
196    }
197
198
199    /// <summary>
200    /// Returns a <see cref="System.String"/> that represents this instance.
201    /// </summary>
202    /// <returns>
203    /// A <see cref="System.String"/> that represents this instance.
204    /// </returns>
205    public override string ToString() {
206      return ToString(true);
207    }
208
209
210    /// <summary>
211    /// Lexicographically compare version information and make sure type and assembly
212    /// names are identical. This function recursively checks generic type arguments.
213    /// </summary>
214    /// <param name="typeName">Name of the type.</param>
215    /// <returns>
216    ///   <c>true</c> if is newer than the specified type name; otherwise, <c>false</c>.
217    /// </returns>
218    public bool IsNewerThan(TypeName typeName) {
219      try {
220        if (this.ClassName != typeName.ClassName ||
221          this.Namespace != typeName.Namespace ||
222          this.AssemblyName != typeName.AssemblyName)
223          throw new Exception("Cannot compare versions of different types");
224        if (CompareVersions(
225          this.AssemblyAttribues["Version"],
226          typeName.AssemblyAttribues["Version"]) > 0)
227          return true;
228        IEnumerator<TypeName> thisIt = this.GenericArgs.GetEnumerator();
229        IEnumerator<TypeName> tIt = typeName.GenericArgs.GetEnumerator();
230        while (thisIt.MoveNext()) {
231          tIt.MoveNext();
232          if (thisIt.Current.IsNewerThan(tIt.Current))
233            return true;
234        }
235        return false;
236      }
237      catch (KeyNotFoundException) {
238        throw new Exception("Could not extract version information from type string");
239      }
240    }
241
242
243    /// <summary>
244    /// Make sure major and minor version number are identical. This function
245    /// recursively checks generic type arguments.
246    /// </summary>
247    /// <param name="typeName">Name of the type.</param>
248    /// <returns>
249    ///   <c>true</c> if the specified type names are compatible; otherwise, <c>false</c>.
250    /// </returns>
251    public bool IsCompatible(TypeName typeName) {
252      try {
253        if (this.ClassName != typeName.ClassName ||
254          this.Namespace != typeName.Namespace ||
255          this.AssemblyName != typeName.AssemblyName)
256          throw new Exception("Cannot compare versions of different types");
257        Version thisVersion = new Version(this.AssemblyAttribues["Version"]);
258        Version tVersion = new Version(typeName.AssemblyAttribues["Version"]);
259        if (thisVersion.Major != tVersion.Major ||
260          thisVersion.Minor != tVersion.Minor)
261          return false;
262        IEnumerator<TypeName> thisIt = this.GenericArgs.GetEnumerator();
263        IEnumerator<TypeName> tIt = typeName.GenericArgs.GetEnumerator();
264        while (thisIt.MoveNext()) {
265          tIt.MoveNext();
266          if (!thisIt.Current.IsCompatible(tIt.Current))
267            return false;
268        }
269        return true;
270      }
271      catch (KeyNotFoundException) {
272        throw new Exception("Could not extract version infomration from type string");
273      }
274    }
275
276    private static int CompareVersions(string v1string, string v2string) {
277      return new Version(v1string).CompareTo(new Version(v2string));
278    }
279  }
280}
Note: See TracBrowser for help on using the repository browser.