Search in sources :

Example 1 with DefinitionPath

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath in project hale by halestudio.

the class Pattern method match.

/**
 * Matches the type against the encoding pattern.
 *
 * @param type the type definition
 * @param path the definition path
 * @param gmlNs the GML namespace
 * @param checkedTypes the type definitions that have already been checked
 *            (to prevent cycles)
 * @param remainingElements the remaining elements to match
 *
 * @return the new path if there is a match, <code>null</code> otherwise
 */
private static DefinitionPath match(TypeDefinition type, DefinitionPath path, String gmlNs, HashSet<TypeDefinition> checkedTypes, List<PatternElement> remainingElements) {
    if (remainingElements == null || remainingElements.isEmpty()) {
        return null;
    }
    if (checkedTypes.contains(type)) {
        return null;
    } else {
        checkedTypes.add(type);
    }
    PatternElement first = remainingElements.get(0);
    PatternElement checkAgainst;
    boolean allowAttributeDescent;
    boolean removeFirstForAttributeDescent = false;
    boolean allowSubtypeDescent = true;
    switch(first.getType()) {
        case ONE_ELEMENT:
            // only descend
            checkAgainst = null;
            allowAttributeDescent = true;
            // first element may not be
            removeFirstForAttributeDescent = true;
            // special case: was last element
            if (remainingElements.size() == 1) {
                return path;
            }
            break;
        case ANY_ELEMENTS:
            // check against the next named element
            PatternElement named = null;
            for (int i = 1; i < remainingElements.size() && named == null; i++) {
                PatternElement element = remainingElements.get(i);
                if (element.getType().equals(ElementType.NAMED_ELEMENT)) {
                    named = element;
                }
            }
            if (named == null) {
                // no named element
                return null;
            } else {
                checkAgainst = named;
            }
            allowAttributeDescent = true;
            break;
        case NAMED_ELEMENT:
            // check the current
            checkAgainst = first;
            // only allow sub-type descent
            allowAttributeDescent = false;
            break;
        default:
            // $NON-NLS-1$
            throw new IllegalStateException("Unknown pattern element type");
    }
    if (checkAgainst != null) {
        // get the last path element
        QName elementName = path.getLastName();
        QName name = checkAgainst.getName();
        // inject namespace if needed
        if (name.getNamespaceURI() == GML_NAMESPACE_PLACEHOLDER) {
            name = new QName(gmlNs, name.getLocalPart());
        }
        // check direct match
        if (name.equals(elementName)) {
            // match for the element name -> we are on the right track
            int index = remainingElements.indexOf(checkAgainst);
            if (index == remainingElements.size() - 1) {
                // is last - we have a full match
                return path;
            }
            // remove the element (and any leading wildcards) from the queue
            remainingElements = remainingElements.subList(index + 1, remainingElements.size());
            // for a name match, no sub-type descent is allowed
            allowSubtypeDescent = false;
            // but an attribute descent is ok
            allowAttributeDescent = true;
        } else {
        // no name match
        // sub-type descent is still allowed, don't remove element
        }
    }
    if (allowSubtypeDescent) {
    // step down sub-types
    // XXX now represented in choices
    // XXX sub-type must work through parent choice
    // for (SchemaElement element : type.getSubstitutions(path.getLastName())) {
    // DefinitionPath candidate = match(
    // element.getType(),
    // new DefinitionPath(path).addSubstitution(element),
    // gmlNs,
    // new HashSet<TypeDefinition>(checkedTypes),
    // new ArrayList<PatternElement>(remainingElements));
    // 
    // if (candidate != null) {
    // return candidate;
    // }
    // }
    }
    if (allowAttributeDescent) {
        if (removeFirstForAttributeDescent) {
            remainingElements.remove(0);
        }
        // step down properties
        @java.lang.SuppressWarnings("unchecked") Iterable<ChildDefinition<?>> children = (Iterable<ChildDefinition<?>>) ((path.isEmpty()) ? (type.getChildren()) : (type.getDeclaredChildren()));
        Iterable<DefinitionPath> childPaths = GmlWriterUtil.collectPropertyPaths(children, path, true);
        for (DefinitionPath childPath : childPaths) {
            DefinitionPath candidate = match(childPath.getLastType(), childPath, gmlNs, new HashSet<TypeDefinition>(checkedTypes), new ArrayList<PatternElement>(remainingElements));
            if (candidate != null) {
                return candidate;
            }
        }
    }
    return null;
}
Also used : QName(javax.xml.namespace.QName) ChildDefinition(eu.esdihumboldt.hale.common.schema.model.ChildDefinition) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath)

