use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.
the class AbstractTypeMatcher method findCandidates.
/**
* Find candidates for a possible path
*
* @param elementType the start element type
* @param elementName the start element name
* @param unique if the start element cannot be repeated
* @param matchParam the match parameter
* @param maxDepth the maximum depth that is allowed for paths
*
* @return the path candidates
*/
public List<DefinitionPath> findCandidates(TypeDefinition elementType, QName elementName, boolean unique, T matchParam, int maxDepth) {
Queue<PathCandidate> candidates = new LinkedList<PathCandidate>();
PathCandidate base = new PathCandidate(elementType, new DefinitionPath(elementType, elementName, unique), new HashSet<TypeDefinition>());
candidates.add(base);
List<DefinitionPath> results = new ArrayList<>();
while (!candidates.isEmpty()) {
PathCandidate candidate = candidates.poll();
TypeDefinition type = candidate.getType();
DefinitionPath basePath = candidate.getPath();
HashSet<TypeDefinition> checkedTypes = candidate.getCheckedTypes();
if (basePath.getSteps().size() >= maxDepth) {
// max depth already reached, only direct match allowed
// check if there is a direct match
DefinitionPath path = matchPath(type, matchParam, basePath);
if (path != null) {
if (results.isEmpty()) {
// first result -> adjust max depth
maxDepth = path.getSteps().size();
}
results.add(path);
}
// skip sub paths
continue;
}
if (checkedTypes.contains(type)) {
// prevent cycles
continue;
} else {
checkedTypes.add(type);
}
// check if there is a direct match
DefinitionPath path = matchPath(type, matchParam, basePath);
if (path != null) {
if (results.isEmpty()) {
// first result -> adjust max depth
maxDepth = path.getSteps().size();
}
results.add(path);
// skip sub paths
continue;
}
if (!type.getConstraint(AbstractFlag.class).isEnabled()) {
// only allow stepping down properties if the type is not
// abstract
// step down properties
// XXX why differentiate here?
@SuppressWarnings("unchecked") Iterable<ChildDefinition<?>> children = (Iterable<ChildDefinition<?>>) ((basePath.isEmpty() || basePath.getLastElement().isProperty()) ? (type.getChildren()) : (type.getDeclaredChildren()));
Iterable<DefinitionPath> childPaths = GmlWriterUtil.collectPropertyPaths(children, basePath, true);
for (DefinitionPath childPath : childPaths) {
// only descend into elements
candidates.add(new PathCandidate(childPath.getLastType(), childPath, new HashSet<TypeDefinition>(checkedTypes)));
}
}
// step down sub-types - elements may be downcast using xsi:type
if (!type.getConstraint(AbstractFlag.class).isEnabled()) {
for (@SuppressWarnings("unused") TypeDefinition subtype : type.getSubTypes()) {
// FIXME how to determine which types are ok for xsi:type?!
// if (!substitutionTypes.contains(subtype)) { // only types that are no valid substitutions
// // add candidate
// // Name element = basePath.getLastName(); // the element name that will be extended with xsi:type
// candidates.add(new PathCandidate(subtype,
// new DefinitionPath(basePath).addDowncast(subtype),
// new HashSet<TypeDefinition>(checkedTypes)));
// }
}
}
}
return results;
}
use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.
the class MergeUtil method resolvePropertyPath.
/**
* Get the property path for a value representing a property configured as
* Merge function parameter and resolve it to an entity definition.
*
* @param value the value representation of the parameter
* @param parentType the parent type of the property (the type that is
* merged)
* @return the entity definition resolved from the property path
* @throws IllegalStateException if the property path cannot be resolved
*/
public static EntityDefinition resolvePropertyPath(Value value, TypeDefinition parentType) {
List<QName> propertyPath = MergeUtil.getPropertyPath(value);
List<ChildDefinition<?>> path = new ArrayList<>();
Definition<?> parent = parentType;
for (QName element : propertyPath) {
ChildDefinition<?> child = DefinitionUtil.getChild(parent, element);
if (child != null) {
path.add(child);
parent = child;
} else {
throw new IllegalStateException("Could not resolve child " + element + " in parent " + parent);
}
}
if (path.isEmpty()) {
throw new IllegalStateException("No elements in property path");
}
List<ChildContext> contexts = path.stream().map(ChildContext::new).collect(Collectors.toList());
return AlignmentUtil.createEntity(parentType, contexts, SchemaSpaceID.SOURCE, null);
}
use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.
the class JaxbToEntityDefinition method convert.
/**
* Converts the given property to a property entity definition.
*
* @param property the property to convert
* @param types the type index to use
* @param schemaSpace the schema space to assign
* @return the property entity definition
*/
public static PropertyEntityDefinition convert(PropertyType property, TypeIndex types, SchemaSpaceID schemaSpace) {
TypeDefinition typeDef = types.getType(asName(property.getType()));
Filter filter = getTypeFilter(property);
List<ChildContext> path = new ArrayList<ChildContext>();
DefinitionGroup parent = typeDef;
for (ChildContextType childContext : property.getChild()) {
if (parent == null) {
throw new IllegalStateException("Could not resolve property entity definition: child not present");
}
Pair<ChildDefinition<?>, List<ChildDefinition<?>>> childs = PropertyBean.findChild(parent, asName(childContext));
// if the child is still null throw an exception
if (childs == null || childs.getFirst() == null) {
String childName = asName(childContext).getLocalPart();
String parentName;
if (parent instanceof Definition<?>) {
parentName = ((Definition<?>) parent).getName().getLocalPart();
} else {
parentName = parent.getIdentifier();
}
throw new IllegalStateException(MessageFormat.format("Could not resolve property entity definition: child {0} not found in parent {1}", childName, parentName));
}
ChildDefinition<?> child = childs.getFirst();
if (childs.getSecond() != null) {
for (ChildDefinition<?> pathElems : childs.getSecond()) {
path.add(new ChildContext(contextName(childContext.getContext()), contextIndex(childContext.getIndex()), createCondition(childContext.getCondition()), pathElems));
}
}
path.add(new ChildContext(contextName(childContext.getContext()), contextIndex(childContext.getIndex()), createCondition(childContext.getCondition()), child));
if (child instanceof DefinitionGroup) {
parent = (DefinitionGroup) child;
} else if (child.asProperty() != null) {
parent = child.asProperty().getPropertyType();
} else {
parent = null;
}
}
return new PropertyEntityDefinition(typeDef, path, schemaSpace, filter);
}
use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.
the class PropertyBean method findChild.
/**
* The function to look for a child as ChildDefinition or as Group
*
* @param parent the starting point to traverse from
* @param childName the name of the parent's child
* @return a pair of child and a list with the full path from parent to the
* child or <code>null</code> if no such child was found
*/
public static Pair<ChildDefinition<?>, List<ChildDefinition<?>>> findChild(DefinitionGroup parent, QName childName) {
ChildDefinition<?> child = parent.getChild(childName);
if (child == null) {
// if the namespace is not null
if (childName.getNamespaceURI().equals(XMLConstants.NULL_NS_URI)) {
// get all children and iterate over them
Collection<? extends ChildDefinition<?>> children = DefinitionUtil.getAllChildren(parent);
for (ChildDefinition<?> _child : children) {
// different namespace we overwrite child
if (_child.getName().getLocalPart().equals(childName.getLocalPart())) {
child = _child;
break;
}
}
}
}
if (child != null) {
return new Pair<ChildDefinition<?>, List<ChildDefinition<?>>>(child, null);
}
Collection<? extends ChildDefinition<?>> children = DefinitionUtil.getAllChildren(parent);
for (ChildDefinition<?> groupChild : children) {
if (groupChild.asGroup() != null) {
GroupPropertyDefinition temp = groupChild.asGroup();
if (findChild(temp, childName) != null) {
Pair<ChildDefinition<?>, List<ChildDefinition<?>>> recTemp = findChild(temp, childName);
if (recTemp.getSecond() == null) {
List<ChildDefinition<?>> second = new ArrayList<ChildDefinition<?>>();
second.add(temp);
ChildDefinition<?> first = recTemp.getFirst();
return new Pair<ChildDefinition<?>, List<ChildDefinition<?>>>(first, second);
} else {
recTemp.getSecond().add(0, temp);
}
}
}
}
return null;
}
use of eu.esdihumboldt.hale.common.schema.model.ChildDefinition in project hale by halestudio.
the class DefaultTypeDefinition method getInheritedChildren.
/**
* Get the unmodifiable map of inherited children.
*
* @return the inherited children, names mapped to definitions
*/
protected Map<QName, ChildDefinition<?>> getInheritedChildren() {
initInheritedChildren();
if (overriddenChildren == null || overriddenChildren.isEmpty()) {
return Collections.unmodifiableMap(inheritedChildren);
} else {
Map<QName, ChildDefinition<?>> result = new LinkedHashMap<>();
for (Entry<QName, ChildDefinition<?>> entry : inheritedChildren.entrySet()) {
QName name = entry.getKey();
ChildDefinition<?> child = overriddenChildren.get(name);
if (child == null) {
child = entry.getValue();
}
result.put(name, child);
}
return result;
}
}
Aggregations