Search in sources :

Example 1 with Type

use of org.opengis.util.Type in project sis by apache.

the class DefaultRecordSchemaTest method testCreateRecordType.

/**
 * Tests {@link DefaultRecordSchema#createRecordType(CharSequence, Map)}.
 */
@Test
public void testCreateRecordType() {
    final DefaultRecordSchema schema = new DefaultRecordSchema(null, null, "MySchema");
    final Map<CharSequence, Class<?>> members = new LinkedHashMap<>(8);
    assertNull(members.put("city", String.class));
    assertNull(members.put("latitude", Double.class));
    assertNull(members.put("longitude", Double.class));
    assertNull(members.put("population", Integer.class));
    final RecordType recordType = schema.createRecordType("MyRecordType", members);
    /*
         * Inspect properties.
         */
    assertSame("container", schema, recordType.getContainer());
    assertEquals("typeName", Names.createTypeName("MySchema", ":", "MyRecordType"), recordType.getTypeName());
    int count = 0;
    for (final Map.Entry<MemberName, Type> entry : recordType.getMemberTypes().entrySet()) {
        final String expectedName;
        final String expectedType;
        final Class<?> expectedClass;
        switch(count) {
            case 0:
                {
                    expectedName = "city";
                    expectedType = "OGC:CharacterString";
                    expectedClass = String.class;
                    break;
                }
            case 1:
                {
                    expectedName = "latitude";
                    expectedType = "OGC:Real";
                    expectedClass = Double.class;
                    break;
                }
            case 2:
                {
                    expectedName = "longitude";
                    expectedType = "OGC:Real";
                    expectedClass = Double.class;
                    break;
                }
            case 3:
                {
                    expectedName = "population";
                    expectedType = "OGC:Integer";
                    expectedClass = Integer.class;
                    break;
                }
            default:
                {
                    throw new AssertionError(count);
                }
        }
        final Type type = entry.getValue();
        assertEquals(expectedName, entry.getKey().toString());
        assertEquals(expectedType, type.getTypeName().toFullyQualifiedName().toString());
        assertEquals(expectedClass, ((SimpleAttributeType) type).getValueClass());
        count++;
    }
    /*
         * The DefaultRecordType(TypeName, RecordSchema, Map) constructor performs many argument checks, so
         * we use that constructor as a way to perform a final validation, especially regarding namespaces.
         */
    final DefaultRecordType copy = new DefaultRecordType(recordType.getTypeName(), recordType.getContainer(), recordType.getMemberTypes());
    assertEquals(recordType, copy);
}
Also used : LinkedHashMap(java.util.LinkedHashMap) SimpleAttributeType(org.apache.sis.internal.simple.SimpleAttributeType) RecordType(org.opengis.util.RecordType) Type(org.opengis.util.Type) RecordType(org.opengis.util.RecordType) MemberName(org.opengis.util.MemberName) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) Test(org.junit.Test)

Example 2 with Type

use of org.opengis.util.Type in project sis by apache.

the class DefaultRecordSchema method createRecordType.

/**
 * 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 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);
    RecordType record;
    synchronized (description) {
        record = description.get(typeName);
        if (record == null) {
            record = new DefaultRecordType(name, this, memberTypes, nameFactory);
            description.put(name, 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) {
            // Finished comparison successfully.
            return record;
        }
        final Map.Entry<CharSequence, Class<?>> e1 = it1.next();
        final Map.Entry<MemberName, Type> e2 = it2.next();
        if (!e2.getKey().tip().toString().equals(e1.toString())) {
            // Member names differ.
            break;
        }
        if (!((SimpleAttributeType) e2.getValue()).getValueClass().equals(e1.getValue())) {
            // Value classes differ.
            break;
        }
    }
    throw new IllegalArgumentException(Errors.format(Errors.Keys.RecordAlreadyDefined_2, getSchemaName(), typeName));
}
Also used : TypeName(org.opengis.util.TypeName) SimpleAttributeType(org.apache.sis.internal.simple.SimpleAttributeType) SimpleAttributeType(org.apache.sis.internal.simple.SimpleAttributeType) Type(org.opengis.util.Type) RecordType(org.opengis.util.RecordType) RecordType(org.opengis.util.RecordType) MemberName(org.opengis.util.MemberName) WeakValueHashMap(org.apache.sis.util.collection.WeakValueHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map)

Example 3 with Type

use of org.opengis.util.Type in project sis by apache.

the class DefaultRecordType method readObject.

/**
 * Invoked on deserialization for restoring the transient fields.
 * See {@link #writeObject(ObjectOutputStream)} for the stream data description.
 *
 * @param  in  the input stream from which to deserialize an object.
 * @throws IOException if an I/O error occurred while reading or if the stream contains invalid data.
 * @throws ClassNotFoundException if the class serialized on the stream is not on the classpath.
 */
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);
}
Also used : XmlType(javax.xml.bind.annotation.XmlType) RecordType(org.opengis.util.RecordType) Type(org.opengis.util.Type) InvalidObjectException(java.io.InvalidObjectException) MemberName(org.opengis.util.MemberName) LinkedHashMap(java.util.LinkedHashMap)

