Changeset 8641 for trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary
- Timestamp:
- 09/13/12 11:49:29 (12 years ago)
- Location:
- trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary
- Files:
-
- 1 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/TypeLoader.cs
r7259 r8641 26 26 27 27 namespace 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 } 28 44 29 internal class TypeLoader { 30 31 public static Type Load(string typeNameString) { 45 private static Type LoadInternal(string typeNameString) { 32 46 Type type; 33 47 try { 34 48 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 35 57 } 36 58 catch (Exception) { 37 59 Logger.Warn(String.Format( 38 60 "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); 76 63 } 77 64 return type; 78 65 } 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 79 140 } 80 141 } -
trunk/sources/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs
r7259 r8641 41 41 /// <value>The namespace.</value> 42 42 [Storable] 43 public string Namespace { get; private set; } 43 #region Mono Compatibility 44 // mono: setting the namespace is needed for generating ObjectEqualityComparer type names in the TypeLoader 45 public string Namespace { get; internal set; } 46 #endregion 44 47 45 48 /// <summary> … … 48 51 /// <value>The name of the class.</value> 49 52 [Storable] 50 public string ClassName { get; private set; } 53 #region Mono Compatibility 54 public string ClassName { get; internal set; } 55 #endregion 51 56 52 57 /// <summary> … … 235 240 } 236 241 return false; 237 } catch (KeyNotFoundException) { 242 } 243 catch (KeyNotFoundException) { 238 244 throw new Exception("Could not extract version information from type string"); 239 245 } … … 272 278 } 273 279 return true; 274 } catch (KeyNotFoundException) { 280 } 281 catch (KeyNotFoundException) { 275 282 throw new Exception("Could not extract version infomration from type string"); 276 283 }
Note: See TracChangeset
for help on using the changeset viewer.