Search in sources :

Example 6 with MutableGroup

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

the class GroupPath method isValid.

/**
 * Determines if the group path in this configuration is valid in respect to
 * the creation of new groups based on the contained definition groups.
 *
 * @return if the path is valid
 */
public boolean isValid() {
    if (children == null || children.isEmpty()) {
        // parents is assumed to be valid
        return true;
    }
    MutableGroup parentGroup = parents.get(parents.size() - 1);
    DefinitionGroup parentDef = parentGroup.getDefinition();
    for (DefinitionGroup child : children) {
        if (child instanceof GroupPropertyDefinition) {
            if (!GroupUtil.allowAdd(parentGroup, parentDef, ((GroupPropertyDefinition) child).getName())) {
                return false;
            }
        } else {
            // XXX TypeDefinitions not supported in path
            return false;
        }
        // prepare next iteration
        parentGroup = null;
        parentDef = child;
    }
    return true;
}
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 7 with MutableGroup

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

the class GroupPath method createChildGroups.

/**
 * Create groups for the children in the path (which are only represented as
 * definitions). May only be called if the path is valid. This will also
 * update the path to include the groups instead of the definitions.
 *
 * @return the list of created groups
 *
 * @see #isValid()
 */
protected List<MutableGroup> createChildGroups() {
    MutableGroup parent = parents.get(parents.size() - 1);
    final List<MutableGroup> result = new ArrayList<MutableGroup>();
    for (DefinitionGroup child : children) {
        checkState(child instanceof GroupPropertyDefinition);
        // create group
        MutableGroup group = new DefaultGroup(child);
        // add to parent
        QName propertyName = ((GroupPropertyDefinition) child).getName();
        parent.addProperty(propertyName, group);
        // add to result
        result.add(group);
        // prepare for next iteration
        parent = group;
    }
    // update children and parents
    children.clear();
    parents.addAll(result);
    return result;
}
Also used : GroupPropertyDefinition(eu.esdihumboldt.hale.common.schema.model.GroupPropertyDefinition) QName(javax.xml.namespace.QName) ArrayList(java.util.ArrayList) DefaultGroup(eu.esdihumboldt.hale.common.instance.model.impl.DefaultGroup) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup)

Example 8 with MutableGroup

use of eu.esdihumboldt.hale.common.instance.model.MutableGroup 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 9 with MutableGroup

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

the class Rename method structuralRename.

/**
 * Performs a structural rename on the given source object to the given
 * target definition.
 *
 * @param source the source value (or group/instance)
 * @param targetDefinition the target definition
 * @param allowIgnoreNamespaces if for the structure comparison, namespaces
 *            may be ignored
 * @param instanceFactory the instance factory
 * @param copyGeometries specifies if geometry objects should be copied
 * @return the transformed value (or group/instance) or NO_MATCH
 */
