Search in sources :

Example 1 with DefaultRepresentativeFraction

use of org.apache.sis.metadata.iso.identification.DefaultRepresentativeFraction in project sis by apache.

the class Freezer method clone.

/**
 * Returns an unmodifiable copy of the specified object.
 * This method performs the following heuristic tests:
 *
 * <ul>
 *   <li>If the specified object is an instance of {@code ModifiableMetadata},
 *       then {@link ModifiableMetadata#unmodifiable()} is invoked on that object.</li>
 *   <li>Otherwise, if the object is a {@linkplain Collection collection}, then the
 *       content is copied into a new collection of similar type, with values replaced
 *       by their unmodifiable variant.</li>
 *   <li>Otherwise, if the object implements the {@link Cloneable} interface,
 *       then a clone is returned.</li>
 *   <li>Otherwise, the object is assumed immutable and returned unchanged.</li>
 * </ul>
 *
 * @param  object  the object to convert in an immutable one.
 * @return a presumed immutable view of the specified object.
 */
@Override
public Object clone(final Object object) throws CloneNotSupportedException {
    /*
         * CASE 1 - The object is an org.apache.sis.metadata.* implementation. It may have
         *          its own algorithm for creating an unmodifiable view of metadata.
         */
    if (object instanceof ModifiableMetadata) {
        return ((ModifiableMetadata) object).unmodifiable();
    }
    if (object instanceof DefaultRepresentativeFraction) {
        final DefaultRepresentativeFraction c = ((DefaultRepresentativeFraction) object).clone();
        c.freeze();
        return c;
    }
    /*
         * CASE 2 - The object is a collection. All elements are replaced by their
         *          unmodifiable variant and stored in a new collection of similar
         *          type.
         */
    if (object instanceof Collection<?>) {
        Collection<?> collection = (Collection<?>) object;
        final boolean isSet = (collection instanceof Set<?>);
        final Object[] array = collection.toArray();
        switch(array.length) {
            case 0:
                {
                    collection = isSet ? Collections.EMPTY_SET : Collections.EMPTY_LIST;
                    break;
                }
            case 1:
                {
                    final Object value = clone(array[0]);
                    collection = isSet ? Collections.singleton(value) : Collections.singletonList(value);
                    break;
                }
            default:
                {
                    if (isSet) {
                        if (collection instanceof EnumSet<?>) {
                            collection = Collections.unmodifiableSet(((EnumSet<?>) collection).clone());
                        } else if (collection instanceof CodeListSet<?>) {
                            collection = Collections.unmodifiableSet(((CodeListSet<?>) collection).clone());
                        } else {
                            clones(array);
                            collection = CollectionsExt.immutableSet(false, array);
                        }
                    } else {
                        /*
                         * Do not use the SIS Checked* classes since we don't need type checking anymore.
                         * Conservatively assumes a List if we are not sure to have a Set since the list
                         * is less destructive (no removal of duplicated values).
                         */
                        clones(array);
                        collection = UnmodifiableArrayList.wrap(array);
                    }
                    break;
                }
        }
        return collection;
    }
    /*
         * CASE 3 - The object is a map. Copies all entries in a new map and replaces all values
         *          by their unmodifiable variant. The keys are assumed already immutable.
         */
    if (object instanceof Map<?, ?>) {
        final Map<Object, Object> map = new LinkedHashMap<>((Map<?, ?>) object);
        for (final Map.Entry<Object, Object> entry : map.entrySet()) {
            entry.setValue(clone(entry.getValue()));
        }
        return CollectionsExt.unmodifiableOrCopy(map);
    }
    /*
         * CASE 4 - The object is presumed cloneable.
         */
    if (object instanceof Cloneable) {
        return super.clone(object);
    }
    /*
         * CASE 5 - Any other case. The object is assumed immutable and returned unchanged.
         */
    return object;
}
Also used : CodeListSet(org.apache.sis.util.collection.CodeListSet) DefaultRepresentativeFraction(org.apache.sis.metadata.iso.identification.DefaultRepresentativeFraction) LinkedHashMap(java.util.LinkedHashMap) Collection(java.util.Collection) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

Collection (java.util.Collection)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 DefaultRepresentativeFraction (org.apache.sis.metadata.iso.identification.DefaultRepresentativeFraction)1 CodeListSet (org.apache.sis.util.collection.CodeListSet)1