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;
}
}
}
}
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;
}
}
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());
}
}
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;
}
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;
}
}
}
}
Aggregations