Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 3935 was 3935, checked in by epitzer, 14 years ago

Add EasyXmlGenerator for easier review of generated XML. (#1139)

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.Linq;
24using System.Text;
25using System.Text.RegularExpressions;
26using System.Reflection.Emit;
27using System.Collections.Generic;
28using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
29
30namespace HeuristicLab.Persistence.Auxiliary {
31
32  /// <summary>
33  /// Contains a more modular representation of type names that can
34  /// be used to compare versions and ignore extended assembly
35  /// attributes.
36  /// </summary>
37  [StorableClass]
38  public class TypeName {
39
40    /// <summary>
41    /// Gets or sets the namespace.
42    /// </summary>
43    /// <value>The namespace.</value>
44    [Storable]
45    public string Namespace { get; private set; }
46
47    /// <summary>
48    /// Gets or sets the name of the class.
49    /// </summary>
50    /// <value>The name of the class.</value>
51    [Storable]
52    public string ClassName { get; private set; }
53
54    /// <summary>
55    /// Gets or sets the generic args.
56    /// </summary>
57    /// <value>The generic args.</value>
58    [Storable]
59    public List<TypeName> GenericArgs { get; internal set; }
60
61    /// <summary>
62    /// Gets a value indicating whether this instance is generic.
63    /// </summary>
64    /// <value>
65    ///   <c>true</c> if this instance is generic; otherwise, <c>false</c>.
66    /// </value>
67    public bool IsGeneric { get { return GenericArgs.Count > 0; } }
68
69    /// <summary>
70    /// Gets or sets the memory magic (point or array declaration).
71    /// </summary>
72    /// <value>The memory magic.</value>
73    [Storable]
74    public string MemoryMagic { get; internal set; }
75
76    /// <summary>
77    /// Gets or sets the name of the assembly.
78    /// </summary>
79    /// <value>The name of the assembly.</value>
80    [Storable]
81    public string AssemblyName { get; internal set; }
82
83    /// <summary>
84    /// Gets or sets the assembly attribues.
85    /// </summary>
86    /// <value>The assembly attribues.</value>
87    [Storable]
88    public Dictionary<string, string> AssemblyAttribues { get; internal set; }
89
90    /// <summary>
91    /// Gets or sets a value indicating whether this instance is reference.
92    /// </summary>
93    /// <value>
94    ///   <c>true</c> if this instance is reference; otherwise, <c>false</c>.
95    /// </value>
96    [Storable]
97    public bool IsReference { get; internal set; }
98
99
100
101    /// <summary>
102    /// Initializes a new instance of the <see cref="TypeName"/> class.
103    /// </summary>
104    /// <param name="nameSpace">The namespace.</param>
105    /// <param name="className">Name of the class.</param>
106    internal TypeName(string nameSpace, string className) {
107      Namespace = nameSpace;
108      ClassName = className;
109      GenericArgs = new List<TypeName>();
110      MemoryMagic = "";
111      AssemblyAttribues = new Dictionary<string, string>();
112    }
113
114
115    /// <summary>
116    /// Returns a <see cref="System.String"/> that represents this instance.
117    /// </summary>
118    /// <param name="full">if set to <c>true</c> includes full information
119    /// about generic parameters and assembly properties.</param>
120    /// <returns>
121    /// A <see cref="System.String"/> that represents this instance.
122    /// </returns>
123    public string ToString(bool full) {
124      return ToString(full, true);
125    }
126
127
128    /// <summary>
129    /// Returns a <see cref="System.String"/> that represents this instance.
130    /// </summary>
131    /// <param name="full">if set to <c>true</c> includes full information
132    /// about generic parameters and assembly properties.</param>
133    /// <param name="includeAssembly">if set to <c>true</c> include assembly properties and generic parameters.</param>
134    /// <returns>
135    /// A <see cref="System.String"/> that represents this instance.
136    /// </returns>
137    public string ToString(bool full, bool includeAssembly) {     
138      StringBuilder sb = new StringBuilder();
139      if (!string.IsNullOrEmpty(Namespace))
140        sb.Append(Namespace).Append('.');
141      sb.Append(ClassName);
142      if (IsGeneric) {
143        sb.Append('`').Append(GenericArgs.Count).Append('[');
144        bool first = true;
145        foreach (TypeName t in GenericArgs) {
146          if (first)
147            first = false;
148          else
149            sb.Append(',');
150          sb.Append('[').Append(t.ToString(full)).Append(']');
151        }
152        sb.Append(']');
153      }
154      sb.Append(MemoryMagic);
155      if (includeAssembly && AssemblyName != null) {
156        sb.Append(", ").Append(AssemblyName);
157        if (full)
158          foreach (var property in AssemblyAttribues)
159            sb.Append(", ").Append(property.Key).Append('=').Append(property.Value);
160      }
161      return sb.ToString();
162    }
163
164    public string GetTypeNameInCode(HashSet<string> omitNamespaces) {
165      StringBuilder sb = new StringBuilder();
166      if (!string.IsNullOrEmpty(Namespace) && omitNamespaces == null || !omitNamespaces.Contains(Namespace))
167        sb.Append(Namespace).Append('.');
168      sb.Append(ClassName);
169      if (IsGeneric) {
170        sb.Append("<");
171        sb.Append(
172          string.Join(", ",
173            GenericArgs
174              .Select(a => a.GetTypeNameInCode(omitNamespaces))
175              .ToArray()));
176        sb.Append(">");
177      }
178      sb.Append(MemoryMagic);
179      return sb.ToString();
180    }
181
182    public string GetTypeNameInCode(bool includeAllNamespaces) {
183      StringBuilder sb = new StringBuilder();
184      if (includeAllNamespaces)
185        sb.Append(Namespace).Append('.');
186      sb.Append(ClassName);
187      if (IsGeneric) {
188        sb.Append("<");
189        sb.Append(
190          string.Join(", ",
191            GenericArgs
192              .Select(a => a.GetTypeNameInCode(includeAllNamespaces))
193              .ToArray()));
194        sb.Append(">");
195      }
196      sb.Append(MemoryMagic);
197      return sb.ToString();
198    }
199
200
201    /// <summary>
202    /// Returns a <see cref="System.String"/> that represents this instance.
203    /// </summary>
204    /// <returns>
205    /// A <see cref="System.String"/> that represents this instance.
206    /// </returns>
207    public override string ToString() {
208      return ToString(true);
209    }
210
211
212    /// <summary>
213    /// Lexicographically compare version information and make sure type and assembly
214    /// names are identical. This function recursively checks generic type arguments.
215    /// </summary>
216    /// <param name="typeName">Name of the type.</param>
217    /// <returns>
218    ///   <c>true</c> if is newer than the specified type name; otherwise, <c>false</c>.
219    /// </returns>
220    public bool IsNewerThan(TypeName typeName) {
221      try {
222        if (this.ClassName != typeName.ClassName ||
223          this.Namespace != typeName.Namespace ||
224          this.AssemblyName != typeName.AssemblyName)
225          throw new Exception("Cannot compare versions of different types");
226        if (CompareVersions(
227          this.AssemblyAttribues["Version"],
228          typeName.AssemblyAttribues["Version"]) > 0)
229          return true;
230        IEnumerator<TypeName> thisIt = this.GenericArgs.GetEnumerator();
231        IEnumerator<TypeName> tIt = typeName.GenericArgs.GetEnumerator();
232        while (thisIt.MoveNext()) {
233          tIt.MoveNext();
234          if (thisIt.Current.IsNewerThan(tIt.Current))
235            return true;
236        }
237        return false;
238      } catch (KeyNotFoundException) {
239        throw new Exception("Could not extract version information from type string");
240      }
241    }
242
243
244    /// <summary>
245    /// Make sure major and minor version number are identical. This function
246    /// recursively checks generic type arguments.
247    /// </summary>
248    /// <param name="typeName">Name of the type.</param>
249    /// <returns>
250    ///   <c>true</c> if the specified type names are compatible; otherwise, <c>false</c>.
251    /// </returns>
252    public bool IsCompatible(TypeName typeName) {
253      try {
254        if (this.ClassName != typeName.ClassName ||
255          this.Namespace != typeName.Namespace ||
256          this.AssemblyName != typeName.AssemblyName)
257          throw new Exception("Cannot compare versions of different types");
258        Version thisVersion = new Version(this.AssemblyAttribues["Version"]);
259        Version tVersion = new Version(typeName.AssemblyAttribues["Version"]);
260        if (thisVersion.Major != tVersion.Major ||
261          thisVersion.Minor != tVersion.Minor)
262          return false;
263        IEnumerator<TypeName> thisIt = this.GenericArgs.GetEnumerator();
264        IEnumerator<TypeName> tIt = typeName.GenericArgs.GetEnumerator();
265        while (thisIt.MoveNext()) {
266          tIt.MoveNext();
267          if (!thisIt.Current.IsCompatible(tIt.Current))
268            return false;
269        }
270        return true;
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.