Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
08/18/12 21:21:30 (12 years ago)
Author:
ascheibe
Message:

#1861 applied persistence patches

Location:
branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeLoader.cs

    r7259 r8500  
    2626
    2727namespace HeuristicLab.Persistence.Auxiliary {
    28 
    29   internal class TypeLoader {
    30 
    31     public static Type Load(string typeNameString) {
    32       Type type;
    33       try {
    34         type = Type.GetType(typeNameString, true);
    35       }
    36       catch (Exception) {
    37         Logger.Warn(String.Format(
    38           "Cannot load type \"{0}\", falling back to partial name", typeNameString));
    39         try {
    40           TypeName typeName = TypeNameParser.Parse(typeNameString);
     28 
     29  internal class TypeLoader {
     30   
     31    public static Type Load(string typeNameString) {
     32      try {
     33        // try to load type normally
     34        return LoadInternal(typeNameString);
     35      } catch (PersistenceException) {
     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    }
     43   
     44    private static Type LoadInternal(string typeNameString) {
     45      Type type;
     46      try {
     47        type = Type.GetType(typeNameString, true);
     48        // TODO: workaround until [mono bug #580](http://bugzilla.xamarin.com/show_bug.cgi?id=580) is fixed
     49        if(type.AssemblyQualifiedName != typeNameString)
     50          throw new TypeLoadException(
     51            String.Format(
     52            @"Could not load requested type ""{0}"", loaded ""{1}"" instead.",
     53            typeNameString, type.AssemblyQualifiedName));
     54      }
     55      catch (Exception) {
     56        Logger.Warn(String.Format(
     57          "Cannot load type \"{0}\", falling back to partial name", typeNameString));
     58        type = LoadWithPartialName(typeNameString);
     59        CheckCompatibility(typeNameString, type);
     60      }
     61      return type;
     62    }
     63   
     64    private static Type LoadWithPartialName(string typeNameString) {
     65      try {
     66        TypeName typeName = TypeNameParser.Parse(typeNameString);
    4167#pragma warning disable 0618
    42           Assembly a = Assembly.LoadWithPartialName(typeName.AssemblyName);
    43           // the suggested Assembly.Load() method fails to load assemblies outside the GAC
     68        Assembly a = Assembly.LoadWithPartialName(typeName.AssemblyName);
     69        // the suggested Assembly.Load() method fails to load assemblies outside the GAC
    4470#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         }
    76       }
    77       return type;
    78     }
    79   }
     71        return a.GetType(typeName.ToString(false, false), true);
     72      }
     73      catch (Exception) {
     74        throw new PersistenceException(String.Format(
     75          "Could not load type \"{0}\"",
     76          typeNameString));
     77      }
     78    }
     79   
     80    private static void CheckCompatibility(string typeNameString, Type type) {
     81      try {
     82        TypeName requestedTypeName = TypeNameParser.Parse(typeNameString);
     83        TypeName loadedTypeName = TypeNameParser.Parse(type.AssemblyQualifiedName);
     84        if (!requestedTypeName.IsCompatible(loadedTypeName))
     85          throw new PersistenceException(String.Format(
     86            "Serialized type is incompatible with available type: serialized: {0}, loaded: {1}",
     87            typeNameString,
     88            type.AssemblyQualifiedName));
     89        if (requestedTypeName.IsNewerThan(loadedTypeName))
     90          throw new PersistenceException(String.Format(
     91            "Serialized type is newer than available type: serialized: {0}, loaded: {1}",
     92            typeNameString,
     93            type.AssemblyQualifiedName));
     94      }
     95      catch (PersistenceException) {
     96        throw;
     97      }
     98      catch (Exception e) {
     99        Logger.Warn(String.Format(
     100          "Could not perform version check requested type was {0} while loaded type is {1}:",
     101          typeNameString,
     102          type.AssemblyQualifiedName),
     103                    e);
     104      }
     105    }
     106   
     107    /// <summary>
     108    /// Returns the corresponding type for the Mono runtime
     109    /// </summary>
     110    /// <returns>
     111    /// The remapped typeNameString, or the original string if no mapping was found
     112    /// </returns>
     113    /// <param name='typeNameString'>
     114    /// Type name string.
     115    /// </param>
     116    private static string GetMonoType(string typeNameString) {
     117      TypeName typeName = TypeNameParser.Parse(typeNameString);
     118     
     119      // map System.RuntimeType to System.MonoType
     120      if(typeName.Namespace == "System" && typeName.ClassName == "RuntimeType") {
     121        //TODO: use preprocessor and __MonoCS__
     122        typeName = TypeNameParser.Parse("System.MonoType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
     123      } else
     124        // map System.Collections.Generic.ObjectEqualityComparer to HeuristicLab.Mono.ObjectEqualityComparer
     125      if(typeName.Namespace == "System.Collections.Generic" && typeName.ClassName == "ObjectEqualityComparer") {
     126        TypeName oecInfo = TypeNameParser.Parse(typeof(TypeName).AssemblyQualifiedName);
     127        typeName.Namespace = "HeuristicLab.Persistence.Mono";
     128        typeName.AssemblyName = oecInfo.AssemblyName;
     129        typeName.AssemblyAttribues.Clear();
     130        typeName.AssemblyAttribues["Version"] = oecInfo.AssemblyAttribues["Version"];
     131        typeName.AssemblyAttribues["Culture"] = oecInfo.AssemblyAttribues["Culture"];
     132        typeName.AssemblyAttribues["PublicKeyToken"] = oecInfo.AssemblyAttribues["PublicKeyToken"];
     133      }
     134     
     135      return typeName.ToString(true, true);
     136    }
     137  }
    80138}
  • branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs

    r7259 r8500  
    4141    /// <value>The namespace.</value>
    4242    [Storable]
    43     public string Namespace { get; private set; }
     43    public string Namespace { get; internal set; }
    4444
    4545    /// <summary>
  • branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs

    r7259 r8500  
    4040    }
    4141
    42     public bool CanSerialize(Type type) {
    43       return type == typeof(Type) ||
    44              type.VersionInvariantName() == "System.RuntimeType, mscorlib";
    45     }
     42  public bool CanSerialize(Type type) {
     43    return type == typeof(Type) ||
     44      type.VersionInvariantName() == "System.RuntimeType, mscorlib" ||
     45      type.VersionInvariantName() == "System.MonoType, mscorlib";
     46  }
    4647
    4748    public string JustifyRejection(Type type) {
    48       return "not System.Type nor System.RuntimeType";
     49    return "not System.Type, System.RuntimeType nor System.MonoType";
    4950    }
    5051
  • branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj

    r8440 r8500  
    129129    <Compile Include="Auxiliary\TypeNameParser.cs" />
    130130    <Compile Include="Auxiliary\ReflectionTools.cs" />
     131    <Compile Include="Auxiliary\ObjectEqualityComparer.cs" />
    131132    <None Include="Plugin.cs.frame" />
    132133    <Compile Include="Core\Configuration.cs" />
Note: See TracChangeset for help on using the changeset viewer.