use of eu.esdihumboldt.hale.io.xsd.model.XmlElement in project hale by halestudio.
the class XmlTypeDefinition method getDescription.
@Override
public String getDescription() {
String desc = super.getDescription();
if (desc != null && !desc.isEmpty()) {
return desc;
}
// if no description is present, try the description of the associated
// element
XmlElements elements = getConstraint(XmlElements.class);
if (elements.getElements().size() == 1) {
// only use element description if it's unique
XmlElement element = elements.getElements().iterator().next();
return element.getDescription();
}
return desc;
}
use of eu.esdihumboldt.hale.io.xsd.model.XmlElement in project hale by halestudio.
the class XsltGenerator method write.
/**
* Generate the XSLT transformation and write it to the given target.
*
* @param target the target output supplier
* @return the report
* @throws Exception if a unrecoverable error occurs during the process
*/
public IOReport write(LocatableOutputSupplier<? extends OutputStream> target) throws Exception {
Template root = ve.getTemplate(Templates.ROOT, "UTF-8");
VelocityContext context = XslTransformationUtil.createStrictVelocityContext();
// project info
context.put("info", ProjectXslInfo.getInfo(projectInfo));
// collects IDs of type cells
Set<String> typeIds = new HashSet<String>();
// type cells
for (Cell typeCell : alignment.getTypeCells()) {
if (typeCell.getTransformationMode() != TransformationMode.disabled) {
// ignore disabled cells
Entity targetEntity = CellUtil.getFirstEntity(typeCell.getTarget());
if (targetEntity != null) {
// assign identifiers for type transformations
String targetName = targetEntity.getDefinition().getDefinition().getName().getLocalPart();
String id = cellIdentifiers.getId(typeCell, targetName);
typeIds.add(id);
} else {
reporter.warn(new IOMessageImpl("Ignoring type relation without target type", null));
}
}
}
// collects IDs of type cells mapped to target element names
Map<String, QName> targetElements = new HashMap<String, QName>();
// container
File container = new File(workDir, "container.xsl");
progress.setCurrentTask("Generating container");
generateContainer(typeIds, container, targetElements);
Set<String> passiveCellIds = new HashSet<String>(typeIds);
progress.setCurrentTask("Generate type transformations");
// all active cells templates
for (Entry<String, QName> entry : targetElements.entrySet()) {
// generate XSL fragments for type transformations
String id = entry.getKey();
QName elementName = entry.getValue();
Cell typeCell = cellIdentifiers.getObject(id);
// this is not a passive cell
passiveCellIds.remove(id);
XmlElement targetElement = targetSchema.getElements().get(elementName);
String filename = "_" + id + ".xsl";
File file = new File(workDir, filename);
includes.add(filename);
generateTypeTransformation(id, targetElement, typeCell, file);
}
// all passive cell templates
for (String passiveId : passiveCellIds) {
Cell typeCell = cellIdentifiers.getObject(passiveId);
String filename = "_" + passiveId + ".xsl";
File file = new File(workDir, filename);
includes.add(filename);
// XXX dummy target element
XmlElement targetElement = new XmlElement(new QName(NS_XSL_DEFINITIONS, "dummy"), null, null);
generateTypeTransformation(passiveId, targetElement, typeCell, file);
// for passive cells no variables should be created
typeIds.remove(passiveId);
}
// namespaces that occur additionally to the fixed namespaces
Map<String, String> additionalNamespaces = new HashMap<String, String>(prefixes.asMap());
for (String fixedPrefix : FIXED_PREFIXES.keySet()) {
additionalNamespaces.remove(fixedPrefix);
}
context.put("additionalNamespaces", additionalNamespaces);
// types cells
/*
* The type identifiers are used as variable name to store the result of
* the equally named template.
*/
context.put("targets", typeIds);
// includes
// TODO check if files to include are actually there?
context.put("includes", includes);
OutputStream out = target.getOutput();
XMLPrettyPrinter printer = new XMLPrettyPrinter(out);
Future<?> ready = printer.start();
Writer writer = new OutputStreamWriter(printer, "UTF-8");
try {
root.merge(context, writer);
writer.flush();
} finally {
writer.close();
ready.get();
out.close();
}
reporter.setSuccess(reporter.getErrors().isEmpty());
return reporter;
}
use of eu.esdihumboldt.hale.io.xsd.model.XmlElement in project hale by halestudio.
the class XslTransformationUtil method selectInstances.
/**
* Create a XPath statement to select instances specified by the given type
* entity definition.
*
* @param ted the type entity definition
* @param context the context for the XPath expression, e.g. the empty
* string for the document root or <code>/</code> for anywhere in
* the document
* @param namespaces the namespace context
* @return the XPath expression or <code>null</code> if there are no
* elements that match the type
*/
public static String selectInstances(TypeEntityDefinition ted, String context, NamespaceContext namespaces) {
TypeDefinition type = ted.getDefinition();
// get the XML elements associated to the type
XmlElements elements = type.getConstraint(XmlElements.class);
if (elements.getElements().isEmpty()) {
/*
* XXX dirty hack
*
* In CityGML 1.0 no element for AppearanceType is defined, only a
* property that is not detected in this way. The source route
* element is not known here, so we also cannot do a search based on
* the type. Thus for now we handle it as a special case.
*/
QName typeName = ted.getDefinition().getName();
if ("http://www.opengis.net/citygml/appearance/1.0".equals(typeName.getNamespaceURI()) && "AppearanceType".equals(typeName.getLocalPart())) {
// create a dummy XML element
elements = new XmlElements();
elements.addElement(new XmlElement(new QName("http://www.opengis.net/citygml/appearance/1.0", "Appearance"), ted.getDefinition(), null));
} else
// XXX dirty hack end
return null;
}
// XXX which elements should be used?
// for now use all elements
StringBuilder select = new StringBuilder();
boolean first = true;
for (XmlElement element : elements.getElements()) {
if (first) {
first = false;
} else {
select.append(" | ");
}
select.append(context);
select.append('/');
String ns = element.getName().getNamespaceURI();
if (ns != null && !ns.isEmpty()) {
String prefix = namespaces.getPrefix(ns);
if (prefix != null && !prefix.isEmpty()) {
select.append(prefix);
select.append(':');
}
}
select.append(element.getName().getLocalPart());
}
// filter
if (ted.getFilter() != null) {
String filterxpath = FilterToXPath.toXPath(ted.getDefinition(), namespaces, ted.getFilter());
if (filterxpath != null && !filterxpath.isEmpty()) {
select.insert(0, '(');
select.append(")[");
select.append(StringEscapeUtils.escapeXml(filterxpath));
select.append(']');
}
}
return select.toString();
}
use of eu.esdihumboldt.hale.io.xsd.model.XmlElement in project hale by halestudio.
the class XsltExport method execute.
@Override
protected IOReport execute(ProgressIndicator progress, IOReporter reporter) throws IOProviderConfigurationException, IOException {
File templateDir = Files.createTempDir();
progress.begin("Generate XSLT", ProgressIndicator.UNKNOWN);
try {
log.info("Template directory: " + templateDir.getAbsolutePath());
XmlIndex targetIndex = StreamGmlWriter.getXMLIndex(getTargetSchema());
if (targetIndex == null) {
throw new IllegalStateException("Target schema contains no XML schema");
}
XmlIndex sourceIndex = StreamGmlWriter.getXMLIndex(getSourceSchema());
if (sourceIndex == null) {
throw new IllegalStateException("Source schema contains no XML schema");
}
init(sourceIndex, targetIndex);
XmlElement containerElement = StreamGmlWriter.getConfiguredContainerElement(this, targetIndex);
if (containerElement == null) {
throw new IllegalStateException("No target container element specified");
}
XsltGenerator generator = new XsltGenerator(templateDir, getAlignment(), sourceIndex, targetIndex, reporter, progress, containerElement, getSourceContext(), projectInfo) {
@Override
protected void writeContainerIntro(XMLStreamWriter writer, XsltGenerationContext context) throws XMLStreamException, IOException {
XsltExport.this.writeContainerIntro(writer, context);
}
};
return generator.write(getTarget());
} catch (Exception e) {
reporter.error(new IOMessageImpl("XSLT generation failed", e));
reporter.setSuccess(false);
return reporter;
} finally {
progress.end();
try {
FileUtils.deleteDirectory(templateDir);
} catch (Exception e) {
// failure to delete the directory is not fatal
log.warn("Failed to delete temporary directory", e);
}
}
}
use of eu.esdihumboldt.hale.io.xsd.model.XmlElement 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;
}
Aggregations