Search in sources :

Example 6 with PropertyType

use of org.opengis.feature.PropertyType in project geotoolkit by Geomatys.

the class AbstractReadingTests method testReaders.

/**
 * test different readers.
 */
private void testReaders(final FeatureSet featureSet, final ExpectedResult candidate) throws Exception {
    final FeatureType type = featureSet.getType();
    final Collection<? extends PropertyType> properties = type.getProperties(true);
    try (Stream<Feature> stream = featureSet.features(true)) {
        stream.forEach((Feature t) -> {
        // do nothing
        });
        throw new Exception("Asking for a reader without any query whould raise an error.");
    } catch (Exception ex) {
    // ok
    }
    // property -------------------------------------------------------------
    {
        // check only id query
        final FeatureQuery query = new FeatureQuery();
        query.setProjection(new FeatureQuery.NamedExpression(FF.property(AttributeConvention.IDENTIFIER)));
        FeatureSet subset = featureSet.subset(query);
        FeatureType limited = subset.getType();
        assertNotNull(limited);
        assertTrue(limited.getProperties(true).size() == 1);
        try (Stream<Feature> stream = subset.features(false)) {
            final Iterator<Feature> ite = stream.iterator();
            while (ite.hasNext()) {
                final Feature f = ite.next();
                assertNotNull(FeatureExt.getId(f));
            }
        }
        for (final PropertyType desc : properties) {
            if (desc instanceof Operation)
                continue;
            final FeatureQuery sq = new FeatureQuery();
            sq.setProjection(new FeatureQuery.NamedExpression(FF.property(desc.getName().tip().toString())));
            subset = featureSet.subset(sq);
            limited = subset.getType();
            assertNotNull(limited);
            assertTrue(limited.getProperties(true).size() == 1);
            assertNotNull(limited.getProperty(desc.getName().toString()));
            try (Stream<Feature> stream = subset.features(false)) {
                final Iterator<Feature> ite = stream.iterator();
                while (ite.hasNext()) {
                    final Feature f = ite.next();
                    assertNotNull(f.getProperty(desc.getName().toString()));
                }
            }
        }
    }
    // sort by --------------------------------------------------------------
    for (final PropertyType desc : properties) {
        if (!(desc instanceof AttributeType)) {
            continue;
        }
        final AttributeType att = (AttributeType) desc;
        if (att.getMaximumOccurs() > 1) {
            // do not test sort by on multi occurence properties
            continue;
        }
        final Class clazz = att.getValueClass();
        if (!Comparable.class.isAssignableFrom(clazz) || Geometry.class.isAssignableFrom(clazz)) {
            // can not make a sort by on this attribut.
            continue;
        }
        final FeatureQuery query = new FeatureQuery();
        query.setSortBy(FF.sort(FF.property(desc.getName().tip().toString()), SortOrder.ASCENDING));
        FeatureSet subset = featureSet.subset(query);
        // count should not change with a sort by
        assertEquals(candidate.size, FeatureStoreUtilities.getCount(subset, true).intValue());
        try (Stream<Feature> stream = subset.features(false)) {
            final Iterator<Feature> reader = stream.iterator();
            Comparable last = null;
            while (reader.hasNext()) {
                final Feature f = reader.next();
                Object obj = f.getProperty(desc.getName().toString()).getValue();
                if (obj instanceof Identifier)
                    obj = ((Identifier) obj).getCode();
                final Comparable current = (Comparable) obj;
                if (current != null) {
                    if (last != null) {
                        // check we have the correct order.
                        assertTrue(current.compareTo(last) >= 0);
                    }
                    last = current;
                } else {
                // any restriction about where should be placed the feature with null values ? before ? after ?
                }
            }
        }
        query.setSortBy(FF.sort(FF.property(desc.getName().tip().toString()), SortOrder.DESCENDING));
        subset = featureSet.subset(query);
        // count should not change with a sort by
        assertEquals(candidate.size, FeatureStoreUtilities.getCount(subset, true).intValue());
        try (Stream<Feature> stream = subset.features(false)) {
            final Iterator<Feature> reader = stream.iterator();
            Comparable last = null;
            while (reader.hasNext()) {
                final Feature f = reader.next();
                Object obj = f.getProperty(desc.getName().toString()).getValue();
                if (obj instanceof Identifier)
                    obj = ((Identifier) obj).getCode();
                final Comparable current = (Comparable) obj;
                if (current != null) {
                    if (last != null) {
                        // check we have the correct order.
                        assertTrue(current.compareTo(last) <= 0);
                    }
                    last = current;
                } else {
                // any restriction about where should be placed the feature with null values ? before ? after ?
                }
            }
        }
    }
    // start ----------------------------------------------------------------
    if (candidate.size > 1) {
        List<ResourceId> ids = new ArrayList<>();
        try (Stream<Feature> stream = featureSet.features(false)) {
            final Iterator<Feature> ite = stream.iterator();
            while (ite.hasNext()) {
                ids.add(FeatureExt.getId(ite.next()));
            }
        }
        // skip the first element
        final FeatureQuery query = new FeatureQuery();
        query.setOffset(1);
        try (Stream<Feature> stream = featureSet.subset(query).features(false)) {
            final Iterator<Feature> ite = stream.iterator();
            int i = 1;
            while (ite.hasNext()) {
                assertEquals(FeatureExt.getId(ite.next()), ids.get(i));
                i++;
            }
        }
    }
    // max ------------------------------------------------------------------
    if (candidate.size > 1) {
        final FeatureQuery query = new FeatureQuery();
        query.setLimit(1);
        int i = 0;
        try (Stream<Feature> stream = featureSet.subset(query).features(false)) {
            final Iterator<Feature> ite = stream.iterator();
            while (ite.hasNext()) {
                ite.next();
                i++;
            }
        }
        assertEquals(1, i);
    }
    // filter ---------------------------------------------------------------
    // filters are tested more deeply in the filter module
    // we just make a few tests here for sanity check
    // todo should we make more deep tests ?
    Set<ResourceId> ids = new HashSet<>();
    try (Stream<Feature> stream = featureSet.features(false)) {
        final Iterator<Feature> ite = stream.iterator();
        // peek only one on two ids
        boolean oneOnTwo = true;
        while (ite.hasNext()) {
            final Feature feature = ite.next();
            if (oneOnTwo) {
                ids.add(FeatureExt.getId(feature));
            }
            oneOnTwo = !oneOnTwo;
        }
    }
    Set<ResourceId> remaining = new HashSet<>(ids);
    final FeatureQuery query = new FeatureQuery();
    final Filter f;
    switch(ids.size()) {
        case 0:
            f = Filter.exclude();
            break;
        case 1:
            f = ids.iterator().next();
            break;
        default:
            f = FF.or(ids);
            break;
    }
    query.setSelection(f);
    try (Stream<Feature> stream = featureSet.subset(query).features(false)) {
        final Iterator<Feature> ite = stream.iterator();
        while (ite.hasNext()) {
            remaining.remove(FeatureExt.getId(ite.next()));
        }
    }
    assertTrue(remaining.isEmpty());
}
Also used : FeatureType(org.opengis.feature.FeatureType) ArrayList(java.util.ArrayList) FeatureQuery(org.apache.sis.storage.FeatureQuery) PropertyType(org.opengis.feature.PropertyType) Operation(org.opengis.feature.Operation) Feature(org.opengis.feature.Feature) Identifier(org.opengis.metadata.Identifier) AttributeType(org.opengis.feature.AttributeType) Iterator(java.util.Iterator) Stream(java.util.stream.Stream) HashSet(java.util.HashSet) IllegalNameException(org.apache.sis.storage.IllegalNameException) Geometry(org.locationtech.jts.geom.Geometry) ResourceId(org.opengis.filter.ResourceId) Filter(org.opengis.filter.Filter) FeatureSet(org.apache.sis.storage.FeatureSet)

