Skip to content

Commit

Permalink
Merge pull request #1667 from lat-lon/fix/gmlToolReferenceDataXPath-9…
Browse files Browse the repository at this point in the history
…590-181

Fixed evaluation of reference data (3.5)
  • Loading branch information
copierrj authored Apr 10, 2024
2 parents 7d0b68e + 138437c commit 5455f8c
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -967,23 +967,23 @@ private List<Mapping> generateMapping(XSWildcard wildCard, int occurrence, Mappi
private boolean referenceDataHasProperty(CycleAnalyser cycleAnalyser) {
if (referenceData == null || !useRefDataProps)
return true;
List<QName> xpath = cycleAnalyser.getPath();
List<PathStep> xpath = cycleAnalyser.getPath();
QName featureTypeName = cycleAnalyser.getFeatureTypeName();
return referenceData.hasProperty(featureTypeName, xpath);
}

private boolean referenceDataPropertyIsNil(CycleAnalyser cycleAnalyser) {
if (referenceData == null || !useRefDataProps)
return false;
List<QName> xpath = cycleAnalyser.getPath();
List<PathStep> xpath = cycleAnalyser.getPath();
QName featureTypeName = cycleAnalyser.getFeatureTypeName();
return referenceData.isPropertyNilled(featureTypeName, xpath);
}

private boolean referenceDataHasOnlyOne(CycleAnalyser cycleAnalyser) {
if (referenceData == null)
return false;
List<QName> xpath = cycleAnalyser.getPath();
List<PathStep> xpath = cycleAnalyser.getPath();
QName featureTypeName = cycleAnalyser.getFeatureTypeName();
return referenceData.hasZeroOrOneProperty(featureTypeName, xpath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class CycleAnalyser {

private static final Logger LOG = LoggerFactory.getLogger(CycleAnalyser.class);

private final List<QName> path = new ArrayList<>();
private final List<PathStep> path = new ArrayList<>();

private final List<XSElementDeclaration> parentEls = new ArrayList<>();

Expand Down Expand Up @@ -67,7 +67,7 @@ public boolean checkStopAtCycle(XSComplexTypeDefinition typeDef) {
* @param pt never <code>null</code>
*/
public void start(PropertyType pt) {
path.add(pt.getName());
path.add(new PathStep(pt.getName()));
}

/**
Expand All @@ -87,7 +87,7 @@ public void add(XSComplexTypeDefinition typeDef) {
if (typeDef.getAnonymous())
return;
parentCTs.add(typeDef);
path.add(getQName(typeDef));
path.add(new PathStep(getQName(typeDef), true));
}

/**
Expand All @@ -96,7 +96,7 @@ public void add(XSComplexTypeDefinition typeDef) {
*/
public void add(XSElementDeclaration elDecl) {
parentEls.add(elDecl);
path.add(getQName(elDecl));
path.add(new PathStep(getQName(elDecl)));
}

/**
Expand Down Expand Up @@ -143,21 +143,22 @@ public QName getFeatureTypeName() {
/**
* @return the current path. May be empty but never <code>null</code>
*/
public List<QName> getPath() {
public List<PathStep> getPath() {
return path;
}

private void log() {
StringBuffer sb = new StringBuffer();
Map<QName, Integer> nameToCycleDepth = new HashMap<>();
for (QName step : path) {
for (PathStep pathStep : path) {
QName stepName = pathStep.getName();
sb.append("\n -> ");
if (nameToCycleDepth.containsKey(step))
nameToCycleDepth.put(step, (nameToCycleDepth.get(step) + 1));
if (nameToCycleDepth.containsKey(stepName))
nameToCycleDepth.put(stepName, (nameToCycleDepth.get(stepName) + 1));
else
nameToCycleDepth.put(step, 0);
sb.append(step);
sb.append(" (cycle depth: ").append(nameToCycleDepth.get(step)).append(")");
nameToCycleDepth.put(stepName, 0);
sb.append(stepName);
sb.append(" (cycle depth: ").append(nameToCycleDepth.get(stepName)).append(")");
}
LOG.info("Current path:" + sb.toString());
}
Expand Down Expand Up @@ -191,11 +192,16 @@ private boolean stop(QName qname) {
}

private long currentCycleDepth(QName qname) {
return this.path.stream().filter(e -> qname.equals(e)).count();
return this.path.stream().filter(e -> qname.equals(e.getName())).count();
}

private <T> boolean isLast(List<T> list, T entry) {
return list.lastIndexOf(entry) == list.size() - 1;
}

private boolean isLast(List<PathStep> list, QName entry) {
PathStep last = list.get(list.size() - 1);
return entry.equals(last.getName());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static org.deegree.commons.xml.CommonNamespaces.XSINS;
import static org.deegree.commons.xml.CommonNamespaces.XSI_PREFIX;
Expand Down Expand Up @@ -63,7 +65,7 @@ private void addFeature(Feature feature) {
}

@Override
public boolean hasProperty(QName featureTypeName, List<QName> xpath) {
public boolean hasProperty(QName featureTypeName, List<PathStep> xpath) {
List<Feature> featuresOfType = this.features.get(featureTypeName);
if (featuresOfType != null && !featuresOfType.isEmpty()) {
for (Feature feature : featuresOfType) {
Expand All @@ -75,7 +77,7 @@ public boolean hasProperty(QName featureTypeName, List<QName> xpath) {
}

@Override
public boolean isPropertyNilled(QName featureTypeName, List<QName> xpath) {
public boolean isPropertyNilled(QName featureTypeName, List<PathStep> xpath) {
List<Feature> featuresOfType = this.features.get(featureTypeName);
if (featuresOfType != null && !featuresOfType.isEmpty()) {
for (Feature feature : featuresOfType) {
Expand All @@ -87,7 +89,7 @@ public boolean isPropertyNilled(QName featureTypeName, List<QName> xpath) {
}

@Override
public boolean hasZeroOrOneProperty(QName featureTypeName, List<QName> xpath) {
public boolean hasZeroOrOneProperty(QName featureTypeName, List<PathStep> xpath) {
List<Feature> featuresOfType = this.features.get(featureTypeName);
if (featuresOfType != null && !featuresOfType.isEmpty()) {
for (Feature feature : featuresOfType) {
Expand All @@ -104,54 +106,55 @@ public boolean shouldFeatureTypeMapped(QName featureTypeName) {
return features.containsKey(featureTypeName);
}

private boolean hasProperty(Feature feature, List<QName> xpath) {
private boolean hasProperty(Feature feature, List<PathStep> xpath) {
if (xpath.isEmpty())
return true;
Iterator<QName> iterator = xpath.iterator();
QName firstProperty = iterator.next();
List<Property> properties = feature.getProperties(firstProperty);
Iterator<PathStep> iterator = xpath.iterator();
PathStep firstProperty = getNext(iterator);
List<Property> properties = feature.getProperties(firstProperty.getName());
return hasProperty(iterator, properties);
}

private <T extends ElementNode> boolean hasProperty(Iterator<QName> iterator, List<T> properties) {
if (!iterator.hasNext()) {
private <T extends TypedObjectNode> boolean hasProperty(Iterator<PathStep> iterator, List<T> properties) {
PathStep next = getNext(iterator);
if (next == null) {
if (properties.size() >= 1)
return true;
else
return false;
}
else {
QName next = iterator.next();
for (ElementNode property : properties) {
List<ElementNode> subProperties = getChildsByName(property, next);
for (TypedObjectNode property : properties) {
List<TypedObjectNode> subProperties = getChildsByName(property, next);
if (hasProperty(iterator, subProperties))
return true;
}
return false;
}
}

private boolean hasNilledPropertyOrIsMissing(Feature feature, List<QName> xpath) {
private boolean hasNilledPropertyOrIsMissing(Feature feature, List<PathStep> xpath) {
if (xpath.isEmpty()) {
return true;
}
Iterator<QName> iterator = xpath.iterator();
QName firstProperty = iterator.next();
List<Property> properties = feature.getProperties(firstProperty);
Iterator<PathStep> iterator = xpath.iterator();
PathStep firstProperty = getNext(iterator);
List<Property> properties = feature.getProperties(firstProperty.getName());
return hasNilledPropertyOrIsMissing(iterator, properties);
}

private <T extends ElementNode> boolean hasNilledPropertyOrIsMissing(Iterator<QName> iterator, List<T> properties) {
if (iterator.hasNext()) {
QName next = iterator.next();
for (ElementNode property : properties) {
List<ElementNode> subProperties = getChildsByName(property, next);
private <T extends TypedObjectNode> boolean hasNilledPropertyOrIsMissing(Iterator<PathStep> iterator,
List<T> properties) {
PathStep next = getNext(iterator);
if (next != null) {
for (TypedObjectNode property : properties) {
List<TypedObjectNode> subProperties = getChildsByName(property, next);
if (hasNilledPropertyOrIsMissing(iterator, subProperties))
return true;
}
}
else if (!properties.isEmpty()) {
for (ElementNode property : properties) {
for (TypedObjectNode property : properties) {
if (!isNilTrue(property))
return false;
}
Expand All @@ -160,52 +163,82 @@ else if (!properties.isEmpty()) {
return false;
}

private boolean isNilTrue(ElementNode property) {
Map<QName, PrimitiveValue> attributes = property.getAttributes();
private boolean isNilTrue(TypedObjectNode property) {
if (!(property instanceof ElementNode))
return false;
Map<QName, PrimitiveValue> attributes = ((ElementNode) property).getAttributes();
PrimitiveValue nil = attributes.get(new QName(XSINS, "nil", XSI_PREFIX));
if (nil == null)
return false;
return Boolean.parseBoolean(nil.getAsText());
}

private boolean hasMoreThanOne(Feature feature, List<QName> xpath) {
private boolean hasMoreThanOne(Feature feature, List<PathStep> xpath) {
if (xpath.isEmpty())
return true;
Iterator<QName> iterator = xpath.iterator();
QName firstProperty = iterator.next();
List<Property> properties = feature.getProperties(firstProperty);
Iterator<PathStep> iterator = xpath.iterator();
PathStep firstProperty = getNext(iterator);
List<Property> properties = feature.getProperties(firstProperty.getName());
return hasMoreThanOne(iterator, properties);
}

private <T extends ElementNode> boolean hasMoreThanOne(Iterator<QName> iterator, List<T> properties) {
if (!iterator.hasNext()) {
private <T extends TypedObjectNode> boolean hasMoreThanOne(Iterator<PathStep> iterator, List<T> properties) {
PathStep next = getNext(iterator);
if (next == null) {
if (properties.size() > 1)
return true;
else
return false;
}
else {
QName next = iterator.next();
for (ElementNode property : properties) {
List<ElementNode> subProperties = getChildsByName(property, next);
for (TypedObjectNode property : properties) {
List<TypedObjectNode> subProperties = getChildsByName(property, next);
if (hasMoreThanOne(iterator, subProperties))
return true;
}
return false;
}
}

private List<ElementNode> getChildsByName(ElementNode property, QName propertyName) {
List<ElementNode> properties = new ArrayList<>();
List<TypedObjectNode> children = property.getChildren();
for (TypedObjectNode child : children) {
private List<TypedObjectNode> getChildsByName(TypedObjectNode property, PathStep pathStep) {
if (property instanceof ElementNode)
return getChildsByName((ElementNode) property, pathStep);
if (property instanceof GenericFeature)
return getChildsByName((GenericFeature) property, pathStep);
return Collections.emptyList();
}

private List<TypedObjectNode> getChildsByName(ElementNode property, PathStep pathStep) {
List<TypedObjectNode> properties = new ArrayList<>();
for (TypedObjectNode child : property.getChildren()) {
if (child instanceof ElementNode) {
QName name = ((ElementNode) child).getName();
if (name.equals(propertyName))
properties.add((ElementNode) child);
if (name.equals(pathStep.getName()))
properties.add(child);
}
else if (child instanceof GenericFeature) {
QName name = ((GenericFeature) child).getName();
if (name.equals(pathStep.getName()))
properties.add(child);
}
}
return properties;
}

private List<TypedObjectNode> getChildsByName(GenericFeature property, PathStep pathStep) {
return property.getProperties(pathStep.getName())
.stream()
.map(prop -> (TypedObjectNode) prop)
.collect(Collectors.toList());
}

private PathStep getNext(Iterator<PathStep> iterator) {
while (iterator.hasNext()) {
PathStep next = iterator.next();
if (!next.isTypeDefinition())
return next;
}
return null;
}

}
Loading

0 comments on commit 5455f8c

Please sign in to comment.