akshayyn / cloning

Automatically exported from code.google.com/p/cloning
Other
0 stars 0 forks source link

assign feature #19

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Adding this would allow transferring from one object to another:

    public <T> void assign(T target, T o) {
        if (o == null) {
            return;
        }
        if (dumpClonedClasses) {
            System.out.println("start assign>" + o.getClass());
        }
        final Map<Object, Object> clones = new IdentityHashMap<Object, Object>(16);
        try {
            cloneInternal(o, target, clones);
        } catch (final IllegalAccessException e) {
            throw new CloningException("error during cloning of " + o, e);
        }
    }

and cloneInternal modified little bit, I just dump it here:

public <T> T cloneInternal(final T o, final T startWith, final Map<Object, 
Object> clones) throws IllegalAccessException {
        if (o == null) {
            return null;
        }
        if (o == this) {
            return null;
        }
        if (ignoredInstances.containsKey(o)) {
            return o;
        }
        final Class<T> clz;
        if (startWith != null) {
            clz = (Class<T>) startWith.getClass();
        } else {
            clz = (Class<T>) o.getClass();
        }
        if (clz.isEnum()) {
            return o;
        }
        // skip cloning ignored classes
        if (nullInstead.contains(clz)) {
            return null;
        }
        if (ignored.contains(clz)) {
            return o;
        }
        for (final Class<?> iClz : ignoredInstanceOf) {
            if (iClz.isAssignableFrom(clz)) {
                return o;
            }
        }
        if (isImmutable(clz)) {
            return o;
        }
        if (o instanceof IFreezable) {
            final IFreezable f = (IFreezable) o;
            if (f.isFrozen()) {
                return o;
            }
        }
        final Object clonedPreviously = clones != null ? clones.get(o) : null;
        if (clonedPreviously != null) {
            return (T) clonedPreviously;
        }

        final Object fastClone = fastClone(o, clones);
        if (fastClone != null) {
            if (clones != null) {
                clones.put(o, fastClone);
            }
            return (T) fastClone;
        }

        if (dumpClonedClasses) {
            System.out.println("clone>" + clz);
        }
        if (clz.isArray()) {
            final int length = Array.getLength(o);
            final T newInstance = (T) Array.newInstance(clz.getComponentType(), length);
            if (clones != null) {
                clones.put(o, newInstance);
            }
            for (int i = 0; i < length; i++) {
                final Object v = Array.get(o, i);
                final Object clone = clones != null ? cloneInternal(v, null, clones) : v;
                Array.set(newInstance, i, clone);
            }
            return newInstance;
        }

        final T newInstance;
        if (startWith != null) {
            newInstance = startWith;
        } else {
            newInstance = newInstance(clz);
        }
        if (clones != null) {
            clones.put(o, newInstance);
        }
        final List<Field> fields = allFields(clz);
        for (final Field field : fields) {
            final int modifiers = field.getModifiers();
            if (!Modifier.isStatic(modifiers)) {
                if (nullTransient && Modifier.isTransient(modifiers)) {
                    // request by Jonathan : transient fields can be null-ed
                    final Class<?> type = field.getType();
                    if (!type.isPrimitive()) {
                        field.set(newInstance, null);
                    }
                } else {
                    final Object fieldObject = field.get(o);
                    final boolean shouldClone = (cloneSynthetics || !cloneSynthetics && !field.isSynthetic()) && (cloneAnonymousParent || !cloneAnonymousParent && !isAnonymousParent(field));
                    final Object fieldObjectClone = clones != null ? shouldClone ? cloneInternal(fieldObject, null, clones) : fieldObject : fieldObject;
                    field.set(newInstance, fieldObjectClone);
                    if (dumpClonedClasses && fieldObjectClone != fieldObject) {
                        System.out.println("cloned field>" + field + "  -- of class " + o.getClass());
                    }
                }
            }
        }
        return newInstance;
    }

It needs to be called with null as startWith

Maybe there is a nicer way, but copying from one object to another seems to be 
a nice feature, I think.

Original issue reported on code.google.com by v...@gmx.net on 16 Jul 2013 at 2:17

GoogleCodeExporter commented 8 years ago
Hi, I think cloner.copyPropertiesOfInheritedClass does that, right? I'll close 
the issue, if you think the methods are different please reopen

Original comment by kostas.k...@googlemail.com on 16 Jul 2013 at 9:28