sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Martin Desruisseaux (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (SIS-113) Support deep copy of metadata objects
Date Wed, 12 Mar 2014 10:56:42 GMT

    [ https://issues.apache.org/jira/browse/SIS-113?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13931631#comment-13931631
] 

Martin Desruisseaux commented on SIS-113:
-----------------------------------------

Example of a possible implementation:

{code:java}
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Collection;
import java.util.IdentityHashMap;
import org.apache.sis.metadata.AbstractMetadata;
import org.apache.sis.metadata.KeyNamePolicy;
import org.apache.sis.metadata.ValueExistencePolicy;

public class DeepCopy {
    public static AbstractMetadata clone(final AbstractMetadata metadata) {
        return clone(metadata, new IdentityHashMap<AbstractMetadata,AbstractMetadata>());
    }

    private static AbstractMetadata clone(final AbstractMetadata metadata, final Map<AbstractMetadata,AbstractMetadata>
done) {
        AbstractMetadata clone = done.get(metadata);
        if (clone == null) {
            clone = shallowCopy(metadata);
            done.put(metadata, clone);
            for (Map.Entry<String,Object> entry : clone.getStandard().asValueMap(metadata,
                    KeyNamePolicy.JAVABEANS_PROPERTY, ValueExistencePolicy.NON_NULL).entrySet())
            {
                final Object value = entry.getValue();
                if (value instanceof AbstractMetadata) {
                    entry.setValue(clone((AbstractMetadata) value, done));
                } else if (value instanceof Collection<?>) {
                    final List<Object> list = new ArrayList<>((Collection<?>)
value);
                    boolean modified = false;
                    for (int i=list.size(); --i>=0;) {
                        final Object element = list.get(i);
                        if (element instanceof AbstractMetadata) {
                            list.set(i, clone((AbstractMetadata) element, done));
                            modified = true;
                        }
                    }
                    if (modified) {
                        entry.setValue(list);
                    }
                }
            }
        }
        return clone;
    }

    private static AbstractMetadata shallowCopy(final AbstractMetadata metadata) {
        final Class<?> c = metadata.getClass();
        try {
            return (AbstractMetadata) c.getConstructor(metadata.getStandard().getInterface(c)).newInstance(metadata);
        } catch (ReflectiveOperationException e) {
            throw new IllegalArgumentException("Malformed metadata class.", e); // TODO: define
a better exception.
        }
    }
}
{code}


> Support deep copy of metadata objects
> -------------------------------------
>
>                 Key: SIS-113
>                 URL: https://issues.apache.org/jira/browse/SIS-113
>             Project: Spatial Information Systems
>          Issue Type: New Feature
>          Components: Metadata
>    Affects Versions: 0.3
>            Reporter: Martin Desruisseaux
>            Assignee: Martin Desruisseaux
>
> Current metadata implementations provide constructors performing shallow copy of metadata
objects. We also need a method providing a deep copy. It shall not be a constructor (using
reflection in constructors is unsafe).



--
This message was sent by Atlassian JIRA
(v6.2#6252)

Mime
View raw message