sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1607958 - in /sis/branches/JDK8/core/sis-utility/src: main/java/org/apache/sis/internal/simple/ main/java/org/apache/sis/util/iso/ main/java/org/apache/sis/util/resources/ test/java/org/apache/sis/test/suite/ test/java/org/apache/sis/util/...
Date Fri, 04 Jul 2014 23:21:27 GMT
Author: desruisseaux
Date: Fri Jul  4 23:21:26 2014
New Revision: 1607958

URL: http://svn.apache.org/r1607958
Log:
Complete a little bit more the support of Record and RecordType (not yet tested).
This is needed for support of ISO 19115 metadata - the lack of RecordType support
was a problematic hole. However XML (un)marshalling is not yet implemented.

Added:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
  (with props)
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
  (with props)
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
  (with props)
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java

Added: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java?rev=1607958&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
(added)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.internal.simple;
+
+import java.io.Serializable;
+import org.opengis.util.Type;
+import org.opengis.feature.AttributeType;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.util.TypeName;
+
+
+/**
+ * A simple attribute type containing only a name and a class of values.
+ * Such simple type are suitable for use in ISO 19103 {@link org.opengis.util.RecordType}
+ * in addition to ISO 19109 {@link org.opengis.feature.FeatureType}.
+ *
+ * @param <V> The type of attribute value.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public final class SimpleAttributeType<V> implements AttributeType<V>, Type,
Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -4130729627352535488L;
+
+    /**
+     * The name for this attribute type.
+     */
+    private final TypeName name;
+
+    /**
+     * The class of value for attributes of this type.
+     */
+    private final Class<V> valueClass;
+
+    /**
+     * Creates a new attribute type for the given name and class of values.
+     *
+     * @param name       The name for this attribute type (shall not be null).
+     * @param valueClass The class of value for attributes of this type (shall not be null).
+     */
+    public SimpleAttributeType(final TypeName name, final Class<V> valueClass) {
+        this.name       = name;
+        this.valueClass = valueClass;
+    }
+
+    /**
+     * Returns the name of this attribute type (ISO 19109).
+     *
+     * @return The name of this attribute type.
+     */
+    @Override
+    public GenericName getName() {
+        return name;
+    }
+
+    /**
+     * Returns the name of this attribute type (ISO 19103).
+     *
+     * @return The name of this attribute type.
+     */
+    @Override
+    public TypeName getTypeName() {
+        return name;
+    }
+
+    /**
+     * Returns the class of value for attributes of this type.
+     *
+     * @return The class of value for attributes of this type.
+     */
+    @Override
+    public Class<V> getValueClass() {
+        return valueClass;
+    }
+
+    /**
+     * Returns 1 as of simple feature definition.
+     *
+     * @return Always 1.
+     */
+    @Override
+    public int getMinimumOccurs() {
+        return 1;
+    }
+
+    /**
+     * Returns 1 as of simple feature definition.
+     *
+     * @return Always 1.
+     */
+    @Override
+    public int getMaximumOccurs() {
+        return 1;
+    }
+
+    /**
+     * Not used for this simple attribute type.
+     *
+     * @return Always {@code null}.
+     */
+    @Override
+    public V getDefaultValue() {
+        return null;
+    }
+
+    /**
+     * Not used for this simple attribute type.
+     *
+     * @return Always {@code null}.
+     */
+    @Override
+    public InternationalString getDefinition() {
+        return null;
+    }
+
+    /**
+     * Not used for this simple attribute type.
+     *
+     * @return Always {@code null}.
+     */
+    @Override
+    public InternationalString getDesignation() {
+        return null;
+    }
+
+    /**
+     * Not used for this simple attribute type.
+     *
+     * @return Always {@code null}.
+     */
+    @Override
+    public InternationalString getDescription() {
+        return null;
+    }
+
+    /**
+     * Returns a hash code value for this type.
+     *
+     * @return A hash code value.
+     */
+    @Override
+    public int hashCode() {
+        return name.hashCode() ^ valueClass.hashCode();
+    }
+
+    /**
+     * Compares this attribute type with the given object for equality.
+     *
+     * @param object The object to compare with this attribute type.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public boolean equals(final Object object) {
+        if (object == this) {
+            return true;
+        }
+        if (object instanceof SimpleAttributeType) {
+            final SimpleAttributeType<?> other = (SimpleAttributeType<?>) object;
+            return name.equals(other.name) && valueClass.equals(other.valueClass);
+        }
+        return false;
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java?rev=1607958&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
(added)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.iso;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Date;
+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.NameFactory;
+import org.opengis.util.NameSpace;
+import org.opengis.util.RecordType;
+import org.apache.sis.util.Numbers;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ObjectConverter;
+import org.apache.sis.util.ObjectConverters;
+import org.apache.sis.util.resources.Errors;
+import org.apache.sis.internal.system.DefaultFactories;
+import org.apache.sis.internal.simple.SimpleAttributeType;
+import org.apache.sis.internal.converter.SurjectiveConverter;
+
+
+/**
+ * A factory for creating {@code RecordType} and {@code Record} instances.
+ * This factory provides the following methods for creating instances:
+ *
+ * <ul>
+ *   <li>{@link #createRecordType(TypeName, Map)}</li>
+ * </ul>
+ *
+ * Subclasses can modify the characteristics of the records to be created
+ * by overriding the following methods:
+ *
+ * <ul>
+ *   <li>{@link #toTypeName(Class)}</li>
+ * </ul>
+ *
+ * {@section Thread safety}
+ * The same {@code DefaultRecordFactory} instance can be safely used by many threads without
synchronization
+ * on the part of the caller if the given {@code NameFactory} is also thread-safe. Subclasses
should make sure
+ * that any overridden methods remain safe to call from multiple threads.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public class DefaultRecordFactory {
+    /**
+     * The factory to use for creating names.
+     */
+    protected final NameFactory nameFactory;
+
+    /**
+     * The pool of attribute types created so far.
+     * Shall be used only in synchronized blocks.
+     */
+    private final Map<Class<?>,Type> attributeTypes;
+
+    /**
+     * The record schemas created by this factory.
+     */
+    private final Map<LocalName,DefaultRecordSchema> schemas;
+
+    /**
+     * The converter to use for converting Java {@link Class} to ISO 19103 {@link Type}.
+     * This converter delegates its work to the {@link #toAttributeType(Class)} method.
+     */
+    private final ObjectConverter<Class<?>,Type> toTypes = new SurjectiveConverter<Class<?>,
Type>() {
+        @SuppressWarnings("unchecked")
+        @Override public Class<Class<?>> getSourceClass() {return (Class) Class.class;}
+        @Override public Class<Type>     getTargetClass() {return Type.class;}
+        @Override public Type apply(Class<?> valueClass)  {return toAttributeType(valueClass);}
+    };
+
+    /**
+     * Creates a new record factory which will use the {@linkplain DefaultNameFactory default
name factory}.
+     */
+    public DefaultRecordFactory() {
+        this(DefaultFactories.NAMES);
+    }
+
+    /**
+     * Creates a new record factory which will use the given name factory.
+     *
+     * @param nameFactory The factory to use for creating names.
+     */
+    public DefaultRecordFactory(final NameFactory nameFactory) {
+        ArgumentChecks.ensureNonNull("nameFactory", nameFactory);
+        this.nameFactory    = nameFactory;
+        this.attributeTypes = new HashMap<>();
+        this.schemas        = new HashMap<>();
+    }
+
+    /**
+     * Returns the schema for the namespace (scope) of the given name.
+     *
+     * @param  typeName The name of the type for which to get a schema.
+     * @return The schema for the namespace (scope) of the given name.
+     * @throws IllegalArgumentException if the given name has no namespace or a global namespace.
+     */
+    private DefaultRecordSchema schemaForScope(final GenericName typeName) throws IllegalArgumentException
{
+        final NameSpace namespace = typeName.scope();
+        if (namespace == null || namespace.isGlobal()) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.MissingNamespace_1,
typeName));
+        }
+        final LocalName schemaName = namespace.name().tip();
+        DefaultRecordSchema schema;
+        synchronized (schemas) {
+            schema = schemas.get(schemaName);
+            if (schema == null) {
+                schema = new DefaultRecordSchema(schemaName);
+                schemas.put(schemaName, schema);
+            }
+        }
+        return schema;
+    }
+
+    /**
+     * Creates a new record type of the given name, which will contains the given members.
+     * Members are declared in iteration order.
+     *
+     * @param  typeName The record type name.
+     * @param  members  The name of each record member, together with the expected value
types.
+     * @return A record type of the given name and members.
+     * @throws IllegalArgumentException If a record already exists for the given name but
with different members.
+     */
+    public RecordType createRecordType(final TypeName typeName, final Map<CharSequence,Class<?>>
members)
+            throws IllegalArgumentException
+    {
+        ArgumentChecks.ensureNonNull("typeName", typeName);
+        ArgumentChecks.ensureNonNull("members",  members);
+        final Map<CharSequence,Type> memberTypes = ObjectConverters.derivedValues(members,
CharSequence.class, toTypes);
+        final DefaultRecordSchema container = schemaForScope(typeName);
+        RecordType record;
+        synchronized (container.description) {
+            record = container.description.get(typeName);
+            if (record == null) {
+                record = new DefaultRecordType(typeName, container, memberTypes, nameFactory);
+                container.description.put(typeName, record);
+                return record;
+            }
+        }
+        /*
+         * If a record type already exists for the given name, verify that it contains the
same members.
+         */
+        final Iterator<Map.Entry<CharSequence,Class<?>>> it1 = members.entrySet().iterator();
+        final Iterator<Map.Entry<MemberName,Type>> it2 = record.getMemberTypes().entrySet().iterator();
+        boolean hasNext;
+        while ((hasNext = it1.hasNext()) == it2.hasNext()) {
+            if (!hasNext) {
+                return record; // Finished comparison successfully.
+            }
+            final Map.Entry<CharSequence,Class<?>> e1 = it1.next();
+            final Map.Entry<MemberName,Type> e2 = it2.next();
+            if (!e2.getKey().tip().toString().equals(e1.toString())) {
+                break; // Member names differ.
+            }
+            if (!((SimpleAttributeType) e2.getValue()).getValueClass().equals(e1.getValue()))
{
+                break; // Value classes differ.
+            }
+        }
+        throw new IllegalArgumentException(Errors.format(Errors.Keys.RecordAlreadyDefined_2,
+                container.getSchemaName(), typeName));
+    }
+
+    /**
+     * Suggests an attribute type for the given value class. For a short list of known classes,
+     * this method returns the ISO 19103 type as used in XML documents. Examples:
+     *
+     * <table class="sis">
+     *   <caption>Attribute types for Java classes (non exhaustive list)</caption>
+     *   <tr><th>Java class</th>        <th>Attribute type</th></tr>
+     *   <tr><td>{@link String}</td>    <td>{@code gco:CharacterString}</td></tr>
+     *   <tr><td>{@link Date}</td>      <td>{@code gco:DateTime}</td></tr>
+     *   <tr><td>{@link Double}</td>    <td>{@code gco:Real}</td></tr>
+     *   <tr><td>{@link Integer}</td>   <td>{@code gco:Integer}</td></tr>
+     *   <tr><td>{@link Boolean}</td>   <td>{@code gco:Boolean}</td></tr>
+     * </table>
+     *
+     * @param  valueClass The value class to represent as an attribute type.
+     * @return Attribute type for the given value class.
+     */
+    private Type toAttributeType(final Class<?> valueClass) {
+        Type type;
+        synchronized (attributeTypes) {
+            type = attributeTypes.get(valueClass);
+        }
+        if (type == null) {
+            type = new SimpleAttributeType<>(toTypeName(valueClass), valueClass);
+            synchronized (attributeTypes) {
+                final Type old = attributeTypes.put(valueClass, type);
+                if (old != null) { // May happen if the type has been computed concurrently.
+                    attributeTypes.put(valueClass, old);
+                    return old;
+                }
+            }
+        }
+        return type;
+    }
+
+    /**
+     * Suggests a type name for the given value class. For a short list of known classes,
+     * this method returns the ISO 19103 type name as used in XML documents. Examples:
+     *
+     * <table class="sis">
+     *   <caption>Type names for Java classes (non exhaustive list)</caption>
+     *   <tr><th>Java class</th>        <th>Type name</th></tr>
+     *   <tr><td>{@link String}</td>    <td>"{@code gco:CharacterString}"</td></tr>
+     *   <tr><td>{@link Date}</td>      <td>"{@code gco:DateTime}"</td></tr>
+     *   <tr><td>{@link Double}</td>    <td>"{@code gco:Real}"</td></tr>
+     *   <tr><td>{@link Integer}</td>   <td>"{@code gco:Integer}"</td></tr>
+     *   <tr><td>{@link Boolean}</td>   <td>"{@code gco:Boolean}"</td></tr>
+     * </table>
+     *
+     * Subclasses can override this method for defining more type names.
+     *
+     * @param  valueClass The value class for which to get a type name.
+     * @return Type name for the given value class.
+     */
+    protected TypeName toTypeName(final Class<?> valueClass) {
+        String ns = "gco";
+        final String name;
+        if (CharSequence.class.isAssignableFrom(valueClass)) {
+            name = "CharacterString";
+        } else if (Number.class.isAssignableFrom(valueClass)) {
+            name = Numbers.isInteger(valueClass) ? "Integer" : "Real";
+        } else if (Date.class.isAssignableFrom(valueClass)) {
+            name = "DateTime";
+        } else if (valueClass == Boolean.class) {
+            name = "Boolean";
+        } else {
+            ns   = "java";
+            name = valueClass.getCanonicalName();
+        }
+        return nameFactory.createTypeName(nameFactory.createNameSpace(
+                nameFactory.createLocalName(null, ns), null), name);
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Added: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java?rev=1607958&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
(added)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -0,0 +1,104 @@
+/*
+ * 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.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.iso;
+
+import java.util.Map;
+import java.util.Collections;
+import java.io.Serializable;
+import org.opengis.util.LocalName;
+import org.opengis.util.TypeName;
+import org.opengis.util.RecordType;
+import org.opengis.util.RecordSchema;
+import org.apache.sis.util.Debug;
+import org.apache.sis.util.collection.WeakValueHashMap;
+
+
+/**
+ * A collection of record types in a given namespace.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+final class DefaultRecordSchema implements RecordSchema, Serializable {
+    /**
+     * For cross-version compatibility.
+     */
+    private static final long serialVersionUID = -7508781073649388985L;
+
+    /**
+     * The schema name given at construction time.
+     */
+    private final LocalName schemaName;
+
+    /**
+     * The record types in the namespace of this schema.
+     */
+    final Map<TypeName,RecordType> description;
+
+    /**
+     * Creates a new schema of the given name.
+     *
+     * @param schemaName The name of the new schema.
+     */
+    DefaultRecordSchema(final LocalName schemaName) {
+        this.schemaName = schemaName;
+        description = new WeakValueHashMap<>(TypeName.class);
+    }
+
+    /**
+     * Returns the schema name.
+     *
+     * @return The schema name.
+     */
+    @Override
+    public LocalName getSchemaName() {
+        return schemaName;
+    }
+
+    /**
+     * Returns the dictionary of all (<var>name</var>, <var>record type</var>)
pairs in this schema.
+     *
+     * @return All (<var>name</var>, <var>record type</var>) pairs
in this schema.
+     */
+    @Override
+    public Map<TypeName, RecordType> getDescription() {
+        return Collections.unmodifiableMap(description);
+    }
+
+    /**
+     * Returns the record type for the given name.
+     * If the type name is not defined within this schema, then this method returns {@code
null}.
+     *
+     * @param  name The name of the type to lookup.
+     * @return The type for the given name, or {@code null} if none.
+     */
+    @Override
+    public RecordType locate(final TypeName name) {
+        return description.get(name);
+    }
+
+    /**
+     * Returns a string representation of this schema for debugging purpose only.
+     */
+    @Debug
+    @Override
+    public String toString() {
+        return "RecordSchema[“" + schemaName + "”]";
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java?rev=1607958&r1=1607957&r2=1607958&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordType.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -24,13 +24,17 @@ import java.io.Serializable;
 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.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.util.collection.Containers;
 import org.apache.sis.internal.util.CollectionsExt;
 
 // Branch-dependent imports
@@ -55,7 +59,7 @@ import java.util.Objects;
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.5
  * @module
  */
 @XmlType(name = "RecordType")
@@ -109,23 +113,61 @@ public class DefaultRecordType implement
 
     /**
      * Creates a new record.
+     * It is caller responsibility to add the new {@code RecordType} in the container
+     * {@linkplain RecordSchema#getDescription() description} map, if desired.
      *
-     * @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.
-     */
-    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()) {
+     * @param typeName  The name that identifies this record type.
+     * @param container The schema that contains this record type.
+     * @param members   The name of the members to be included in this record type.
+     *
+     * @see Records#createType(TypeName, Map)
+     */
+    public DefaultRecordType(final TypeName typeName, final RecordSchema container, Map<MemberName,Type>
members) {
+        ArgumentChecks.ensureNonNull("typeName",  typeName);
+        ArgumentChecks.ensureNonNull("container", container);
+        ArgumentChecks.ensureNonNull("members",   members);
+        final LocalName schemaName = container.getSchemaName();
+        if (schemaName.compareTo(typeName.scope().name().tip()) != 0) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2,
schemaName, typeName));
+        }
+        members = new LinkedHashMap<>(members);
+        members.remove(null);
+        for (final Map.Entry<MemberName,Type> entry : members.entrySet()) {
             final MemberName name = entry.getKey();
             final Type type = entry.getValue();
-            if (type == null || !name.getAttributeType().equals(type.getTypeName())) {
+            if (type == null || name.getAttributeType().compareTo(type.getTypeName()) !=
0) {
                 throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalMemberType_2,
name, type));
             }