Example 7 with PropertyType

use of org.opengis.feature.PropertyType in project geotoolkit by Geomatys.

the class JAXPStreamFeatureReader method readFeature.

private Feature readFeature(final FeatureType featureType, final GenericName tagName) throws XMLStreamException {
    final Feature feature = featureType.newInstance();
    /*
         * We create a map and a collection because we can encounter two cases :
         * - The case featureType defines a property with max occur > 1.
         * - The case featureType defines a property with max occur = 1, and its
         * value instance of collection or map.
         * We store all encountered name with its linked property in the map, so
         * at each value parsed, we can add it in the existing property if its
         * value is a list or map. The collection is the final property store,
         * we add the all the created properties in it (so we can put multiple
         * properties with the same name).
         */
    final List<Entry<Operation, Object>> ops = new ArrayList<>();
    // read attributes
    final int nbAtts = reader.getAttributeCount();
    for (int i = 0; i < nbAtts; i++) {
        final QName attName = reader.getAttributeName(i);
        if ("href".equals(attName.getLocalPart())) {
            // or if can't be resolved we will still have the id
            try {
                final String attVal = reader.getAttributeValue(i);
                feature.setPropertyValue(AttributeConvention.IDENTIFIER, attVal);
            } catch (IllegalArgumentException ex) {
            // do nothing
            }
        } else {
            try {
                final AttributeType pd = (AttributeType) featureType.getProperty("@" + attName.getLocalPart());
                final String attVal = reader.getAttributeValue(i);
                final Object val = ObjectConverters.convert(attVal, pd.getValueClass());
                feature.setPropertyValue(pd.getName().toString(), val);
            } catch (PropertyNotFoundException ex) {
            // do nothing
            }
        }
    }
    boolean doNext = true;
    // read a real complex type
    while (!doNext || reader.hasNext()) {
        if (doNext) {
            reader.next();
        }
        doNext = true;
        int event = reader.getEventType();
        if (event == START_ELEMENT) {
            GenericName propName = nameCache.get(reader.getName());
            // we skip the boundedby attribute if it's present
            if ("boundedBy".equals(propName.tip().toString())) {
                toTagEnd("boundedBy");
                continue;
            }
            final String nameAttribute = reader.getAttributeValue(null, "name");
            // search property
            PropertyType propertyType = null;
            FeatureType associationSubType = null;
            // search direct name
            try {
                propertyType = featureType.getProperty(propName.toString());
            } catch (PropertyNotFoundException e) {
            /*can happen*/
            }
            // search using only local part
            if (propertyType == null) {
                try {
                    propertyType = featureType.getProperty(propName.tip().toString());
                } catch (PropertyNotFoundException e) {
                /*can happen*/
                }
            }
            // search if we are dealing with a subtype of a feature association role value type
            if (propertyType == null) {
                try {
                    final FeatureType candidate = featureTypes.get(propName.toString());
                    if (candidate != null) {
                        // search for a FeatureAssociationRole
                        for (PropertyType pt : featureType.getProperties(true)) {
                            if (pt instanceof FeatureAssociationRole) {
                                final FeatureAssociationRole far = (FeatureAssociationRole) pt;
                                final FeatureType vt = far.getValueType();
                                if (vt.isAssignableFrom(candidate)) {
                                    propertyType = far;
                                    associationSubType = candidate;
                                    // change property name where data will be stored
                                    propName = far.getName();
                                    break;
                                }
                            }
                        }
                    }
                } catch (IllegalNameException ex) {
                    Logger.getLogger(JAXPStreamFeatureReader.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            // skip property if we couldn't find it and user requested it
            if (propertyType == null && Boolean.TRUE.equals(this.properties.get(SKIP_UNEXPECTED_PROPERTY_TAGS))) {
                toTagEnd(propName.tip().toString());
                continue;
            }
            // search if we have an _any attribute available
            if (propertyType == null) {
                try {
                    final AttributeType pd = (AttributeType) featureType.getProperty("_any");
                    // convert the content as a dom node
                    final Document doc = readAsDom(propName.tip().toString());
                    feature.setPropertyValue(pd.getName().toString(), doc);
                    doNext = false;
                    continue;
                } catch (PropertyNotFoundException e) {
                    throw new XMLStreamException("Could not find any property fitting named tag " + propName);
                }
            }
            if (propertyType instanceof Operation) {
                final Operation opType = (Operation) propertyType;
                final PropertyType resultType = (PropertyType) opType.getResult();
                final Object value = readPropertyValue(resultType, null, null);
                ops.add(new AbstractMap.SimpleImmutableEntry<>((Operation) propertyType, value));
                if (resultType.getName().equals(propertyType.getName())) {
                    // we are already on the next element here, jaxb ate one
                    doNext = false;
                }
                continue;
            }
            // read attributes
            if (propertyType instanceof AttributeType) {
                final AttributeType<?> attType = (AttributeType) propertyType;
                final int nbPropAtts = reader.getAttributeCount();
                if (nbPropAtts > 0) {
                    final Attribute att = (Attribute) feature.getProperty(propName.toString());
                    for (int i = 0; i < nbPropAtts; i++) {
                        final QName qname = reader.getAttributeName(i);
                        final GenericName attName = nameCache.get(new QName(qname.getNamespaceURI(), "@" + qname.getLocalPart()));
                        final AttributeType<?> charType = attType.characteristics().get(attName.toString());
                        if (charType != null) {
                            final String attVal = reader.getAttributeValue(i);
                            final Object val = ObjectConverters.convert(attVal, charType.getValueClass());
                            final Attribute chara = charType.newInstance();
                            chara.setValue(val);
                            att.characteristics().put(attName.toString(), chara);
                        }
                    }
                }
            }
            // check if attribute has it's own mapping
            final XSDMapping mapping = GMLConvention.getMapping(propertyType);
            if (mapping != null) {
                mapping.readValue(reader, propName, feature);
            } else {
                // parse the value
                final Object value = readPropertyValue(propertyType, associationSubType, feature);
                setValue(feature, propertyType, propName, nameAttribute, value);
            }
        } else if (event == END_ELEMENT) {
            final QName q = reader.getName();
            if (q.getLocalPart().equals("featureMember") || nameCache.get(q).equals(tagName)) {
                break;
            }
        }
    }
    return feature;
}
Also used : FeatureType(org.opengis.feature.FeatureType) PropertyNotFoundException(org.opengis.feature.PropertyNotFoundException) Attribute(org.opengis.feature.Attribute) XSDMapping(org.geotoolkit.feature.xml.jaxb.mapping.XSDMapping) PropertyType(org.opengis.feature.PropertyType) Operation(org.opengis.feature.Operation) Document(org.w3c.dom.Document) Feature(org.opengis.feature.Feature) Entry(java.util.Map.Entry) GenericName(org.opengis.util.GenericName) AttributeType(org.opengis.feature.AttributeType) IllegalNameException(org.apache.sis.storage.IllegalNameException) QName(javax.xml.namespace.QName) XMLStreamException(javax.xml.stream.XMLStreamException) FeatureAssociationRole(org.opengis.feature.FeatureAssociationRole)

Example 8 with PropertyType

use of org.opengis.feature.PropertyType in project geotoolkit by Geomatys.

the class JAXPStreamFeatureReader method resolveReferences.

/**
 * Replace each feature xlink href characteristic by it's real value if it exist.
 *
 * @param obj
 * @throws DataStoreException
 */
private void resolveReferences(Object obj) throws DataStoreException {
    if (obj instanceof Feature) {
        final Feature feature = (Feature) obj;
        final FeatureType type = feature.getType();
        for (PropertyType pt : type.getProperties(true)) {
            if (pt instanceof AttributeType) {
                AttributeType attType = (AttributeType) pt;
                if (attType.getMaximumOccurs() == 1) {
                    Attribute att = (Attribute) feature.getProperty(pt.getName().toString());
                    Object value = att.getValue();
                    if (value == null) {
                        Attribute charatt = (Attribute) att.characteristics().get(GMLConvention.XLINK_HREF.tip().toString());
                        if (charatt != null) {
                            String refGmlId = (String) charatt.getValue();
                            Object target = index.get(refGmlId);
                            if (target == null && refGmlId.startsWith("#")) {
                                // local references start with a #
                                target = index.get(refGmlId.substring(1));
                            }
                            if (target != null)
                                att.setValue(target);
                        }
                    }
                }
            } else if (pt instanceof FeatureAssociationRole) {
                final Object value = feature.getPropertyValue(pt.getName().toString());
                // if association is a gml:referenceType try to resolve the real feature
                FeatureType valueType = ((FeatureAssociationRole) pt).getValueType();
                if ("AbstractGMLType".equals(valueType.getName().tip().toString())) {
                    if (value instanceof Feature) {
                        Feature f = (Feature) value;
                        try {
                            Object fid = f.getPropertyValue(AttributeConvention.IDENTIFIER);
                            if (String.valueOf(fid).startsWith("#")) {
                                // local references start with a #
                                Feature target = (Feature) index.get(fid.toString().substring(1));
                                if (target != null) {
                                    feature.setPropertyValue(pt.getName().toString(), target);
                                }
                            }
                        } catch (IllegalArgumentException ex) {
                        // do nothing
                        }
                    } else if (value instanceof Collection) {
                        final List<Feature> newFeatures = new ArrayList<>();
                        final Collection col = (Collection) value;
                        Iterator<Feature> iterator = col.iterator();
                        while (iterator.hasNext()) {
                            Feature f = (Feature) iterator.next();
                            try {
                                Object fid = f.getPropertyValue(AttributeConvention.IDENTIFIER);
                                if (String.valueOf(fid).startsWith("#")) {
                                    // local references start with a #
                                    Feature target = (Feature) index.get(fid.toString().substring(1));
                                    if (target != null) {
                                        f = target;
                                    }
                                }
                            } catch (IllegalArgumentException ex) {
                            // do nothing
                            }
                            newFeatures.add(f);
                        }
                        feature.setPropertyValue(pt.getName().toString(), newFeatures);
                    }
                } else {
                    // resolve sub children references
                    resolveReferences(value);
                }
            }
        }
    } else if (obj instanceof WritableFeatureSet) {
        final WritableFeatureSet fs = (WritableFeatureSet) obj;
        final List<Feature> newFeatures = new ArrayList<>();
        try (Stream<Feature> stream = fs.features(false)) {
            Iterator<Feature> iterator = stream.iterator();
            while (iterator.hasNext()) {
                Feature f = iterator.next();
                resolveReferences(f);
                newFeatures.add(f);
            }
        }
        fs.removeIf((Feature t) -> true);
        fs.add(newFeatures.iterator());
    } else if (obj instanceof FeatureSet) {
    // can not update features, not writable
    } else if (obj instanceof Collection) {
        final Collection col = (Collection) obj;
        Iterator<Feature> iterator = col.iterator();
        while (iterator.hasNext()) {
            resolveReferences(iterator.next());
        }
    }
}
Also used : FeatureType(org.opengis.feature.FeatureType) WritableFeatureSet(org.apache.sis.storage.WritableFeatureSet) Attribute(org.opengis.feature.Attribute) PropertyType(org.opengis.feature.PropertyType) Feature(org.opengis.feature.Feature) AttributeType(org.opengis.feature.AttributeType) Stream(java.util.stream.Stream) WritableFeatureSet(org.apache.sis.storage.WritableFeatureSet) InMemoryFeatureSet(org.geotoolkit.storage.memory.InMemoryFeatureSet) FeatureSet(org.apache.sis.storage.FeatureSet) FeatureAssociationRole(org.opengis.feature.FeatureAssociationRole)

Example 9 with PropertyType

use of org.opengis.feature.PropertyType in project geotoolkit by Geomatys.

the class Utils method propertyValueAsList.

public static Collection<?> propertyValueAsList(Feature feature, String propertyName) {
    final Object val = feature.getPropertyValue(propertyName);
    final PropertyType type = feature.getType().getProperty(propertyName);
    if (type instanceof AttributeType) {
        if (((AttributeType) type).getMinimumOccurs() > 1) {
            return (Collection<?>) val;
        } else {
            return Collections.singleton(val);
        }
    } else if (type instanceof FeatureAssociationRole) {
        if (((FeatureAssociationRole) type).getMinimumOccurs() > 1) {
            return (Collection<?>) val;
        } else {
            return Collections.singleton(val);
        }
    } else if (type instanceof Operation) {
        return Collections.singleton(val);
    } else {
        throw new IllegalArgumentException("Unknown propert type : " + type);
    }
}
Also used : AttributeType(org.opengis.feature.AttributeType) Collection(java.util.Collection) GeometryCollection(org.locationtech.jts.geom.GeometryCollection) PropertyType(org.opengis.feature.PropertyType) Operation(org.opengis.feature.Operation) FeatureAssociationRole(org.opengis.feature.FeatureAssociationRole)

Example 10 with PropertyType

use of org.opengis.feature.PropertyType in project geotoolkit by Geomatys.

the class JAXBFeatureTypeReader method getType.

private Object getType(String namespaceURI, ComplexType type, BuildStack stack, boolean useCache) {
    final GenericName name = extractFinalName(namespaceURI, type);
    if (useCache && typesCache.containsKey(name)) {
        return typesCache.get(name);
    }
    for (XSDMapping.Spi mapping : mappings) {
        final XSDMapping map = mapping.create(name, this, type);
        if (map != null) {
            IdentifiedType mappedType = map.getType();
            if (mappedType instanceof AttributeType) {
                AttributeType at = (AttributeType) mappedType;
                AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(at);
                atb.addCharacteristic(XSDMapping.class).setName(GMLConvention.MAPPING).setDefaultValue(map);
                mappedType = atb.build();
            // AttributeType[] att = (AttributeType[]) at.characteristics().values().toArray(new AttributeType[0]);
            // final Map properties = new HashMap();
            // properties.put(AbstractIdentifiedType.NAME_KEY, at.getName());
            // properties.put(AbstractIdentifiedType.DEFINITION_KEY, at.getDefinition());
            // properties.put(AbstractIdentifiedType.DEPRECATED_KEY, ((Deprecable) at).isDeprecated());
            // properties.put(AbstractIdentifiedType.DESCRIPTION_KEY, at.getDescription());
            // properties.put(AbstractIdentifiedType.DESIGNATION_KEY, at.getDesignation());
            // mappedType = new MappedAttributeType(
            // properties,
            // at.getValueClass(),
            // at.getMinimumOccurs(),
            // at.getMaximumOccurs(),
            // at.getDefaultValue(),
            // map,
            // att);
            }
            typesCache.put(name, mappedType);
            return mappedType;
        }
    }
    // special case for gml:ReferenceType
    final String namespace = NamesExt.getNamespace(name);
    if ((GMLConvention.GML_311_NAMESPACE.equals(namespace) || GMLConvention.GML_321_NAMESPACE.equals(namespace)) && "ReferenceType".equals(name.tip().toString())) {
        // note : can't use real AbstractGMLType, recursive object creation
        final QName gml = new QName(namespace, "AbstractGMLType");
        final Object abstractGmlType = getType(gml, stack);
        if (abstractGmlType instanceof GenericName) {
            final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
            FeatureAssociationRole far = ftb.addAssociation((GenericName) abstractGmlType).setName(name).build();
            typesCache.put(name, far);
            return far;
        } else {
            final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
            FeatureAssociationRole far = ftb.addAssociation((FeatureType) abstractGmlType).setName(name).build();
            typesCache.put(name, far);
            return far;
        }
    }
    final boolean deprecated = GMLConvention.isDeprecated(type);
    // read simple content type if defined
    final SimpleContent simpleContent = type.getSimpleContent();
    if (simpleContent != null) {
        final ExtensionType sext = simpleContent.getExtension();
        if (sext != null) {
            // simple type base, it must be : this is the content of the tag <tag>XXX<tag>
            // it is not named, so we call it value
            final QName base = sext.getBase();
            final AttributeType st = (AttributeType) resolveType(base, stack);
            final AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(st);
            atb.setName(name);
            atb.setDeprecated(deprecated);
            // read attributes
            for (PropertyType property : getAnnotatedAttributes(namespaceURI, sext.getAttributeOrAttributeGroup(), stack)) {
                CharacteristicTypeBuilder cb = atb.getCharacteristic(property.getName().toString());
                if (cb == null) {
                    atb.addCharacteristic((AttributeType) property);
                } else {
                // characteristic already exist
                }
            }
            final AttributeType att = atb.build();
            typesCache.put(name, att);
            return att;
        }
        final SimpleRestrictionType restriction = simpleContent.getRestriction();
        if (restriction != null) {
            final QName base = restriction.getBase();
            if (base != null) {
                final ComplexType sct = xsdContext.findComplexType(base);
                if (sct != null) {
                    final AttributeType tct = (AttributeType) getType(namespaceURI, sct, stack, true);
                    final AttributeTypeBuilder atb = new FeatureTypeBuilder().addAttribute(tct);
                    atb.setName(name);
                    atb.setDeprecated(deprecated);
                    // read attributes
                    for (PropertyType property : getAnnotatedAttributes(namespaceURI, restriction.getAttributeOrAttributeGroup(), stack)) {
                        CharacteristicTypeBuilder cb = atb.getCharacteristic(property.getName().toString());
                        if (cb == null) {
                            atb.addCharacteristic((AttributeType) property);
                        } else {
                        // characteristic already exist
                        }
                    }
                    final AttributeType att = atb.build();
                    typesCache.put(name, att);
                    return att;
                } else {
                // final PropertyType restType = resolveType(base, stack);
                // addOrReplace(finalType.builder, atb.create(restType, NamesExt.create(namespaceURI, Utils.VALUE_PROPERTY_NAME), 0, 1, false, null));
                }
            }
        }
        throw new MismatchedFeatureException("Undefined simple type : " + name);
    }
    final FeatureTypeBuilder ftb = new FeatureTypeBuilder();
    ftb.setName(name);
    ftb.setDeprecated(deprecated);
    // read attributes
    for (PropertyType property : getAnnotatedAttributes(namespaceURI, type.getAttributeOrAttributeGroup(), stack)) {
        addProperty(ftb, property);
    }
    // read sequence properties
    for (PropertyType property : getGroupAttributes(namespaceURI, type.getSequence(), stack)) {
        addProperty(ftb, property);
    }
    // read complex content if defined
    final ComplexContent content = type.getComplexContent();
    if (content != null) {
        final ExtensionType extension = content.getExtension();
        if (extension != null) {
            final QName base = extension.getBase();
            if (base != null && !base.getLocalPart().equalsIgnoreCase("anytype")) {
                final Object parent = getType(base, stack);
                if (parent instanceof FeatureType) {
                    ftb.setSuperTypes((FeatureType) parent);
                } else if (parent instanceof GenericName) {
                    // parent type is currently being resolved
                    return name;
                }
            }
            // read attributes
            for (PropertyType property : getAnnotatedAttributes(namespaceURI, extension.getAttributeOrAttributeGroup(), stack)) {
                addProperty(ftb, property);
            }
            // read groups
            for (PropertyType property : getGroupAttributes(namespaceURI, extension.getSequence(), stack)) {
                addProperty(ftb, property);
            }
        }
        /* BIG DIRTY HACK: Needed for GML 2.1.2 support.
             * For geometry definition, GML 2 propose an association to some
             * data-type defined by restiction over an abstract geometry type.
             * But, we do not want it to an association, we want it to be an
             * attribute, for god sake ! So, we cheat and if we find a structure
             * like that, we transform it into attribute (oh god that's awful).
             */
        final ComplexRestrictionType restriction = content.getRestriction();
        if (restriction != null) {
            final QName base = restriction.getBase();
            if (base != null) {
                Object restrictionType = getType(base, stack);
                if (restrictionType instanceof FeatureType) {
                    ftb.setSuperTypes((FeatureType) restrictionType);
                }
            // final ComplexType sct = xsdContext.findComplexType(base);
            // if (sct != null) {
            // final Object obj = getType(base.getNamespaceURI(), sct, stack);
            // if (obj instanceof FeatureType
            // //                                && isGeometric((FeatureType)obj)
            // ) {
            // final ExplicitGroup sequence = sct.getSequence();
            // if (sequence != null) {
            // final List<Element> elements = sequence.getElements();
            // if (elements != null && !elements.isEmpty()) {
            // Element e = sequence.getElements().get(0);
            // return ftb.addAttribute(Geometry.class)
            // .setName(e.getRef().getLocalPart())
            // .setMinimumOccurs(sequence.getMinOccurs())
            // .build();
            // }
            // }
            // } else if (obj instanceof PropertyType) {
            // final PropertyTypeBuilder ptb = new FeatureTypeBuilder().addProperty((PropertyType) obj);
            // if (ptb instanceof PropertyTypeBuilder) {
            // final AttributeTypeBuilder atb = (AttributeTypeBuilder) ptb;
            // // check characteristics
            // for (PropertyType property : getAnnotatedAttributes(namespaceURI, restriction.getAttributeOrAttributeGroup(), stack)) {
            // if (atb.getCharacteristic(property.getName().toString()) == null) {
            // atb.addCharacteristic((AttributeType) property);
            // }
            // }
            // }
            // }
            // }
            }
        }
    }
    // read choice if set
    final ExplicitGroup choice = type.getChoice();
    if (choice != null) {
    // this is the case of gml:location
    }
    // //        if (GMLConvention.isDecoratedProperty(featureType.getName().tip().toString())) {
    // //            //Used by geometry property types but also in some gml profils
    // //            final String decoratedName = NamesExt.toExpandedString(featureType.getName());
    // //
    // //            //this is an encapsulated property, we unroll it
    // //            final Collection<? extends PropertyType> subProps = featureType.getProperties(true);
    // //            //we peek the first association, there should be only one
    // //            //but attributes are possible
    // //            for (PropertyType pt : subProps) {
    // //                if (pt.getName().tip().toString().startsWith("@")) {
    // //                    //ignore xml attributes
    // //                    continue;
    // //                }
    // //
    // //                if (pt instanceof FeatureAssociationRole) {
    // //                    /* HACK : GML 3.1.1 : Only way I've found to manage
    // //                     * geometries as attributes. If we've found an association,
    // //                     * and if it's feature type is a geometric property
    // //                     * (derived from abstract geometric type), well, we
    // //                     * return a geometric property.
    // //                     */
    // //                    final FeatureAssociationRole subFar = (FeatureAssociationRole) pt;
    // //                    FeatureType valueType = subFar.getValueType();
    // //                    FeatureAssociationRole ar = ftb
    // //                            .addAssociation(subFar)
    // //                            .setDescription(GMLConvention.DECORATED_DESCRIPTION+NamesExt.toExpandedString(subFar.getName()))
    // //                            .build();
    // //
    // //                    typesCache.put(name, ar);
    // //                    return featureType;
    // //                } else if (pt instanceof AttributeType) {
    // //                    AttributeType at = (AttributeType) pt;
    // //
    // //                    ftb.clear();
    // //                    at = ftb.addAttribute(at).setDescription(GMLConvention.DECORATED_DESCRIPTION+" "+NamesExt.toExpandedString(at.getName())).build();
    // //                    typesCache.put(name, at);
    // //                    return at;
    // //                }
    // //            }
    // //
    // //            throw new UnsupportedOperationException("Decorated property without any property");
    // //
    // //        }
    // define the default geometry
    PropertyTypeBuilder candidateDefaultGeom = null;
    for (PropertyTypeBuilder ptb : ftb.properties()) {
        if (ptb instanceof AttributeTypeBuilder) {
            Class valueClass = ((AttributeTypeBuilder) ptb).getValueClass();
            if (Geometry.class.isAssignableFrom(valueClass)) {
                XSDMapping mapping = GMLConvention.getMapping(ptb.build());
                if (mapping instanceof GeometryMapping) {
                    if (((GeometryMapping) mapping).isDecorated()) {
                        // keep it as a candidate, we prefere undecorated properties
                        candidateDefaultGeom = ptb;
                    } else {
                        candidateDefaultGeom = null;
                        ((AttributeTypeBuilder) ptb).addRole(AttributeRole.DEFAULT_GEOMETRY);
                        break;
                    }
                }
            }
        }
    }
    if (candidateDefaultGeom != null) {
        ((AttributeTypeBuilder) candidateDefaultGeom).addRole(AttributeRole.DEFAULT_GEOMETRY);
    }
    FeatureType featureType = ftb.build();
    typesCache.put(name, featureType);
    return featureType;
}
Also used : GeometryMapping(org.geotoolkit.feature.xml.jaxb.mapping.GeometryMapping) SimpleRestrictionType(org.geotoolkit.xsd.xml.v2001.SimpleRestrictionType) FeatureType(org.opengis.feature.FeatureType) XSDMapping(org.geotoolkit.feature.xml.jaxb.mapping.XSDMapping) PropertyType(org.opengis.feature.PropertyType) ComplexContent(org.geotoolkit.xsd.xml.v2001.ComplexContent) ExplicitGroup(org.geotoolkit.xsd.xml.v2001.ExplicitGroup) SingleAttributeTypeBuilder(org.geotoolkit.feature.SingleAttributeTypeBuilder) AttributeTypeBuilder(org.apache.sis.feature.builder.AttributeTypeBuilder) PropertyTypeBuilder(org.apache.sis.feature.builder.PropertyTypeBuilder) GenericName(org.opengis.util.GenericName) AttributeType(org.opengis.feature.AttributeType) IdentifiedType(org.opengis.feature.IdentifiedType) FeatureTypeBuilder(org.apache.sis.feature.builder.FeatureTypeBuilder) QName(javax.xml.namespace.QName) ComplexRestrictionType(org.geotoolkit.xsd.xml.v2001.ComplexRestrictionType) CharacteristicTypeBuilder(org.apache.sis.feature.builder.CharacteristicTypeBuilder) MismatchedFeatureException(org.opengis.feature.MismatchedFeatureException) ExtensionType(org.geotoolkit.xsd.xml.v2001.ExtensionType) SimpleContent(org.geotoolkit.xsd.xml.v2001.SimpleContent) FeatureAssociationRole(org.opengis.feature.FeatureAssociationRole) LocalComplexType(org.geotoolkit.xsd.xml.v2001.LocalComplexType) ComplexType(org.geotoolkit.xsd.xml.v2001.ComplexType)

Aggregations

PropertyType (org.opengis.feature.PropertyType)124 AttributeType (org.opengis.feature.AttributeType)55 FeatureType (org.opengis.feature.FeatureType)48 Feature (org.opengis.feature.Feature)41 ArrayList (java.util.ArrayList)38 Geometry (org.locationtech.jts.geom.Geometry)37 FeatureAssociationRole (org.opengis.feature.FeatureAssociationRole)26 GenericName (org.opengis.util.GenericName)26 FeatureTypeBuilder (org.apache.sis.feature.builder.FeatureTypeBuilder)24 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)22 PropertyNotFoundException (org.opengis.feature.PropertyNotFoundException)20 Operation (org.opengis.feature.Operation)18 DataStoreException (org.apache.sis.storage.DataStoreException)16 Test (org.junit.Test)13 LineString (org.locationtech.jts.geom.LineString)12 HashMap (java.util.HashMap)11 Filter (org.opengis.filter.Filter)11 IOException (java.io.IOException)9 SQLException (java.sql.SQLException)9 FeatureSet (org.apache.sis.storage.FeatureSet)9