sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1608468 - in /sis/branches/JDK8/core/sis-utility/src: main/java/org/apache/sis/internal/simple/ main/java/org/apache/sis/util/iso/ test/java/org/apache/sis/test/suite/ test/java/org/apache/sis/util/iso/
Date Mon, 07 Jul 2014 14:17:19 GMT
Author: desruisseaux
Date: Mon Jul  7 14:17:18 2014
New Revision: 1608468

URL: http://svn.apache.org/r1608468
Log:
Merged DefaultRecordFactory with DefaultRecordSchema in the hope to simplify, and added tests.

Added:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
      - copied, changed from r1607958, sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
Removed:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
Modified:
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
    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/iso/Names.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
    sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java

Modified: 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=1608468&r1=1608467&r2=1608468&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleAttributeType.java
[UTF-8] Mon Jul  7 14:17:18 2014
@@ -180,4 +180,14 @@ public final class SimpleAttributeType<V
         }
         return false;
     }
+
+    /**
+     * Returns the type name.
+     *
+     * @return The type name.
+     */
+    @Override
+    public String toString() {
+        return name.toFullyQualifiedName().toString();
+    }
 }

Copied: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
(from r1607958, 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/DefaultRecordSchema.java?p2=sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java&p1=sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java&r1=1607958&r2=1608468&rev=1608468&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/DefaultRecordSchema.java
[UTF-8] Mon Jul  7 14:17:18 2014
@@ -19,31 +19,35 @@ package org.apache.sis.util.iso;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Collections;
 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.RecordSchema;
 import org.opengis.util.RecordType;
+import org.apache.sis.util.Debug;
 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.util.collection.WeakValueHashMap;
 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:
+ * A collection of record types in a given namespace.
+ * This class works also as a factory for creating {@code RecordType} and {@code Record}
instances.
+ * The factory methods are:
  *
  * <ul>
- *   <li>{@link #createRecordType(TypeName, Map)}</li>
+ *   <li>{@link #createRecordType(CharSequence, Map)}</li>
  * </ul>
  *
  * Subclasses can modify the characteristics of the records to be created
@@ -54,31 +58,43 @@ import org.apache.sis.internal.converter
  * </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.
+ * The same {@code DefaultRecordSchema} instance can be safely used by many threads without
synchronization
+ * on the part of the caller if the {@link NameFactory} given to the constructor 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 {
+public class DefaultRecordSchema implements RecordSchema {
     /**
      * The factory to use for creating names.
+     * This is the factory given at construction time.
      */
     protected final NameFactory nameFactory;
 
     /**
-     * The pool of attribute types created so far.
-     * Shall be used only in synchronized blocks.
+     * The {@linkplain #getSchemaName() schema name}.
      */
-    private final Map<Class<?>,Type> attributeTypes;
+    private final LocalName schemaName;
 
     /**
-     * The record schemas created by this factory.
+     * The namespace of {@link RecordType} to be created by this class.
+     * This is also (indirectly) the {@linkplain #getSchemaName() schema name}.
      */
-    private final Map<LocalName,DefaultRecordSchema> schemas;
+    private final NameSpace namespace;
+
+    /**
+     * The record types in the namespace of this schema.
+     */
+    private final Map<TypeName,RecordType> description;
+
+    /**
+     * The pool of attribute types created so far.
+     * Shall be used only in synchronized blocks.
+     */
+    private final Map<Class<?>,Type> attributeTypes;
 
     /**
      * The converter to use for converting Java {@link Class} to ISO 19103 {@link Type}.
@@ -92,46 +108,32 @@ public class DefaultRecordFactory {
     };
 
     /**
-     * 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.
+     * Creates a new schema of the given name.
      *
-     * @param nameFactory The factory to use for creating names.
+     * @param nameFactory The factory to use for creating names, or {@code null} for the
default factory.
+     * @param parent      The parent namespace, or {@code null} if none.
+     * @param schemaName  The name of the new schema.
      */
-    public DefaultRecordFactory(final NameFactory nameFactory) {
-        ArgumentChecks.ensureNonNull("nameFactory", nameFactory);
+    public DefaultRecordSchema(NameFactory nameFactory, final NameSpace parent, final CharSequence
schemaName) {
+        ArgumentChecks.ensureNonNull("schemaName", schemaName);
+        if (nameFactory == null) {
+            nameFactory = DefaultFactories.NAMES;
+        }
         this.nameFactory    = nameFactory;
+        this.schemaName     = nameFactory.createLocalName(parent, schemaName);
+        this.namespace      = nameFactory.createNameSpace(this.schemaName, null);
+        this.description    = new WeakValueHashMap<>(TypeName.class);
         this.attributeTypes = new HashMap<>();
-        this.schemas        = new HashMap<>();
     }
 
     /**
-     * Returns the schema for the namespace (scope) of the given name.
+     * Returns the schema 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.
+     * @return The schema name.
      */
-    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;
+    @Override
+    public LocalName getSchemaName() {
+        return schemaName;
     }
 
     /**
@@ -143,19 +145,19 @@ public class DefaultRecordFactory {
      * @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)
+    public RecordType createRecordType(final CharSequence typeName, final Map<CharSequence,Class<?>>
members)
             throws IllegalArgumentException
     {
         ArgumentChecks.ensureNonNull("typeName", typeName);
         ArgumentChecks.ensureNonNull("members",  members);
+        final TypeName name = nameFactory.createTypeName(namespace, typeName);
         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);
+        synchronized (description) {
+            record = description.get(typeName);
             if (record == null) {
-                record = new DefaultRecordType(typeName, container, memberTypes, nameFactory);
-                container.description.put(typeName, record);
+                record = new DefaultRecordType(name, this, memberTypes, nameFactory);
+                description.put(name, record);
                 return record;
             }
         }
@@ -178,8 +180,7 @@ public class DefaultRecordFactory {
                 break; // Value classes differ.
             }
         }
-        throw new IllegalArgumentException(Errors.format(Errors.Keys.RecordAlreadyDefined_2,
-                container.getSchemaName(), typeName));
+        throw new IllegalArgumentException(Errors.format(Errors.Keys.RecordAlreadyDefined_2,
schemaName, typeName));
     }
 
     /**
@@ -254,4 +255,35 @@ public class DefaultRecordFactory {
         return nameFactory.createTypeName(nameFactory.createNameSpace(
                 nameFactory.createLocalName(null, ns), null), name);
     }
+
+    /**
+     * 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 + "”]";
+    }
 }

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=1608468&r1=1608467&r2=1608468&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] Mon Jul  7 14:17:18 2014
@@ -26,6 +26,7 @@ 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;
@@ -47,13 +48,32 @@ 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.
+ *
+ * <div class="note"><b>Example:</b>
+ * {@preformat java
+ *     DefaultRecordSchema schema = new DefaultRecordSchema(null, null, "MySchema");
+ *     // We recommand to reuse the same DefaultRecordSchema instance 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.
  *
@@ -112,25 +132,37 @@ public class DefaultRecordType implement
     }
 
     /**
-     * Creates a new record.
+     * 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.
      *
-     * @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();
+     * <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 memberTypes 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> memberTypes)
+    {
+        ArgumentChecks.ensureNonNull("typeName",    typeName);
+        ArgumentChecks.ensureNonNull("container",   container);
+        ArgumentChecks.ensureNonNull("memberTypes", memberTypes);
+        /*
+         * 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, typeName));
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2,
schemaName, fullTypeName));
         }
-        members = new LinkedHashMap<>(members);
+        final Map<MemberName,Type> members = new LinkedHashMap<>(memberTypes);
         members.remove(null);
         for (final Map.Entry<MemberName,Type> entry : members.entrySet()) {
             final MemberName name = entry.getKey();
@@ -138,8 +170,9 @@ public class DefaultRecordType implement
             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));
+            if (fullTypeName.compareTo(name.scope().name()) != 0) {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.InconsistentNamespace_2,
+                        fullTypeName, name.toFullyQualifiedName()));
             }
         }
         this.typeName    = typeName;
@@ -157,11 +190,11 @@ public class DefaultRecordType implement
      * @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 Map<? extends CharSequence, ? extends 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()) {
+        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());

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java?rev=1608468&r1=1608467&r2=1608468&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8]
(original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/iso/Names.java [UTF-8]
Mon Jul  7 14:17:18 2014
@@ -17,6 +17,7 @@
 package org.apache.sis.util.iso;
 
 import java.util.Collections;
+import org.opengis.util.TypeName;
 import org.opengis.util.LocalName;
 import org.opengis.util.GenericName;
 import org.opengis.util.NameSpace;
@@ -100,12 +101,8 @@ public final class Names extends Static 
      * Those character sequences are taken verbatim; they are <em>not</em> parsed
into their components.
      *
      * <div class="note"><b>Note:</b> it is possible to split the {@code
namespace} and {@code localPart}
-     * strings into smaller name components. If such finer grain control is desired, one
can use
-     * {@link DefaultNameFactory} instead of this {@code Names} class.</div>
-     *
-     * <div class="note"><b>Performance note:</b> this method is okay for
<em>casual</em> use. If many names need
-     * to be created in the same namespace, then {@link DefaultNameFactory#createLocalName(NameSpace,
CharSequence)}
-     * is more efficient since it allows to create the {@code NameSpace} object only once.</div>
+     * strings into smaller name components (e.g. namespaces contained in other namespaces).
If such finer
+     * grain control is desired, one can use {@link DefaultNameFactory} instead of this {@code
Names} class.</div>
      *
      * The following table shows where the strings given in argument will go:
      *
@@ -117,7 +114,7 @@ public final class Names extends Static 
      * </table></blockquote>
      *
      * <div class="note"><b>Example:</b>
-     * for a name created by {@code create("http://www.opengis.net/gml/srs/epsg.xml", "#",
"4326")}:
+     * for a name created by {@code createLocalName("http://www.opengis.net/gml/srs/epsg.xml",
"#", "4326")}:
      * <blockquote><table class="compact" summary="Examples of return values for
a name built by this method.">
      *   <tr><td>• <code>name.{@linkplain DefaultLocalName#toString()
toString()}</code></td>
      *       <td>returns the {@code "4326"} string.</td></tr>
@@ -129,6 +126,10 @@ public final class Names extends Static 
      *       <td>returns the {@code "{http://www.opengis.net/gml/srs/epsg.xml}4326"}
string.</td></tr>
      * </table></blockquote></div>
      *
+     * <div class="note"><b>Performance note:</b> this method is okay for
<em>casual</em> use. If many names need
+     * to be created in the same namespace, then {@link DefaultNameFactory#createLocalName(NameSpace,
CharSequence)}
+     * is more efficient since it allows to create the {@code NameSpace} object only once.</div>
+     *
      * @param  namespace The namespace, or {@code null} for the global namespace.
      * @param  separator The separator between the namespace and the local part.
      * @param  localPart The name which is locale in the given namespace.
@@ -141,6 +142,29 @@ public final class Names extends Static 
     }
 
     /**
+     * Creates a type name which is local in the given namespace.
+     * The character sequences can be either {@link String} or {@link InternationalString}
instances.
+     * Those character sequences are taken verbatim; they are <em>not</em> parsed
into their components.
+     *
+     * <div class="note"><b>Example:</b> {@code createTypeName("gco", ":",
"Integer")} returns a name
+     * which can be used for representing the type of {@code <gco:Integer>} elements
in XML files.</div>
+     *
+     * <div class="note"><b>Performance note:</b> this method is okay for
<em>casual</em> use. If many names need
+     * to be created in the same namespace, then {@link DefaultNameFactory#createTypeName(NameSpace,
CharSequence)}
+     * is more efficient since it allows to create the {@code NameSpace} object only once.</div>
+     *
+     * @param  namespace The namespace, or {@code null} for the global namespace.
+     * @param  separator The separator between the namespace and the local part.
+     * @param  localPart The name which is locale in the given namespace.
+     * @return A local name in the given namespace.
+     */
+    public static TypeName createTypeName(final CharSequence namespace, final String separator,
final CharSequence localPart) {
+        ensureNonNull("localPart", localPart);
+        ensureNonNull("separator", separator);
+        return DefaultFactories.NAMES.createTypeName(createNameSpace(namespace, separator),
localPart);
+    }
+
+    /**
      * Formats the given name in <cite>expanded form</cite> close to the Java
Content Repository (JCR) definition.
      * The expanded form is defined as below:
      *

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=1608468&r1=1608467&r2=1608468&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] Mon Jul  7 14:17:18 2014
@@ -26,7 +26,7 @@ import org.junit.BeforeClass;
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.4
+ * @version 0.5
  * @module
  */
 @Suite.SuiteClasses({
@@ -88,6 +88,7 @@ import org.junit.BeforeClass;
     org.apache.sis.util.iso.NamesTest.class,
     org.apache.sis.internal.simple.SimpleReferenceIdentifierTest.class,
     org.apache.sis.util.iso.DefaultRecordTypeTest.class,
+    org.apache.sis.util.iso.DefaultRecordSchemaTest.class,
 
     // Measurements and formatting.
     org.apache.sis.measure.SexagesimalConverterTest.class,

Modified: 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=1608468&r1=1608467&r2=1608468&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/util/iso/DefaultRecordTypeTest.java
[UTF-8] Mon Jul  7 14:17:18 2014
@@ -16,10 +16,20 @@
  */
 package org.apache.sis.util.iso;
 
-import org.apache.sis.test.TestCase;
+import java.util.Collections;
+import org.opengis.util.Type;
+import org.opengis.util.MemberName;
+import org.opengis.util.NameSpace;
+import org.apache.sis.internal.simple.SimpleAttributeType;
+
+// Test imports
 import org.junit.Test;
+import org.apache.sis.test.TestCase;
+import org.apache.sis.test.DependsOn;
+import org.apache.sis.test.DependsOnMethod;
 
-import static org.apache.sis.test.Assert.*;
+import static org.junit.Assert.*;
+import static org.apache.sis.test.TestUtilities.getSingleton;
 
 
 /**
@@ -30,11 +40,105 @@ import static org.apache.sis.test.Assert
  * @version 0.5
  * @module
  */
+@DependsOn(AbstractNameTest.class)
 public final strictfp class DefaultRecordTypeTest extends TestCase {
+    /** Value of {@link DefaultRecordType#getContainer()}.   */ private DefaultRecordSchema
container;
+    /** Value of {@link DefaultRecordType#getTypeName()}.    */ private DefaultTypeName 
   recordTypeName;
+    /** Value of {@link DefaultRecordType#getMembers()}.     */ private DefaultMemberName
  memberName;
+    /** Value of {@link DefaultRecordType#getMemberTypes()}. */ private DefaultTypeName 
   memberTypeName;
+
+    /**
+     * Initializes the private fields.
+     * This method shall be invoked only once per test.
+     */
+    private void init() {
+        final DefaultNameSpace recordNamespace;
+        final DefaultNameSpace memberNamespace;
+
+        recordNamespace = new DefaultNameSpace (null, "MyNameSpace", ":", ":");
+        recordTypeName  = new DefaultTypeName  (recordNamespace, "MyRecordType");
+        memberNamespace = new DefaultNameSpace (recordNamespace, "MyRecordType", ":", ":");
+        memberTypeName  = new DefaultTypeName  (new DefaultNameSpace(null, "gco", ":", ":"),
"Integer");
+        memberName      = new DefaultMemberName(memberNamespace, "aMember", memberTypeName);
+        container       = new DefaultRecordSchema(null, null, "MyNameSpace");
+        assertEquals("MyNameSpace:MyRecordType:aMember", memberName.toFullyQualifiedName().toString());
+    }
+
+    /**
+     * Creates a new record type from the current values of private fields.
+     */
+    private DefaultRecordType create() throws IllegalArgumentException {
+        final Type memberType = new SimpleAttributeType<>(memberTypeName, Integer.class);
+        return new DefaultRecordType(recordTypeName, container, Collections.singletonMap(memberName,
memberType));
+    }
+
+    /**
+     * Tests the construction of {@link DefaultRecordType}, and opportunistically tests
+     * {@link DefaultRecordType#locate(MemberName)}.
+     */
+    @Test
+    public void testConstructor() {
+        init();
+        final DefaultRecordType type = create();
+        assertSame("container",   container,      type.getContainer());
+        assertSame("typeName",    recordTypeName, type.getTypeName());
+        assertSame("members",     memberName,     getSingleton(type.getMembers()));
+        assertSame("memberTypes", memberName,     getSingleton(type.getMemberTypes().keySet()));
+        assertSame("memberTypes", memberTypeName, getSingleton(type.getMemberTypes().values()).getTypeName());
+        assertSame("locate",      memberTypeName, type.locate(memberName));
+        assertNull("locate",                      type.locate(new DefaultMemberName(null,
"otherMember", memberTypeName)));
+    }
+
     /**
-     * TODO
+     * Ensures that constructions of {@link DefaultRecordType} with
+     * inconsistent arguments throw an exception.
      */
     @Test
-    public void test() {
+    @DependsOnMethod("testConstructor")
+    public void testArgumentChecks() {
+        init();
+        final DefaultTypeName  correctRecordName      = recordTypeName;
+        final NameSpace        correctMemberNamespace = memberName.scope();
+        final DefaultNameSpace wrongNamespace         = new DefaultNameSpace(null, "WrongNameSpace",
":", ":");
+        /*
+         * RecordType namespace validation.
+         * Constructor shall require "MyNameSpace:MyRecordType".
+         */
+        recordTypeName = new DefaultTypeName(wrongNamespace, "MyRecordType");
+        try {
+            create();
+            fail("Should have detected namespace mismatch.");
+        } catch (IllegalArgumentException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("MyNameSpace"));                 // Expected
name.
+            assertTrue(message, message.contains("WrongNameSpace:MyRecordType")); // Actual
namespace.
+        }
+        /*
+         * MemberName namespace validation.
+         * Constructor shall require "MyNameSpace:MyRecordType:aMember".
+         */
+        recordTypeName = correctRecordName;
+        memberName = new DefaultMemberName(wrongNamespace, "aMember", memberTypeName);
+        try {
+            create();
+            fail("Should have detected namespace mismatch.");
+        } catch (IllegalArgumentException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("MyNameSpace:MyRecordType"));  // Expected
name.
+            assertTrue(message, message.contains("WrongNameSpace:aMember"));    // Actual
namespace.
+        }
+        /*
+         * MemberName type validation.
+         */
+        final DefaultTypeName otherType = new DefaultTypeName(memberTypeName.scope(), "Real");
+        memberName = new DefaultMemberName(correctMemberNamespace, "aMember", otherType);
+        try {
+            create();
+            fail("Should have detected type mismatch.");
+        } catch (IllegalArgumentException e) {
+            final String message = e.getMessage();
+            assertTrue(message, message.contains("aMember"));
+            assertTrue(message, message.contains("gco:Integer"));
+        }
     }
 }



Mime
View raw message