You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2014/07/12 00:58:30 UTC
svn commit: r1609863 [1/2] - in /sis/branches/JDK7: ./
core/sis-feature/src/main/java/org/apache/sis/feature/
core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/
core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/
core/sis-...
Author: desruisseaux
Date: Fri Jul 11 22:58:29 2014
New Revision: 1609863
URL: http://svn.apache.org/r1609863
Log:
Merge from the JDK8 branch.
Added:
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/LegacyTelephones.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/LegacyTelephones.java
sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultContactTest.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/citation/DefaultContactTest.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java
- copied, changed from r1609862, sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/RecordDefinition.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/RecordDefinition.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordSchemaTest.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordSchemaTest.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTest.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTest.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/SerializableRecordSchema.java
- copied unchanged from r1609862, sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/SerializableRecordSchema.java
Modified:
sis/branches/JDK7/ (props changed)
sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_RestrictionCode.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/AbstractParty.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java
sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java
sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java
sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/constraint/DefaultLegalConstraintsTest.java
sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/package-info.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.java
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages.properties
sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/resources/Messages_fr.properties
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/CollectionsExtTest.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/util/iso/TypesTest.java
Propchange: sis/branches/JDK7/
------------------------------------------------------------------------------
Merged /sis/branches/JDK8:r1607690-1609862
Modified: sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/DefaultFeatureType.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -276,9 +276,9 @@ public class DefaultFeatureType extends
minimumOccurs = ((AttributeType<?>) property).getMinimumOccurs();
maximumOccurs = ((AttributeType<?>) property).getMaximumOccurs();
isSimple &= (minimumOccurs == maximumOccurs);
- } else if (property instanceof FieldType) { // TODO: check for AssociationRole instead (after GeoAPI upgrade).
- minimumOccurs = ((FieldType) property).getMinimumOccurs();
- maximumOccurs = ((FieldType) property).getMaximumOccurs();
+ } else if (property instanceof FeatureAssociationRole) {
+ minimumOccurs = ((FeatureAssociationRole) property).getMinimumOccurs();
+ maximumOccurs = ((FeatureAssociationRole) property).getMaximumOccurs();
isSimple = false;
} else {
continue; // For feature operations, maximumOccurs is implicitly 0.
Modified: sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-feature/src/main/java/org/apache/sis/feature/FeatureFormat.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -198,7 +198,14 @@ header: for (int i=0; ; i++) {
if (feature != null) {
value = feature.getPropertyValue(propertyType.getName().toString());
if (value == null) {
- if (propertyType instanceof FieldType && ((FieldType) propertyType).getMinimumOccurs() == 0) {
+ if (propertyType instanceof AttributeType &&
+ ((AttributeType) propertyType).getMinimumOccurs() == 0)
+ {
+ continue; // If no value, skip the full row.
+ }
+ if (propertyType instanceof FeatureAssociationRole &&
+ ((FeatureAssociationRole) propertyType).getMinimumOccurs() == 0)
+ {
continue; // If no value, skip the full row.
}
}
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_RestrictionCode.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_RestrictionCode.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_RestrictionCode.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/code/MD_RestrictionCode.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -47,15 +47,27 @@ public final class MD_RestrictionCode ex
}
/**
- * {@inheritDoc}
+ * Fix the spelling of words that changed between ISO 19115:2003 and ISO 19115:2014,
+ * then wraps the proxy value into an adapter.
+ *
+ * <p>The spelling of "license" was changed to "licence" in latest standard, but XML
+ * marshalling shall use the previous spelling until XML schema are updated.</p>
+ *
+ * @param proxy The proxy version of {@link CodeList}, to be marshalled.
+ * @return The adapter that wraps the proxy value.
*/
@Override
protected MD_RestrictionCode wrap(CodeListProxy proxy) {
+ if ("licence".equals(proxy.codeListValue)) {
+ proxy.codeListValue = "license";
+ }
return new MD_RestrictionCode(proxy);
}
/**
- * {@inheritDoc}
+ * Returns the class of code list wrapped by this adapter.
+ *
+ * @return The code list class.
*/
@Override
protected Class<Restriction> getCodeListClass() {
@@ -75,10 +87,16 @@ public final class MD_RestrictionCode ex
/**
* Invoked by JAXB on unmarshalling.
+ * This method performs the reverse of the {@link #wrap(CodeListProxy)} spelling change:
+ * it converts "license" (ISO 19115:2003) to "licence" (ISO 19115:2014) in order to have
+ * only one {@code CodeList} instance for both.
*
* @param proxy The unmarshalled value.
*/
public void setElement(final CodeListProxy proxy) {
+ if ("license".equals(proxy.codeListValue)) {
+ proxy.codeListValue = "licence";
+ }
this.proxy = proxy;
}
}
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/LegacyPropertyAdapter.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -22,6 +22,7 @@ import java.util.Collections;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.sis.metadata.AbstractMetadata;
+import org.apache.sis.internal.jaxb.Context;
import org.apache.sis.util.resources.Messages;
import org.apache.sis.util.ArgumentChecks;
@@ -159,8 +160,8 @@ public abstract class LegacyPropertyAdap
}
caller.warningOccurred = true;
}
- MetadataUtilities.warning(callerClass, callerMethod,
- Messages.Keys.IgnoredPropertiesAfterFirst_1, valueClass);
+ Context.warningOccured(Context.current(), callerClass, callerMethod,
+ Messages.class, Messages.Keys.IgnoredPropertiesAfterFirst_1, valueClass);
}
return value;
}
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/Cloner.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -105,7 +105,11 @@ final class Cloner extends org.apache.si
} else {
// Conservatively assumes a List if we are not sure to have a Set,
// since the list is less destructive (no removal of duplicated).
- collection = Containers.unmodifiableList(array);
+ switch (array.length) {
+ case 0: collection = Collections.EMPTY_LIST; break; // Redundant with isEmpty(), but we are paranoiac.
+ case 1: collection = Collections.singletonList(array[0]); break;
+ default: collection = Containers.unmodifiableList(array); break;
+ }
}
}
return collection;
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/ModifiableMetadata.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -385,7 +385,7 @@ public abstract class ModifiableMetadata
if (unmodifiable == FREEZING) {
/*
* freeze() method is under progress. The source collection is already
- * an unmodifiable instance created by unmodifiable(Object).
+ * an unmodifiable instance created by Cloner.clone(Object).
*/
assert collectionType(elementType).isInstance(source);
return (Collection<E>) source;
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -1100,9 +1100,7 @@ class PropertyAccessor {
{
assert type.isInstance(metadata1) : metadata1;
assert type.isInstance(metadata2) : metadata2;
- final int count = (mode == ComparisonMode.STRICT &&
- EXTRA_GETTER.getDeclaringClass().isInstance(metadata2)) ? allCount : standardCount;
- for (int i=0; i<count; i++) {
+ for (int i=0; i<standardCount; i++) {
final Method method = getters[i];
final Object value1 = get(method, metadata1);
final Object value2 = get(method, metadata2);
@@ -1118,6 +1116,16 @@ class PropertyAccessor {
return false;
}
}
+ /*
+ * One final check for the IdentifiedObjects.getIdentifiers() collection.
+ */
+ if (mode == ComparisonMode.STRICT && EXTRA_GETTER.getDeclaringClass().isInstance(metadata2)) {
+ final Object value1 = get(EXTRA_GETTER, metadata1);
+ final Object value2 = get(EXTRA_GETTER, metadata2);
+ if (!isNullOrEmpty(value1) || !isNullOrEmpty(value2)) {
+ return Utilities.deepEquals(value1, value2, mode);
+ }
+ }
return true;
}
@@ -1134,7 +1142,20 @@ class PropertyAccessor {
final Cloner cloner = new Cloner();
for (int i=0; i<allCount; i++) {
final Method setter = setters[i];
- if (setter != null && !setter.isAnnotationPresent(Deprecated.class)) {
+ if (setter != null) {
+ if (setter.isAnnotationPresent(Deprecated.class)) {
+ /*
+ * We need to skip deprecated setter methods, because those methods may delegate
+ * their work to other setter methods in different objects and those objects may
+ * have been made unmodifiable by previous iteration in this loop. If we do not
+ * skip them, we get an UnmodifiableMetadataException in the call to set(…).
+ *
+ * Note that in some cases, only the setter method is deprecated, not the getter.
+ * This happen when Apache SIS classes represent a more recent ISO standard than
+ * the GeoAPI interfaces.
+ */
+ continue;
+ }
final Method getter = getters[i];
final Object source = get(getter, metadata);
final Object target = cloner.clone(source);
@@ -1142,7 +1163,7 @@ class PropertyAccessor {
arguments[0] = target;
set(setter, metadata, arguments);
/*
- * We invoke the set(...) method which do not perform type conversion
+ * We invoke the set(…) method variant that do not perform type conversion
* because we don't want it to replace the immutable collection created
* by ModifiableMetadata.unmodifiable(source). Conversion should not be
* required anyway because the getter method should have returned a value
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/AbstractParty.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/AbstractParty.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/AbstractParty.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/AbstractParty.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -28,7 +28,7 @@ import org.apache.sis.util.iso.Types;
/**
- * Information about the individual and / or organisation of the party.
+ * Information about the individual and / or organization of the party.
*
* @author Rémi Maréchal (Geomatys)
* @author Martin Desruisseaux (Geomatys)
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultCitation.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -174,7 +174,7 @@ public class DefaultCitation extends ISO
* Constructs a citation with the specified responsible party.
* This convenience constructor initializes the citation title
* to the first non-null of the following properties:
- * {@linkplain DefaultResponsibleParty#getOrganisationName() organisation name},
+ * {@linkplain DefaultResponsibleParty#getOrganisationName() organization name},
* {@linkplain DefaultResponsibleParty#getPositionName() position name} or
* {@linkplain DefaultResponsibleParty#getIndividualName() individual name}.
*
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultContact.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -16,6 +16,9 @@
*/
package org.apache.sis.metadata.iso.citation;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
@@ -24,7 +27,11 @@ import org.opengis.metadata.citation.Add
import org.opengis.metadata.citation.Contact;
import org.opengis.metadata.citation.Telephone;
import org.opengis.metadata.citation.OnlineResource;
+import org.opengis.metadata.citation.TelephoneType;
import org.apache.sis.metadata.iso.ISOMetadata;
+import org.apache.sis.util.resources.Messages;
+import org.apache.sis.internal.jaxb.Context;
+import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
/**
@@ -33,8 +40,9 @@ import org.apache.sis.metadata.iso.ISOMe
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Touraïvane (IRD)
* @author Cédric Briançon (Geomatys)
+ * @author Rémi Maréchal (Geomatys)
* @since 0.3 (derived from geotk-2.1)
- * @version 0.3
+ * @version 0.5
* @module
*/
@XmlType(name = "CI_Contact_Type", propOrder = {
@@ -49,22 +57,22 @@ public class DefaultContact extends ISOM
/**
* Serial number for inter-operability with different versions.
*/
- private static final long serialVersionUID = 3844283689911660546L;
+ private static final long serialVersionUID = -969735574940462381L;
/**
* Telephone numbers at which the organization or individual may be contacted.
*/
- private Telephone phone;
+ private Collection<Telephone> phones;
/**
- * Physical and email address at which the organization or individual may be contacted.
+ * Physical and email addresses at which the organization or individual may be contacted.
*/
- private Address address;
+ private Collection<Address> addresses;
/**
* On-line information that can be used to contact the individual or organization.
*/
- private OnlineResource onlineResource;
+ private Collection<OnlineResource> onlineResources;
/**
* Time period (including time zone) when individuals can contact the organization or individual.
@@ -77,6 +85,11 @@ public class DefaultContact extends ISOM
private InternationalString contactInstructions;
/**
+ * Type of the contact.
+ */
+ private InternationalString contactType;
+
+ /**
* Constructs an initially empty contact.
*/
public DefaultContact() {
@@ -89,7 +102,7 @@ public class DefaultContact extends ISOM
* organization, or {@code null} if none.
*/
public DefaultContact(final OnlineResource resource) {
- this.onlineResource = resource;
+ this.onlineResources = singleton(resource, OnlineResource.class);
}
/**
@@ -104,11 +117,12 @@ public class DefaultContact extends ISOM
public DefaultContact(final Contact object) {
super(object);
if (object != null) {
- phone = object.getPhone();
- address = object.getAddress();
- onlineResource = object.getOnlineResource();
+ phones = copyCollection(object.getPhones(), Telephone.class);
+ addresses = copyCollection(object.getAddresses(), Address.class);
+ onlineResources = copyCollection(object.getOnlineResources(), OnlineResource.class);
hoursOfService = object.getHoursOfService();
contactInstructions = object.getContactInstructions();
+ contactType = object.getContactType();
}
}
@@ -140,64 +154,208 @@ public class DefaultContact extends ISOM
/**
* Returns telephone numbers at which the organization or individual may be contacted.
*
+ * @return Telephone numbers at which the organization or individual may be contacted.
+ *
+ * @since 0.5
+ */
+ @Override
+ public Collection<Telephone> getPhones() {
+ return phones = nonNullCollection(phones, Telephone.class);
+ }
+
+ /**
+ * Sets telephone numbers at which the organization or individual may be contacted.
+ *
+ * @param newValues The new telephones.
+ *
+ * @since 0.5
+ */
+ public void setPhones(Collection<? extends Telephone> newValues) {
+ phones = writeCollection(newValues, phones, Telephone.class);
+ /*
+ * Code below this point will be deleted after we removed the deprecated methods in DefaultTelephone.
+ * This code notifies all DefaultTelephone instances about the the list of phones in order to allow
+ * the deprecated Telephone.getVoices() and Telephone.getFacsimiles() methods to fetches information
+ * from the phones list.
+ */
+ if (phones != null) {
+ boolean modified = false;
+ final Telephone[] p = phones.toArray(new Telephone[newValues.size()]);
+ for (int i=0; i<p.length; i++) {
+ final Telephone phone = p[i];
+ if (phone instanceof DefaultTelephone) {
+ p[i] = ((DefaultTelephone) phone).setOwner(phones);
+ modified |= (p[i] != phone);
+ }
+ }
+ if (modified) {
+ phones.clear();
+ phones.addAll(Arrays.asList(p));
+ }
+ }
+ }
+
+ /**
+ * Returns telephone numbers at which the organization or individual may be contacted.
+ * This method returns the first telephone number associated to {@link TelephoneType#VOICE}
+ * or {@link TelephoneType#FACSIMILE FACSIMILE}.
+ *
* @return Telephone numbers at which the organization or individual may be contacted, or {@code null}.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by {@link #getPhones()}.
*/
@Override
+ @Deprecated
@XmlElement(name = "phone")
- public Telephone getPhone() {
+ public final Telephone getPhone() {
+ Telephone phone = null;
+ if (phones != null) {
+ TelephoneType ignored = null;
+ for (final Telephone c : phones) {
+ final TelephoneType type = c.getNumberType();
+ if (TelephoneType.VOICE.equals(type) || TelephoneType.FACSIMILE.equals(type)) {
+ if (phone == null) {
+ phone = c;
+ }
+ } else if (ignored == null) {
+ ignored = type;
+ }
+ }
+ if (ignored != null) {
+ Context.warningOccured(Context.current(), DefaultContact.class, "getPhone",
+ Messages.class, Messages.Keys.IgnoredPropertyAssociatedTo_1, ignored.toString());
+ }
+ }
return phone;
}
/**
* Sets telephone numbers at which the organization or individual may be contacted.
+ * This method delegates to {@link #setPhones(Collection)}.
*
* @param newValue The new telephone, or {@code null} if none.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by {@link #setPhones(Collection)}.
*/
- public void setPhone(final Telephone newValue) {
- checkWritePermission();
- phone = newValue;
+ @Deprecated
+ public final void setPhone(Telephone newValue) {
+ Collection<Telephone> newValues = null;
+ if (newValue != null) {
+ if (newValue instanceof DefaultTelephone) {
+ newValues = ((DefaultTelephone) newValue).getOwner();
+ } else {
+ newValues = new ArrayList<>(4);
+ for (String number : newValue.getVoices()) {
+ newValues.add(new DefaultTelephone(number, TelephoneType.VOICE));
+ }
+ for (String number : newValue.getFacsimiles()) {
+ newValues.add(new DefaultTelephone(number, TelephoneType.FACSIMILE));
+ }
+ }
+ }
+ setPhones(newValues);
+ }
+
+ /**
+ * Returns the physical and email addresses at which the organization or individual may be contacted.
+ *
+ * @return Physical and email addresses at which the organization or individual may be contacted, or {@code null}.
+ *
+ * @since 0.5
+ */
+ @Override
+ public Collection<Address> getAddresses() {
+ return addresses = nonNullCollection(addresses, Address.class);
+ }
+
+ /**
+ * Sets the physical and email addresses at which the organization or individual may be contacted.
+ *
+ * @param newValues The new addresses.
+ *
+ * @since 0.5
+ */
+ public void setAddresses(final Collection<? extends Address> newValues) {
+ addresses = writeCollection(newValues, addresses, Address.class);
}
/**
* Returns the physical and email address at which the organization or individual may be contacted.
+ * This method returns the first {@link #getAddresses() adress} element, or null if none.
*
* @return Physical and email address at which the organization or individual may be contacted, or {@code null}.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by {@link #getAddresses()}.
*/
@Override
+ @Deprecated
@XmlElement(name = "address")
- public Address getAddress() {
- return address;
+ public final Address getAddress() {
+ return LegacyPropertyAdapter.getSingleton(addresses, Address.class, null, DefaultContact.class, "getAddress");
}
/**
* Sets the physical and email address at which the organization or individual may be contacted.
+ * This method delegates to {@link #setAddresses(Collection)}.
*
* @param newValue The new address, or {@code null} if none.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by {@link #setAddresses(Collectio)}.
*/
- public void setAddress(final Address newValue) {
- checkWritePermission();
- address = newValue;
+ @Deprecated
+ public final void setAddress(final Address newValue) {
+ setAddresses(LegacyPropertyAdapter.asCollection(newValue));
+ }
+
+ /**
+ * Returns on-line information that can be used to contact the individual or organization.
+ *
+ * @return On-line information that can be used to contact the individual or organization.
+ *
+ * @since 0.5
+ */
+ @Override
+ public Collection<OnlineResource> getOnlineResources() {
+ return onlineResources = nonNullCollection(onlineResources, OnlineResource.class);
+ }
+
+ /**
+ * Sets on-line information that can be used to contact the individual or organization.
+ *
+ * @param newValues The new online resources.
+ *
+ * @since 0.5
+ */
+ public void setOnlineResources(final Collection<? extends OnlineResource> newValues) {
+ onlineResources = writeCollection(newValues, onlineResources, OnlineResource.class);
}
/**
- * Return on-line information that can be used to contact the individual or organization.
+ * Returns on-line information that can be used to contact the individual or organization.
+ * This method returns the first {@link #getOnlineResources() online resource} element, or null if none.
*
* @return On-line information that can be used to contact the individual or organization, or {@code null}.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by {@link #getOnlineResources()}.
*/
@Override
+ @Deprecated
@XmlElement(name = "onlineResource")
public OnlineResource getOnlineResource() {
- return onlineResource;
+ return LegacyPropertyAdapter.getSingleton(onlineResources, OnlineResource.class, null, DefaultContact.class, "getOnlineResource");
}
/**
* Sets on-line information that can be used to contact the individual or organization.
+ * This method delegates to {@link #setOnlineResources(Collection)}.
*
* @param newValue The new online resource, or {@code null} if none.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by {@link #setOnlineResources(Collection)}.
*/
+ @Deprecated
public void setOnlineResource(final OnlineResource newValue) {
- checkWritePermission();
- onlineResource = newValue;
+ setOnlineResources(LegacyPropertyAdapter.asCollection(newValue));
}
/**
@@ -241,4 +399,30 @@ public class DefaultContact extends ISOM
checkWritePermission();
contactInstructions = newValue;
}
+
+ /**
+ * Type of the contact.
+ * Returns {@code null} if none.
+ *
+ * @return Type of the contact, or {@code null} if none.
+ *
+ * @since 0.5
+ */
+ @Override
+/// @XmlElement(name = "contactType")
+ public InternationalString getContactType() {
+ return contactType;
+ }
+
+ /**
+ * Sets new type of the contact.
+ *
+ * @param newValue The new type of the contact.
+ *
+ * @since 0.5
+ */
+ public void setContactType(final InternationalString newValue) {
+ checkWritePermission();
+ contactType = newValue;
+ }
}
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultResponsibleParty.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -30,7 +30,7 @@ import org.opengis.util.InternationalStr
* organizations associated with the dataset.
*
* @deprecated As of ISO 19115:2014, the {@code ResponsibleParty} type has been replaced by {@code Responsibility}
- * to allow more flexible associations of individuals, organisations, and roles.
+ * to allow more flexible associations of individuals, organizations, and roles.
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Touraïvane (IRD)
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/DefaultTelephone.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -1,4 +1,4 @@
-/*
+ /*
* 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.
@@ -16,22 +16,42 @@
*/
package org.apache.sis.metadata.iso.citation;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.XmlType;
import org.opengis.metadata.citation.Telephone;
+import org.opengis.metadata.citation.TelephoneType;
+import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.metadata.iso.ISOMetadata;
/**
* Telephone numbers for contacting the responsible individual or organization.
*
+ * {@section Differences between versions 2003 and 2014 of ISO 19115}
+ * For any contact having more than one telephone number, the way to organize the information
+ * changed significantly between the two versions of ISO standard:
+ *
+ * <ul>
+ * <li>In ISO 19115:2003, each {@code Contact} had only one {@code Telephone} instance, but that instance
+ * could have an arbitrary amount of "voice" and "facsimile" numbers. The methods (now deprecated) were
+ * {@link DefaultContact#getPhone()}, {@link #getVoices()} and {@link #getFacsimiles()}.</li>
+ * <li>In ISO 19115:2014, each {@code Contact} has an arbitrary amount of {@code Telephone} instances, and
+ * each telephone has exactly one number. The new methods are {@link DefaultContact#getPhones()},
+ * {@link #getNumber()} and {@link #getNumberType()}.</li>
+ * </ul>
+ *
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Cédric Briançon (Geomatys)
- * @since 0.3 (derived from geotk-2.1)
- * @version 0.3
+ * @author Rémi Maréchal (Geomatys)
+ * @since 0.5 (derived from geotk-2.1)
+ * @version 0.5
* @module
+ *
+ * @see DefaultContact#getPhones()
*/
@XmlType(name = "CI_Telephone_Type", propOrder = {
"voices",
@@ -42,17 +62,17 @@ public class DefaultTelephone extends IS
/**
* Serial number for inter-operability with different versions.
*/
- private static final long serialVersionUID = -1920621361930970869L;
+ private static final long serialVersionUID = 5156405432420742237L;
/**
- * Telephone numbers by which individuals can speak to the responsible organization or individual.
+ * Telephone number by which individuals can contact responsible organization or individual.
*/
- private Collection<String> voices;
+ private String number;
/**
- * Telephone numbers of a facsimile machine for the responsible organization or individual.
+ * Type of telephone number.
*/
- private Collection<String> facsimiles;
+ private TelephoneType numberType;
/**
* Constructs a default telephone.
@@ -61,6 +81,19 @@ public class DefaultTelephone extends IS
}
/**
+ * Constructs a telephone with the given number and type.
+ *
+ * @param number The telephone number, or {@code null}.
+ * @param numberType The type of telephone number, or {@code null}.
+ *
+ * @since 0.5
+ */
+ public DefaultTelephone(final String number, final TelephoneType numberType) {
+ this.number = number;
+ this.numberType = numberType;
+ }
+
+ /**
* Constructs a new instance initialized with the values from the specified metadata object.
* This is a <cite>shallow</cite> copy constructor, since the other metadata contained in the
* given object are not recursively copied.
@@ -72,8 +105,8 @@ public class DefaultTelephone extends IS
public DefaultTelephone(final Telephone object) {
super(object);
if (object != null) {
- voices = copyCollection(object.getVoices(), String.class);
- facsimiles = copyCollection(object.getFacsimiles(), String.class);
+ number = object.getNumber();
+ numberType = object.getNumberType();
}
}
@@ -103,42 +136,171 @@ public class DefaultTelephone extends IS
}
/**
+ * Returns the telephone number by which individuals can contact responsible organization or individual.
+ *
+ * @return Telephone number by which individuals can contact responsible organization or individual.
+ *
+ * @since 0.5
+ */
+ @Override
+/// @XmlElement(name = "number", required = true)
+ public String getNumber() {
+ return number;
+ }
+
+ /**
+ * Sets the telephone number by which individuals can contact responsible organization or individual.
+ *
+ * @param newValue The new telephone number by which individuals can contact responsible organization or individual.
+ *
+ * @since 0.5
+ */
+ public void setNumber(final String newValue) {
+ checkWritePermission();
+ number = newValue;
+ }
+
+ /**
+ * Returns the type of telephone number, or {@code null} if none.
+ *
+ * @return Type of telephone number, or {@code null} if none.
+ *
+ * @since 0.5
+ */
+ @Override
+/// @XmlElement(name = "numberType")
+ public TelephoneType getNumberType() {
+ return numberType;
+ }
+
+ /**
+ * Set the type of telephone number.
+ *
+ * @param newValue The new type of telephone number.
+ *
+ * @since 0.5
+ */
+ public void setNumberType(final TelephoneType newValue) {
+ checkWritePermission();
+ numberType = newValue;
+ }
+
+ /**
+ * For implementation of {@link #getVoices()} and {@link #getFacsimiles()} deprecated methods.
+ * Shall be the telephones list of the enclosing {@link DefaultContact} object.
+ *
+ * <p>This field references the same collection than {@link DefaultContact#phones} when possible.
+ * Note that the link between this collection and {@code DefaultContact.phones} is broken when
+ * {@link DefaultContact#freeze()} is invoked, since the {@code Cloner.clone(Object)} method
+ * creates a new (unmodifiable) collection.</p>
+ *
+ * @deprecated This field will be removed after we removed the deprecated public methods.
+ */
+ @Deprecated
+ private Collection<Telephone> owner;
+
+ /**
+ * Specifies the collection which contains this telephone number.
+ * This method is invoked by {@link DefaultContact#setPhones(Collection)}
+ * when the contact "takes possession" of a {@code DefaultTelephone}.
+ *
+ * <p>This method will be removed after we removed the deprecated public methods.</p>
+ *
+ * @param phones The collection which should contains this telephone number.
+ * @return {@code this}, or a copy of this instance if we conservatively choose to not modify this instance.
+ */
+ final DefaultTelephone setOwner(final Collection<Telephone> phones) {
+ if (owner != phones) {
+ if (owner != null && !CollectionsExt.identityEquals(owner.iterator(), phones.iterator())) {
+ final DefaultTelephone copy = new DefaultTelephone(this);
+ copy.owner = phones;
+ return copy;
+ }
+ owner = phones;
+ }
+ return this;
+ }
+
+ /**
+ * Returns the collection that own this telephone number, or create a new collection.
+ * Creating a new collection is needed when this phone number has not yet been given
+ * to a {@link DefaultContact}.
+ *
+ * <p>This method will be removed after we removed the deprecated public methods.</p>
+ */
+ final Collection<Telephone> getOwner() {
+ if (owner == null) {
+ if (isModifiable()) {
+ owner = new ArrayList<>(4);
+ owner.add(this);
+ } else {
+ owner = Collections.<Telephone>singletonList(this);
+ }
+ }
+ return owner;
+ }
+
+ /**
* Returns the telephone numbers by which individuals can speak to the responsible organization or individual.
+ * This method searches in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact that own
+ * this phone is known.
*
* @return Telephone numbers by which individuals can speak to the responsible organization or individual.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #getNumber() number}
+ * with {@link TelephoneType#VOICE}.
*/
@Override
+ @Deprecated
@XmlElement(name = "voice")
- public Collection<String> getVoices() {
- return voices = nonNullCollection(voices, String.class);
+ public final Collection<String> getVoices() {
+ return new LegacyTelephones(getOwner(), TelephoneType.VOICE);
}
/**
* Sets the telephone numbers by which individuals can speak to the responsible organization or individual.
+ * This method writes in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact that own
+ * this phone is known.
*
* @param newValues The new telephone numbers, or {@code null} if none.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #setNumber(String) number}
+ * with {@link TelephoneType#VOICE}.
*/
- public void setVoices(final Collection<? extends String> newValues) {
- voices = writeCollection(newValues, voices, String.class);
+ @Deprecated
+ public final void setVoices(final Collection<? extends String> newValues) {
+ ((LegacyTelephones) getVoices()).setValues(newValues);
}
/**
* Returns the telephone numbers of a facsimile machine for the responsible organization or individual.
+ * This method searches in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact
+ * that own this phone is known.
*
* @return Telephone numbers of a facsimile machine for the responsible organization or individual.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #getNumber() number}
+ * with {@link TelephoneType#FACSIMILE}.
*/
@Override
+ @Deprecated
@XmlElement(name = "facsimile")
- public Collection<String> getFacsimiles() {
- return facsimiles = nonNullCollection(facsimiles, String.class);
+ public final Collection<String> getFacsimiles() {
+ return new LegacyTelephones(getOwner(), TelephoneType.FACSIMILE);
}
/**
* Sets the telephone number of a facsimile machine for the responsible organization or individual.
+ * This method writes in the {@linkplain DefaultContact#getPhones() contact phones}, if the contact
+ * that own this phone is known.
*
* @param newValues The new telephone number, or {@code null} if none.
+ *
+ * @deprecated As of ISO 19115:2014, replaced by a {@linkplain #setNumber(String) number}
+ * with {@link TelephoneType#FACSIMILE}.
*/
- public void setFacsimiles(final Collection<? extends String> newValues) {
- facsimiles = writeCollection(newValues, facsimiles, String.class);
+ @Deprecated
+ public final void setFacsimiles(final Collection<? extends String> newValues) {
+ ((LegacyTelephones) getFacsimiles()).setValues(newValues);
}
}
Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/content/DefaultCoverageDescription.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -30,9 +30,9 @@ import org.opengis.metadata.content.Rang
import org.opengis.metadata.content.RangeElementDescription;
import org.opengis.util.RecordType;
import org.apache.sis.xml.Namespaces;
+import org.apache.sis.internal.jaxb.Context;
import org.apache.sis.util.resources.Messages;
import org.apache.sis.internal.metadata.LegacyPropertyAdapter;
-import org.apache.sis.internal.metadata.MetadataUtilities;
/**
@@ -229,8 +229,8 @@ public class DefaultCoverageDescription
if (type == null) {
type = t;
} else {
- MetadataUtilities.warning(DefaultCoverageDescription.class, "getContentType",
- Messages.Keys.IgnoredPropertiesAfterFirst_1, CoverageContentType.class);
+ Context.warningOccured(Context.current(), DefaultCoverageDescription.class, "getContentType",
+ Messages.class, Messages.Keys.IgnoredPropertiesAfterFirst_1, CoverageContentType.class);
break;
}
}
Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeNodeTest.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -86,7 +86,7 @@ public final strictfp class TreeNodeTest
final DefaultContact contact = new DefaultContact();
final DefaultAddress address = new DefaultAddress();
address.getElectronicMailAddresses().add("Some email");
- contact.setAddress(address);
+ contact.getAddresses().add(address);
party.setContactInfo(contact);
citation.getCitedResponsibleParties().add(party);
return citation;
@@ -236,7 +236,7 @@ public final strictfp class TreeNodeTest
ONE, // citedResponsibleParty
null, // individualName
null, // contactInfo
- null, // address
+ ZERO, // address
ZERO, // electronicMailAddress
null, // role
ZERO, // presentationForm
Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/DefaultMetadataTest.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -57,7 +57,7 @@ public final strictfp class DefaultMetad
private Object[] parameters;
/**
- * For internal {@code DefaultLegalConstraints} usage.
+ * For internal {@code DefaultMetadata} usage.
*
* @return {@code Object.class}.
*/
Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/constraint/DefaultLegalConstraintsTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/constraint/DefaultLegalConstraintsTest.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/constraint/DefaultLegalConstraintsTest.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/constraint/DefaultLegalConstraintsTest.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -27,7 +27,7 @@ import org.apache.sis.util.logging.Warni
import org.apache.sis.test.XMLTestCase;
import org.junit.Test;
-import static org.junit.Assert.*;
+import static org.apache.sis.test.Assert.*;
import static org.apache.sis.test.TestUtilities.getSingleton;
@@ -36,7 +36,7 @@ import static org.apache.sis.test.TestUt
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
- * @version 0.4
+ * @version 0.5
* @module
*/
public final strictfp class DefaultLegalConstraintsTest extends XMLTestCase implements WarningListener<Object> {
@@ -119,4 +119,34 @@ public final strictfp class DefaultLegal
assertEquals("warning", "NullCollectionElement_1", resourceKey);
assertArrayEquals("warning", new String[] {"CodeListSet<Restriction>"}, parameters);
}
+
+ /**
+ * Tests (un)marshalling of a XML fragment containing the {@link Restriction#LICENCE} code.
+ * The spelling changed between ISO 19115:2003 and 19115:2014, from "license" to "licence".
+ * We need to ensure that XML marshalling use the old spelling, until the XML schema is updated.
+ *
+ * @throws JAXBException If an error occurred during the during unmarshalling processes.
+ */
+ @Test
+ public void testLicenceCode() throws JAXBException {
+ final String xml =
+ "<gmd:MD_LegalConstraints xmlns:gmd=\"" + Namespaces.GMD + "\">\n" +
+ " <gmd:useConstraints>\n" +
+ " <gmd:MD_RestrictionCode"
+ + " codeList=\"http://schemas.opengis.net/iso/19139/20070417/resources/Codelist/gmxCodelists.xml#MD_RestrictionCode\""
+ + " codeListValue=\"license\"" // Note the "s" - from old ISO 19115:2013 spelling.
+ + " codeSpace=\"eng\">Licence</gmd:MD_RestrictionCode>\n" + // Note the "c" - this one come from resource file.
+ " </gmd:useConstraints>\n" +
+ "</gmd:MD_LegalConstraints>\n";
+
+ final DefaultLegalConstraints c = new DefaultLegalConstraints();
+ c.getUseConstraints().add(Restriction.LICENCE);
+ assertXmlEquals(xml, marshal(c), "xmlns:*");
+ /*
+ * Unmarshall and ensure that we got back the original LICENCE code, not a new "LICENSE" code.
+ */
+ final DefaultLegalConstraints actual = unmarshal(xml);
+ assertSame(Restriction.LICENCE, getSingleton(actual.getUseConstraints()));
+ assertEquals(c, actual);
+ }
}
Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -60,6 +60,7 @@ import org.junit.BeforeClass;
org.apache.sis.xml.XLinkMarshallingTest.class,
// ISO implementations.
+ org.apache.sis.metadata.iso.citation.DefaultContactTest.class,
org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
org.apache.sis.metadata.iso.maintenance.DefaultScopeDescriptionTest.class,
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/CollectionsExt.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -51,7 +51,7 @@ import org.apache.sis.internal.jdk8.Func
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3 (derived from geotk-3.00)
- * @version 0.4
+ * @version 0.5
* @module
*/
public final class CollectionsExt extends Static {
@@ -634,4 +634,21 @@ public final class CollectionsExt extend
}
return map;
}
+
+ /**
+ * Returns {@code true} if the next elements returned by the given iterators are the same.
+ * This method compares using the identity operation ({@code ==}), not {@code equals(Object)}.
+ *
+ * @param it1 The first iterator.
+ * @param it2 The second iterator.
+ * @return If both iterators return the same objects.
+ */
+ public static boolean identityEquals(final Iterator<?> it1, final Iterator<?> it2) {
+ while (it1.hasNext()) {
+ if (!it2.hasNext() || it1.next() != it2.next()) {
+ return false;
+ }
+ }
+ return !it2.hasNext();
+ }
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultLocalName.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -60,6 +60,9 @@ import java.util.Objects;
* @since 0.3 (derived from geotk-2.1)
* @version 0.3
* @module
+ *
+ * @see DefaultNameSpace
+ * @see DefaultScopedName
*/
@XmlType(name = "LocalName") // Actually 'gml:CodeType', but the later is used elsewhere.
@XmlRootElement(name = "LocalName")
@@ -309,7 +312,7 @@ public class DefaultLocalName extends Ab
* Invoked by {@link #hashCode()} for computing the hash code value when first needed.
*/
@Override
- final int computeHashCode() {
+ int computeHashCode() {
return Objects.hash(scope, name) ^ (int) serialVersionUID;
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultMemberName.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -24,6 +24,9 @@ import org.opengis.util.TypeName;
import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+// Branch-dependent imports
+import java.util.Objects;
+
/**
* The name to identify a member of a {@linkplain org.opengis.util.Record record}.
@@ -41,8 +44,12 @@ import static org.apache.sis.util.Argume
*
* @author Guilhem Legal (Geomatys)
* @since 0.3 (derived from geotk-3.17)
- * @version 0.3
+ * @version 0.5
* @module
+ *
+ * @see DefaultTypeName
+ * @see DefaultNameFactory
+ * @see DefaultRecordType
*/
@XmlRootElement(name = "MemberName")
public class DefaultMemberName extends DefaultLocalName implements MemberName {
@@ -87,4 +94,23 @@ public class DefaultMemberName extends D
public TypeName getAttributeType() {
return attributeType;
}
+
+ /**
+ * Compares this member name with the specified object for equality.
+ *
+ * @param object The object to compare with this name for equality.
+ * @return {@code true} if the given object is equal to this name.
+ */
+ @Override
+ public boolean equals(final Object object) {
+ return super.equals(object) && Objects.equals(attributeType, ((DefaultMemberName) object).attributeType);
+ }
+
+ /**
+ * Invoked by {@link #hashCode()} for computing the hash code value when first needed.
+ */
+ @Override
+ final int computeHashCode() {
+ return super.computeHashCode() + Objects.hashCode(attributeType);
+ }
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameFactory.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -72,6 +72,13 @@ import static org.apache.sis.util.iso.De
* @since 0.3 (derived from geotk-2.1)
* @version 0.5
* @module
+ *
+ * @see Names
+ * @see DefaultNameSpace
+ * @see DefaultScopedName
+ * @see DefaultLocalName
+ * @see DefaultTypeName
+ * @see DefaultMemberName
*/
public class DefaultNameFactory extends AbstractFactory implements NameFactory {
/**
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultNameSpace.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -55,6 +55,12 @@ import java.util.Objects;
* @since 0.3 (derived from geotk-3.00)
* @version 0.3
* @module
+ *
+ * @see DefaultScopedName
+ * @see DefaultLocalName
+ * @see DefaultTypeName
+ * @see DefaultMemberName
+ * @see DefaultNameFactory
*/
public class DefaultNameSpace implements NameSpace, Serializable {
/**
@@ -78,8 +84,10 @@ public class DefaultNameSpace implements
* We don't use direct reference to {@code GLOBAL} because {@code null} is used as a sentinel
* value for stopping iterative searches (using GLOBAL would have higher risk of never-ending
* loops in case of bug), and in order to reduce the stream size during serialization.
+ *
+ * @see #parent()
*/
- final DefaultNameSpace parent;
+ private final DefaultNameSpace parent;
/**
* The name of this namespace, usually as a {@link String} or an {@link InternationalString}.
@@ -122,8 +130,7 @@ public class DefaultNameSpace implements
private transient WeakValueHashMap<String,Object> childs;
/**
- * Creates the global namespace. This constructor can be invoked by {@link GlobalNameSpace}
- * only.
+ * Creates the global namespace. This constructor can be invoked by {@link GlobalNameSpace} only.
*/
DefaultNameSpace() {
this.parent = null;
@@ -151,7 +158,7 @@ public class DefaultNameSpace implements
protected DefaultNameSpace(final DefaultNameSpace parent, CharSequence name,
final String headSeparator, final String separator)
{
- this.parent = parent;
+ this.parent = (parent != GlobalNameSpace.GLOBAL) ? parent : null;
ensureNonNull("name", name);
ensureNonNull("headSeparator", headSeparator);
ensureNonNull("separator", separator);
@@ -248,6 +255,13 @@ public class DefaultNameSpace implements
}
/**
+ * Returns the parent namespace, replacing null parent by {@link GlobalNameSpace#GLOBAL}.
+ */
+ final DefaultNameSpace parent() {
+ return (parent != null) ? parent : GlobalNameSpace.GLOBAL;
+ }
+
+ /**
* Returns the depth of the given namespace.
*
* @param ns The namespace for which to get the depth, or {@code null}.
@@ -398,7 +412,7 @@ public class DefaultNameSpace implements
}
}
}
- assert child.parent == this;
+ assert child.parent() == this;
return child;
}
@@ -518,7 +532,7 @@ public class DefaultNameSpace implements
* @return The unique instance.
*/
Object readResolve() {
- final DefaultNameSpace p = (parent != null) ? parent : GlobalNameSpace.GLOBAL;
+ final DefaultNameSpace p = parent();
final String key = key(name);
final WeakValueHashMap<String,Object> pool = p.childs;
synchronized (pool) {
Copied: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java (from r1609862, sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java?p2=sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java&p1=sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java&r1=1609862&r2=1609863&rev=1609863&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecord.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -186,6 +186,12 @@ public class DefaultRecord implements Re
}
throw new NoSuchElementException();
}
+
+ /** Unsupported operation. */
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
}
/**
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -18,20 +18,29 @@ package org.apache.sis.util.iso;
import java.util.Set;
import java.util.Map;
-import java.util.Collections;
import java.util.LinkedHashMap;
+import java.util.Arrays;
import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.InvalidObjectException;
import javax.xml.bind.annotation.XmlType;
import org.opengis.util.Type;
import org.opengis.util.TypeName;
+import org.opengis.util.LocalName;
import org.opengis.util.MemberName;
+import org.opengis.util.GenericName;
+import org.opengis.util.NameSpace;
+import org.opengis.util.NameFactory;
import org.opengis.util.Record;
import org.opengis.util.RecordType;
import org.opengis.util.RecordSchema;
-import org.apache.sis.util.Debug;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
-import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.util.collection.Containers;
+import org.apache.sis.util.ObjectConverters;
+import org.apache.sis.internal.converter.SurjectiveConverter;
// Branch-dependent imports
import java.util.Objects;
@@ -43,23 +52,52 @@ import java.util.Objects;
* arbitrary amount of {@linkplain #getMembers() members} as (<var>name</var>, <var>type</var>) pairs.
* A {@code RecordType} may therefore contain another {@code RecordType} as a member.
*
- * {@section Comparison with Java reflection}
+ * <div class="note"><b>Comparison with Java reflection:</b>
* {@code RecordType} instances can be though as equivalent to instances of the Java {@link Class} class.
* The set of members in a {@code RecordType} can be though as equivalent to the set of fields in a class.
+ * </div>
+ *
+ * {@section Instantiation}
+ * The easiest way to create {@code DefaultRecordType} instances is to use the
+ * {@link DefaultRecordSchema#createRecordType(CharSequence, Map)} method.
+ * Example:
+ *
+ * <div class="note">
+ * {@preformat java
+ * DefaultRecordSchema schema = new DefaultRecordSchema(null, null, "MySchema");
+ * // The same instance can be reused for all records to create in that schema.
+ *
+ * Map<CharSequence,Class<?>> members = new LinkedHashMap<>();
+ * members.put("city", String .class);
+ * members.put("latitude", Double .class);
+ * members.put("longitude", Double .class);
+ * members.put("population", Integer.class);
+ * RecordType record = schema.createRecordType("MyRecordType", members);
+ * }
+ * </div>
*
* {@section Immutability and thread safety}
- * This class is immutable and thus inherently thread-safe if the {@link TypeName} and {@link RecordSchema} arguments,
- * as well as all ({@link MemberName}, {@link Type}) entries in the map given to the constructor, are also immutable.
+ * This class is immutable and thus inherently thread-safe if the {@link TypeName}, the {@link RecordSchema}
+ * and all ({@link MemberName}, {@link Type}) entries in the map given to the constructor are also immutable.
* Subclasses shall make sure that any overridden methods remain safe to call from multiple threads and do not change
* any public {@code RecordType} state.
*
+ * {@section Serialization}
+ * This class is serializable if all elements given to the constructor are also serializable.
+ * Note in particular that {@link DefaultRecordSchema} is currently <strong>not</strong> serializable,
+ * so users wanting serialization may need to provide their own schema.
+ *
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.5
* @module
+ *
+ * @see DefaultRecord
+ * @see DefaultRecordSchema
+ * @see DefaultMemberName
*/
@XmlType(name = "RecordType")
-public class DefaultRecordType implements RecordType, Serializable {
+public class DefaultRecordType extends RecordDefinition implements RecordType, Serializable {
/**
* For cross-version compatibility.
*/
@@ -80,20 +118,18 @@ public class DefaultRecordType implement
private final RecordSchema container;
/**
- * The dictionary of (<var>name</var>, <var>type</var>) pairs.
+ * The type of each members.
*
- * @see #getMembers()
* @see #getMemberTypes()
*/
- private final Map<MemberName,Type> memberTypes;
+ private transient Type[] memberTypes;
/**
* Empty constructor only used by JAXB.
*/
private DefaultRecordType() {
- typeName = null;
- container = null;
- memberTypes = Collections.emptyMap();
+ typeName = null;
+ container = null;
}
/**
@@ -104,32 +140,116 @@ public class DefaultRecordType implement
public DefaultRecordType(final RecordType other) {
typeName = other.getTypeName();
container = other.getContainer();
- memberTypes = other.getMemberTypes();
+ memberTypes = computeTransientFields(other.getMemberTypes());
+ }
+
+ /**
+ * Creates a new record in the given schema.
+ * It is caller responsibility to add the new {@code RecordType} in the container
+ * {@linkplain RecordSchema#getDescription() description} map, if desired.
+ *
+ * <p>This constructor is provided mostly for developers who want to create {@code DefaultRecordType}
+ * instances in their own {@code RecordSchema} implementation. Otherwise if the default record schema
+ * implementation is sufficient, the {@link DefaultRecordSchema#createRecordType(CharSequence, Map)}
+ * method provides an easier alternative.</p>
+ *
+ * @param typeName The name that identifies this record type.
+ * @param container The schema that contains this record type.
+ * @param members The name and type of the members to be included in this record type.
+ *
+ * @see DefaultRecordSchema#createRecordType(CharSequence, Map)
+ */
+ public DefaultRecordType(final TypeName typeName, final RecordSchema container,
+ final Map<? extends MemberName, ? extends Type> members)
+ {
+ ArgumentChecks.ensureNonNull("typeName", typeName);
+ ArgumentChecks.ensureNonNull("container", container);
+ ArgumentChecks.ensureNonNull("members", members);
+ this.typeName = typeName;
+ this.container = container;
+ this.memberTypes = computeTransientFields(members);
+ /*
+ * Ensure that the record namespace is equals to the schema name. For example if the schema
+ * name is "MyNameSpace", then the record type name can be "MyNameSpace:MyRecordType".
+ */
+ final LocalName schemaName = container.getSchemaName();
+ final GenericName fullTypeName = typeName.toFullyQualifiedName();
+ if (schemaName.compareTo(typeName.scope().name().tip()) != 0) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2, schemaName, fullTypeName));
+ }
+ final int size = size();
+ for (int i=0; i<size; i++) {
+ final MemberName name = getName(i);
+ final Type type = this.memberTypes[i];
+ if (type == null || name.getAttributeType().compareTo(type.getTypeName()) != 0) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalMemberType_2, name, type));
+ }
+ if (fullTypeName.compareTo(name.scope().name()) != 0) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2,
+ fullTypeName, name.toFullyQualifiedName()));
+ }
+ }
}
/**
- * Creates a new record.
+ * Creates a new record from member names specified as character sequence.
+ * This constructor builds the {@link MemberName} instance itself.
*
* @param typeName The name that identifies this record type.
* @param container The schema that contains this record type.
- * @param memberTypes The name of the members to be included in this record type.
+ * @param members The name of the members to be included in this record type.
+ * @param nameFactory The factory to use for instantiating {@link MemberName}.
*/
- public DefaultRecordType(final TypeName typeName, final RecordSchema container, Map<MemberName,Type> memberTypes) {
- ArgumentChecks.ensureNonNull("typeName", typeName);
- ArgumentChecks.ensureNonNull("container", container);
- ArgumentChecks.ensureNonNull("memberTypes", memberTypes);
- memberTypes = new LinkedHashMap<>(memberTypes);
- memberTypes.remove(null);
- for (final Map.Entry<MemberName,Type> entry : memberTypes.entrySet()) {
- final MemberName name = entry.getKey();
- final Type type = entry.getValue();
- if (type == null || !name.getAttributeType().equals(type.getTypeName())) {
- throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalMemberType_2, name, type));
+ DefaultRecordType(final TypeName typeName, final RecordSchema container,
+ final Map<? extends CharSequence, ? extends Type> members, final NameFactory nameFactory)
+ {
+ this.typeName = typeName;
+ this.container = container;
+ final NameSpace namespace = nameFactory.createNameSpace(typeName, null);
+ final Map<MemberName,Type> memberTypes = new LinkedHashMap<>(Containers.hashMapCapacity(members.size()));
+ for (final Map.Entry<? extends CharSequence, ? extends Type> entry : members.entrySet()) {
+ final Type type = entry.getValue();
+ final CharSequence name = entry.getKey();
+ final MemberName member = nameFactory.createMemberName(namespace, name, type.getTypeName());
+ if (memberTypes.put(member, type) != null) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.DuplicatedElement_1, member));
}
}
- this.typeName = typeName;
- this.container = container;
- this.memberTypes = CollectionsExt.unmodifiableOrCopy(memberTypes);
+ this.memberTypes = computeTransientFields(memberTypes);
+ }
+
+ /**
+ * Invoked on deserialization for restoring the transient fields.
+ * See {@link #writeObject(ObjectOutputStream)} for the stream data description.
+ */
+ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ final int size = in.readInt();
+ final Map<MemberName,Type> members = new LinkedHashMap<>(Containers.hashMapCapacity(size));
+ for (int i=0; i<size; i++) {
+ final MemberName member = (MemberName) in.readObject();
+ final Type type = (Type) in.readObject();
+ if (members.put(member, type) != null) {
+ throw new InvalidObjectException(Errors.format(Errors.Keys.DuplicatedElement_1, member));
+ }
+ }
+ memberTypes = computeTransientFields(members);
+ }
+
+ /**
+ * Invoked on serialization for writing the member names and their type.
+ *
+ * @serialData The number of members as an {@code int}, followed by a
+ * ({@code MemberName}, {@code Type}) pair for each member.
+ */
+ private void writeObject(final ObjectOutputStream out) throws IOException {
+ final int size = size();
+ out.defaultWriteObject();
+ out.writeInt(size);
+ for (int i=0; i<size; i++) {
+ out.writeObject(getName(i));
+ out.writeObject(memberTypes[i]);
+ }
}
/**
@@ -159,6 +279,14 @@ public class DefaultRecordType implement
}
/**
+ * Returns {@code this} since {@link RecordDefinition} is the definition of this record type.
+ */
+ @Override
+ final RecordType getRecordType() {
+ return this;
+ }
+
+ /**
* Returns the name that identifies this record type. If this {@code RecordType} is contained in a
* {@linkplain DefaultRecordSchema record schema}, then the record type name shall be valid in the
* {@linkplain DefaultNameSpace name space} of the record schema:
@@ -167,9 +295,10 @@ public class DefaultRecordType implement
* NameSpace namespace = getContainer().getSchemaName().scope()
* }
*
- * {@section Comparison with Java reflection}
+ * <div class="note"><b>Comparison with Java reflection:</b>
* If we think about this {@code RecordType} as equivalent to a {@code Class} instance,
* then this method can be think as the equivalent of the Java {@link Class#getName()} method.
+ * </div>
*
* @return The name that identifies this record type.
*/
@@ -192,15 +321,20 @@ public class DefaultRecordType implement
* Returns the dictionary of all (<var>name</var>, <var>type</var>) pairs in this record type.
* The returned map is unmodifiable.
*
- * {@section Comparison with Java reflection}
+ * <div class="note"><b>Comparison with Java reflection:</b>
* If we think about this {@code RecordType} as equivalent to a {@code Class} instance, then
* this method can be though as the related to the Java {@link Class#getFields()} method.
+ * </div>
*
* @return The dictionary of (<var>name</var>, <var>type</var>) pairs, or an empty map if none.
*/
@Override
- public Map<MemberName, Type> getMemberTypes() {
- return memberTypes;
+ public Map<MemberName,Type> getMemberTypes() {
+ return ObjectConverters.derivedValues(memberIndices(), MemberName.class, new SurjectiveConverter<Integer,Type>() {
+ @Override public Class<Integer> getSourceClass() {return Integer.class;}
+ @Override public Class<Type> getTargetClass() {return Type.class;}
+ @Override public Type apply(final Integer index) {return getType(index);}
+ });
}
/**
@@ -215,7 +349,14 @@ public class DefaultRecordType implement
*/
@Override
public Set<MemberName> getMembers() {
- return memberTypes.keySet();
+ return memberIndices().keySet();
+ }
+
+ /**
+ * Returns the type at the given index.
+ */
+ final Type getType(final int index) {
+ return memberTypes[index];
}
/**
@@ -226,17 +367,18 @@ public class DefaultRecordType implement
* getMemberTypes().get(memberName).getTypeName();
* }
*
- * {@section Comparison with Java reflection}
+ * <div class="note"><b>Comparison with Java reflection:</b>
* If we think about this {@code RecordType} as equivalent to a {@code Class} instance, then
* this method can be though as related to the Java {@link Class#getField(String)} method.
+ * </div>
*
* @param memberName The attribute name for which to get the associated type name.
* @return The associated type name, or {@code null} if none.
*/
@Override
public TypeName locate(final MemberName memberName) {
- final Type type = memberTypes.get(memberName);
- return (type != null) ? type.getTypeName() : null;
+ final Integer index = indexOf(memberName);
+ return (index != null) ? getType(index).getTypeName() : null;
}
/**
@@ -273,9 +415,10 @@ public class DefaultRecordType implement
}
if (other != null && other.getClass() == getClass()) {
final DefaultRecordType that = (DefaultRecordType) other;
- return Objects.equals(typeName, that.typeName) &&
- Objects.equals(container, that.container) &&
- Objects.equals(memberTypes, that.memberTypes);
+ return Objects.equals(typeName, that.typeName) &&
+ Objects.equals(container, that.container) &&
+ Arrays .equals(memberTypes, that.memberTypes) &&
+ memberIndices().equals(that.memberIndices());
}
return false;
}
@@ -285,19 +428,6 @@ public class DefaultRecordType implement
*/
@Override
public int hashCode() {
- int code = memberTypes.hashCode();
- if (typeName != null) code = 31*code + typeName .hashCode();
- if (container != null) code = 31*code + container.hashCode();
- return code;
- }
-
- /**
- * Returns a string representation of this {@code RecordType}.
- * The string representation is for debugging purpose and may change in any future SIS version.
- */
- @Debug
- @Override
- public String toString() {
- return "RecordType[\"" + typeName + "\"]";
+ return Objects.hashCode(typeName) + 31*(memberIndices().hashCode() + 31*Arrays.hashCode(memberTypes));
}
}
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultScopedName.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -52,6 +52,9 @@ import org.apache.sis.internal.util.Unmo
* @since 0.3 (derived from geotk-2.1)
* @version 0.3
* @module
+ *
+ * @see DefaultNameSpace
+ * @see DefaultLocalName
*/
@XmlType(name = "ScopedName") // Actually 'gml:CodeType', but the later is used elsewhere.
@XmlRootElement(name = "ScopedName")
@@ -183,7 +186,7 @@ public class DefaultScopedName extends A
final LocalName lastName = locals[index-1];
final NameSpace lastScope = lastName.scope();
final NameSpace tailScope = name.scope();
- if (tailScope instanceof DefaultNameSpace && ((DefaultNameSpace) tailScope).parent == lastScope) {
+ if (tailScope instanceof DefaultNameSpace && ((DefaultNameSpace) tailScope).parent() == lastScope) {
/*
* If the tail is actually the tip (a LocalName), remember the tail so we
* don't need to create it again later. Then copy the tail after the path.
Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java?rev=1609863&r1=1609862&r2=1609863&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java [UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultTypeName.java [UTF-8] Fri Jul 11 22:58:29 2014
@@ -39,6 +39,9 @@ import org.opengis.util.NameSpace;
* @since 0.3 (derived from geotk-3.00)
* @version 0.3
* @module
+ *
+ * @see DefaultMemberName
+ * @see DefaultNameFactory
*/
@XmlRootElement(name = "TypeName")
public class DefaultTypeName extends DefaultLocalName implements TypeName {