Search in sources :

Example 51 with PropertyDefinition

use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.

the class GroupUtil method determineProperty.

/**
 * Determine the property definition for the given property name.
 *
 * @param groups the stack of the current group objects. The topmost element
 *            is the current group object
 * @param propertyName the property name
 * @param strict states if for assessing possible property definitions
 *            strict checks regarding the structure are applied
 * @param allowFallback states if with strict mode being enabled, falling
 *            back to non-strict mode is allowed (this will not be
 *            propagated to subsequent calls)
 * @param ignoreNamespaces if a property with a differing namespace may be
 *            accepted
 * @return the group property or <code>null</code> if none is found
 */
private static GroupProperty determineProperty(List<MutableGroup> groups, QName propertyName, boolean strict, boolean allowFallback, boolean ignoreNamespaces) {
    if (groups.isEmpty()) {
        return null;
    }
    // the current group
    final MutableGroup currentGroup = groups.get(groups.size() - 1);
    // the queue to collect the siblings of the current group with
    LinkedList<GroupPath> siblings = new LinkedList<GroupPath>();
    /*
		 * Policy: find the property as high in the hierarchy as possible
		 * 
		 * This might lead to problems with some special schemas, e.g. if a
		 * group is defined that allows unbounded occurrences of an element X
		 * and the parent type allows one occurrence there will be trouble if we
		 * have more than two or three of those elements (depending on group and
		 * element cardinalities).
		 * 
		 * If this really poses a problem in the practice we might need
		 * configuration parameters to use different policies. IMHO (ST) in well
		 * designed schemas this problem will not occur.
		 * 
		 * This problem only arises because we read all the data from the stream
		 * and don't know anything about what comes ahead - another possibility
		 * could be to change this behavior where needed.
		 */
    // preferred 1: property of a parent group
    List<MutableGroup> keep = new ArrayList<MutableGroup>(groups);
    List<MutableGroup> close = new ArrayList<MutableGroup>();
    // sort groups in those that must be kept and those that may be closed
    for (int i = keep.size() - 1; i >= 0 && allowClose(keep.get(i)); i--) {
        close.add(0, keep.get(i));
        keep.remove(i);
    }
    if (!close.isEmpty()) {
        // collect parents groups
        List<MutableGroup> parents = new ArrayList<MutableGroup>(close);
        // remove current group
        parents.remove(parents.size() - 1);
        if (!keep.isEmpty()) {
            // insert top allowed parent first
            parents.add(0, keep.get(0));
        // in list
        }
        int maxDescent = close.size() - 1;
        // prototype that is copied for each parent
        List<MutableGroup> stackPrototype = new ArrayList<MutableGroup>(keep);
        LinkedList<GroupPath> level = new LinkedList<GroupPath>();
        LinkedList<GroupPath> nextLevel = new LinkedList<GroupPath>();
        for (int i = 0; i < parents.size(); i++) {
            // add existing parent
            GroupPath path = new GroupPath(new ArrayList<MutableGroup>(stackPrototype), null);
            level.addFirst(path);
            GroupProperty gp = null;
            // check for a direct match in the group
            PropertyDefinition property = determineDirectProperty(parents.get(i), propertyName, strict, ignoreNamespaces);
            if (property != null) {
                gp = new GroupProperty(property, path);
            }
            if (gp == null && maxDescent >= 0) {
                // >= 0 because also for
                // maxDescent 0 we get
                // siblings
                // check the sub-properties
                gp = determineSubProperty(level, propertyName, nextLevel, 0, strict, ignoreNamespaces);
            }
            if (gp != null) {
                return gp;
            }
            // prepare stack prototype for next parent
            if (i + 1 < parents.size()) {
                stackPrototype.add(parents.get(i + 1));
            }
            // swap lists, clear nextLevel
            LinkedList<GroupPath> tmp = level;
            level = nextLevel;
            nextLevel = tmp;
            nextLevel.clear();
        }
        siblings = level;
    }
    // preferred 2: property of the current group
    PropertyDefinition property = determineDirectProperty(currentGroup, propertyName, strict, ignoreNamespaces);
    if (property != null) {
        return new GroupProperty(property, new GroupPath(groups, null));
    }
    // preferred 3: property of a sub-group, sibling group or sibling
    // sub-group
    // add current group
    siblings.addFirst(new GroupPath(groups, null));
    // check the sub-properties
    GroupProperty gp = determineSubProperty(siblings, propertyName, null, -1, strict, ignoreNamespaces);
    if (gp != null) {
        return gp;
    }
    if (strict && allowFallback) {
        // fall-back: property in any group without validity checks
        // XXX though allowClose will still be strict
        log.warn(MessageFormat.format("Could not find valid property path for {0}, source data might be invalid regarding the source schema.", propertyName));
        return determineProperty(groups, propertyName, false, false, ignoreNamespaces);
    }
    return null;
}
Also used : ArrayList(java.util.ArrayList) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) GroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) LinkedList(java.util.LinkedList)