+            if (typeName.compareTo(name.scope().name()) != 0) {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2,
typeName, name));
+            }
+        }
+        this.typeName    = typeName;
+        this.container   = container;
+        this.memberTypes = CollectionsExt.unmodifiableOrCopy(members);
+    }
+
+    /**
+     * 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 members     The name of the members to be included in this record type.
+     * @param nameFactory The factory to use for instantiating {@link MemberName}.
+     */
+    DefaultRecordType(final TypeName typeName, final RecordSchema container,
+            final Map<CharSequence,Type> members, final NameFactory nameFactory)
+    {
+        final NameSpace namespace = nameFactory.createNameSpace(typeName, null);
+        final Map<MemberName,Type> memberTypes = new LinkedHashMap<>(Containers.hashMapCapacity(members.size()));
+        for (final Map.Entry<CharSequence,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;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1607958&r1=1607957&r2=1607958&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -373,6 +373,11 @@ public final class Errors extends Indexe
         public static final short InconsistentAttribute_2 = 47;
 
         /**
+         * Expected “{0}” namespace for “{1}”.
+         */
+        public static final short InconsistentNamespace_2 = 162;
+
+        /**
          * Inconsistent table columns.
          */
         public static final short InconsistentTableColumns = 48;
@@ -453,6 +458,11 @@ public final class Errors extends Indexe
         public static final short MissingAuthority_1 = 135;
 
         /**
+         * “{0}” has no namespace.
+         */
+        public static final short MissingNamespace_1 = 163;
+
+        /**
          * This operation requires the “{0}” module.
          */
         public static final short MissingRequiredModule_1 = 61;
@@ -668,6 +678,11 @@ public final class Errors extends Indexe
         public static final short PropertyNotFound_2 = 71;
 
         /**
+         * Record “{1}” is already defined in schema “{0}”.
+         */
+        public static final short RecordAlreadyDefined_2 = 161;
+
+        /**
          * Recursive call while creating an object for the “{0}” key.
          */
         public static final short RecursiveCreateCallForKey_1 = 99;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1607958&r1=1607957&r2=1607958&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Fri Jul  4 23:21:26 2014
@@ -84,6 +84,7 @@ IncompatiblePropertyValue_1       = Prop
 IncompatibleUnit_1                = Unit \u201c{0}\u201d is incompatible with current value.
 IncompatibleUnits_2               = Units \u201c{0}\u201d and \u201c{1}\u201d are incompatible.
 InconsistentAttribute_2           = Value \u201c{1}\u201d of attribute \u2018{0}\u2019 is
inconsistent with other attributes.
+InconsistentNamespace_2           = Expected \u201c{0}\u201d namespace for \u201c{1}\u201d.
 InconsistentTableColumns          = Inconsistent table columns.
 IdentifierAlreadyBound_1          = Identifier \u201c{0}\u201d is already associated to another
object.
 IndexOutOfBounds_1                = Index {0} is out of bounds.
@@ -101,6 +102,7 @@ MismatchedParameterDescriptor_1   = Mism
 MismatchedPropertyType_1          = Mismatched type for \u201c{0}\u201d property.
 MismatchedValueClass_3            = Class of \u201c{0}\u201d values is \u2018{2}\u2019, but
the requested type is \u2018{1}\u2019.
 MissingAuthority_1                = No authority was specified for code \u201c{0}\u201d.
The expected syntax is \u201cAUTHORITY:CODE\u201d.
+MissingNamespace_1                = \u201c{0}\u201d has no namespace.
 MissingRequiredModule_1           = This operation requires the \u201c{0}\u201d module.
 MissingSchemeInURI                = Missing scheme in URI.
 MissingValueForOption_1           = Missing value for \u201c{0}\u201d option.
@@ -145,9 +147,10 @@ OddArrayLength_1                  = Arra
 PropertyAlreadyExists_2           = Property \u201c{1}\u201d is already exists in \u201c{0}\u201d.
 ParameterNotFound_2               = No parameter named \u201c{1}\u201d has been found in
\u201c{0}\u201d.
 PropertyNotFound_2                = No property named \u201c{1}\u201d has been found in \u201c{0}\u201d.
-SingularMatrix                    = Matrix is singular.
+RecordAlreadyDefined_2            = Record \u201c{1}\u201d is already defined in schema \u201c{0}\u201d.
 RecursiveCreateCallForKey_1       = Recursive call while creating an object for the \u201c{0}\u201d
key.
 RequireDecimalSeparator           = A decimal separator is required.
+SingularMatrix                    = Matrix is singular.
 StalledThread_1                   = Thread \u201c{0}\u201d seems stalled.
 StreamIsForwardOnly_1             = Can not move backward in the \u201c{0}\u201d stream.
 TooFewArguments_2                 = Expected at least {0} argument{0,choice,1#|2#s}, but
got {1}.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1607958&r1=1607957&r2=1607958&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Fri Jul  4 23:21:26 2014
@@ -74,6 +74,7 @@ IncompatiblePropertyValue_1       = La v
 IncompatibleUnit_1                = L\u2019unit\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est
pas compatible avec la valeur actuelle.
 IncompatibleUnits_2               = Les unit\u00e9s \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb
ne sont pas compatibles.
 InconsistentAttribute_2           = La valeur \u00ab\u202f{1}\u202f\u00bb de l\u2019attribut
\u2018{0}\u2019 n\u2019est pas coh\u00e9rente avec celles des autres attributs.
+InconsistentNamespace_2           = L\u2019espace de nom \u201c{0}\u201d \u00e9tait attendu
pour \u201c{1}\u201d.
 InconsistentTableColumns          = Les colonnes des tables ne sont pas coh\u00e9rentes.
 IdentifierAlreadyBound_1          = L\u2019identifiant \u00ab\u202f{0}\u202f\u00bb est d\u00e9j\u00e0
associ\u00e9 \u00e0 un autre objet.
 IndexOutOfBounds_1                = L\u2019index {0} est en dehors des limites permises.
@@ -91,6 +92,7 @@ MismatchedParameterDescriptor_1   = Le d
 MismatchedPropertyType_1          = Le type de la propri\u00e9t\u00e9 \u00ab\u202f{0}\u202f\u00bb
ne correspond pas.
 MismatchedValueClass_3            = Les valeurs de \u00ab\u202f{0}\u202f\u00bb sont de la
classe \u2018{2}\u2019, alors que le type demand\u00e9 \u00e9tait \u2018{1}\u2019.
 MissingAuthority_1                = Aucune autorit\u00e9 n\u2019a \u00e9t\u00e9 sp\u00e9cifi\u00e9e
pour le code \u00ab\u202f{0}\u202f\u00bb. Le format attendu est \u00ab\u202fAUTORIT\u00c9:CODE\u202f\u00bb.
+MissingNamespace_1                = \u201c{0}\u201d est d\u00e9fini sans espace de noms.
 MissingRequiredModule_1           = Cette op\u00e9ration requiert le module \u00ab\u202f{0}\u202f\u00bb.
 MissingSchemeInURI                = Il manque le sch\u00e9ma d\u2019URI.
 MissingValueForOption_1           = Aucune valeur n\u2019a \u00e9t\u00e9 d\u00e9finie pour
l\u2019option \u00ab\u202f{0}\u202f\u00bb.
@@ -134,6 +136,7 @@ OddArrayLength_1                  = La l
 PropertyAlreadyExists_2           = La propri\u00e9t\u00e9 \u00ab\u202f{1}\u202f\u00bb existe
d\u00e9j\u00e0 dans \u00ab\u202f{0}\u202f\u00bb.
 ParameterNotFound_2               = Aucun param\u00e8tre nomm\u00e9 \u00ab\u202f{1}\u202f\u00bb
n\u2019a \u00e9t\u00e9 trouv\u00e9 dans \u00ab\u202f{0}\u202f\u00bb.
 PropertyNotFound_2                = Aucune propri\u00e9t\u00e9 nomm\u00e9e \u00ab\u202f{1}\u202f\u00bb
n\u2019a \u00e9t\u00e9 trouv\u00e9e dans \u00ab\u202f{0}\u202f\u00bb.
+RecordAlreadyDefined_2            = L\u2019enregistrement \u00ab\u202f{1}\u202f\u00bb est
d\u00e9j\u00e0 d\u00e9finit dans le sch\u00e9ma \u00ab\u202f{0}\u202f\u00bb.
 RecursiveCreateCallForKey_1       = Appel r\u00e9cursif lors de la cr\u00e9ation d\u2019un
objet pour la cl\u00e9 \u00ab\u202f{0}\u202f\u00bb.
 RequireDecimalSeparator           = Un s\u00e9parateur d\u00e9cimal est requis.
 SingularMatrix                    = La matrice est singuli\u00e8re.

Modified: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java?rev=1607958&r1=1607957&r2=1607958&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -87,6 +87,7 @@ import org.junit.BeforeClass;
     org.apache.sis.util.iso.DefaultNameFactoryTest.class,
     org.apache.sis.util.iso.NamesTest.class,
     org.apache.sis.internal.simple.SimpleReferenceIdentifierTest.class,
+    org.apache.sis.util.iso.DefaultRecordTypeTest.class,
 
     // Measurements and formatting.
     org.apache.sis.measure.SexagesimalConverterTest.class,

Added: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java?rev=1607958&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
(added)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
[UTF-8] Fri Jul  4 23:21:26 2014
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.util.iso;
+
+import org.apache.sis.test.TestCase;
+import org.junit.Test;
+
+import static org.apache.sis.test.Assert.*;
+
+
+/**
+ * Tests the {@link DefaultRecordType} implementation.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @since   0.5
+ * @version 0.5
+ * @module
+ */
+public final strictfp class DefaultRecordTypeTest extends TestCase {
+    /**
+     * TODO
+     */
+    @Test
+    public void test() {
+    }
+}

Propchange: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8



Mime
View raw message