Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
09/13/12 11:49:29 (10 years ago)
Author:
ascheibe
Message:

#1952 (#1937) added Mono support to persistence

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/TypeLoader.cs

    r7259 r8641  
    2626
    2727namespace HeuristicLab.Persistence.Auxiliary {
     28  internal class TypeLoader {
     29    public static Type Load(string typeNameString) {
     30      try {
     31        // try to load type normally
     32        return LoadInternal(typeNameString);
     33      }
     34      catch (PersistenceException) {
     35        #region Mono Compatibility
     36        // if that fails, try to load Mono type
     37        string monoTypeNameString = GetMonoType(typeNameString);
     38        Logger.Info(String.Format(@"Trying to load Mono type ""{0}"" instead of type ""{1}""",
     39                                  monoTypeNameString, typeNameString));
     40        return LoadInternal(monoTypeNameString);
     41      }
     42        #endregion
     43    }
    2844
    29   internal class TypeLoader {
    30 
    31     public static Type Load(string typeNameString) {
     45    private static Type LoadInternal(string typeNameString) {
    3246      Type type;
    3347      try {
    3448        type = Type.GetType(typeNameString, true);
     49        #region Mono Compatibility
     50        // mono: workaround until Mono bug #580 (http://bugzilla.xamarin.com/show_bug.cgi?id=580) is fixed
     51        if (type.AssemblyQualifiedName != typeNameString)
     52          throw new TypeLoadException(
     53            String.Format(
     54            @"Could not load requested type ""{0}"", loaded ""{1}"" instead.",
     55            typeNameString, type.AssemblyQualifiedName));
     56        #endregion
    3557      }
    3658      catch (Exception) {
    3759        Logger.Warn(String.Format(
    3860          "Cannot load type \"{0}\", falling back to partial name", typeNameString));
    39         try {
    40           TypeName typeName = TypeNameParser.Parse(typeNameString);
    41 #pragma warning disable 0618
    42           Assembly a = Assembly.LoadWithPartialName(typeName.AssemblyName);
    43           // the suggested Assembly.Load() method fails to load assemblies outside the GAC
    44 #pragma warning restore 0618
    45           type = a.GetType(typeName.ToString(false, false), true);
    46         }
    47         catch (Exception) {
    48           throw new PersistenceException(String.Format(
    49             "Could not load type \"{0}\"",
    50             typeNameString));
    51         }
    52         try {
    53           TypeName requestedTypeName = TypeNameParser.Parse(typeNameString);
    54           TypeName loadedTypeName = TypeNameParser.Parse(type.AssemblyQualifiedName);
    55           if (!requestedTypeName.IsCompatible(loadedTypeName))
    56             throw new PersistenceException(String.Format(
    57               "Serialized type is incompatible with available type: serialized: {0}, loaded: {1}",
    58               typeNameString,
    59               type.AssemblyQualifiedName));
    60           if (requestedTypeName.IsNewerThan(loadedTypeName))
    61             throw new PersistenceException(String.Format(
    62               "Serialized type is newer than available type: serialized: {0}, loaded: {1}",
    63               typeNameString,
    64               type.AssemblyQualifiedName));
    65         }
    66         catch (PersistenceException) {
    67           throw;
    68         }
    69         catch (Exception e) {
    70           Logger.Warn(String.Format(
    71             "Could not perform version check requested type was {0} while loaded type is {1}:",
    72             typeNameString,
    73             type.AssemblyQualifiedName),
    74             e);
    75         }
     61        type = LoadWithPartialName(typeNameString);
     62        CheckCompatibility(typeNameString, type);
    7663      }
    7764      return type;
    7865    }
     66
     67    private static Type LoadWithPartialName(string typeNameString) {
     68      try {
     69        TypeName typeName = TypeNameParser.Parse(typeNameString);
     70#pragma warning disable 0618
     71        Assembly a = Assembly.LoadWithPartialName(typeName.AssemblyName);
     72        // the suggested Assembly.Load() method fails to load assemblies outside the GAC
     73#pragma warning restore 0618
     74        return a.GetType(typeName.ToString(false, false), true);
     75      }
     76      catch (Exception) {
     77        throw new PersistenceException(String.Format(
     78          "Could not load type \"{0}\"",
     79          typeNameString));
     80      }
     81    }
     82
     83    private static void CheckCompatibility(string typeNameString, Type type) {
     84      try {
     85        TypeName requestedTypeName = TypeNameParser.Parse(typeNameString);
     86        TypeName loadedTypeName = TypeNameParser.Parse(type.AssemblyQualifiedName);
     87        if (!requestedTypeName.IsCompatible(loadedTypeName))
     88          throw new PersistenceException(String.Format(
     89            "Serialized type is incompatible with available type: serialized: {0}, loaded: {1}",
     90            typeNameString,
     91            type.AssemblyQualifiedName));
     92        if (requestedTypeName.IsNewerThan(loadedTypeName))
     93          throw new PersistenceException(String.Format(
     94            "Serialized type is newer than available type: serialized: {0}, loaded: {1}",
     95            typeNameString,
     96            type.AssemblyQualifiedName));
     97      }
     98      catch (PersistenceException) {
     99        throw;
     100      }
     101      catch (Exception e) {
     102        Logger.Warn(String.Format(
     103          "Could not perform version check requested type was {0} while loaded type is {1}:",
     104          typeNameString,
     105          type.AssemblyQualifiedName),
     106                    e);
     107      }
     108    }
     109
     110    #region Mono Compatibility
     111    /// <summary>
     112    /// Returns the corresponding type for the Mono runtime
     113    /// </summary>
     114    /// <returns>
     115    /// The remapped typeNameString, or the original string if no mapping was found
     116    /// </returns>
     117    private static string GetMonoType(string typeNameString) {
     118      TypeName typeName = TypeNameParser.Parse(typeNameString);
     119
     120      // map System.RuntimeType to System.MonoType
     121      if (typeName.Namespace == "System" && typeName.ClassName == "RuntimeType") {
     122        // we use Int32 here because we get all the information about Mono's mscorlib and just have to change the class name
     123        typeName = TypeNameParser.Parse(typeof(System.Int32).AssemblyQualifiedName);
     124        typeName.ClassName = "MonoType";
     125      } else if (typeName.Namespace == "System.Collections.Generic" && typeName.ClassName == "ObjectEqualityComparer") {
     126        // map System.Collections.Generic.ObjectEqualityComparer to HeuristicLab.Mono.ObjectEqualityComparer       
     127        // we need the information about the Persistence assembly, so we use TypeName here because it is contained in this assembly
     128        TypeName oecInfo = TypeNameParser.Parse(typeof(TypeName).AssemblyQualifiedName);
     129        typeName.Namespace = "HeuristicLab.Persistence.Mono";
     130        typeName.AssemblyName = oecInfo.AssemblyName;
     131        typeName.AssemblyAttribues.Clear();
     132        typeName.AssemblyAttribues["Version"] = oecInfo.AssemblyAttribues["Version"];
     133        typeName.AssemblyAttribues["Culture"] = oecInfo.AssemblyAttribues["Culture"];
     134        typeName.AssemblyAttribues["PublicKeyToken"] = oecInfo.AssemblyAttribues["PublicKeyToken"];
     135      }
     136
     137      return typeName.ToString(true, true);
     138    }
     139    #endregion
    79140  }
    80141}
Note: See TracChangeset for help on using the changeset viewer.