Example 52 with PropertyDefinition

use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.

the class StreamGmlWriter method writeProperties.

/**
 * Write attribute or element properties.
 *
 * @param parent the parent group
 * @param children the child definitions
 * @param attributes <code>true</code> if attribute properties shall be
 *            written, <code>false</code> if element properties shall be
 *            written
 * @param parentIsNil if the parent property is nil
 * @param report the reporter
 * @throws XMLStreamException if writing the attributes/elements fails
 */
private void writeProperties(Group parent, Collection<? extends ChildDefinition<?>> children, boolean attributes, boolean parentIsNil, IOReporter report) throws XMLStreamException {
    if (parent == null) {
        return;
    }
    boolean parentIsChoice = parent.getDefinition() instanceof GroupPropertyDefinition && ((GroupPropertyDefinition) parent.getDefinition()).getConstraint(ChoiceFlag.class).isEnabled();
    for (ChildDefinition<?> child : children) {
        Object[] values = parent.getProperty(child.getName());
        if (child.asProperty() != null) {
            PropertyDefinition propDef = child.asProperty();
            boolean isAttribute = propDef.getConstraint(XmlAttributeFlag.class).isEnabled();
            if (attributes && isAttribute) {
                if (values != null && values.length > 0) {
                    boolean allowWrite = true;
                    // special case handling: omit nilReason
                    if (getParameter(PARAM_OMIT_NIL_REASON).as(Boolean.class, true)) {
                        Cardinality propCard = propDef.getConstraint(Cardinality.class);
                        if ("nilReason".equals(propDef.getName().getLocalPart()) && propCard.getMinOccurs() < 1) {
                            allowWrite = parentIsNil;
                        }
                    }
                    // write attribute
                    if (allowWrite) {
                        // nilReason "unpopulated"
                        if ("nilReason".equals(propDef.getName().getLocalPart()) && "unpopulated".equals(values[0])) {
                            // TODO more strict check to ensure that this is
                            // a GML nilReason? (check property type and
                            // parent types)
                            writeAttribute("other:unpopulated", propDef);
                        } else {
                            // default
                            writeAttribute(values[0], propDef);
                        }
                    }
                    if (values.length > 1) {
                    // TODO warning?!
                    }
                }
            } else if (!attributes && !isAttribute) {
                int numValues = 0;
                if (values != null) {
                    // write element
                    for (Object value : values) {
                        writeElement(value, propDef, report);
                    }
                    numValues = values.length;
                }
                // only if parent is not a choice
                if (!parentIsChoice) {
                    Cardinality cardinality = propDef.getConstraint(Cardinality.class);
                    if (cardinality.getMinOccurs() > numValues) {
                        if (propDef.getConstraint(NillableFlag.class).isEnabled()) {
                            // nillable element
                            for (int i = numValues; i < cardinality.getMinOccurs(); i++) {
                                // write nil element
                                writeElement(null, propDef, report);
                            }
                        } else {
                            for (int i = numValues; i < cardinality.getMinOccurs(); i++) {
                                // write empty element
                                GmlWriterUtil.writeEmptyElement(writer, propDef.getName());
                            }
                        // TODO add warning to report
                        }
                    }
                }
            }
        } else if (child.asGroup() != null) {
            // handle to child groups
            if (values != null) {
                for (Object value : values) {
                    if (value instanceof Group) {
                        writeProperties((Group) value, DefinitionUtil.getAllChildren(child.asGroup()), attributes, parentIsNil, report);
                    } else {
                    // TODO warning/error?
                    }
                }
            }
        }
    }
}
Also used : GroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup) Group(eu.esdihumboldt.hale.common.instance.model.Group) Cardinality(eu.esdihumboldt.hale.common.schema.model.constraint.property.Cardinality) XmlAttributeFlag(eu.esdihumboldt.hale.io.xsd.constraint.XmlAttributeFlag) GroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition)