Example 2 with DefinitionPath

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath in project hale by halestudio.

the class PatternTest method testDirect.

/**
 * Test a direct match
 */
@Ignore
@Test
public void testDirect() {
    // $NON-NLS-1$
    Pattern pattern = Pattern.parse("Curve");
    TypeDefinition start = createCurveType();
    DefinitionPath path = pattern.match(start, new DefinitionPath(start, CURVE_ELEMENT, false), GML_NS);
    // $NON-NLS-1$
    assertNotNull("A match should have been found", path);
    // $NON-NLS-1$
    assertTrue("Path should be empty", path.isEmpty());
    assertEquals(start, path.getLastType());
}
Also used : DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DefaultTypeDefinition(eu.esdihumboldt.hale.common.schema.model.impl.DefaultTypeDefinition) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 3 with DefinitionPath

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath in project hale by halestudio.

the class StreamGmlWriter method write.

/**
 * Write the given instances to an {@link XMLStreamWriter}.<br>
 * <br>
 * Use {@link #createWriter(OutputStream, IOReporter)} to create a properly
 * configured writer for this method.
 *
 * @param instances the instance collection
 * @param writer the writer to write the instances to
 * @param reporter the reporter
 * @param progress the progress
 * @see #createWriter(OutputStream, IOReporter)
 */
