Index: /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/ObjectEqualityComparer.cs
===================================================================
--- /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/ObjectEqualityComparer.cs (revision 8500)
+++ /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/ObjectEqualityComparer.cs (revision 8500)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see .
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Persistence.Mono {
+
+ //work around mono's missing ObjectEqualityComparer
+ [Serializable]
+ public class ObjectEqualityComparer : EqualityComparer {
+ public override int GetHashCode(T obj) {
+ return EqualityComparer.Default.GetHashCode(obj);
+ }
+ public override bool Equals(T a, T b) {
+ return EqualityComparer.Default.Equals(a, b);
+ }
+ }
+}
+
Index: /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeLoader.cs
===================================================================
--- /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeLoader.cs (revision 8499)
+++ /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeLoader.cs (revision 8500)
@@ -26,55 +26,113 @@
namespace HeuristicLab.Persistence.Auxiliary {
-
- internal class TypeLoader {
-
- public static Type Load(string typeNameString) {
- Type type;
- try {
- type = Type.GetType(typeNameString, true);
- }
- catch (Exception) {
- Logger.Warn(String.Format(
- "Cannot load type \"{0}\", falling back to partial name", typeNameString));
- try {
- TypeName typeName = TypeNameParser.Parse(typeNameString);
+
+ internal class TypeLoader {
+
+ public static Type Load(string typeNameString) {
+ try {
+ // try to load type normally
+ return LoadInternal(typeNameString);
+ } catch (PersistenceException) {
+ // if that fails, try to load mono type
+ string monoTypeNameString = GetMonoType(typeNameString);
+ Logger.Info(String.Format(@"Trying to load Mono type ""{0}"" instead of type ""{1}""",
+ monoTypeNameString, typeNameString));
+ return LoadInternal(monoTypeNameString);
+ }
+ }
+
+ private static Type LoadInternal(string typeNameString) {
+ Type type;
+ try {
+ type = Type.GetType(typeNameString, true);
+ // TODO: workaround until [mono bug #580](http://bugzilla.xamarin.com/show_bug.cgi?id=580) is fixed
+ if(type.AssemblyQualifiedName != typeNameString)
+ throw new TypeLoadException(
+ String.Format(
+ @"Could not load requested type ""{0}"", loaded ""{1}"" instead.",
+ typeNameString, type.AssemblyQualifiedName));
+ }
+ catch (Exception) {
+ Logger.Warn(String.Format(
+ "Cannot load type \"{0}\", falling back to partial name", typeNameString));
+ type = LoadWithPartialName(typeNameString);
+ CheckCompatibility(typeNameString, type);
+ }
+ return type;
+ }
+
+ private static Type LoadWithPartialName(string typeNameString) {
+ try {
+ TypeName typeName = TypeNameParser.Parse(typeNameString);
#pragma warning disable 0618
- Assembly a = Assembly.LoadWithPartialName(typeName.AssemblyName);
- // the suggested Assembly.Load() method fails to load assemblies outside the GAC
+ Assembly a = Assembly.LoadWithPartialName(typeName.AssemblyName);
+ // the suggested Assembly.Load() method fails to load assemblies outside the GAC
#pragma warning restore 0618
- type = a.GetType(typeName.ToString(false, false), true);
- }
- catch (Exception) {
- throw new PersistenceException(String.Format(
- "Could not load type \"{0}\"",
- typeNameString));
- }
- try {
- TypeName requestedTypeName = TypeNameParser.Parse(typeNameString);
- TypeName loadedTypeName = TypeNameParser.Parse(type.AssemblyQualifiedName);
- if (!requestedTypeName.IsCompatible(loadedTypeName))
- throw new PersistenceException(String.Format(
- "Serialized type is incompatible with available type: serialized: {0}, loaded: {1}",
- typeNameString,
- type.AssemblyQualifiedName));
- if (requestedTypeName.IsNewerThan(loadedTypeName))
- throw new PersistenceException(String.Format(
- "Serialized type is newer than available type: serialized: {0}, loaded: {1}",
- typeNameString,
- type.AssemblyQualifiedName));
- }
- catch (PersistenceException) {
- throw;
- }
- catch (Exception e) {
- Logger.Warn(String.Format(
- "Could not perform version check requested type was {0} while loaded type is {1}:",
- typeNameString,
- type.AssemblyQualifiedName),
- e);
- }
- }
- return type;
- }
- }
+ return a.GetType(typeName.ToString(false, false), true);
+ }
+ catch (Exception) {
+ throw new PersistenceException(String.Format(
+ "Could not load type \"{0}\"",
+ typeNameString));
+ }
+ }
+
+ private static void CheckCompatibility(string typeNameString, Type type) {
+ try {
+ TypeName requestedTypeName = TypeNameParser.Parse(typeNameString);
+ TypeName loadedTypeName = TypeNameParser.Parse(type.AssemblyQualifiedName);
+ if (!requestedTypeName.IsCompatible(loadedTypeName))
+ throw new PersistenceException(String.Format(
+ "Serialized type is incompatible with available type: serialized: {0}, loaded: {1}",
+ typeNameString,
+ type.AssemblyQualifiedName));
+ if (requestedTypeName.IsNewerThan(loadedTypeName))
+ throw new PersistenceException(String.Format(
+ "Serialized type is newer than available type: serialized: {0}, loaded: {1}",
+ typeNameString,
+ type.AssemblyQualifiedName));
+ }
+ catch (PersistenceException) {
+ throw;
+ }
+ catch (Exception e) {
+ Logger.Warn(String.Format(
+ "Could not perform version check requested type was {0} while loaded type is {1}:",
+ typeNameString,
+ type.AssemblyQualifiedName),
+ e);
+ }
+ }
+
+ ///
+ /// Returns the corresponding type for the Mono runtime
+ ///
+ ///
+ /// The remapped typeNameString, or the original string if no mapping was found
+ ///
+ ///
+ /// Type name string.
+ ///
+ private static string GetMonoType(string typeNameString) {
+ TypeName typeName = TypeNameParser.Parse(typeNameString);
+
+ // map System.RuntimeType to System.MonoType
+ if(typeName.Namespace == "System" && typeName.ClassName == "RuntimeType") {
+ //TODO: use preprocessor and __MonoCS__
+ typeName = TypeNameParser.Parse("System.MonoType, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
+ } else
+ // map System.Collections.Generic.ObjectEqualityComparer to HeuristicLab.Mono.ObjectEqualityComparer
+ if(typeName.Namespace == "System.Collections.Generic" && typeName.ClassName == "ObjectEqualityComparer") {
+ TypeName oecInfo = TypeNameParser.Parse(typeof(TypeName).AssemblyQualifiedName);
+ typeName.Namespace = "HeuristicLab.Persistence.Mono";
+ typeName.AssemblyName = oecInfo.AssemblyName;
+ typeName.AssemblyAttribues.Clear();
+ typeName.AssemblyAttribues["Version"] = oecInfo.AssemblyAttribues["Version"];
+ typeName.AssemblyAttribues["Culture"] = oecInfo.AssemblyAttribues["Culture"];
+ typeName.AssemblyAttribues["PublicKeyToken"] = oecInfo.AssemblyAttribues["PublicKeyToken"];
+ }
+
+ return typeName.ToString(true, true);
+ }
+ }
}
Index: /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs
===================================================================
--- /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs (revision 8499)
+++ /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Auxiliary/TypeName.cs (revision 8500)
@@ -41,5 +41,5 @@
/// The namespace.
[Storable]
- public string Namespace { get; private set; }
+ public string Namespace { get; internal set; }
///
Index: /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs
===================================================================
--- /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs (revision 8499)
+++ /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/Default/CompositeSerializers/TypeSerializer.cs (revision 8500)
@@ -40,11 +40,12 @@
}
- public bool CanSerialize(Type type) {
- return type == typeof(Type) ||
- type.VersionInvariantName() == "System.RuntimeType, mscorlib";
- }
+ public bool CanSerialize(Type type) {
+ return type == typeof(Type) ||
+ type.VersionInvariantName() == "System.RuntimeType, mscorlib" ||
+ type.VersionInvariantName() == "System.MonoType, mscorlib";
+ }
public string JustifyRejection(Type type) {
- return "not System.Type nor System.RuntimeType";
+ return "not System.Type, System.RuntimeType nor System.MonoType";
}
Index: /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj (revision 8499)
+++ /branches/HeuristicLab.Mono/HeuristicLab.Persistence/3.3/HeuristicLab.Persistence-3.3.csproj (revision 8500)
@@ -129,4 +129,5 @@
+