Example 53 with PropertyDefinition

use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.

the class AbstractGeometryWriter method writePos.

/**
 * Write coordinates into a pos property
 *
 * @param writer the XML stream writer
 * @param coordinates the coordinates to write
 * @param elementType the type of the encompassing element
 * @param gmlNs the GML namespace
 * @param posName the name of the desired DirectPositionType property, or
 *            <code>null</code> if any
 * @param decimalFormatter a decimal formatter to format geometry
 *            coordinates or <code>null</code> to use
 *            <code>Double.toString()</code>
 * @return if writing the coordinates was successful
 * @throws XMLStreamException if an error occurs writing the coordinates
 */
protected static boolean writePos(XMLStreamWriter writer, Coordinate[] coordinates, TypeDefinition elementType, String gmlNs, String posName, DecimalFormat decimalFormatter) throws XMLStreamException {
    PropertyDefinition posAttribute = null;
    // XXX is this enough? or must groups be handled?
    for (PropertyDefinition att : DefinitionUtil.getAllProperties(elementType)) {
        if (att.getPropertyType().getName().equals(new QName(gmlNs, "DirectPositionType"))) {
            // found a property with DirectPositionType
            if (posName == null || posName.equals(att.getName().getLocalPart())) {
                posAttribute = att;
                break;
            }
        }
    }
    if (posAttribute != null) {
        // TODO possibly write repeated positions
        writer.writeStartElement(posAttribute.getName().getNamespaceURI(), posAttribute.getName().getLocalPart());
        // write coordinates separated by spaces
        if (coordinates.length > 0) {
            Coordinate coordinate = coordinates[0];
            writer.writeCharacters(DecimalFormatUtil.applyFormatter(coordinate.x, decimalFormatter));
            // $NON-NLS-1$
            writer.writeCharacters(" ");
            writer.writeCharacters(DecimalFormatUtil.applyFormatter(coordinate.y, decimalFormatter));
            if (!Double.isNaN(coordinate.z)) {
                // $NON-NLS-1$
                writer.writeCharacters(" ");
                writer.writeCharacters(DecimalFormatUtil.applyFormatter(coordinate.z, decimalFormatter));
            }
        }
        writer.writeEndElement();
        return true;
    } else {
        return false;
    }
}
Also used : Coordinate(com.vividsolutions.jts.geom.Coordinate) QName(javax.xml.namespace.QName) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition)

Example 54 with PropertyDefinition

use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.

the class FunctionExecutor method convert.

/**
 * Convert a value according to a target property entity definition.
 *
 * @param value the value to convert
 * @param propertyEntityDefinition the target property entity definition
 * @return the converted object
 * @throws ConversionException if an error occurs during conversion
 */
private Object convert(Object value, PropertyEntityDefinition propertyEntityDefinition) throws ConversionException {
    if (value == null) {
        return null;
    }
    PropertyDefinition def = propertyEntityDefinition.getDefinition();
    Binding binding = def.getPropertyType().getConstraint(Binding.class);
    Class<?> target = binding.getBinding();
    // special handling for Value
    if (value instanceof Value) {
        // try value's internal conversion
        Object result = ((Value) value).as(target);
        if (result != null) {
            return result;
        } else {
            // unwrap value
            value = ((Value) value).getValue();
            if (value == null) {
                return null;
            }
        }
    }
    if (target.isAssignableFrom(value.getClass())) {
        return value;
    }
    if (Collection.class.isAssignableFrom(target) && target.isAssignableFrom(List.class)) {
        // collection / list
        ElementType elementType = def.getPropertyType().getConstraint(ElementType.class);
        return ConversionUtil.getAsList(value, elementType.getBinding(), true);
    }
    return ConversionUtil.getAs(value, target);
}
Also used : Binding(eu.esdihumboldt.hale.common.schema.model.constraint.type.Binding) ElementType(eu.esdihumboldt.hale.common.schema.model.constraint.type.ElementType) MultiValue(eu.esdihumboldt.cst.MultiValue) PropertyValue(eu.esdihumboldt.hale.common.align.transformation.function.PropertyValue) Value(eu.esdihumboldt.hale.common.core.io.Value) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition)

Example 55 with PropertyDefinition

use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.

the class GenerateDuplicates method generateMapping.

