Search in sources :

Example 1 with MutableGroup

use of eu.esdihumboldt.hale.common.instance.model.MutableGroup in project hale by halestudio.

the class StreamGmlHelper method parseProperties.

/**
 * Populates an instance or group with its properties based on the given XML
 * stream reader.
 *
 * @param reader the XML stream reader
 * @param group the group to populate with properties
 * @param strict if associating elements with properties should be done
 *            strictly according to the schema, otherwise a fall-back is
 *            used trying to populate values also on invalid property paths
 * @param srsDimension the dimension of the instance or <code>null</code>
 * @param crsProvider CRS provider in case no CRS is specified, may be
 *            <code>null</code>
 * @param crs CRS definition to use if the property contains a geometry that
 *            does not carry its own srsName attribute
 * @param parentType the type of the topmost instance
 * @param propertyPath the property path down from the topmost instance
 * @param onlyAttributes if only attributes should be parsed
 * @param ignoreNamespaces if parsing of the XML instances should allow
 *            types and properties with namespaces that differ from those
 *            defined in the schema
 * @param ioProvider the I/O Provider to get value
 * @throws XMLStreamException if parsing the properties failed
 */
private static void parseProperties(XMLStreamReader reader, MutableGroup group, boolean strict, Integer srsDimension, CRSProvider crsProvider, CRSDefinition crs, TypeDefinition parentType, List<QName> propertyPath, boolean onlyAttributes, boolean ignoreNamespaces, IOProvider ioProvider) throws XMLStreamException {
    final MutableGroup topGroup = group;
    // attributes (usually only present in Instances)
    for (int i = 0; i < reader.getAttributeCount(); i++) {
        QName propertyName = reader.getAttributeName(i);
        // XXX might also be inside a group? currently every attribute group
        // should be flattened
        // for group support there would have to be some other kind of
        // handling than for elements, cause order doesn't matter for
        // attributes
        ChildDefinition<?> child = GroupUtil.findChild(group.getDefinition(), propertyName, ignoreNamespaces);
        if (child != null && child.asProperty() != null) {
            // add property value
            addSimpleProperty(group, child.asProperty(), reader.getAttributeValue(i));
        } else {
            // suppress warnings for xsi attributes (e.g. xsi:nil)
            boolean suppress = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(propertyName.getNamespaceURI());
            if (!suppress) {
                log.warn(MessageFormat.format("No property ''{0}'' found in type ''{1}'', value is ignored", propertyName, group.getDefinition().getIdentifier()));
            }
        }
    }
    Stack<MutableGroup> groups = new Stack<MutableGroup>();
    groups.push(topGroup);
    // elements
    if (!onlyAttributes && hasElements(group.getDefinition())) {
        int open = 1;
        while (open > 0 && reader.hasNext()) {
            int event = reader.next();
            switch(event) {
                case XMLStreamConstants.START_ELEMENT:
                    // determine property definition, allow fall-back to
                    // non-strict mode
                    GroupProperty gp = GroupUtil.determineProperty(groups, reader.getName(), !strict, ignoreNamespaces);
                    if (gp != null) {
                        // update the stack from the path
                        groups = gp.getPath().getAllGroups(strict);
                        // get group object from stack
                        group = groups.peek();
                        PropertyDefinition property = gp.getProperty();
                        List<QName> path = new ArrayList<QName>(propertyPath);
                        path.add(property.getName());
                        if (hasElements(property.getPropertyType())) {
                            // use an instance as value
                            Instance inst = parseInstance(reader, property.getPropertyType(), null, strict, srsDimension, crsProvider, parentType, path, true, ignoreNamespaces, ioProvider, crs);
                            if (inst != null) {
                                group.addProperty(property.getName(), inst);
                            }
                        } else {
                            if (hasAttributes(property.getPropertyType())) {
                                // no elements but attributes
                                // use an instance as value, it will be assigned
                                // an instance value if possible
                                Instance inst = parseInstance(reader, property.getPropertyType(), null, strict, srsDimension, crsProvider, parentType, path, true, ignoreNamespaces, ioProvider);
                                if (inst != null) {
                                    group.addProperty(property.getName(), inst);
                                }
                            } else {
                                // no elements and no attributes
                                // use simple value
                                String value = readText(reader);
                                if (value != null) {
                                    addSimpleProperty(group, property, value);
                                }
                            }
                        }
                    } else {
                        log.warn(MessageFormat.format("No property ''{0}'' found in type ''{1}'', value is ignored", reader.getLocalName(), topGroup.getDefinition().getIdentifier()));
                    }
                    if (reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
                        // only increase open if the current event is not
                        // already the end element (because we used
                        // getElementText)
                        open++;
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    open--;
                    break;
            }
        }
    }
}
Also used : MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) Instance(eu.esdihumboldt.hale.common.instance.model.Instance) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) QName(javax.xml.namespace.QName) ArrayList(java.util.ArrayList) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) Stack(java.util.Stack)

