Author: desruisseaux Date: Tue Feb 28 12:40:56 2017 New Revision: 1784733 URL: http://svn.apache.org/viewvc?rev=1784733&view=rev Log: Complete MetadataCopier for performing deep copy of metadata objects (SIS-355).
Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java (with props) sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java (with props) Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/Freezer.java sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/Freezer.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/Freezer.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/Freezer.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/Freezer.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -19,13 +19,13 @@ package org.apache.sis.metadata; import java.util.Map; import java.util.Set; import java.util.EnumSet; -import java.util.Iterator; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; -import org.apache.sis.util.collection.Containers; +import org.apache.sis.internal.util.Cloner; import org.apache.sis.util.collection.CodeListSet; import org.apache.sis.internal.util.CollectionsExt; +import org.apache.sis.internal.util.UnmodifiableArrayList; import org.apache.sis.metadata.iso.identification.DefaultRepresentativeFraction; @@ -39,7 +39,7 @@ import org.apache.sis.metadata.iso.ident * @version 0.8 * @module */ -final class Freezer extends org.apache.sis.internal.util.Cloner { +final class Freezer extends Cloner { /** * Creates a new {@code Freezer} instance. */ @@ -47,7 +47,7 @@ final class Freezer extends org.apache.s } /** - * Tells {@link #clone(Object)} to return the original object + * Tells {@link Cloner#clone(Object)} to return the original object * if no public {@code clone()} method is found. */ @Override @@ -59,7 +59,7 @@ final class Freezer extends org.apache.s * Recursively clones all elements in the given array. */ private void clones(final Object[] array) throws CloneNotSupportedException { - for (int i=0; i<array.length; i++) { + for (int i=0; i < array.length; i++) { array[i] = clone(array[i]); } } @@ -134,7 +134,7 @@ final class Freezer extends org.apache.s * is less destructive (no removal of duplicated values). */ clones(array); - collection = Containers.unmodifiableList(array); + collection = UnmodifiableArrayList.wrap(array); } break; } @@ -147,8 +147,7 @@ final class Freezer extends org.apache.s */ if (object instanceof Map<?,?>) { final Map<Object,Object> map = new LinkedHashMap<>((Map<?,?>) object); - for (final Iterator<Map.Entry<Object,Object>> it=map.entrySet().iterator(); it.hasNext();) { - final Map.Entry<Object,Object> entry = it.next(); + for (final Map.Entry<Object,Object> entry : map.entrySet()) { entry.setValue(clone(entry.getValue())); } return CollectionsExt.unmodifiableOrCopy(map); Added: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java?rev=1784733&view=auto ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java (added) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -0,0 +1,228 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.metadata; + +import java.util.Set; +import java.util.EnumSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.IdentityHashMap; +import java.util.Arrays; +import java.util.Collection; +import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.collection.CodeListSet; + + +/** + * Performs deep copies of given metadata instances. This class performs a <em>copies</em>, not clones, + * since the copied metadata may not be instances of the same class than the original metadata. + * This class performs the following steps: + * + * <ul> + * <li>Get the {@linkplain MetadataStandard#getImplementation implementation class} of the given metadata instance.</li> + * <li>Create a {@linkplain Class#newInstance() new instance} of the implementation class using the public no-argument constructor.</li> + * <li>Invoke all non-deprecated setter methods on the new instance with the corresponding value from the given metadata.</li> + * <li>If any of the values copied in above step is itself a metadata, recursively performs deep copy on those metadata instances too.</li> + * </ul> + * + * This class supports cyclic graphs in the metadata tree. It may return the given {@code metadata} object directly + * if the {@linkplain MetadataStandard#getImplementation implementation class} does not provide any setter method. + * + * <p>This class is not thread-safe. + * In multi-threads environment, each thread should use its own {@code MetadataCopier} instance.</p> + * + * <div class="section">Recommended alternative</div> + * Deep metadata copies are sometime useful when using an existing metadata as a template. + * But the {@link ModifiableMetadata#unmodifiable()} method may provide a better way to use a metadata as a template, + * as it returns a snapshot and allows the caller to continue to modify the original metadata object and create new + * snapshots. Example: + * + * {@preformat java + * // Prepare a Citation to be used as a template. + * DefaultCitation citation = new DefaultCitation(); + * citation.getCitedResponsibleParties(someAuthor); + * + * // Set the title and get a first snapshot. + * citation.setTitle(new SimpleInternationalString("A title")); + * Citation myFirstCitation = (Citation) citation.unmodifiable(); + * + * // Change the title and get another snapshot. + * citation.setTitle(new SimpleInternationalString("Another title")); + * Citation mySecondCitation = (Citation) citation.unmodifiable(); + * } + * + * This approach allows sharing the children that have the same content, thus reducing memory usage. In above example, + * the {@code someAuthor} {@linkplain org.apache.sis.metadata.iso.citation.DefaultCitation#getCitedResponsibleParties() + * cited responsible party} is the same instance in both citations. In comparison, deep copy operations unconditionally + * duplicate everything, no matter if it was needed or not. Nevertheless deep copies are still sometime useful, + * for example when we do not have the original {@link ModifiableMetadata} instance anymore. + * + * <p>{@code MetadataCopier} is also useful for converting a metadata tree of unknown implementations (for example the + * result of a call to {@link org.apache.sis.metadata.sql.MetadataSource#lookup(Class, String)}) into instances of the + * public {@link AbstractMetadata} subclasses. But note that shallow copies as provided by the {@code castOrCopy(…)} + * static methods in each {@code AbstractMetadata} subclass are sometime sufficient.</p> + * + * @author Martin Desruisseaux (Geomatys) + * @since 0.8 + * @version 0.8 + * @module + * + * @see ModifiableMetadata#unmodifiable() +*/ +public class MetadataCopier { + /** + * The default metadata standard to use for object that are not {@link AbstractMetadata} instances, + * or {@code null} if none. + */ + private final MetadataStandard standard; + + /** + * The metadata objects that have been copied so far. + * This is used for resolving cyclic graphs. + */ + final Map<Object,Object> copies; + + /** + * Creates a new metadata copier. + * + * @param standard the default metadata standard to use for object that are not {@link AbstractMetadata} instances, + * or {@code null} if none. + */ + public MetadataCopier(final MetadataStandard standard) { + this.standard = standard; + copies = new IdentityHashMap<>(); + } + + /** + * Performs a potentially deep copy of a metadata object of unknown type. + * The return value does not need to be of the same class than the argument. + * + * @param metadata the metadata object to copy, or {@code null}. + * @return a copy of the given metadata object, or {@code null} if the given argument is {@code null}. + * @throws UnsupportedOperationException if there is no implementation class for a metadata to copy, + * or an implementation class does not provide a public default constructor. + */ + public Object copy(final Object metadata) { + try { + return copyRecursively(null, metadata); + } finally { + copies.clear(); + } + } + + /** + * Performs a potentially deep copy of the given metadata object. + * This method is preferred to {@link #copy(Object)} when the type is known. + * + * @param <T> compile-time value of the {@code type} argument. + * @param type the interface of the metadata object to copy. + * @param metadata the metadata object to copy, or {@code null}. + * @return a copy of the given metadata object, or {@code null} if the given argument is {@code null}. + * @throws UnsupportedOperationException if there is no implementation class for a metadata to copy, + * or an implementation class does not provide a public default constructor. + */ + public <T> T copy(final Class<T> type, final T metadata) { + ArgumentChecks.ensureNonNull("type", type); + try { + return type.cast(copyRecursively(type, metadata)); + } finally { + copies.clear(); + } + } + + /** + * Performs the actual copy operation on a single metadata instance. + * This method is invoked by all public {@code copy(…)} method with the root {@code metadata} + * object in argument, then is invoked recursively for all properties in that metadata object. + * If a metadata property is a collection, then this method is invoked for each element in the collection. + * + * <p>Subclasses can override this method if they need some control on the copy process.</p> + * + * @param type the interface of the metadata object to copy, or {@code null} if unspecified. + * @param metadata the metadata object to copy, or {@code null}. + * @return a copy of the given metadata object, or {@code null} if the given argument is {@code null}. + * @throws UnsupportedOperationException if there is no implementation class for a metadata to copy, + * or an implementation class does not provide a public default constructor. + */ + protected Object copyRecursively(final Class<?> type, final Object metadata) { + if (metadata != null) { + MetadataStandard std = standard; + if (metadata instanceof AbstractMetadata) { + std = ((AbstractMetadata) metadata).getStandard(); + } + if (std != null) { + final PropertyAccessor accessor = std.getAccessor(new CacheKey(metadata.getClass(), type), false); + if (accessor != null) try { + return accessor.copy(metadata, this); + } catch (RuntimeException e) { + throw e; + } catch (Exception e) { + /* + * In our PropertyAccessor.copy(…) implementation, checked exceptions can only be thrown + * by the constructor. Note that Class.newInstance() may throw more checked exceptions + * than the ones declared in its method signature, so we really need to catch Exception + * (ReflectiveOperationException is not sufficient). + */ + throw new UnsupportedOperationException(Errors.format(Errors.Keys.CanNotCopy_1, accessor.type), e); + } + } + } + return metadata; + } + + /** + * Verifies if the given metadata value is a map or a collection before to invoke + * {@link #copyRecursively(Class, Object)} for metadata elements. This method is + * invoked by {@link PropertyAccessor#copy(Object, MetadataCopier)}. + */ + final Object copyAny(final Class<?> type, final Object metadata) { + if (!type.isInstance(metadata)) { + if (metadata instanceof Collection<?>) { + Collection<?> c = (Collection<?>) metadata; + if (c.isEmpty()) { + return null; + } + if (c instanceof EnumSet<?> || c instanceof CodeListSet<?>) { + /* + * Enum and CodeList elements can not be cloned. Do not clone their collection neither; + * we presume that the setter method will do that itself. + */ + } else { + final Object[] array = c.toArray(); + for (int i=0; i < array.length; i++) { + array[i] = copyRecursively(type, array[i]); + } + c = Arrays.asList(array); + if (metadata instanceof Set<?>) { + c = new LinkedHashSet<>(c); + } + } + return c; + } + if (metadata instanceof Map<?,?>) { + final Map<Object,Object> copy = new LinkedHashMap<>((Map<?,?>) metadata); + for (final Map.Entry<Object,Object> entry : copy.entrySet()) { + entry.setValue(copyRecursively(type, entry.getValue())); + } + return copy; + } + } + return copyRecursively(type, metadata); + } +} Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataCopier.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8 Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -19,7 +19,6 @@ package org.apache.sis.metadata; import java.util.Set; import java.util.Map; import java.util.LinkedHashSet; -import java.util.IdentityHashMap; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.ConcurrentMap; @@ -36,8 +35,6 @@ import org.apache.sis.util.Classes; import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.collection.TreeTable; import org.apache.sis.util.collection.CheckedContainer; -import org.apache.sis.util.collection.BackingStoreException; -import org.apache.sis.util.resources.Errors; import org.apache.sis.internal.system.Modules; import org.apache.sis.internal.system.Semaphores; import org.apache.sis.internal.system.SystemListener; @@ -1045,48 +1042,6 @@ public class MetadataStandard implements } /** - * Returns a deep copy of the given metadata object. This method performs a <em>copy</em>, not a clone, - * since the copied metadata may not be of the same class than the original metadata. - * This method performs the following step: - * - * <ul> - * <li>Get the {@linkplain #getImplementation implementation class} of the given metadata instance.</li> - * <li>Create a new instance of the implementation class using the public no-argument constructor.</li> - * <li>Invoke all non-deprecated setter methods on the new instance with the corresponding value from - * the given metadata.</li> - * <li>If any of the values copied in above step is itself a metadata, recursively performs deep copy - * on those metadata instances too.</li> - * </ul> - * - * This method supports cyclic graphs. This method may return the given {@code metadata} object directly - * if the {@linkplain #getImplementation implementation class} does not provide any setter method. - * - * @param metadata the metadata object to copy, or {@code null}. - * @return A copy of the given metadata object, or {@code null} if the given argument is {@code null}. - * @throws ClassCastException if the metadata object does not implement a metadata interface of the expected package. - * @throws UnsupportedOperationException if there is no implementation class for at least one metadata to copy, - * or an implementation class does not provide a public default constructor. - * - * @since 0.8 - */ - Object deepCopy(final Object metadata) throws ClassCastException { - if (metadata != null) { - final PropertyAccessor accessor = getAccessor(new CacheKey(metadata.getClass()), true); - final Map<Object,Object> copies = new IdentityHashMap<>(); - try { - return accessor.deepCopy(metadata, copies); - } catch (ReflectiveOperationException e) { - throw new UnsupportedOperationException(Errors.format(Errors.Keys.CanNotCopy_1, accessor.type)); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { // Other non-checked exception may be throw by default metadata constructor. - throw new BackingStoreException(e); - } - } - return metadata; - } - - /** * Returns a string representation of this metadata standard. * This is for debugging purpose only and may change in any future version. */ Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -165,6 +165,8 @@ public abstract class ModifiableMetadata * </ul> * * @return an unmodifiable copy of this metadata. + * + * @see MetadataCopier */ public AbstractMetadata unmodifiable() { /* @@ -675,6 +677,7 @@ public abstract class ModifiableMetadata * Creates a <strong>shallow</strong> copy of this metadata. * The clone operation is required for the internal working of the {@link #unmodifiable()} method, * which needs <em>shallow</em> copies of metadata entities. + * For deep copies, see {@link MetadataCopier}. * * <div class="section">API note</div> * While {@link Cloneable}, the {@code ModifiableMetadata} subclasses should not provide @@ -688,6 +691,9 @@ public abstract class ModifiableMetadata * * @return a <em>shallow</em> copy of this metadata. * @throws CloneNotSupportedException if the clone is not supported. + * + * @see #unmodifiable() + * @see MetadataCopier */ @Override protected ModifiableMetadata clone() throws CloneNotSupportedException { Modified: sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -1201,7 +1201,7 @@ class PropertyAccessor { } /** - * Returns a deep copy of the given metadata object. + * Returns a potentially deep copy of the given metadata object. * * @param metadata the metadata object to copy. * @param copies a map of metadata objects already copied. @@ -1210,24 +1210,25 @@ class PropertyAccessor { * @throws Exception if an error occurred while creating the copy. This include any * checked checked exception that the no-argument constructor may throw. */ - final Object deepCopy(final Object metadata, final Map<Object,Object> copies) throws Exception { + final Object copy(final Object metadata, final MetadataCopier copier) throws Exception { if (setters == null) { return metadata; } - Object copy = copies.get(metadata); + Object copy = copier.copies.get(metadata); if (copy == null) { copy = implementation.newInstance(); - copies.put(metadata, copy); // Need to be first in case of cyclic graphs. + copier.copies.put(metadata, copy); // Need to be first in case of cyclic graphs. final Object[] arguments = new Object[1]; for (int i=0; i<allCount; i++) { final Method setter = setters[i]; if (setter != null && !setter.isAnnotationPresent(Deprecated.class)) { - final Method getter = getters[i]; - Object value = get(getter, metadata); + Object value = get(getters[i], metadata); if (value != null) { - // TODO: perform deep copy here. - arguments[0] = value; - set(setter, copy, arguments); + value = copier.copyAny(elementTypes[i], value); + if (value != null) { + arguments[0] = value; + set(setter, copy, arguments); + } } } } Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/MergerTest.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -21,6 +21,7 @@ import java.util.Locale; import java.util.Iterator; import java.util.Collections; import java.nio.charset.StandardCharsets; +import org.opengis.metadata.citation.Citation; import org.opengis.metadata.content.ContentInformation; import org.opengis.metadata.content.CoverageDescription; import org.opengis.metadata.content.FeatureCatalogueDescription; @@ -36,7 +37,6 @@ import org.apache.sis.test.TestCase; import org.junit.Test; import static org.apache.sis.test.Assert.*; -import org.opengis.metadata.citation.Citation; /** Added: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java?rev=1784733&view=auto ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java (added) +++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sis.metadata; + +import org.apache.sis.metadata.iso.citation.DefaultCitation; +import org.apache.sis.metadata.iso.citation.HardCodedCitations; +import org.apache.sis.test.DependsOn; +import org.apache.sis.test.TestCase; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.apache.sis.test.TestUtilities.getSingleton; + + +/** + * Tests the {@link MetadataCopier} class. + * Unless otherwise specified, all tests use the {@link MetadataStandard#ISO_19115} constant. + * + * @author Martin Desruisseaux (Geomatys) + * @since 0.8 + * @version 0.8 + * @module + * + * @see org.apache.sis.internal.metadata.MergerTest + */ +@DependsOn(MetadataStandardTest.class) +public final strictfp class MetadataCopierTest extends TestCase { + /** + * Tests {@link MetadataCopier#copy(Object)}. + */ + @Test + public void testCopy() { + final MetadataCopier copier = new MetadataCopier(MetadataStandard.ISO_19115); + final DefaultCitation original = HardCodedCitations.EPSG; + final DefaultCitation copy = (DefaultCitation) copier.copy(original); + assertNotSame(original, copy); + assertNotSame(getSingleton(original.getCitedResponsibleParties()), + getSingleton(copy.getCitedResponsibleParties())); + assertEquals(original, copy); + } +} Propchange: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataCopierTest.java ------------------------------------------------------------------------------ svn:mime-type = text/plain;charset=UTF-8 Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -356,21 +356,6 @@ public final strictfp class MetadataStan } /** - * Tests {@link MetadataStandard#deepCopy(Object)}. - */ - @Test - @DependsOnMethod("testEquals") - public void testDeepCopy() { - standard = MetadataStandard.ISO_19115; - final DefaultCitation original = HardCodedCitations.EPSG; - final DefaultCitation copy = (DefaultCitation) standard.deepCopy(original); - assertNotSame(original, copy); -// assertNotSame(getSingleton(original.getCitedResponsibleParties()), -// getSingleton(copy.getCitedResponsibleParties())); - assertEquals(original, copy); - } - - /** * Tests serialization of pre-defined constants. */ @Test Modified: sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1784733&r1=1784732&r2=1784733&view=diff ============================================================================== --- sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original) +++ sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Tue Feb 28 12:40:56 2017 @@ -52,6 +52,7 @@ import org.junit.BeforeClass; org.apache.sis.metadata.MetadataStandardTest.class, org.apache.sis.metadata.PrunerTest.class, org.apache.sis.metadata.AbstractMetadataTest.class, + org.apache.sis.metadata.MetadataCopierTest.class, org.apache.sis.internal.metadata.MergerTest.class, // XML marshalling.