protected void write(InstanceCollection instances, PrefixAwareStreamWriter writer, ProgressIndicator progress, IOReporter reporter) {
    this.writer = writer;
    try {
        final SubtaskProgressIndicator sub = new SubtaskProgressIndicator(progress) {

            @Override
            protected String getCombinedTaskName(String taskName, String subtaskName) {
                return taskName + " (" + subtaskName + ")";
            }
        };
        progress = sub;
        progress.begin(getTaskName(), instances.size());
        XmlElement container = findDefaultContainter(targetIndex, reporter);
        TypeDefinition containerDefinition = (container == null) ? (null) : (container.getType());
        QName containerName = (container == null) ? (null) : (container.getName());
        if (containerDefinition == null) {
            XmlElement containerElement = getConfiguredContainerElement(this, getXMLIndex());
            containerDefinition = containerElement.getType();
            containerName = containerElement.getName();
        }
        if (containerDefinition == null || containerName == null) {
            throw new IllegalStateException("No root element/container found");
        }
        /*
			 * Add schema for container to validation schemas, if the namespace
			 * differs from the main namespace or additional schemas.
			 * 
			 * Needed for validation based on schemaLocation attribute.
			 */
        if (!containerName.getNamespaceURI().equals(targetIndex.getNamespace()) && !additionalSchemas.containsKey(containerName.getNamespaceURI())) {
            try {
                @SuppressWarnings("null") final URI containerSchemaLoc = stripFragment(container.getLocation());
                if (containerSchemaLoc != null) {
                    addValidationSchema(containerName.getNamespaceURI(), new Locatable() {

                        @Override
                        public URI getLocation() {
                            return containerSchemaLoc;
                        }
                    }, null);
                }
            } catch (Exception e) {
                reporter.error(new IOMessageImpl("Could not determine location of container definition", e));
            }
        }
        // additional schema namespace prefixes
        for (Entry<String, String> schemaNs : additionalSchemaPrefixes.entrySet()) {
            GmlWriterUtil.addNamespace(writer, schemaNs.getKey(), schemaNs.getValue());
        }
        writer.writeStartDocument();
        if (documentWrapper != null) {
            documentWrapper.startWrap(writer, reporter);
        }
        GmlWriterUtil.writeStartElement(writer, containerName);
        // generate mandatory id attribute (for feature collection)
        String containerId = getParameter(PARAM_CONTAINER_ID).as(String.class);
        GmlWriterUtil.writeID(writer, containerDefinition, null, false, containerId);
        // write schema locations
        StringBuffer locations = new StringBuffer();
        String noNamespaceLocation = null;
        if (targetIndex.getNamespace() != null && !targetIndex.getNamespace().isEmpty()) {
            locations.append(targetIndex.getNamespace());
            // $NON-NLS-1$
            locations.append(" ");
            locations.append(targetIndex.getLocation().toString());
        } else {
            noNamespaceLocation = targetIndex.getLocation().toString();
        }
        for (Entry<String, Locatable> schema : additionalSchemas.entrySet()) {
            if (schema.getKey() != null && !schema.getKey().isEmpty()) {
                if (locations.length() > 0) {
                    // $NON-NLS-1$
                    locations.append(" ");
                }
                locations.append(schema.getKey());
                // $NON-NLS-1$
                locations.append(" ");
                locations.append(schema.getValue().getLocation().toString());
            } else {
                noNamespaceLocation = schema.getValue().getLocation().toString();
            }
        }
        if (locations.length() > 0) {
            // $NON-NLS-1$
            writer.writeAttribute(SCHEMA_INSTANCE_NS, "schemaLocation", locations.toString());
        }
        if (noNamespaceLocation != null) {
            // $NON-NLS-1$
            writer.writeAttribute(// $NON-NLS-1$
            SCHEMA_INSTANCE_NS, // $NON-NLS-1$
            "noNamespaceSchemaLocation", noNamespaceLocation);
        }
        writeAdditionalElements(writer, containerDefinition, reporter);
        // write the instances
        ResourceIterator<Instance> itInstance = instances.iterator();
        try {
            Map<TypeDefinition, DefinitionPath> paths = new HashMap<TypeDefinition, DefinitionPath>();
            long lastUpdate = 0;
            int count = 0;
            Descent lastDescent = null;
            while (itInstance.hasNext() && !progress.isCanceled()) {
                Instance instance = itInstance.next();
                TypeDefinition type = instance.getDefinition();
                /*
					 * Skip all objects that are no features when writing to a
					 * GML feature collection.
					 */
                boolean skip = useFeatureCollection && !GmlWriterUtil.isFeatureType(type);
                if (skip) {
                    progress.advance(1);
                    continue;
                }
                // get stored definition path for the type
                DefinitionPath defPath;
                if (paths.containsKey(type)) {
                    // get the stored path, may be null
                    defPath = paths.get(type);
                } else {
                    // determine a valid definition path in the container
                    defPath = findMemberAttribute(containerDefinition, containerName, type);
                    // store path (may be null)
                    paths.put(type, defPath);
                }
                if (defPath != null) {
                    // write the feature
                    lastDescent = Descent.descend(writer, defPath, lastDescent, false);
                    writeMember(instance, type, reporter);
                } else {
                    reporter.warn(new IOMessageImpl(MessageFormat.format("No compatible member attribute for type {0} found in root element {1}, one instance was skipped", type.getDisplayName(), containerName.getLocalPart()), null));
                }
                progress.advance(1);
                count++;
                long now = System.currentTimeMillis();
                // only update every 100 milliseconds
                if (now - lastUpdate > 100 || !itInstance.hasNext()) {
                    lastUpdate = now;
                    sub.subTask(String.valueOf(count) + " instances");
                }
            }
            if (lastDescent != null) {
                lastDescent.close();
            }
        } finally {
            itInstance.close();
        }
        // FeatureCollection
        writer.writeEndElement();
        if (documentWrapper != null) {
            documentWrapper.endWrap(writer, reporter);
        }
        writer.writeEndDocument();
        writer.close();
        reporter.setSuccess(reporter.getErrors().isEmpty());
    } catch (Exception e) {
        reporter.error(new IOMessageImpl(e.getLocalizedMessage(), e));
        reporter.setSuccess(false);
    } finally {
        progress.end();
    }
}
Also used : Instance(eu.esdihumboldt.hale.common.instance.model.Instance) HashMap(java.util.HashMap) QName(javax.xml.namespace.QName) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) SubtaskProgressIndicator(eu.esdihumboldt.hale.common.core.io.impl.SubtaskProgressIndicator) URI(java.net.URI) IOProviderConfigurationException(eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException) URISyntaxException(java.net.URISyntaxException) XMLStreamException(javax.xml.stream.XMLStreamException) IOException(java.io.IOException) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) XmlElement(eu.esdihumboldt.hale.io.xsd.model.XmlElement) DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent) Locatable(eu.esdihumboldt.hale.common.core.io.supplier.Locatable)

Example 4 with DefinitionPath

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath in project hale by halestudio.

the class XsltGenerator method writeContainerFragment.

/**
 * Write the container fragment.
 *
 * @param templateFile the file to write to
 * @param groupedResults the result variable names grouped by associated
 *            target type
 * @param targetElements an empty map that is populated with variable names
 *            mapped to target element names
 * @throws IOException if an error occurs writing the template
 * @throws XMLStreamException if an error occurs writing XML content to the
 *             template
 */