public static Object structuralRename(Object source, ChildDefinition<?> targetDefinition, boolean allowIgnoreNamespaces, InstanceFactory instanceFactory, boolean copyGeometries) {
    if (!(source instanceof Group)) {
        // source simple value
        if (targetDefinition.asProperty() != null) {
            // target can have value
            TypeDefinition propertyType = targetDefinition.asProperty().getPropertyType();
            if (copyGeometries || !isGeometry(source)) {
                if (propertyType.getChildren().isEmpty()) {
                    // simple value
                    return convertValue(source, targetDefinition.asProperty().getPropertyType());
                } else {
                    // instance with value
                    MutableInstance instance = instanceFactory.createInstance(propertyType);
                    instance.setDataSet(DataSet.TRANSFORMED);
                    instance.setValue(convertValue(source, propertyType));
                    return instance;
                }
            } else {
                return Result.NO_MATCH;
            }
        }
    }
    // source is group or instance
    if (targetDefinition.asProperty() != null) {
        // target can have value
        TypeDefinition propertyType = targetDefinition.asProperty().getPropertyType();
        if (source instanceof Instance) {
            // source has value
            if (propertyType.getChildren().isEmpty()) {
                // simple value
                return convertValue(((Instance) source).getValue(), targetDefinition.asProperty().getPropertyType());
            } else {
                // instance with value
                MutableInstance instance = instanceFactory.createInstance(targetDefinition.asProperty().getPropertyType());
                instance.setDataSet(DataSet.TRANSFORMED);
                if (copyGeometries || !isGeometry(((Instance) source).getValue())) {
                    instance.setValue(convertValue(((Instance) source).getValue(), targetDefinition.asProperty().getPropertyType()));
                }
                renameChildren((Group) source, instance, targetDefinition, allowIgnoreNamespaces, instanceFactory, copyGeometries);
                return instance;
            }
        } else {
            // source has no value
            if (targetDefinition.asProperty().getPropertyType().getChildren().isEmpty())
                // no match possible
                return Result.NO_MATCH;
            else {
                // instance with no value set
                MutableInstance instance = instanceFactory.createInstance(targetDefinition.asProperty().getPropertyType());
                instance.setDataSet(DataSet.TRANSFORMED);
                if (renameChildren((Group) source, instance, targetDefinition, allowIgnoreNamespaces, instanceFactory, copyGeometries))
                    return instance;
                else
                    // no child matched and no value
                    return Result.NO_MATCH;
            }
        }
    } else if (targetDefinition.asGroup() != null) {
        // target can not have a value
        if (targetDefinition.asGroup().getDeclaredChildren().isEmpty())
            // target neither has a value nor
            return Result.NO_MATCH;
        else // children?
        {
            // group
            MutableGroup group = new DefaultGroup(targetDefinition.asGroup());
            if (renameChildren((Group) source, group, targetDefinition, allowIgnoreNamespaces, instanceFactory, copyGeometries))
                return group;
            else
                // no child matched and no value
                return Result.NO_MATCH;
        }
    } else {
        // neither asProperty nor asGroup -> illegal ChildDefinition
        throw new IllegalStateException("Illegal child type.");
    }
}
Also used : Group(eu.esdihumboldt.hale.common.instance.model.Group) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) DefaultGroup(eu.esdihumboldt.hale.common.instance.model.impl.DefaultGroup) MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) Instance(eu.esdihumboldt.hale.common.instance.model.Instance) 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) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition)

Example 10 with MutableGroup

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

the class StreamGmlWriterTest method fillFeatureTest.

/**
 * Create a feature, fill it with values, write it as GML, validate the GML
 * and load the GML file again to compare the loaded values with the ones
 * that were written
 *
 * @param elementName the element name of the feature type to use, if
 *            <code>null</code> a random element will be used
 * @param targetSchema the schema to use, the first element will be used for
 *            the type of the feature
 * @param values the values to set on the feature
 * @param testName the name of the test
 * @param srsName the SRS name
 * @param skipValueTest if the check for equality shall be skipped
 * @param expectWriteFail if the GML writing is expected to fail
 * @param windingOrderParam winding order parameter or <code>null</code>
 * @return the validation report or the GML writing report if writing
 *         expected to fail
 * @throws Exception if any error occurs
 */