private void generateMapping() {
    System.out.println("Indexing example cells...");
    // index all cells based on the target property name
    SetMultimap<String, Cell> exampleCells = HashMultimap.create();
    for (Cell cell : examples.getCells()) {
        if (cell.getTarget().size() == 1) {
            // only supports cells with one target
            EntityDefinition entityDef = CellUtil.getFirstEntity(cell.getTarget()).getDefinition();
            if (entityDef.getDefinition() instanceof PropertyDefinition) {
                if (ADE_NS.equals(entityDef.getDefinition().getName().getNamespaceURI())) {
                    exampleCells.put(entityDef.getDefinition().getName().getLocalPart(), cell);
                } else
                    System.out.println("WARNING: ignoring cell with non-ADE target property");
            } else
                System.out.println("WARNING: ignoring type cell");
        } else
            System.out.println("WARNING: ignoring cell with multiple or no targets");
    }
    // collect all ADE feature types
    List<TypeDefinition> featureTypes = BGISAppUtil.getADEFeatureTypes(targetSchema);
    // visit ADE properties and create cells
    System.out.println("Generating mapping from example cells for");
    String cellNote = MessageFormat.format("Generated through duplication of example cells on BGIS ADE feature types.\n" + "{0,date,medium}", new Date());
    DuplicateVisitor visitor = new DuplicateVisitor(exampleCells, cellNote);
    for (TypeDefinition type : featureTypes) {
        System.out.println(type.getDisplayName() + "...");
        visitor.accept(new TypeEntityDefinition(type, SchemaSpaceID.TARGET, null));
    }
    if (visitor.getCells().isEmpty()) {
        System.out.println("WARNING: no cells were created");
    } else {
        System.out.println(visitor.getCells().size() + " cells were created.");
    }
    // create alignment
    MutableAlignment align = new DefaultAlignment();
    for (MutableCell cell : visitor.getCells()) {
        align.addCell(cell);
    }
    this.alignment = align;
}
Also used : MutableCell(eu.esdihumboldt.hale.common.align.model.MutableCell) MutableAlignment(eu.esdihumboldt.hale.common.align.model.MutableAlignment) PropertyDefinition(eu.esdihumboldt.hale.common.schema.model.PropertyDefinition) Date(java.util.Date) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) TypeEntityDefinition(eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition) EntityDefinition(eu.esdihumboldt.hale.common.align.model.EntityDefinition) TypeEntityDefinition(eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition) DefaultAlignment(eu.esdihumboldt.hale.common.align.model.impl.DefaultAlignment) Cell(eu.esdihumboldt.hale.common.align.model.Cell) MutableCell(eu.esdihumboldt.hale.common.align.model.MutableCell)

Aggregations

PropertyDefinition (eu.esdihumboldt.hale.common.schema.model.PropertyDefinition)64 TypeDefinition (eu.esdihumboldt.hale.common.schema.model.TypeDefinition)38 QName (javax.xml.namespace.QName)24 ChildContext (eu.esdihumboldt.hale.common.align.model.ChildContext)12 PropertyEntityDefinition (eu.esdihumboldt.hale.common.align.model.impl.PropertyEntityDefinition)12 GroupPropertyDefinition (eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition)11 ArrayList (java.util.ArrayList)11 EntityDefinition (eu.esdihumboldt.hale.common.align.model.EntityDefinition)10 DefaultTypeDefinition (eu.esdihumboldt.hale.common.schema.model.impl.DefaultTypeDefinition)10 DefaultPropertyDefinition (eu.esdihumboldt.hale.common.schema.model.impl.DefaultPropertyDefinition)9 Test (org.junit.Test)9 Cell (eu.esdihumboldt.hale.common.align.model.Cell)8 TypeEntityDefinition (eu.esdihumboldt.hale.common.align.model.impl.TypeEntityDefinition)8 Cardinality (eu.esdihumboldt.hale.common.schema.model.constraint.property.Cardinality)7 XmlIndex (eu.esdihumboldt.hale.io.xsd.model.XmlIndex)7 DefaultInputSupplier (eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier)6 URI (java.net.URI)6 Entity (eu.esdihumboldt.hale.common.align.model.Entity)5 Property (eu.esdihumboldt.hale.common.align.model.Property)5 MutableAlignment (eu.esdihumboldt.hale.common.align.model.MutableAlignment)4