sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1478414 - in /sis/branches/JDK7/sis-metadata/src: main/java/org/apache/sis/metadata/ test/java/org/apache/sis/metadata/ test/java/org/apache/sis/metadata/iso/citation/
Date Thu, 02 May 2013 15:30:13 GMT
Author: desruisseaux
Date: Thu May  2 15:30:13 2013
New Revision: 1478414

URL: http://svn.apache.org/r1478414
Log:
Renamed 'shallowCopy' as 'append', with slight semantic change, prior removal.
We will remove that 'append' method in the next commit because it is replaced by the copy
constructors,
and appending (or merging) metadata may be tricky since there is various way to merge bounding
box,
child metadata objects, etc. We do this commit prior removal in order to have a starting point
in the
history if we decide in a future version that we need append functionality.

Modified:
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
    sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
    sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java?rev=1478414&r1=1478413&r2=1478414&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/AbstractMetadata.java
[UTF-8] Thu May  2 15:30:13 2013
@@ -45,7 +45,7 @@ import static org.apache.sis.util.Argume
  *
  * <ul>
  *   <li>{@link #prune()}</li>
- *   <li>{@link #shallowCopy(Object)}</li>
+ *   <li>{@link #append(Object)}</li>
  *   <li>{@link #asMap()} with {@code put} operations</li>
  * </ul>
  *
@@ -154,15 +154,11 @@ public abstract class AbstractMetadata i
     }
 
     /**
-     * Copies the values from the specified metadata. The {@code source} metadata must implements
-     * the same metadata interface (defined by the {@linkplain #getStandard() standard})
than this
-     * class, but doesn't need to be the same implementation class.
+     * Appends to this metadata all non-empty values from the specified metadata. The {@code
source} metadata
+     * must implements the same metadata interface (defined by the {@linkplain #getStandard()
standard}) than
+     * this class, but doesn't need to be the same implementation class.
      * The default implementation performs the copy using Java reflections.
      *
-     * {@note This method is intended to provide the functionality of a <cite>copy
constructor</cite>.
-     * We do not provide copy constructor directly because usage of Java reflection in this
context
-     * is unsafe (we could invoke subclass methods before the subclasses construction is
completed).}
-     *
      * @param  source The metadata to copy values from.
      * @throws ClassCastException if the specified metadata doesn't implements the expected
      *         metadata interface.
@@ -170,9 +166,9 @@ public abstract class AbstractMetadata i
      *         corresponding to the {@code get*()} methods found in the implemented interface,
or
      *         if this instance is not modifiable for some other reason.
      */
-    public void shallowCopy(final Object source) throws ClassCastException, UnmodifiableMetadataException
{
+    public void append(final Object source) throws ClassCastException, UnmodifiableMetadataException
{
         ensureNonNull("source", source);
-        getStandard().shallowCopy(source, this);
+        getStandard().append(source, this);
     }
 
     /**
@@ -182,8 +178,21 @@ public abstract class AbstractMetadata i
      *
      * <p>The map supports the {@link Map#put(Object, Object) put(…)} and {@link
Map#remove(Object)
      * remove(…)} operations if the underlying metadata object contains setter methods.
-     * The keys are case-insensitive and can be either the JavaBeans property name or
-     * the UML identifier.</p>
+     * The {@code remove(…)} method is implemented by a call to {@code put(…, null)}.</p>
+     *
+     * <p>The keys are case-insensitive and can be either the JavaBeans property name,
the getter method name
+     * or the {@linkplain org.opengis.annotation.UML#identifier() UML identifier}. The value
given to a call
+     * to the {@code put(…)} method shall be an instance of the type expected by the corresponding
setter method,
+     * or an instance of a type {@linkplain org.apache.sis.util.ObjectConverters#find(Class,
Class) convertible}
+     * to the expected type.</p>
+     *
+     * <p>Calls to {@code put(…)} replace the previous value, with one noticeable
exception: if the metadata
+     * property associated to the given key is a {@link java.util.Collection} but the given
value is a single
+     * element (not a collection), then the given value is {@linkplain java.util.Collection#add(Object)
added}
+     * to the existing collection. In other words, the returned map behaves as a <cite>multi-values
map</cite>
+     * for the properties that allow multiple values. If the intend is to unconditionally
discard all previous
+     * values, then make sure that the given value is a collection when the associated metadata
property expects
+     * such collection.</p>
      *
      * <p>The default implementation is equivalent to the following method call:</p>
      *

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java?rev=1478414&r1=1478413&r2=1478414&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/MetadataStandard.java
[UTF-8] Thu May  2 15:30:13 2013
@@ -571,8 +571,23 @@ public class MetadataStandard {
      *
      * <p>The map supports the {@link Map#put(Object, Object) put(…)} and {@link
Map#remove(Object)
      * remove(…)} operations if the underlying metadata object contains setter methods.
-     * The keys are case-insensitive and can be either the JavaBeans property name or
-     * the UML identifier.</p>
+     * The {@code remove(…)} method is implemented by a call to {@code put(…, null)}.
+     * Note that whether the entry appears as effectively removed from the map or just cleared
+     * (i.e. associated to a null value) depends on the {@code valuePolicy} argument.</p>
+     *
+     * <p>The keys are case-insensitive and can be either the JavaBeans property name,
the getter method name
+     * or the {@linkplain org.opengis.annotation.UML#identifier() UML identifier}. The value
given to a call
+     * to the {@code put(…)} method shall be an instance of the type expected by the corresponding
setter method,
+     * or an instance of a type {@linkplain org.apache.sis.util.ObjectConverters#find(Class,
Class) convertible}
+     * to the expected type.</p>
+     *
+     * <p>Calls to {@code put(…)} replace the previous value, with one noticeable
exception: if the metadata
+     * property associated to the given key is a {@link java.util.Collection} but the given
value is a single
+     * element (not a collection), then the given value is {@linkplain java.util.Collection#add(Object)
added}
+     * to the existing collection. In other words, the returned map behaves as a <cite>multi-values
map</cite>
+     * for the properties that allow multiple values. If the intend is to unconditionally
discard all previous
+     * values, then make sure that the given value is a collection when the associated metadata
property expects
+     * such collection.</p>
      *
      * @param  metadata The metadata object to view as a map.
      * @param  keyPolicy Determines the string representation of map keys.
@@ -629,11 +644,11 @@ public class MetadataStandard {
     }
 
     /**
-     * Copies all metadata from source to target.
+     * Appends all non-empty metadata from source to target.
      * The source must implements the same metadata interface than the target.
      *
      * <p>If the source contains any null or empty properties, then those properties
will
-     * <strong>not</strong> overwrite the corresponding properties in the destination
metadata.</p>
+     * not overwrite the corresponding properties in the destination metadata.</p>
      *
      * @param  source The metadata to copy.
      * @param  target The target metadata.
@@ -644,7 +659,7 @@ public class MetadataStandard {
      *
      * @see ModifiableMetadata#clone()
      */
-    public void shallowCopy(final Object source, final Object target)
+    public void append(final Object source, final Object target)
             throws ClassCastException, UnmodifiableMetadataException
     {
         ensureNonNull("target", target);
@@ -654,7 +669,7 @@ public class MetadataStandard {
             throw new ClassCastException(Errors.format(Errors.Keys.IllegalArgumentClass_3,
                     "source", accessor.type, source.getClass()));
         }
-        if (!accessor.shallowCopy(source, target)) {
+        if (!accessor.append(source, target)) {
             throw new UnmodifiableMetadataException(Errors.format(Errors.Keys.UnmodifiableMetadata));
         }
     }

Modified: sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1478414&r1=1478413&r2=1478414&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] Thu May  2 15:30:13 2013
@@ -68,7 +68,7 @@ import static org.apache.sis.util.collec
  *   <li>The standard properties defined by the GeoAPI (or other standard) interfaces.
  *       Those properties are the only one accessible by most methods in this class,
  *       except {@link #equals(Object, Object, ComparisonMode, boolean)},
- *       {@link #shallowCopy(Object, Object)} and {@link #freeze(Object)}.</li>
+ *       {@link #append(Object, Object)} and {@link #freeze(Object)}.</li>
  *
  *   <li>Extra properties defined by the {@link IdentifiedObject} interface. Those
properties
  *       invisible in the ISO 19115 model, but appears in ISO 19139 XML marshalling. So we
do
@@ -207,9 +207,9 @@ final class PropertyAccessor {
      * looking for a converter, and also reduce thread contention since it reduces the number
      * of calls to the synchronized {@link ObjectConverters#find(Class, Class)} method.
      *
-     * @see #set(int, Object, Object, boolean)
+     * @see #convert(Object[], Class)
      */
-    private transient volatile ObjectConverter<?,?> converter;
+    private transient volatile ObjectConverter<?,?> lastConverter;
 
     /**
      * The property information, including the name and restrictions on valid values.
@@ -298,7 +298,7 @@ final class PropertyAccessor {
                  * If we found no setter method expecting an argument of the same type than
the
                  * argument returned by the GeoAPI method,  try again with the type returned
by
                  * the implementation class. It is typically the same type, but sometime
it may
-                 * be a subtype.
+                 * be a parent type.
                  *
                  * It is a necessary condition that the type returned by the getter is assignable
                  * to the type expected by the setter.  This contract is required by the
'freeze'
@@ -712,7 +712,7 @@ final class PropertyAccessor {
                     copy = old = null;
                 }
                 final Object[] newValues = new Object[] {value};
-                converter = convert(getter, metadata, old, newValues, elementTypes[index],
converter);
+                convert(getter, metadata, old, newValues, elementTypes[index], false);
                 set(setter, metadata, newValues);
                 return copy;
             }
@@ -759,149 +759,172 @@ final class PropertyAccessor {
 
     /**
      * Converts a value to the type required by a setter method.
+     * The values are converted in-place in the {@code newValues} array. We use an array
instead
+     * of a single argument and return value because an array will be needed anyway for invoking
+     * the {@link #convert(Object[], Class)} and {@link Method#invoke(Object, Object[])}
methods.
+     *
+     * {@section The collection special case}
+     * If the metadata property is a collection, then there is a choice:
+     *
+     * <ul>
+     *   <li>If {@code append} is {@code true}, then the new value (which may itself
be a collection)
+     *       is unconditionally added to the previous collection.</li>
+     *   <li>If {@code append} is {@code false} and the new value is <strong>not</strong>
a collection,
+     *       then the new value is added to the existing collection. In other words, we behave
as a
+     *       <cite>multi-values map</cite> for the properties that allow multi-values.</li>
+     *   <li>Otherwise the new collection replaces the previous collection. All previous
values
+     *       are discarded.</li>
+     * </ul>
+     *
+     * Adding new values to the previous collection may or may not change the original metadata
+     * depending on whether those collections are live or not. In Apache SIS implementation,
+     * those collections are live. However this method can be though as if the collections
were
+     * not live, since the caller will invoke the setter method with the collection anyway.
      *
      * @param getter      The method to use for fetching the previous value.
-     * @param metadata    The metadata object to query.
+     * @param metadata    The metadata object to query and modify.
      * @param oldValue    The value returned by {@code get(getter, metadata)}, or {@code
null} if unknown.
      *                    This parameter is only an optimization for avoiding to invoke the
getter method
      *                    twice if the value is already known.
-     * @param newValues   The argument to convert. It must be an array of length 1.
-     *                    The content of this array will be modified in-place.
-     * @param elementType The type required by the setter method.
-     * @param converter   The last converter used, or {@code null} if none.
-     *                    This converter is provided only as a hint and doesn't need to be
accurate.
-     * @return The last converter used, or {@code null}.
+     * @param newValues   The argument to convert. The content of this array will be modified
in-place.
+     *                    Current implementation requires an array of length 1, however this
restriction
+     *                    may be relaxed in a future SIS version if needed.
+     * @param elementType The target type (if singleton) or the type of elements in the collection.
+     * @param append      If {@code true} and the value is a collection, then that collection
will be added
+     *                    to any previously existing collection instead of replacing it.
      * @throws ClassCastException if the element of the {@code arguments} array is not of
the expected type.
      * @throws BackingStoreException If the implementation threw a checked exception.
      */
-    private static ObjectConverter<?,?> convert(final Method getter, final Object metadata,
-            final Object oldValue, final Object[] newValues, Class<?> elementType,
-            ObjectConverter<?,?> converter) throws ClassCastException, BackingStoreException
+    private void convert(final Method getter, final Object metadata, Object oldValue, final
Object[] newValues,
+            Class<?> elementType, final boolean append) throws ClassCastException,
BackingStoreException
     {
         assert newValues.length == 1;
         Object newValue = newValues[0];
+        Class<?> targetType = getter.getReturnType();
         if (newValue == null) {
             // Can't test elementType, because it has been converted to the wrapper class.
-            final Class<?> type = getter.getReturnType();
-            if (type.isPrimitive()) {
-                newValues[0] = Numbers.valueOfNil(type);
+            if (targetType.isPrimitive()) {
+                newValues[0] = Numbers.valueOfNil(targetType);
             }
+            return;
+        }
+        if (!Collection.class.isAssignableFrom(targetType)) {
+            /*
+             * We do not expect a collection. The provided argument should not be a
+             * collection neither. It should be some class convertible to targetType.
+             *
+             * If nevertheless the user provided a collection and this collection contains
+             * no more than 1 element, then as a convenience we will extract the singleton
+             * element and process it as if it had been directly provided in argument.
+             */
+            if (newValue instanceof Collection<?>) {
+                final Iterator<?> it = ((Collection<?>) newValue).iterator();
+                if (!it.hasNext()) { // If empty, process like null argument.
+                    newValues[0] = null;
+                    return;
+                }
+                final Object next = it.next();
+                if (!it.hasNext()) { // Singleton
+                    newValue = next;
+                }
+                // Other cases: let the collection unchanged. It is likely to
+                // cause an exception later. The message should be appropriate.
+            }
+            // Getter type (targetType) shall be the same than the setter type (elementType).
+            assert elementType == Numbers.primitiveToWrapper(targetType) : elementType;
+            targetType = elementType; // Ensure that we use primitive wrapper.
         } else {
-            Class<?> targetType = getter.getReturnType();
-            if (!Collection.class.isAssignableFrom(targetType)) {
-                /*
-                 * We do not expect a collection. The provided argument should not be a
-                 * collection neither. It should be some class convertible to targetType.
-                 *
-                 * If nevertheless the user provided a collection and this collection contains
-                 * no more than 1 element, then as a convenience we will extract the singleton
-                 * element and process it as if it had been directly provided in argument.
-                 */
-                if (newValue instanceof Collection<?>) {
-                    final Iterator<?> it = ((Collection<?>) newValue).iterator();
-                    if (!it.hasNext()) { // If empty, process like null argument.
-                        newValues[0] = null;
-                        return converter;
-                    }
-                    final Object next = it.next();
-                    if (!it.hasNext()) { // Singleton
-                        newValue = next;
-                    }
-                    // Other cases: let the collection unchanged. It is likely to
-                    // cause an exception later. The message should be appropriate.
-                }
-                // Getter type (targetType) shall be the same than the setter type (elementType).
-                assert elementType == Numbers.primitiveToWrapper(targetType) : elementType;
-                targetType = elementType; // Ensure that we use primitive wrapper.
-            } else {
-                /*
-                 * We expect a collection. Collections are handled in one of the two ways
below:
-                 *
-                 *   - If the user gives a collection, the user's collection replaces any
-                 *     previous one. The content of the previous collection is discarded.
-                 *
-                 *   - If the user gives a single value, it will be added to the existing
-                 *     collection (if any). The previous values are not discarded. This
-                 *     allow for incremental filling of a property.
-                 *
-                 * The code below prepares an array of elements to be converted and wraps
that
-                 * array in a List (to be converted to a Set after this block if required).
It
-                 * is okay to convert the elements after the List creation since the list
is a
-                 * wrapper.
-                 */
-                final Collection<?> addTo;
-                final Object[] elements;
-                if (newValue instanceof Collection<?>) {
-                    elements = ((Collection<?>) newValue).toArray();
-                    newValue = Arrays.asList(elements); // Content will be converted later.
-                    addTo = null;
-                } else {
-                    elements = new Object[] {newValue};
-                    newValue = addTo = (Collection<?>) (oldValue != null ? oldValue
: get(getter, metadata));
-                    if (addTo == null) {
-                        // No previous collection. Create one.
-                        newValue = Arrays.asList(elements);
-                    } else if (addTo instanceof CheckedContainer<?>) {
+            /*
+             * We expect a collection. Collections are handled in one of the two ways below:
+             *
+             *   - If the user gives a collection, the user's collection replaces any
+             *     previous one. The content of the previous collection is discarded.
+             *
+             *   - If the user gives a single value, it will be added to the existing
+             *     collection (if any). The previous values are not discarded. This
+             *     allow for incremental filling of a property.
+             *
+             * The code below prepares an array of elements to be converted and wraps that
+             * array in a List (to be converted to a Set after this block if required). It
+             * is okay to convert the elements after the List creation since the list is
a
+             * wrapper.
+             */
+            final boolean isCollection = (newValue instanceof Collection<?>);
+            final Object[] elements = isCollection ? ((Collection<?>) newValue).toArray()
: new Object[] {newValue};
+            final List<Object> elementList = Arrays.asList(elements); // Converted
later (see above comment).
+            newValue = elementList; // Still contains the same values, but now guaranteed
to be a collection.
+            Collection<?> addTo = null;
+            if (!isCollection || append) {
+                if (oldValue == null) {
+                    oldValue = get(getter, metadata);
+                }
+                if (oldValue != null) {
+                    addTo = (Collection<?>) oldValue;
+                    if (addTo instanceof CheckedContainer<?>) {
                         // Get the explicitly-specified element type.
                         elementType = ((CheckedContainer<?>) addTo).getElementType();
                     }
-                }
-                if (elementType != null) {
-                    converter = convert(elements, elementType, converter);
-                }
-                /*
-                 * We now have objects of the appropriate type. If we have a singleton to
be added
-                 * in an existing collection, add it now. In that case the 'newValue' should
refer
-                 * to the 'addTo' collection. We rely on the ModifiableMetadata.writeCollection(…)
-                 * optimization for detecting that the new collection is the same instance
than
-                 * the old one so there is nothing to do. We could exit from the method,
but let
-                 * it continues in case the user override the 'setFoo(...)' method.
-                 */
-                if (addTo != null) {
-                    /*
-                     * Unsafe addition into a collection. In SIS implementation, the collection
is
-                     * actually an instance of CheckedCollection, so the check will be performed
at
-                     * runtime. However other implementations could use unchecked collection.
-                     * There is not much we can do...
-                     */
-                    // No @SuppressWarnings because this is a real hole.
-                    ((Collection<Object>) addTo).add(elements[0]);
+                    newValue = addTo;
                 }
             }
+            if (elementType != null) {
+                convert(elements, elementType);
+            }
             /*
-             * If the expected type was not a collection, the conversion of user value happen
-             * here. Otherwise conversion from List to Set (if needed) happen here.
+             * We now have objects of the appropriate type. If we have a singleton to be
added
+             * in an existing collection, add it now. In that case the 'newValue' should
refer
+             * to the 'addTo' collection. We rely on the ModifiableMetadata.writeCollection(…)
+             * optimization for detecting that the new collection is the same instance than
+             * the old one so there is nothing to do. We could exit from the method, but
let
+             * it continues in case the user override the 'setFoo(…)' method.
              */
-            newValues[0] = newValue;
-            converter = convert(newValues, targetType, converter);
+            if (addTo != null) {
+                /*
+                 * Unsafe addition into a collection. In SIS implementation, the collection
is
+                 * actually an instance of CheckedCollection, so the check will be performed
at
+                 * runtime. However other implementations could use unchecked collection.
+                 * There is not much we can do...
+                 */
+                // No @SuppressWarnings because this is a real hole.
+                ((Collection) addTo).addAll(elementList);
+            }
         }
-        return converter;
+        /*
+         * If the expected type was not a collection, the conversion of user value happen
+         * here. Otherwise conversion from List to Set (if needed) happen here.
+         */
+        newValues[0] = newValue;
+        convert(newValues, targetType);
     }
 
     /**
      * Converts values in the specified array to the given type.
-     * The given converter will be used if suitable, or a new one fetched otherwise.
+     * The array content is modified in-place. This method accepts an array instead than
+     * a single value because the values to convert may be the content of a collection.
      *
      * @param  elements   The array which contains element to convert.
      * @param  targetType The base type of target elements.
-     * @param  converter  The proposed converter, or {@code null}.
-     * @return The last converter used, or {@code null}.
      * @throws ClassCastException If an element can't be converted.
      */
     @SuppressWarnings({"unchecked","rawtypes"})
-    private static ObjectConverter<?,?> convert(final Object[] elements, final Class<?>
targetType,
-            ObjectConverter<?,?> converter) throws ClassCastException
-    {
+    private void convert(final Object[] elements, final Class<?> targetType) throws
ClassCastException {
+        boolean hasNewConverter = false;
+        ObjectConverter<?,?> converter = null;
         for (int i=0; i<elements.length; i++) {
             final Object value = elements[i];
             if (value != null) {
                 final Class<?> sourceType = value.getClass();
                 if (!targetType.isAssignableFrom(sourceType)) try {
-                    if (converter == null
-                            || !converter.getSourceClass().isAssignableFrom(sourceType)
-                            || !targetType.isAssignableFrom(converter.getTargetClass()))
+                    if (converter == null) {
+                        converter = lastConverter; // Volatile field - read only if needed.
+                    }
+                    // Require the exact same classes, not parent or subclass,
+                    // otherwise the converter could be stricter than necessary.
+                    if (converter == null || converter.getSourceClass() != sourceType
+                                          || converter.getTargetClass() != targetType)
                     {
                         converter = ObjectConverters.find(sourceType, targetType);
+                        hasNewConverter = true;
                     }
                     elements[i] = ((ObjectConverter) converter).convert(value);
                 } catch (UnconvertibleObjectException cause) {
@@ -912,7 +935,9 @@ final class PropertyAccessor {
                 }
             }
         }
-        return converter;
+        if (hasNewConverter) {
+            lastConverter = converter; // Volatile field - store only if needed.
+        }
     }
 
     /**
@@ -1005,27 +1030,26 @@ final class PropertyAccessor {
     }
 
     /**
-     * Copies all non-empty metadata from source to target. The source can be any implementation
+     * Appends all non-empty metadata from source to target. The source can be any implementation
      * of the metadata interface, but the target must be the implementation expected by this
class.
      *
      * <p>If the source contains any null or empty properties, then those properties
will
-     * <strong>not</strong> overwrite the corresponding properties in the destination
metadata.</p>
+     * not overwrite the corresponding properties in the destination metadata.</p>
      *
      * @param  source The metadata to copy.
-     * @param  target The target metadata.
+     * @param  target The target metadata where to append.
      * @return {@code true} in case of success, or {@code false} if at least
      *         one setter method was not found.
      * @throws UnmodifiableMetadataException if the target metadata is unmodifiable.
      * @throws BackingStoreException If the implementation threw a checked exception.
      */
-    public boolean shallowCopy(final Object source, final Object target)
+    public boolean append(final Object source, final Object target)
             throws UnmodifiableMetadataException, BackingStoreException
     {
         // Because this PropertyAccesssor is designed for the target, we must
         // check if the extra methods are suitable for the source object.
-        ObjectConverter<?,?> converter = this.converter;
-        boolean success = true;
         assert type.isInstance(source) : Classes.getClass(source);
+        boolean success = true;
         final Object[] arguments = new Object[1];
         for (int i=0; i<standardCount; i++) {
             final Method getter = getters[i];
@@ -1036,14 +1060,13 @@ final class PropertyAccessor {
                 }
                 final Method setter = setters[i];
                 if (setter != null) {
-                    converter = convert(getter, target, null, arguments, elementTypes[i],
converter);
+                    convert(getter, target, null, arguments, elementTypes[i], true);
                     set(setter, target, arguments);
                 } else {
                     success = false;
                 }
             }
         }
-        this.converter = converter;
         return success;
     }
 

Modified: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java?rev=1478414&r1=1478413&r2=1478414&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/MetadataStandardTest.java
[UTF-8] Thu May  2 15:30:13 2013
@@ -89,21 +89,21 @@ public final strictfp class MetadataStan
     }
 
     /**
-     * Tests the shallow copy. For this test, we need to use a class that doesn't have any
{@code getIdentifiers()}
+     * Tests appending values. For this test, we need to use a class that doesn't have any
{@code getIdentifiers()}
      * method inherited from GeoAPI interfaces. The class will inherit the {@code getIdentifiers()}
method defined
      * by SIS in the parent class, which doesn't have corresponding {@code setIdentifiers(...)}
method.
      */
     @Test
-    public void testShallowCopy() {
+    public void testAppend() {
         final AbstractCompleteness source = new AbstractCompleteness();
         final AbstractCompleteness target = new AbstractCompleteness();
         source.setMeasureDescription(new SimpleInternationalString("Some description"));
-        target.getStandard().shallowCopy(source, target);
+        target.getStandard().append(source, target);
         assertEquals("Copy of measureDescription:", "Some description", target.getMeasureDescription().toString());
         assertEquals("Copy of measureDescription:", source, target);
 
         source.setMeasureDescription(null);
-        target.getStandard().shallowCopy(source, target);
+        target.getStandard().append(source, target);
         assertEquals("Measure description should not have been removed, since we skipped
null values.",
                 "Some description", target.getMeasureDescription().toString());
     }

Modified: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java?rev=1478414&r1=1478413&r2=1478414&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
[UTF-8] Thu May  2 15:30:13 2013
@@ -327,14 +327,14 @@ public final strictfp class PropertyAcce
     }
 
     /**
-     * Tests the {@link PropertyAccessor#shallowCopy(Object, Object)} method.
+     * Tests the {@link PropertyAccessor#append(Object, Object)} method.
      */
     @Test
-    public void testShallowCopy() {
+    public void testAppend() {
         final DefaultCitation original = HardCodedCitations.ISO;
         final DefaultCitation copy = new DefaultCitation();
         final PropertyAccessor accessor = createPropertyAccessor();
-        assertTrue("The copy should have modified the destination.", accessor.shallowCopy(original,
copy));
+        assertTrue("The copy should have modified the destination.", accessor.append(original,
copy));
         assertEquals("International Organization for Standardization", copy.getTitle().toString());
 
         Collection<?> values = copy.getAlternateTitles();

Modified: sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java?rev=1478414&r1=1478413&r2=1478414&view=diff
==============================================================================
--- sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultCitationDateTest.java
[UTF-8] Thu May  2 15:30:13 2013
@@ -41,7 +41,7 @@ public final strictfp class DefaultCitat
      * @see <a href="http://jira.geotoolkit.org/browse/GEOTK-170">GEOTK-170</a>
      */
     @Test
-    public void testShallowCopy() {
+    public void testCopyConstructor() {
         final CitationDate original = new CitationDate() {
             @Override public Date     getDate()     {return new Date(1305716658508L);}
             @Override public DateType getDateType() {return DateType.CREATION;}



Mime
View raw message