Class ModifiableMetadata

  • All Implemented Interfaces:
    Emptiable, Lenient­Comparable
    Direct Known Subclasses:
    ISOMetadata

    public abstract class ModifiableMetadata
    extends AbstractMetadata
    Base class of metadata having an editable content. Newly created Modifiable­Metadata are initially in editable state. The metadata can be populated using the setter methods provided by subclasses, then transition to the final state for making it safe to share by many consumers.
    Tip for subclass implementations
    Subclasses can follow the pattern below for every get and set methods, with a different processing for singleton value or for collections.
    public class MyMetadata {
    
        // ==== Example for a singleton value =============================
    
        private Foo property;
    
        public Foo getProperty() {
            return property;
        }
    
        public void setProperty(Foo newValue) {
            checkWritePermission();
            property = newValue;
        }
    
        // ==== Example for a collection ==================================
    
        private Collection<Foo> properties;
    
        public Collection<Foo> getProperties() {
            return properties = nonNullCollection(properties, Foo.class);
        }
    
        public void setProperties(Collection<Foo> newValues) {
            // the call to checkWritePermission() is implicit
            properties = writeCollection(newValues, properties, Foo.class);
        }
    }
    Since:
    0.3

    Defined in the sis-metadata module

    • Method Detail

      • state

        public ModifiableMetadata.State state()
        Tells whether this instance of metadata is editable. This is initially Modifiable­Metadata​.State​.EDITABLE for new Modifiable­Metadata instances, but can be changed by a call to transition­To(State).

        Modifiable­Metadata​.State​.FINAL implies that all properties are also final. This recursivity does not necessarily apply to other states. For example Modifiable­Metadata​.State​.EDITABLE does not imply that all Modifiable­Metadata children are also editable.

        API note: the Modifiable­Metadata state is not a metadata per se, but rather an information about this particular instance of a metadata class. Two metadata instances may be in different states but still have the same metadata content. For this reason, this method does not have get prefix for avoiding confusion with getter and setter methods of metadata properties.
        Returns:
        the state (editable, completable or final) of this Modifiable­Metadata instance.
        Since:
        1.0
      • isModifiable

        @Deprecated
        public final boolean isModifiable()
        Deprecated.
        Replaced by state() != State​.FINAL. See SIS-81.
        Returns true if this metadata is modifiable. This method returns false if freeze() has been invoked on this object.
        Returns:
        true if this metadata is modifiable.
        See Also:
        freeze(), check­Write­Permission()
      • unmodifiable

        @Deprecated
        public AbstractMetadata unmodifiable()
        Deprecated.
        Replaced by Metadata­Copier​.for­Modifiable(get­Standard()).copy(this)​.transition(State​.FINAL).
        Returns an unmodifiable copy of this metadata. Any attempt to modify a property of the returned object will throw an Unmodifiable­Metadata­Exception. The state of this object is not modified.

        This method is useful for reusing the same metadata object as a template. For example:

        DefaultCitation myCitation = new DefaultCitation();
        myCitation.setTitle(new SimpleInternationalString("The title of my book"));
        myCitation.setEdition(new SimpleInternationalString("First edition"));
        final Citation firstEdition = (Citation) myCitation.unmodifiable();
        
        myCitation.setEdition(new SimpleInternationalString("Second edition"));
        final Citation secondEdition = (Citation) myCitation.unmodifiable();
        // The title of the second edition is unchanged compared to the first edition.
        The default implementation makes the following choice:
        • If this metadata is itself unmodifiable, then this method returns this unchanged.
        • Otherwise this method clone this metadata and freeze the clone before to return it.
        Returns:
        an unmodifiable copy of this metadata.
        See Also:
        Metadata­Copier
      • freeze

        @Deprecated
        public void freeze()
        Deprecated.
        Replaced by transition(State​.FINAL).
        Declares this metadata and all its properties as unmodifiable. Any attempt to modify a property after this method call will throw an Unmodifiable­Metadata­Exception. If this metadata is already unmodifiable, then this method does nothing.

        Subclasses usually do not need to override this method since the default implementation performs its work using Java reflection.

        See Also:
        state(), check­Write­Permission()
      • checkWritePermission

        protected void checkWritePermission​(Object current)
                                     throws UnmodifiableMetadataException
        Checks if changes in the metadata are allowed. All set­Foo(…) methods in subclasses shall invoke this method (directly or indirectly) before to apply any change. The current property value should be specified in argument.
        Parameters:
        current - the current value, or null if none.
        Throws:
        Unmodifiable­Metadata­Exception - if this metadata is unmodifiable.
        Since:
        1.0
        See Also:
        state()
      • writeList

        protected final <E> List<E> writeList​(Collection<? extends E> source,
                                              List<E> target,
                                              Class<E> elementType)
                                       throws UnmodifiableMetadataException
        Writes the content of the source collection into the target list, creating it if needed. This method performs the following steps:
        • Invokes check­Write­Permission(Object) in order to ensure that this metadata is modifiable.
        • If source is null or empty, returns null (meaning that the metadata property is not provided).
        • If target is null, creates a new List.
        • Copies the content of the given source into the target.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        source - the source list, or null.
        target - the target list, or null if not yet created.
        element­Type - the base type of elements to put in the list.
        Returns:
        a list (possibly the target instance) containing the source elements, or null if the source was null.
        Throws:
        Unmodifiable­Metadata­Exception - if this metadata is unmodifiable.
        See Also:
        non­Null­List(List, Class)
      • writeSet

        protected final <E> Set<E> writeSet​(Collection<? extends E> source,
                                            Set<E> target,
                                            Class<E> elementType)
                                     throws UnmodifiableMetadataException
        Writes the content of the source collection into the target set, creating it if needed. This method performs the following steps:
        • Invokes check­Write­Permission(Object) in order to ensure that this metadata is modifiable.
        • If source is null or empty, returns null (meaning that the metadata property is not provided).
        • If target is null, creates a new Set.
        • Copies the content of the given source into the target.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        source - the source set, or null.
        target - the target set, or null if not yet created.
        element­Type - the base type of elements to put in the set.
        Returns:
        a set (possibly the target instance) containing the source elements, or null if the source was null.
        Throws:
        Unmodifiable­Metadata­Exception - if this metadata is unmodifiable.
        See Also:
        non­Null­Set(Set, Class)
      • writeCollection

        protected final <E> Collection<E> writeCollection​(Collection<? extends E> source,
                                                          Collection<E> target,
                                                          Class<E> elementType)
                                                   throws UnmodifiableMetadataException
        Writes the content of the source collection into the target list or set, creating it if needed. This method performs the following steps:
        • Invokes check­Write­Permission(Object) in order to ensure that this metadata is modifiable.
        • If source is null or empty, returns null (meaning that the metadata property is not provided).
        • If target is null, creates a new Set or a new List depending on the value returned by collection­Type(Class).
        • Copies the content of the given source into the target.
        Choosing a collection type
        Implementations shall invoke write­List or write­Set methods instead than this method when the collection type is enforced by ISO specification. When the type is not enforced by the specification, some freedom are allowed at implementer choice. The default implementation invokes collection­Type(Class) in order to get a hint about whether a List or a Set should be used.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        source - the source collection, or null.
        target - the target collection, or null if not yet created.
        element­Type - the base type of elements to put in the collection.
        Returns:
        a collection (possibly the target instance) containing the source elements, or null if the source was null.
        Throws:
        Unmodifiable­Metadata­Exception - if this metadata is unmodifiable.
      • writeMap

        protected final <K,​V> Map<K,​V> writeMap​(Map<? extends K,​? extends V> source,
                                                            Map<K,​V> target,
                                                            Class<K> keyType)
                                                     throws UnmodifiableMetadataException
        Writes the content of the source map into the target map, creating it if needed. This method performs the following steps:
        • Invokes check­Write­Permission(Object) in order to ensure that this metadata is modifiable.
        • If source is null or empty, returns null (meaning that the metadata property is not provided).
        • If target is null, creates a new Map.
        • Copies the content of the given source into the target.
        Type Parameters:
        K - the type of keys represented by the Class argument.
        V - the type of values in the map.
        Parameters:
        source - the source map, or null.
        target - the target map, or null if not yet created.
        key­Type - the base type of keys to put in the map.
        Returns:
        a map (possibly the target instance) containing the source entries, or null if the source was null.
        Throws:
        Unmodifiable­Metadata­Exception - if this metadata is unmodifiable.
        Since:
        1.0
        See Also:
        non­Null­Map(Map, Class)
      • copyList

        protected final <E> List<E> copyList​(Collection<? extends E> source,
                                             Class<E> elementType)
        Creates a list with the content of the source collection, or returns null if the source is null or empty. This is a convenience method for copying fields in subclass copy constructors.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        source - the source collection, or null.
        element­Type - the base type of elements to put in the list.
        Returns:
        a list containing the source elements, or null if the source was null or empty.
      • copySet

        protected final <E> Set<E> copySet​(Collection<? extends E> source,
                                           Class<E> elementType)
        Creates a set with the content of the source collection, or returns null if the source is null or empty. This is a convenience method for copying fields in subclass copy constructors.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        source - the source collection, or null.
        element­Type - the base type of elements to put in the set.
        Returns:
        a set containing the source elements, or null if the source was null or empty.
      • copyCollection

        protected final <E> Collection<E> copyCollection​(Collection<? extends E> source,
                                                         Class<E> elementType)
        Creates a list or set with the content of the source collection, or returns null if the source is null or empty. This is a convenience method for copying fields in subclass copy constructors.

        The collection type is selected as described in the non­Null­Collection(Collection, Class).

        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        source - the source collection, or null.
        element­Type - the base type of elements to put in the collection.
        Returns:
        a collection containing the source elements, or null if the source was null or empty.
      • copyMap

        protected final <K,​V> Map<K,​V> copyMap​(Map<? extends K,​? extends V> source,
                                                           Class<K> keyType)
        Creates a map with the content of the source map, or returns null if the source is null or empty. This is a convenience method for copying fields in subclass copy constructors.
        Type Parameters:
        K - the type of keys represented by the Class argument.
        V - the type of values in the map.
        Parameters:
        source - the source map, or null.
        key­Type - the base type of keys to put in the map.
        Returns:
        a map containing the source entries, or null if the source was null or empty.
        Since:
        1.0
      • singleton

        protected final <E> Collection<E> singleton​(E value,
                                                    Class<E> elementType)
        Creates a singleton list or set containing only the given value, if non-null. This is a convenience method for initializing fields in subclass constructors.

        The collection type is selected as described in the non­Null­Collection(Collection, Class).

        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        value - the singleton value to put in the returned collection, or null.
        element­Type - the element type (used only if value is non-null).
        Returns:
        a new modifiable collection containing the given value, or null if the given value was null.
      • nonNullList

        protected final <E> List<E> nonNullList​(List<E> current,
                                                Class<E> elementType)
        Returns the specified list, or a new one if current is null. This is a convenience method for implementation of get­Foo() methods.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        current - the existing list, or null if the list has not yet been created.
        element­Type - the element type (used only if current is null).
        Returns:
        current, or a new list if current is null.
      • nonNullSet

        protected final <E> Set<E> nonNullSet​(Set<E> current,
                                              Class<E> elementType)
        Returns the specified set, or a new one if current is null. This is a convenience method for implementation of get­Foo() methods.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        current - the existing set, or null if the set has not yet been created.
        element­Type - the element type (used only if current is null).
        Returns:
        current, or a new set if current is null.
      • nonNullCollection

        protected final <E> Collection<E> nonNullCollection​(Collection<E> current,
                                                            Class<E> elementType)
        Returns the specified collection, or a new one if current is null. This is a convenience method for implementation of get­Foo() methods.
        Choosing a collection type
        Implementations shall invoke non­Null­List(…) or non­Null­Set(…) instead than this method when the collection type is enforced by ISO specification. When the type is not enforced by the specification, some freedom are allowed at implementer choice. The default implementation invokes collection­Type(Class) in order to get a hint about whether a List or a Set should be used.
        Type Parameters:
        E - the type represented by the Class argument.
        Parameters:
        current - the existing collection, or null if the collection has not yet been created.
        element­Type - the element type (used only if current is null).
        Returns:
        current, or a new collection if current is null.
      • nonNullMap

        protected final <K,​V> Map<K,​V> nonNullMap​(Map<K,​V> current,
                                                              Class<K> keyType)
        Returns the specified map, or a new one if current is null. This is a convenience method for implementation of get­Foo() methods.
        Type Parameters:
        K - the type of keys represented by the Class argument.
        V - the type of values in the map.
        Parameters:
        current - the existing map, or null if the map has not yet been created.
        key­Type - the key type (used only if current is null).
        Returns:
        current, or a new map if current is null.
        Since:
        1.0
      • collectionType

        protected <E> Class<? extends Collection<E>> collectionType​(Class<E> elementType)
        Returns the type of collection to use for the given type. The current implementation can return only two values: Set.class if the property should not accept duplicated values, or List.class otherwise. Future SIS versions may accept other types.

        The default implementation returns Set.class if the element type is assignable to Code­List, Enum, String, Charset, Locale or Currency, and List.class otherwise. Subclasses can override this method for choosing different kind of collections. Note however that Set should be used only with immutable element types, for hash code stability.

        Type Parameters:
        E - the type of elements in the collection to be created.
        Parameters:
        element­Type - the type of elements in the collection to be created.
        Returns:
        List​.class or Set​.class depending on whether the property shall accept duplicated values or not.