Example 2 with MutableGroup

use of eu.esdihumboldt.hale.common.instance.model.MutableGroup in project hale by halestudio.

the class InstanceBuilder method getValue.

/**
 * Get the value for a target node.
 *
 * @param node the target node
 * @param typeLog the type transformation log
 * @return the value or {@link NoObject#NONE} representing no value
 */
private Object getValue(TargetNode node, TransformationLog typeLog) {
    if (node.getChildren(true).isEmpty()) {
        // simple leaf
        if (node.isDefined()) {
            // XXX this is done in FunctionExecutor
            return node.getResult();
        } else {
            return NoObject.NONE;
        }
    }
    boolean isProperty = node.getDefinition().asProperty() != null;
    boolean isGroup = node.getDefinition().asGroup() != null;
    if (isProperty && node.isDefined()) {
        // it's a property and we have a value/values
        Object nodeValue = node.getResult();
        if (!(nodeValue instanceof MultiValue)) {
            // pack single value into multivalue
            MultiValue nodeMultiValue = new MultiValue();
            nodeMultiValue.add(nodeValue);
            nodeValue = nodeMultiValue;
        }
        MultiValue nodeMultiValue = (MultiValue) nodeValue;
        if (!nodeMultiValue.isEmpty()) {
            // Create n instances
            MultiValue resultMultiValue = new MultiValue(nodeMultiValue.size());
            for (Object value : nodeMultiValue) {
                // the value may have been wrapped in an Instance
                if (value instanceof Instance) {
                    value = ((Instance) value).getValue();
                }
                MutableInstance instance = new DefaultInstance(node.getDefinition().asProperty().getPropertyType(), null);
                instance.setValue(value);
                // XXX since this is the same for all instances maybe do
                // this on a dummy and only copy properties for each?
                // XXX MultiValue w/ target node children => strange results
                populateGroup(instance, node, typeLog);
                resultMultiValue.add(instance);
            }
            return resultMultiValue;
        }
    // if nodeMultiValue is empty fall through to below
    // it the instance could still have children even without a value
    }
    // it's a property or group with no value
    MutableGroup group;
    if (isGroup) {
        group = new DefaultGroup(node.getDefinition().asGroup());
    } else if (isProperty) {
        group = new DefaultInstance(node.getDefinition().asProperty().getPropertyType(), null);
    } else {
        throw new IllegalStateException("Illegal child definition");
    }
    // populate with children
    if (populateGroup(group, node, typeLog)) {
        return group;
    } else {
        return NoObject.NONE;
    }
}
Also used : MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) Instance(eu.esdihumboldt.hale.common.instance.model.Instance) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) DefaultGroup(eu.esdihumboldt.hale.common.instance.model.impl.DefaultGroup) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) MultiValue(eu.esdihumboldt.cst.MultiValue)

Example 3 with MutableGroup

use of eu.esdihumboldt.hale.common.instance.model.MutableGroup in project hale by halestudio.

the class GroupPath method allowAdd.

/**
 * Determines if the adding a property value for the given property to the
 * last element in the path is allowed.
 *
 * @param propertyName the property name
 * @param strict states if additional checks are applied apart from whether
 *            the property exists
 * @param ignoreNamespaces if a property with a differing namespace may be
 *            accepted
 * @return if adding the property value to the last element in the path is
 *         allowed
 */
public boolean allowAdd(QName propertyName, boolean strict, boolean ignoreNamespaces) {
    if (children == null || children.isEmpty()) {
        // check last parent
        MutableGroup parent = parents.get(parents.size() - 1);
        ChildDefinition<?> child = GroupUtil.findChild(parent.getDefinition(), propertyName, ignoreNamespaces);
        if (child.asProperty() != null) {
            return !strict || GroupUtil.allowAdd(parent, null, child.asProperty().getName());
        } else {
            return false;
        }
    } else {
        // check last child
        DefinitionGroup child = children.get(children.size() - 1);
        ChildDefinition<?> property = GroupUtil.findChild(child, propertyName, ignoreNamespaces);
        if (property == null) {
            return false;
        }
        if (child instanceof GroupPropertyDefinition && ((GroupPropertyDefinition) child).getConstraint(ChoiceFlag.class).isEnabled()) {
            // group is a choice
            return true;
        }
        return !strict || GroupUtil.allowAdd(null, child, property.getName());
    }
}
Also used : GroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup)

Example 4 with MutableGroup

use of eu.esdihumboldt.hale.common.instance.model.MutableGroup in project hale by halestudio.

the class GroupUtil method determineSubProperty.

