Пример #1
1
 protected OperatorGraph(OperatorGraph original, Cloner cloner)
   : base(original, cloner) {
   operators = cloner.Clone(original.operators);
   initialOperator = cloner.Clone(original.initialOperator);
   visualizationInfo = cloner.Clone(original.visualizationInfo);
   Initialize();
 }
Пример #2
0
        public void TestCloningAllDeepCloneables()
        {
            PluginLoader.Assemblies.ToArray();
              bool success = true;
              foreach (Type deepCloneableType in ApplicationManager.Manager.GetTypes(typeof(IDeepCloneable))) {
            // skip types that explicitely choose not to deep-clone every member
            if (excludedTypes.Contains(deepCloneableType)) continue;
            // test only types contained in HL plugin assemblies
            if (!PluginLoader.Assemblies.Contains(deepCloneableType.Assembly)) continue;
            // test only instantiable types
            if (deepCloneableType.IsAbstract || !deepCloneableType.IsClass) continue;

            IDeepCloneable item = null;
            try {
              item = (IDeepCloneable)Activator.CreateInstance(deepCloneableType, nonPublic: false);
            } catch { continue; } // no default constructor

            IDeepCloneable clone = null;
            try {
              clone = (IDeepCloneable)item.Clone(new Cloner());
            } catch (Exception e) {
              TestContext.WriteLine(Environment.NewLine + deepCloneableType.FullName + ":");
              TestContext.WriteLine("ERROR! " + e.GetType().Name + @" was thrown during cloning.
            All IDeepCloneable items with a default constructor should be cloneable when using that constructor!");
              success = false;
              continue;
            }
            var intersections = CheckTotalInequality(item, clone).Where(x => x.GetType().FullName.StartsWith("HeuristicLab"));
            if (!intersections.Any()) continue;

            if (!ProcessEqualObjects(item, intersections))
              success = false;
              }
              Assert.IsTrue(success, "There are potential errors in deep cloning objects.");
        }
Пример #3
0
        private bool ProcessEqualObjects(IDeepCloneable item, IEnumerable<object> intersections)
        {
            bool success = true;
              bool headerWritten = false;

              foreach (object o in intersections) {
            string typeName = o.GetType().FullName;
            if (excludedTypes.Contains(o.GetType())) {
              //TestContext.WriteLine("Skipping excluded type " + typeName);
            } else if (o is IDeepCloneable) {
              string info = (o is IItem) ? ((IItem)o).ItemName + ((o is INamedItem) ? ", " + ((INamedItem)o).Name : String.Empty) : String.Empty;
              if (!headerWritten) {
            TestContext.WriteLine(Environment.NewLine + item.GetType().FullName + ":");
            headerWritten = true;
              }
              TestContext.WriteLine("POTENTIAL ERROR! A DEEPCLONEABLE WAS NOT DEEP CLONED (" + info + "): " + typeName);
              success = false;
            } else {
              Array array = o as Array;
              if (array != null && array.Length == 0) continue; //arrays of length 0 are used inside empty collections
              if (!headerWritten) {
            TestContext.WriteLine(Environment.NewLine + item.GetType().FullName + ":");
            headerWritten = true;
              }
              TestContext.WriteLine("WARNING: An object of type " + typeName + " is referenced in the original and in the clone.");
            }
              }
              return success;
        }
Пример #4
0
 /// <summary>
 /// Initializes a new instance of <see cref="OperatorGraph"/>.
 /// </summary>
 public OperatorGraph()
 {
     operators         = new OperatorSet();
     initialOperator   = null;
     visualizationInfo = null;
     Initialize();
 }
Пример #5
0
        /// <summary>
        /// Returns the clone of an deeply cloned item, if it was already cloned.
        /// </summary>
        /// <param name="original">The original object.</param>
        /// <returns>The clone of the given object, if it was already cloned; null otherwise</returns>
        public IDeepCloneable GetClone(IDeepCloneable original)
        {
            IDeepCloneable clone = null;

            mapping.TryGetValue(original, out clone);
            return(clone);
        }
Пример #6
0
        /// <summary>
        /// Creates a deep clone of this repeated field.
        /// </summary>
        /// <remarks>
        /// If the field type is
        /// a message type, each element is also cloned; otherwise, it is
        /// assumed that the field type is primitive (including string and
        /// bytes, both of which are immutable) and so a simple copy is
        /// equivalent to a deep clone.
        /// </remarks>
        /// <returns>A deep clone of this repeated field.</returns>
        public RepeatedField <T> Clone()
        {
            int len = Count;

            if (len > 0)
            {
                bool isDeepCloner       = base[0] is IDeepCloneable <T>;
                RepeatedField <T> clone = new RepeatedField <T>(len);
                if (isDeepCloner)
                {
                    for (int i = 0; i < len; i++)
                    {
                        IDeepCloneable <T> item = base[i] as IDeepCloneable <T>;
                        if (item != null)
                        {
                            clone.Add(item.Clone());
                        }
                        else
                        {
                            clone.Add(base[i]);
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < len; i++)
                    {
                        clone.Add(base[i]);
                    }
                }
                return(clone);
            }

            return(new RepeatedField <T>());
        }
Пример #7
0
    public T Get()
    {
        var path = GetPath();
        //Console.WriteLine(string.Join(",", path));
        object container = this;

        for (int i = 0; i < path.Count; ++i)
        {
            if (i < path.Count - 1)
            {
                container = container
                            .GetType()
                            .GetField(path[i], BindingFlags.Instance | BindingFlags.NonPublic)
                            .GetValue(container);
            }
            else
            {
                T value = (T)container
                          .GetType()
                          .GetField(path[i], BindingFlags.Instance | BindingFlags.NonPublic)
                          .GetValue(container);
                IDeepCloneable <T> cloneable = value as IDeepCloneable <T>;
                if (cloneable == null)
                {
                    return(value);
                }
                return(cloneable.Clone());
            }
        }
        throw new Exception("Something went wrong");
    }
Пример #8
0
 protected OperatorGraph(OperatorGraph original, Cloner cloner)
     : base(original, cloner)
 {
     operators         = cloner.Clone(original.operators);
     initialOperator   = cloner.Clone(original.initialOperator);
     visualizationInfo = cloner.Clone(original.visualizationInfo);
     Initialize();
 }
        public IDeepCloneable Clone(IDeepCloneable obj)
        {
            if (obj == null)
            {
                return(null);
            }
            IDeepCloneable clone;

            if (cache.TryGetValue(obj, out clone))
            {
                return(clone);
            }
            else
            {
                return(obj.Clone(this));
            }
        }
Пример #10
0
        protected Constraint(Constraint original, Cloner cloner)
            : base(original, cloner)
        {
            constrainedValue = null; //mkommend: intentionally set to null;

            IDeepCloneable constraintDataDeepCloneable = original.constraintData as IDeepCloneable;
            ICloneable     constraintDataCloneable     = original.constraintData as ICloneable;

            if (constraintDataDeepCloneable != null)
            {
                constraintData = cloner.Clone(constraintDataDeepCloneable);
            }
            else if (constraintDataCloneable != null)
            {
                constraintData = constraintDataCloneable.Clone();
            }
            else
            {
                constraintData = original.constraintData;
            }

            constraintOperation = original.constraintOperation;
        }
 public void RegisterClonedObject(IDeepCloneable original, IDeepCloneable clone)
 {
     cache.Add(original, clone);
 }
Пример #12
0
        /// <summary>
        /// Used to deep clone any reference properties on the object (should be done after a MemberwiseClone for which the outcome is 'output')
        /// </summary>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <returns></returns>
        public static void DeepCloneRefProperties(IDeepCloneable input, IDeepCloneable output)
        {
            var inputType  = input.GetType();
            var outputType = output.GetType();

            if (inputType != outputType)
            {
                throw new InvalidOperationException("Both the input and output types must be the same");
            }

            //get the property metadata from cache so we only have to figure this out once per type
            var refProperties = PropCache.GetOrAdd(inputType, type =>
                                                   inputType.GetProperties()
                                                   .Select <PropertyInfo, ClonePropertyInfo?>(propertyInfo =>
            {
                if (
                    //is not attributed with the ignore clone attribute
                    propertyInfo.GetCustomAttribute <DoNotCloneAttribute>() != null
                    //reference type but not string
                    || propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType == typeof(string)
                    //settable
                    || propertyInfo.CanWrite == false
                    //non-indexed
                    || propertyInfo.GetIndexParameters().Any())
                {
                    return(null);
                }


                if (TypeHelper.IsTypeAssignableFrom <IDeepCloneable>(propertyInfo.PropertyType))
                {
                    return(new ClonePropertyInfo(propertyInfo)
                    {
                        IsDeepCloneable = true
                    });
                }

                if (TypeHelper.IsTypeAssignableFrom <IEnumerable>(propertyInfo.PropertyType) &&
                    TypeHelper.IsTypeAssignableFrom <string>(propertyInfo.PropertyType) == false)
                {
                    if (propertyInfo.PropertyType.IsGenericType &&
                        (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable <>) ||
                         propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection <>) ||
                         propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList <>)))
                    {
                        //if it is a IEnumerable<>, IList<T> or ICollection<> we'll use a List<>
                        var genericType = typeof(List <>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments());
                        return(new ClonePropertyInfo(propertyInfo)
                        {
                            GenericListType = genericType
                        });
                    }
                    if (propertyInfo.PropertyType.IsArray ||
                        (propertyInfo.PropertyType.IsInterface && propertyInfo.PropertyType.IsGenericType == false))
                    {
                        //if its an array, we'll create a list to work with first and then convert to array later
                        //otherwise if its just a regular derivative of IEnumerable, we can use a list too
                        return(new ClonePropertyInfo(propertyInfo)
                        {
                            GenericListType = typeof(List <object>)
                        });
                    }
                    //skip instead of trying to create instance of abstract or interface
                    if (propertyInfo.PropertyType.IsAbstract || propertyInfo.PropertyType.IsInterface)
                    {
                        return(null);
                    }

                    //its a custom IEnumerable, we'll try to create it
                    try
                    {
                        var custom = Activator.CreateInstance(propertyInfo.PropertyType);
                        //if it's an IList we can work with it, otherwise we cannot
                        var newList = custom as IList;
                        if (newList == null)
                        {
                            return(null);
                        }
                        return(new ClonePropertyInfo(propertyInfo)
                        {
                            GenericListType = propertyInfo.PropertyType
                        });
                    }
                    catch (Exception)
                    {
                        //could not create this type so we'll skip it
                        return(null);
                    }
                }
                return(new ClonePropertyInfo(propertyInfo));
            })
                                                   .Where(x => x.HasValue)
                                                   .Select(x => x.Value)
                                                   .ToArray());

            foreach (var clonePropertyInfo in refProperties)
            {
                if (clonePropertyInfo.IsDeepCloneable)
                {
                    //this ref property is also deep cloneable so clone it
                    var result = (IDeepCloneable)clonePropertyInfo.PropertyInfo.GetValue(input, null);

                    if (result != null)
                    {
                        //set the cloned value to the property
                        clonePropertyInfo.PropertyInfo.SetValue(output, result.DeepClone(), null);
                    }
                }
                else if (clonePropertyInfo.IsList)
                {
                    var enumerable = (IEnumerable)clonePropertyInfo.PropertyInfo.GetValue(input, null);
                    if (enumerable == null)
                    {
                        continue;
                    }

                    var newList = (IList)Activator.CreateInstance(clonePropertyInfo.GenericListType);

                    var isUsableType = true;

                    //now clone each item
                    foreach (var o in enumerable)
                    {
                        //first check if the item is deep cloneable and copy that way
                        var dc = o as IDeepCloneable;
                        if (dc != null)
                        {
                            newList.Add(dc.DeepClone());
                        }
                        else if (o is string || o.GetType().IsValueType)
                        {
                            //check if the item is a value type or a string, then we can just use it
                            newList.Add(o);
                        }
                        else
                        {
                            //this will occur if the item is not a string or value type or IDeepCloneable, in this case we cannot
                            // clone each element, we'll need to skip this property, people will have to manually clone this list
                            isUsableType = false;
                            break;
                        }
                    }

                    //if this was not usable, skip this property
                    if (isUsableType == false)
                    {
                        continue;
                    }

                    if (clonePropertyInfo.PropertyInfo.PropertyType.IsArray)
                    {
                        //need to convert to array
                        var arr = (object[])Activator.CreateInstance(clonePropertyInfo.PropertyInfo.PropertyType, newList.Count);
                        for (int i = 0; i < newList.Count; i++)
                        {
                            arr[i] = newList[i];
                        }
                        //set the cloned collection
                        clonePropertyInfo.PropertyInfo.SetValue(output, arr, null);
                    }
                    else
                    {
                        //set the cloned collection
                        clonePropertyInfo.PropertyInfo.SetValue(output, newList, null);
                    }
                }
            }
        }
