use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.
the class SequentialIDParameterPage method validateValue.
/**
* Validates if the given value is valid for the target property.
*
* @param value the value to validate
* @return if the value is valid
*/
protected boolean validateValue(String value) {
Cell cell = getWizard().getUnfinishedCell();
List<? extends Entity> targets = cell.getTarget().get(null);
if (!targets.isEmpty()) {
Entity entity = targets.get(0);
Definition<?> def = entity.getDefinition().getDefinition();
if (def instanceof PropertyDefinition) {
TypeDefinition propertyType = ((PropertyDefinition) def).getPropertyType();
Validator validator = propertyType.getConstraint(ValidationConstraint.class).getValidator();
// TODO conversion to binding needed?
String error = validator.validate(value);
// update the example decoration
if (error == null) {
exampleDecoration.hide();
} else {
exampleDecoration.setDescriptionText(error);
exampleDecoration.show();
}
return error == null;
}
}
// no validation possible
return true;
}
use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.
the class AbstractGeometrySchemaService method determineDefaultGeometry.
/**
* Determine the path to a geometry property to be used as default geometry
* for the given type. By default the first geometry property found with a
* breadth first search is used.
*
* @param type the type definition
* @return the path to the default geometry property or <code>null</code> if
* unknown
*/
protected List<QName> determineDefaultGeometry(TypeDefinition type) {
// breadth first search for geometry properties
Queue<Pair<List<QName>, DefinitionGroup>> groups = new LinkedList<Pair<List<QName>, DefinitionGroup>>();
groups.add(new Pair<List<QName>, DefinitionGroup>(new ArrayList<QName>(), type));
List<QName> firstGeometryPath = null;
while (firstGeometryPath == null && !groups.isEmpty()) {
// for each parent group...
Pair<List<QName>, DefinitionGroup> group = groups.poll();
DefinitionGroup parent = group.getSecond();
List<QName> parentPath = group.getFirst();
// max depth for default geometries
if (parentPath.size() > 5)
continue;
// queue
for (ChildDefinition<?> child : DefinitionUtil.getAllChildren(parent)) {
// path for child
List<QName> path = new ArrayList<QName>(parentPath);
path.add(child.getName());
if (child.asProperty() != null) {
PropertyDefinition property = child.asProperty();
TypeDefinition propertyType = property.getPropertyType();
// check if we found a geometry property
if (propertyType.getConstraint(GeometryType.class).isGeometry()) {
// match
firstGeometryPath = path;
} else {
// test children later on
groups.add(new Pair<List<QName>, DefinitionGroup>(path, propertyType));
}
} else if (child.asGroup() != null) {
// test group later on
GroupPropertyDefinition childGroup = child.asGroup();
groups.add(new Pair<List<QName>, DefinitionGroup>(path, childGroup));
} else {
throw new IllegalStateException("Invalid child definition encountered");
}
}
}
if (firstGeometryPath != null) {
// a geometry property was found
return generalizeGeometryProperty(type, firstGeometryPath);
} else {
return null;
}
}
use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition 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.schema.model.PropertyDefinition in project hale by halestudio.
the class GmlWriterUtil method writeID.
/**
* Write any required ID attribute, generating a random ID if needed. If a
* desired ID is given, write it even if the attribute is not required.
*
* @param writer the XML stream writer
* @param type the type definition
* @param parent the parent object, may be <code>null</code>. If it is set
* the value for the ID will be tried to be retrieved from the
* parent object, otherwise a random ID will be generated
* @param onlyIfNotSet if the ID shall only be written if no value is set in
* the parent object
* @param desiredId a desired identifier or <code>null</code>
* @throws XMLStreamException if an error occurs writing the ID
*/
public static void writeID(XMLStreamWriter writer, DefinitionGroup type, Group parent, boolean onlyIfNotSet, @Nullable String desiredId) throws XMLStreamException {
// find ID attribute
PropertyDefinition idProp = null;
for (PropertyDefinition prop : collectProperties(DefinitionUtil.getAllChildren(type))) {
if (prop.getConstraint(XmlAttributeFlag.class).isEnabled() && (desiredId != null || prop.getConstraint(Cardinality.class).getMinOccurs() > 0) && isID(prop.getPropertyType())) {
idProp = prop;
// we assume there is only one ID attribute
break;
}
}
if (idProp == null) {
// no ID attribute found
return;
}
Object value = null;
if (parent != null) {
Object[] values = parent.getProperty(idProp.getName());
if (values != null && values.length > 0) {
value = values[0];
}
if (value != null && onlyIfNotSet) {
// don't write the ID
return;
}
}
if (value == null) {
value = desiredId;
}
if (value != null) {
writeAttribute(writer, value, idProp);
} else {
UUID genID = UUID.randomUUID();
// $NON-NLS-1$
writeAttribute(writer, "_" + genID.toString(), idProp);
}
}
use of eu.esdihumboldt.hale.common.schema.model.PropertyDefinition in project hale by halestudio.
the class AbstractGeometryWriter method writeList.
/**
* Write coordinates into a posList or coordinates 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 decimalFormatter a decimal formatter to format geometry
* coordinates
* @return if writing the coordinates was successful
* @throws XMLStreamException if an error occurs writing the coordinates
*/
private static boolean writeList(XMLStreamWriter writer, Coordinate[] coordinates, TypeDefinition elementType, String gmlNs, DecimalFormat decimalFormatter) throws XMLStreamException {
PropertyDefinition listAttribute = null;
// $NON-NLS-1$
String delimiter = " ";
// $NON-NLS-1$
String setDelimiter = " ";
// check for DirectPositionListType
for (PropertyDefinition att : DefinitionUtil.getAllProperties(elementType)) {
// XXX is this enough? or must groups be handled explicitly?
if (att.getPropertyType().getName().equals(new QName(gmlNs, "DirectPositionListType"))) {
// $NON-NLS-1$
listAttribute = att;
break;
}
}
if (listAttribute == null) {
// check for CoordinatesType
for (PropertyDefinition att : DefinitionUtil.getAllProperties(elementType)) {
if (att.getPropertyType().getName().equals(new QName(gmlNs, "CoordinatesType"))) {
// $NON-NLS-1$
listAttribute = att;
// $NON-NLS-1$
delimiter = ",";
break;
}
}
}
if (listAttribute != null) {
writer.writeStartElement(listAttribute.getName().getNamespaceURI(), listAttribute.getName().getLocalPart());
boolean first = true;
// write coordinates separated by spaces
for (Coordinate coordinate : coordinates) {
if (first) {
first = false;
} else {
writer.writeCharacters(setDelimiter);
}
writer.writeCharacters(DecimalFormatUtil.applyFormatter(coordinate.x, decimalFormatter));
writer.writeCharacters(delimiter);
writer.writeCharacters(DecimalFormatUtil.applyFormatter(coordinate.y, decimalFormatter));
if (!Double.isNaN(coordinate.z)) {
writer.writeCharacters(delimiter);
writer.writeCharacters(DecimalFormatUtil.applyFormatter(coordinate.z, decimalFormatter));
}
}
writer.writeEndElement();
return true;
} else {
return false;
}
}
Aggregations