/**
 * Determine the property definition for the given property name in
 * sub-groups of the given group stack.
 *
 * @param paths the group paths whose children shall be checked for the
 *            property
 * @param propertyName the property name
 * @param leafs the queue is populated with the leafs in the explored
 *            definition group tree that are not processed because of the
 *            max descent, may be <code>null</code> if no population is
 *            needed
 * @param maxDescent the maximum descent, -1 for no maximum descent
 * @param strict states if additional checks are applied apart from whether
 *            the property exists
 * @param ignoreNamespaces if a property with a differing namespace may be
 *            accepted
 * @return the property definition or <code>null</code> if none is found
 */
private static GroupProperty determineSubProperty(Queue<GroupPath> paths, QName propertyName, Queue<GroupPath> leafs, int maxDescent, boolean strict, boolean ignoreNamespaces) {
    if (maxDescent != -1 && maxDescent < 0) {
        return null;
    }
    while (!paths.isEmpty()) {
        GroupPath path = paths.poll();
        DefinitionGroup lastDef = null;
        if (path.getChildren() != null && !path.getChildren().isEmpty()) {
            // check if path is a valid result
            if (path.allowAdd(propertyName, strict, ignoreNamespaces)) {
                ChildDefinition<?> property = findChild(path.getLastDefinition(), propertyName, ignoreNamespaces);
                if (property != null && property.asProperty() != null) {
                    // return group property
                    return new GroupProperty(property.asProperty(), path);
                } else {
                    log.error("False positive for property candidate.");
                }
            }
            lastDef = path.getLastDefinition();
        } else {
            // the first path which must not be checked, just the children
            // must be added to the queue
            List<MutableGroup> parents = path.getParents();
            if (parents != null && !parents.isEmpty()) {
                lastDef = parents.get(parents.size() - 1).getDefinition();
            }
        }
        if (lastDef != null) {
            // add children to queue
            Collection<? extends ChildDefinition<?>> children = DefinitionUtil.getAllChildren(lastDef);
            for (ChildDefinition<?> child : children) {
                if (child.asGroup() != null && (path.getChildren() == null || !path.getChildren().contains(child.asGroup()))) {
                    // (check for
                    // definition cycle)
                    List<DefinitionGroup> childDefs = new ArrayList<DefinitionGroup>();
                    if (path.getChildren() != null) {
                        childDefs.addAll(path.getChildren());
                    }
                    childDefs.add(child.asGroup());
                    GroupPath newPath = new GroupPath(path.getParents(), childDefs);
                    // check if path is valid
                    if (!strict || newPath.isValid()) {
                        // check max descent
                        if (maxDescent >= 0 && newPath.getChildren().size() > maxDescent) {
                            if (leafs != null) {
                                leafs.add(newPath);
                            }
                        } else {
                            paths.add(newPath);
                        }
                    }
                }
            }
        }
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup)

Example 5 with MutableGroup

use of eu.esdihumboldt.hale.common.instance.model.MutableGroup in project hale by halestudio.

the class StreamGmlHelper method parseProperties.

/**
 * Populates an instance or group with its properties based on the given XML
 * stream reader.
 *
 * @param reader the XML stream reader
 * @param group the group to populate with properties
 * @param strict if associating elements with properties should be done
 *            strictly according to the schema, otherwise a fall-back is
 *            used trying to populate values also on invalid property paths
 * @param srsDimension the dimension of the instance or <code>null</code>
 * @param crsProvider CRS provider in case no CRS is specified, may be
 *            <code>null</code>
 * @param crs CRS definition to use if the property contains a geometry that
 *            does not carry its own srsName attribute
 * @param parentType the type of the topmost instance
 * @param propertyPath the property path down from the topmost instance
 * @param onlyAttributes if only attributes should be parsed
 * @param ignoreNamespaces if parsing of the XML instances should allow
 *            types and properties with namespaces that differ from those
 *            defined in the schema
 * @param ioProvider the I/O Provider to get value
 * @throws XMLStreamException if parsing the properties failed
 */
private static void parseProperties(XMLStreamReader reader, MutableGroup group, boolean strict, AtomicInteger srsDimension, CRSProvider crsProvider, CRSDefinition crs, TypeDefinition parentType, List<QName> propertyPath, boolean onlyAttributes, boolean ignoreNamespaces, IOProvider ioProvider) throws XMLStreamException {
    final MutableGroup topGroup = group;
    // attributes (usually only present in Instances)
    for (int i = 0; i < reader.getAttributeCount(); i++) {
        QName propertyName = reader.getAttributeName(i);
        // XXX might also be inside a group? currently every attribute group
        // should be flattened
        // for group support there would have to be some other kind of
        // handling than for elements, cause order doesn't matter for
        // attributes
        ChildDefinition<?> child = GroupUtil.findChild(group.getDefinition(), propertyName, ignoreNamespaces);
        if (child != null && child.asProperty() != null) {
            // add property value
            addSimpleProperty(group, child.asProperty(), reader.getAttributeValue(i));
        } else {
            // suppress warnings for xsi attributes (e.g. xsi:nil)
            boolean suppress = XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(propertyName.getNamespaceURI());
            if (!suppress) {
                log.warn(MessageFormat.format("No property ''{0}'' found in type ''{1}'', value is ignored", propertyName, group.getDefinition().getIdentifier()));
            }
        }
    }
    Stack<MutableGroup> groups = new Stack<MutableGroup>();
    groups.push(topGroup);
    // elements
    if (!onlyAttributes && hasElements(group.getDefinition())) {
        int open = 1;
        while (open > 0 && reader.hasNext()) {
            int event = reader.next();
            switch(event) {
                case XMLStreamConstants.START_ELEMENT:
                    // determine property definition, allow fall-back to
                    // non-strict mode
                    GroupProperty gp = GroupUtil.determineProperty(groups, reader.getName(), !strict, ignoreNamespaces);
                    if (gp != null) {
                        // update the stack from the path
                        groups = gp.getPath().getAllGroups(strict);
                        // get group object from stack
                        group = groups.peek();
                        PropertyDefinition property = gp.getProperty();
                        List<QName> path = new ArrayList<QName>(propertyPath);
                        path.add(property.getName());
                        if (hasElements(property.getPropertyType())) {
                            // use an instance as value
                            Instance inst = parseInstance(reader, property.getPropertyType(), null, strict, srsDimension, crsProvider, parentType, path, true, ignoreNamespaces, ioProvider, crs);
                            if (inst != null) {
                                group.addProperty(property.getName(), inst);
                            }
                        } else {
                            if (hasAttributes(property.getPropertyType())) {
                                // no elements but attributes
                                // use an instance as value, it will be assigned
                                // an instance value if possible
                                Instance inst = parseInstance(reader, property.getPropertyType(), null, strict, srsDimension, crsProvider, parentType, path, true, ignoreNamespaces, ioProvider);
                                if (inst != null) {
                                    group.addProperty(property.getName(), inst);
                                }
                            } else {
                                // no elements and no attributes
                                // use simple value
                                String value = readText(reader);
                                if (value != null) {
                                    addSimpleProperty(group, property, value);
                                }
                            }
                        }
                    } else {
                        log.warn(MessageFormat.format("No property ''{0}'' found in type ''{1}'', value is ignored", reader.getLocalName(), topGroup.getDefinition().getIdentifier()));
                    }
                    if (reader.getEventType() != XMLStreamConstants.END_ELEMENT) {
                        // only increase open if the current event is not
                        // already the end element (because we used
                        // getElementText)
                        open++;
                    }
                    break;
                case XMLStreamConstants.END_ELEMENT:
                    open--;
                    break;
            }
        }
    }
}
Also used : MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) Instance(eu.esdihumboldt.hale.common.instance.model.Instance) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) QName(javax.xml.namespace.QName) ArrayList(java.util.ArrayList) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) Stack(java.util.Stack)