private void writeContainerFragment(File templateFile, Multimap<TypeDefinition, String> groupedResults, Map<String, QName> targetElements) throws XMLStreamException, IOException {
    XMLStreamWriter writer = XslTransformationUtil.setupXMLWriter(new BufferedOutputStream(new FileOutputStream(templateFile)), prefixes);
    try {
        // write container
        GmlWriterUtil.writeStartElement(writer, targetContainer.getName());
        // generate an eventual required identifier on the container
        GmlWriterUtil.writeRequiredID(writer, targetContainer.getType(), null, false);
        writeContainerIntro(writer, context);
        // cache definition paths
        Map<TypeDefinition, DefinitionPath> paths = new HashMap<TypeDefinition, DefinitionPath>();
        Descent lastDescent = null;
        for (Entry<TypeDefinition, String> entry : groupedResults.entries()) {
            TypeDefinition type = entry.getKey();
            // get stored definition path for the type
            DefinitionPath defPath;
            if (paths.containsKey(type)) {
                // get the stored path, may be null
                defPath = paths.get(type);
            } else {
                // determine a valid definition path in the container
                defPath = findMemberAttribute(targetContainer, type);
                // store path (may be null)
                paths.put(type, defPath);
            }
            if (defPath != null) {
                // insert xsl:for-each at the appropriate position in
                // the path
                defPath = pathInsertForEach(defPath, entry.getValue(), targetElements);
                lastDescent = Descent.descend(writer, defPath, lastDescent, false, true);
                // write single target instance from variable
                GmlWriterUtil.writeEmptyElement(writer, new QName(NS_URI_XSL, "copy-of"));
                writer.writeAttribute("select", ".");
            } else {
                reporter.warn(new IOMessageImpl(MessageFormat.format("No compatible member attribute for type {0} found in root element {1}, one instance was skipped", type.getDisplayName(), targetContainer.getName().getLocalPart()), null));
            }
        }
        if (lastDescent != null) {
            lastDescent.close();
        }
        // end container
        writer.writeEndElement();
    } finally {
        writer.close();
    }
}
Also used : HashMap(java.util.HashMap) XMLStreamWriter(javax.xml.stream.XMLStreamWriter) QName(javax.xml.namespace.QName) FileOutputStream(java.io.FileOutputStream) IOMessageImpl(eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl) DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath) BufferedOutputStream(java.io.BufferedOutputStream) Descent(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition)

Example 5 with DefinitionPath

use of eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath in project hale by halestudio.

the class PatternTest method testDirectFail.

/**
 * Test a direct match that should fails
 */
@Test
public void testDirectFail() {
    // $NON-NLS-1$
    Pattern pattern = Pattern.parse("CurveType");
    TypeDefinition start = createCurveType();
    DefinitionPath path = pattern.match(start, new DefinitionPath(start, CURVE_ELEMENT, false), GML_NS);
    // $NON-NLS-1$
    assertNull("A match should not have been found", path);
}
Also used : DefinitionPath(eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath) TypeDefinition(eu.esdihumboldt.hale.common.schema.model.TypeDefinition) DefaultTypeDefinition(eu.esdihumboldt.hale.common.schema.model.impl.DefaultTypeDefinition) Test(org.junit.Test)

Aggregations

DefinitionPath (eu.esdihumboldt.hale.io.gml.writer.internal.geometry.DefinitionPath)10 TypeDefinition (eu.esdihumboldt.hale.common.schema.model.TypeDefinition)8 DefaultTypeDefinition (eu.esdihumboldt.hale.common.schema.model.impl.DefaultTypeDefinition)3 PathElement (eu.esdihumboldt.hale.io.gml.writer.internal.geometry.PathElement)3 QName (javax.xml.namespace.QName)3 Test (org.junit.Test)3 IOMessageImpl (eu.esdihumboldt.hale.common.core.io.report.impl.IOMessageImpl)2 AbstractTypeMatcher (eu.esdihumboldt.hale.io.gml.writer.internal.geometry.AbstractTypeMatcher)2 Descent (eu.esdihumboldt.hale.io.gml.writer.internal.geometry.Descent)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Ignore (org.junit.Ignore)2 IOProviderConfigurationException (eu.esdihumboldt.hale.common.core.io.IOProviderConfigurationException)1 SubtaskProgressIndicator (eu.esdihumboldt.hale.common.core.io.impl.SubtaskProgressIndicator)1 Locatable (eu.esdihumboldt.hale.common.core.io.supplier.Locatable)1 Instance (eu.esdihumboldt.hale.common.instance.model.Instance)1 ChildDefinition (eu.esdihumboldt.hale.common.schema.model.ChildDefinition)1 XmlAttributeFlag (eu.esdihumboldt.hale.io.xsd.constraint.XmlAttributeFlag)1 XmlElements (eu.esdihumboldt.hale.io.xsd.constraint.XmlElements)1 XmlElement (eu.esdihumboldt.hale.io.xsd.model.XmlElement)1