Пример #13
0
 /// <summary>
 /// Checks if a clone is already registered for a given deeply cloneable item.
 /// </summary>
 /// <param name="item">The original object.</param>
 /// <returns>True if a clone is already registered for the given item; false otherwise</returns>
 public bool ClonedObjectRegistered(IDeepCloneable item)
 {
     return(mapping.ContainsKey(item));
 }
Пример #14
0
 /// <summary>
 /// Registers a new clone for a given deeply cloneable object.
 /// </summary>
 /// <param name="item">The original object.</param>
 /// <param name="clone">The clone of the original object.</param>
 public void RegisterClonedObject(IDeepCloneable item, IDeepCloneable clone)
 {
     mapping.Add(item, clone);
 }
    private bool ProcessEqualObjects(IDeepCloneable item, IEnumerable<object> intersections) {
      bool success = true;
      bool headerWritten = false;

      foreach (object o in intersections) {
        string typeName = o.GetType().FullName;
        if (excludedTypes.Contains(o.GetType())) {
          //TestContext.WriteLine("Skipping excluded type " + typeName);
        } else if (o is IDeepCloneable) {
          string info = (o is IItem) ? ((IItem)o).ItemName + ((o is INamedItem) ? ", " + ((INamedItem)o).Name : String.Empty) : String.Empty;
          if (!headerWritten) {
            TestContext.WriteLine(Environment.NewLine + item.GetType().FullName + ":");
            headerWritten = true;
          }
          TestContext.WriteLine("POTENTIAL ERROR! A DEEPCLONEABLE WAS NOT DEEP CLONED (" + info + "): " + typeName);
          success = false;
        } else {
          Array array = o as Array;
          if (array != null && array.Length == 0) continue; //arrays of length 0 are used inside empty collections
          if (!headerWritten) {
            TestContext.WriteLine(Environment.NewLine + item.GetType().FullName + ":");
            headerWritten = true;
          }
          TestContext.WriteLine("WARNING: An object of type " + typeName + " is referenced in the original and in the clone.");
        }
      }
      return success;
    }
Пример #16
0
 /// <summary>
 /// Initializes a new instance of <see cref="OperatorGraph"/>.
 /// </summary>
 public OperatorGraph() {
   operators = new OperatorSet();
   initialOperator = null;
   visualizationInfo = null;
   Initialize();
 }