public abstract class ModifiableMetadata extends AbstractMetadata implements Cloneable
set*(…)
methods for each corresponding get*()
method. Subclasses can follow the pattern below for every get
and set
methods,
with a different processing for singleton value or for collections.
For singleton value:
public class MyMetadata { private Foo property; public Foo getProperty() { return property; } public void setProperty(Foo newValue) { checkWritePermission(); property = newValue; } }For collections (note that the call to
checkWritePermission()
is implicit):
public class MyMetadata { private Collection<Foo> properties; public Collection<Foo> getProperties() { return properties = nonNullCollection(properties, Foo.class); } public void setProperties(Collection<Foo> newValues) { properties = writeCollection(newValues, properties, Foo.class); } }An initially modifiable metadata may become unmodifiable at a later stage (typically after its construction is completed) by the call to the
freeze()
method.Defined in the sis-metadata
module
Modifier | Constructor and Description |
---|---|
protected |
ModifiableMetadata()
Constructs an initially empty metadata.
|
Modifier and Type | Method and Description |
---|---|
protected void |
checkWritePermission()
Checks if changes in the metadata are allowed.
|
protected ModifiableMetadata |
clone()
Creates a shallow copy of this metadata.
|
protected <E> Class<? extends Collection<E>> |
collectionType(Class<E> elementType)
Returns the type of collection to use for the given type.
|
protected <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. |
protected <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. |
protected <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. |
void |
freeze()
Declares this metadata and all its properties as unmodifiable.
|
boolean |
isModifiable()
Returns
true if this metadata is modifiable. |
protected <E> Collection<E> |
nonNullCollection(Collection<E> c,
Class<E> elementType)
Returns the specified collection, or a new one if
c is null. |
protected <E> List<E> |
nonNullList(List<E> c,
Class<E> elementType)
Returns the specified list, or a new one if
c is null. |
protected <E> Set<E> |
nonNullSet(Set<E> c,
Class<E> elementType)
Returns the specified set, or a new one if
c is null. |
protected <E> Collection<E> |
singleton(E value,
Class<E> elementType)
Creates a singleton list or set containing only the given value, if non-null.
|
AbstractMetadata |
unmodifiable()
Returns an unmodifiable copy of this metadata.
|
protected <E> Collection<E> |
writeCollection(Collection<? extends E> source,
Collection<E> target,
Class<E> elementType)
Writes the content of the
source collection into the target list or set,
creating it if needed. |
protected <E> List<E> |
writeList(Collection<? extends E> source,
List<E> target,
Class<E> elementType)
Writes the content of the
source collection into the target list,
creating it if needed. |
protected <E> Set<E> |
writeSet(Collection<? extends E> source,
Set<E> target,
Class<E> elementType)
Writes the content of the
source collection into the target set,
creating it if needed. |
asMap, asTreeTable, equals, equals, getInterface, getStandard, hashCode, isEmpty, prune, toString
protected ModifiableMetadata()
public final boolean isModifiable()
true
if this metadata is modifiable. This method returns
false
if freeze()
has been invoked on this object.true
if this metadata is modifiable.freeze()
,
checkWritePermission()
public AbstractMetadata unmodifiable()
UnmodifiableMetadataException
. 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:
MetadataCopier
public void freeze()
UnmodifiableMetadataException
.
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.
isModifiable()
,
checkWritePermission()
protected void checkWritePermission() throws UnmodifiableMetadataException
setFoo(…)
methods in subclasses
shall invoke this method (directly or indirectly) before to apply any change.UnmodifiableMetadataException
- if this metadata is unmodifiable.isModifiable()
,
freeze()
protected final <E> List<E> writeList(Collection<? extends E> source, List<E> target, Class<E> elementType) throws UnmodifiableMetadataException
source
collection into the target
list,
creating it if needed. This method performs the following steps:
checkWritePermission()
in order to ensure that this metadata is modifiable.source
is null or empty, returns null
(meaning that the metadata property is not provided).target
is null, creates a new List
.source
into the target.E
- the type represented by the Class
argument.source
- the source list, or null
.target
- the target list, or null
if not yet created.elementType
- the base type of elements to put in the list.target
instance) containing the source
elements, or null
if the source was null.UnmodifiableMetadataException
- if this metadata is unmodifiable.nonNullList(List, Class)
protected final <E> Set<E> writeSet(Collection<? extends E> source, Set<E> target, Class<E> elementType) throws UnmodifiableMetadataException
source
collection into the target
set,
creating it if needed. This method performs the following steps:
checkWritePermission()
in order to ensure that this metadata is modifiable.source
is null or empty, returns null
(meaning that the metadata property is not provided).target
is null, creates a new Set
.source
into the target.E
- the type represented by the Class
argument.source
- the source set, or null
.target
- the target set, or null
if not yet created.elementType
- the base type of elements to put in the set.target
instance) containing the source
elements,
or null
if the source was null.UnmodifiableMetadataException
- if this metadata is unmodifiable.nonNullSet(Set, Class)
protected final <E> Collection<E> writeCollection(Collection<? extends E> source, Collection<E> target, Class<E> elementType) throws UnmodifiableMetadataException
source
collection into the target
list or set,
creating it if needed. This method performs the following steps:
checkWritePermission()
in order to ensure that this metadata is modifiable.source
is null or empty, returns null
(meaning that the metadata property is not provided).target
is null, creates a new Set
or a new List
depending on the value returned by collectionType(Class)
.source
into the target.writeList
or writeSet
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
implementor choice. The default implementation invokes collectionType(Class)
in order to get a hint about whether a List
or a Set
should be used.E
- the type represented by the Class
argument.source
- the source collection, or null
.target
- the target collection, or null
if not yet created.elementType
- the base type of elements to put in the collection.target
instance) containing the source
elements,
or null
if the source was null.UnmodifiableMetadataException
- if this metadata is unmodifiable.protected final <E> List<E> copyList(Collection<? extends E> source, Class<E> elementType)
source
collection,
or returns null
if the source is null
or empty.
This is a convenience method for copying fields in subclass copy constructors.E
- the type represented by the Class
argument.source
- the source collection, or null
.elementType
- the base type of elements to put in the list.source
elements,
or null
if the source was null or empty.protected final <E> Set<E> copySet(Collection<? extends E> source, Class<E> elementType)
source
collection,
or returns null
if the source is null
or empty.
This is a convenience method for copying fields in subclass copy constructors.E
- the type represented by the Class
argument.source
- the source collection, or null
.elementType
- the base type of elements to put in the set.source
elements,
or null
if the source was null or empty.protected final <E> Collection<E> copyCollection(Collection<? extends E> source, Class<E> elementType)
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
nonNullCollection(Collection, Class)
.
E
- the type represented by the Class
argument.source
- the source collection, or null
.elementType
- the base type of elements to put in the collection.source
elements,
or null
if the source was null or empty.protected final <E> Collection<E> singleton(E value, Class<E> elementType)
The collection type is selected as described in the
nonNullCollection(Collection, Class)
.
E
- the type represented by the Class
argument.value
- the singleton value to put in the returned collection, or null
.elementType
- the element type (used only if value
is non-null).null
if the given value was null.protected final <E> List<E> nonNullList(List<E> c, Class<E> elementType)
c
is null.
This is a convenience method for implementation of getFoo()
methods.E
- the type represented by the Class
argument.c
- the existing list, or null
if the list has not yet been created.elementType
- the element type (used only if c
is null).c
, or a new list if c
is null.protected final <E> Set<E> nonNullSet(Set<E> c, Class<E> elementType)
c
is null.
This is a convenience method for implementation of getFoo()
methods.E
- the type represented by the Class
argument.c
- the existing set, or null
if the set has not yet been created.elementType
- the element type (used only if c
is null).c
, or a new set if c
is null.protected final <E> Collection<E> nonNullCollection(Collection<E> c, Class<E> elementType)
c
is null.
This is a convenience method for implementation of getFoo()
methods.
nonNullList(…)
or nonNullSet(…)
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 implementor choice.
The default implementation invokes collectionType(Class)
in order to get a hint about whether
a List
or a Set
should be used.E
- the type represented by the Class
argument.c
- the existing collection, or null
if the collection has not yet been created.elementType
- the element type (used only if c
is null).c
, or a new collection if c
is null.protected <E> Class<? extends Collection<E>> collectionType(Class<E> elementType)
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 CodeList
, 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.
E
- the type of elements in the collection to be created.elementType
- the type of elements in the collection to be created.List.class
or Set.class
depending on whether the
property shall accept duplicated values or not.protected ModifiableMetadata clone() throws CloneNotSupportedException
unmodifiable()
method,
which needs shallow copies of metadata entities.
For deep copies, see MetadataCopier
.
Cloneable
, the ModifiableMetadata
subclasses should not provide
the clone()
operation as part of their public API, because the cloned object
share reference to the same collections than the original object.
Object.clone()
implementation is sufficient in most cases.
The need to override this method should be rare, but may happen if the object
contains for example connection to a database.clone
in class Object
CloneNotSupportedException
- if the clone is not supported.unmodifiable()
,
MetadataCopier
Copyright © 2010–2017 The Apache Software Foundation. All rights reserved.