Aggregations

MutableGroup (eu.esdihumboldt.hale.common.instance.model.MutableGroup)10 Instance (eu.esdihumboldt.hale.common.instance.model.Instance)5 MutableInstance (eu.esdihumboldt.hale.common.instance.model.MutableInstance)5 DefinitionGroup (eu.esdihumboldt.hale.common.schema.model.DefinitionGroup)5 ArrayList (java.util.ArrayList)5 DefaultGroup (eu.esdihumboldt.hale.common.instance.model.impl.DefaultGroup)4 DefaultInstance (eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance)4 GroupPropertyDefinition (eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition)4 QName (javax.xml.namespace.QName)4 PropertyDefinition (eu.esdihumboldt.hale.common.schema.model.PropertyDefinition)3 Stack (java.util.Stack)2 MultiValue (eu.esdihumboldt.cst.MultiValue)1 IOReport (eu.esdihumboldt.hale.common.core.io.report.IOReport)1 DefaultInputSupplier (eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier)1 FileIOSupplier (eu.esdihumboldt.hale.common.core.io.supplier.FileIOSupplier)1 GeoInstanceWriter (eu.esdihumboldt.hale.common.instance.io.GeoInstanceWriter)1 InstanceWriter (eu.esdihumboldt.hale.common.instance.io.InstanceWriter)1 Group (eu.esdihumboldt.hale.common.instance.model.Group)1 InstanceCollection (eu.esdihumboldt.hale.common.instance.model.InstanceCollection)1 DefaultInstanceCollection (eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstanceCollection)1