private IOReport fillFeatureTest(String elementName, URI targetSchema, Map<List<QName>, Object> values, String testName, String srsName, boolean skipValueTest, boolean expectWriteFail, EnumWindingOrderTypes windingOrderParam) throws Exception {
    // load the sample schema
    XmlSchemaReader reader = new XmlSchemaReader();
    reader.setSharedTypes(null);
    reader.setSource(new DefaultInputSupplier(targetSchema));
    IOReport schemaReport = reader.execute(null);
    assertTrue(schemaReport.isSuccess());
    XmlIndex schema = reader.getSchema();
    XmlElement element = null;
    if (elementName == null) {
        element = schema.getElements().values().iterator().next();
        if (element == null) {
            // $NON-NLS-1$
            fail("No element found in the schema");
        }
    } else {
        for (XmlElement candidate : schema.getElements().values()) {
            if (candidate.getName().getLocalPart().equals(elementName)) {
                element = candidate;
                break;
            }
        }
        if (element == null) {
            // $NON-NLS-1$ //$NON-NLS-2$
            fail("Element " + elementName + " not found in the schema");
        }
    }
    if (element == null) {
        throw new IllegalStateException();
    }
    // create feature
    MutableInstance feature = new DefaultInstance(element.getType(), null);
    // set some values
    for (Entry<List<QName>, Object> entry : values.entrySet()) {
        MutableGroup parent = feature;
        List<QName> properties = entry.getKey();
        for (int i = 0; i < properties.size() - 1; i++) {
            QName propertyName = properties.get(i);
            DefinitionGroup def = parent.getDefinition();
            Object[] vals = parent.getProperty(propertyName);
            if (vals != null && vals.length > 0) {
                Object value = vals[0];
                if (value instanceof MutableGroup) {
                    parent = (MutableGroup) value;
                } else {
                    MutableGroup child;
                    ChildDefinition<?> childDef = def.getChild(propertyName);
                    if (childDef.asProperty() != null || value != null) {
                        // create instance
                        child = new DefaultInstance(childDef.asProperty().getPropertyType(), null);
                    } else {
                        // create group
                        child = new DefaultGroup(childDef.asGroup());
                    }
                    if (value != null) {
                        // wrap value
                        ((MutableInstance) child).setValue(value);
                    }
                    parent = child;
                }
            }
        }
        parent.addProperty(properties.get(properties.size() - 1), entry.getValue());
    }
    InstanceCollection instances = new DefaultInstanceCollection(Collections.singleton(feature));
    // write to file
    InstanceWriter writer = new GmlInstanceWriter();
    if (windingOrderParam != null) {
        writer.setParameter(GeoInstanceWriter.PARAM_UNIFY_WINDING_ORDER, Value.of(windingOrderParam));
    }
    writer.setInstances(instances);
    DefaultSchemaSpace schemaSpace = new DefaultSchemaSpace();
    schemaSpace.addSchema(schema);
    writer.setTargetSchema(schemaSpace);
    // $NON-NLS-1$
    File outFile = File.createTempFile(testName, ".gml");
    writer.setTarget(new FileIOSupplier(outFile));
    if (windingOrderParam != null && windingOrderParam == EnumWindingOrderTypes.counterClockwise) {
        assertTrue(writer.getParameter(GeoInstanceWriter.PARAM_UNIFY_WINDING_ORDER).as(EnumWindingOrderTypes.class) == EnumWindingOrderTypes.counterClockwise);
    }
    // new LogProgressIndicator());
    IOReport report = writer.execute(null);
    if (expectWriteFail) {
        assertFalse("Writing the GML output should not be successful", report.isSuccess());
        return report;
    } else {
        assertTrue("Writing the GML output not successful", report.isSuccess());
    }
    List<? extends Locatable> validationSchemas = writer.getValidationSchemas();
    System.out.println(outFile.getAbsolutePath());
    System.out.println(targetSchema.toString());
    // if (!DEL_TEMP_FILES && Desktop.isDesktopSupported()) {
    // Desktop.getDesktop().open(outFile);
    // }
    IOReport valReport = validate(outFile.toURI(), validationSchemas);
    // load file
    InstanceCollection loaded = loadGML(outFile.toURI(), schema);
    ResourceIterator<Instance> it = loaded.iterator();
    try {
        assertTrue(it.hasNext());
        if (!skipValueTest) {
            Instance l = it.next();
            // test values
            for (Entry<List<QName>, Object> entry : values.entrySet()) {
                // XXX conversion?
                Object expected = entry.getValue();
                // String propertyPath = Joiner.on('.').join(Collections2.transform(entry.getKey(), new Function<QName, String>() {
                // 
                // @Override
                // public String apply(QName input) {
                // return input.toString();
                // }
                // }));
                // Collection<Object> propValues = PropertyResolver.getValues(
                // l, propertyPath, true);
                // assertEquals(1, propValues.size());
                // Object value = propValues.iterator().next();
                Collection<GeometryProperty<?>> geoms = GeometryUtil.getAllGeometries(l);
                assertEquals(1, geoms.size());
                Object value = geoms.iterator().next().getGeometry();
                if (expected instanceof Geometry && value instanceof Geometry) {
                    if (windingOrderParam == null || windingOrderParam == EnumWindingOrderTypes.noChanges) {
                        matchGeometries((Geometry) expected, (Geometry) value);
                    }
                    // Winding Order Test.
                    if (windingOrderParam != null) {
                        if (windingOrderParam == EnumWindingOrderTypes.counterClockwise) {
                            assertTrue(((Geometry) expected).getNumGeometries() == ((Geometry) value).getNumGeometries());
                            assertTrue(WindingOrder.isCounterClockwise((Geometry) value));
                        } else if (windingOrderParam == EnumWindingOrderTypes.clockwise) {
                            assertFalse(WindingOrder.isCounterClockwise((Geometry) value));
                        } else {
                            assertTrue(WindingOrder.isCounterClockwise((Geometry) value) == WindingOrder.isCounterClockwise((Geometry) expected));
                        }
                    } else {
                        // TODO check winding order is CCW
                        if (value instanceof Polygon || value instanceof MultiPolygon)
                            assertTrue(WindingOrder.isCounterClockwise((Geometry) value));
                    }
                } else {
                    assertEquals(expected.toString(), value.toString());
                }
            }
            assertFalse(it.hasNext());
        }
    } finally {
        it.close();
    }
    if (DEL_TEMP_FILES) {
        outFile.deleteOnExit();
    }
    return valReport;
}
Also used : GmlInstanceWriter(eu.esdihumboldt.hale.io.gml.writer.GmlInstanceWriter) GeoInstanceWriter(eu.esdihumboldt.hale.common.instance.io.GeoInstanceWriter) InstanceWriter(eu.esdihumboldt.hale.common.instance.io.InstanceWriter) MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) Instance(eu.esdihumboldt.hale.common.instance.model.Instance) IOReport(eu.esdihumboldt.hale.common.core.io.report.IOReport) DefaultInstanceCollection(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstanceCollection) DefinitionGroup(eu.esdihumboldt.hale.common.schema.model.DefinitionGroup) XmlSchemaReader(eu.esdihumboldt.hale.io.xsd.reader.XmlSchemaReader) DefaultInstance(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstance) List(java.util.List) Polygon(org.locationtech.jts.geom.Polygon) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) GeometryProperty(eu.esdihumboldt.hale.common.schema.geometry.GeometryProperty) DefaultInputSupplier(eu.esdihumboldt.hale.common.core.io.supplier.DefaultInputSupplier) QName(javax.xml.namespace.QName) DefaultInstanceCollection(eu.esdihumboldt.hale.common.instance.model.impl.DefaultInstanceCollection) InstanceCollection(eu.esdihumboldt.hale.common.instance.model.InstanceCollection) DefaultGroup(eu.esdihumboldt.hale.common.instance.model.impl.DefaultGroup) DefaultSchemaSpace(eu.esdihumboldt.hale.common.schema.model.impl.DefaultSchemaSpace) XmlIndex(eu.esdihumboldt.hale.io.xsd.model.XmlIndex) MutableGroup(eu.esdihumboldt.hale.common.instance.model.MutableGroup) Point(org.locationtech.jts.geom.Point) MultiPoint(org.locationtech.jts.geom.MultiPoint) Geometry(org.locationtech.jts.geom.Geometry) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) MutableInstance(eu.esdihumboldt.hale.common.instance.model.MutableInstance) XmlElement(eu.esdihumboldt.hale.io.xsd.model.XmlElement) FileIOSupplier(eu.esdihumboldt.hale.common.core.io.supplier.FileIOSupplier) GmlInstanceWriter(eu.esdihumboldt.hale.io.gml.writer.GmlInstanceWriter) File(java.io.File)

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