Example 4 with Type

use of org.opengis.util.Type in project sis by apache.

the class RecordDefinition method computeTransientFields.

/**
 * Invoked on construction or deserialization for computing the transient fields.
 *
 * @param  memberTypes  the (<var>name</var>, <var>type</var>) pairs in this record type.
 * @return the values in the given map. This information is not stored in {@code RecordDefinition}
 *         because not needed by this class, but the {@link DefaultRecordType} subclass will store it.
 */
final Type[] computeTransientFields(final Map<? extends MemberName, ? extends Type> memberTypes) {
    final int size = memberTypes.size();
    members = new MemberName[size];
    memberIndices = new LinkedHashMap<>(Containers.hashMapCapacity(size));
    final Type[] types = new Type[size];
    int i = 0;
    for (final Map.Entry<? extends MemberName, ? extends Type> entry : memberTypes.entrySet()) {
        final Type type = entry.getValue();
        if (type instanceof SimpleAttributeType) {
            final Class<?> c = ((SimpleAttributeType) type).getValueClass();
            if (c != Object.class) {
                if (valueClasses == null) {
                    valueClasses = new Class<?>[size];
                }
                valueClasses[i] = c;
                baseValueClass = Classes.findCommonClass(baseValueClass, c);
            }
        }
        final MemberName name = entry.getKey();
        members[i] = name;
        memberIndices.put(name, i);
        types[i] = type;
        i++;
    }
    memberIndices = CollectionsExt.unmodifiableOrCopy(memberIndices);
    baseValueClass = (baseValueClass != null) ? Numbers.wrapperToPrimitive(baseValueClass) : Object.class;
    return types;
}
Also used : SimpleAttributeType(org.apache.sis.internal.simple.SimpleAttributeType) Type(org.opengis.util.Type) RecordType(org.opengis.util.RecordType) MemberName(org.opengis.util.MemberName) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) SimpleAttributeType(org.apache.sis.internal.simple.SimpleAttributeType)

Example 5 with Type

use of org.opengis.util.Type in project sis by apache.

the class DefaultRecordSchema method toAttributeType.

/**
 * Suggests an attribute type for the given value class. The {@code TypeName} will use the UML identifier
 * of OGC/ISO specification when possible, e.g. {@code "GCO:CharacterString"} for {@code java.lang.String}.
 * See <cite>Mapping Java classes to type names</cite> in {@link DefaultTypeName} javadoc for more information.
 *
 * @param  valueClass  the value class to represent as an attribute type.
 * @return attribute type for the given value class.
 */
final Type toAttributeType(final Class<?> valueClass) {
    if (!TypeNames.isValid(valueClass)) {
        return null;
    }
    Type type = attributeTypes.get(valueClass);
    if (type == null) {
        if (valueClass == Void.TYPE) {
            throw new IllegalArgumentException(Errors.format(Errors.Keys.IllegalArgumentValue_2, "valueClass", "void"));
        }
        final TypeName name = nameFactory.toTypeName(valueClass);
        type = new SimpleAttributeType<>(name, valueClass);
        final Type old = attributeTypes.putIfAbsent(valueClass, type);
        if (old != null) {
            // May happen if the type has been computed concurrently.
            return old;
        }
    }
    return type;
}
Also used : SimpleAttributeType(org.apache.sis.internal.simple.SimpleAttributeType) Type(org.opengis.util.Type) RecordType(org.opengis.util.RecordType) TypeName(org.opengis.util.TypeName)

Aggregations

RecordType (org.opengis.util.RecordType)5 Type (org.opengis.util.Type)5 SimpleAttributeType (org.apache.sis.internal.simple.SimpleAttributeType)4 MemberName (org.opengis.util.MemberName)4 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 TypeName (org.opengis.util.TypeName)2 InvalidObjectException (java.io.InvalidObjectException)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentMap (java.util.concurrent.ConcurrentMap)1 XmlType (javax.xml.bind.annotation.XmlType)1 WeakValueHashMap (org.apache.sis.util.collection.WeakValueHashMap)1 Test (org.junit.Test)1