From 961d20e7b4a9b95e7acb973e1dc28bd9351993e1 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 22 May 2026 11:53:13 +0200 Subject: [PATCH 1/4] pmd warnings --- .../features/gml/app/FeatureProviderWfs.java | 11 - .../gml/app/FeatureProviderWfsAuto.java | 2 +- .../gml/app/FeatureProviderWfsFactory.java | 8 +- .../gml/app/FeatureQueryEncoderWfs.java | 12 +- .../gml/app/FeatureStorePathParserWfs.java | 5 +- .../gml/app/FeatureTokenDecoderGml.java | 479 ++++++++++-------- .../features/gml/app/FilterEncoderWfs.java | 50 +- .../gml/app/GmlMultiplicityTracker.java | 3 - .../features/gml/app/WfsRequestEncoder.java | 10 +- .../gml/domain/GeometryDecoderGml.java | 1 + 10 files changed, 294 insertions(+), 287 deletions(-) diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfs.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfs.java index 0d03fdb91..7bfe77128 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfs.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfs.java @@ -42,7 +42,6 @@ import de.ii.xtraplatform.features.domain.FeatureQuery; import de.ii.xtraplatform.features.domain.FeatureQueryEncoder; import de.ii.xtraplatform.features.domain.FeatureSchema; -import de.ii.xtraplatform.features.domain.FeatureStorePathParser; import de.ii.xtraplatform.features.domain.FeatureStream; import de.ii.xtraplatform.features.domain.FeatureStreamImpl; import de.ii.xtraplatform.features.domain.FeatureTokenDecoder; @@ -53,7 +52,6 @@ import de.ii.xtraplatform.features.domain.SchemaMapping; import de.ii.xtraplatform.features.domain.transform.OnlyQueryables; import de.ii.xtraplatform.features.domain.transform.OnlySortables; -import de.ii.xtraplatform.features.gml.domain.ConnectionInfoWfsHttp; import de.ii.xtraplatform.features.gml.domain.FeatureProviderWfsData; import de.ii.xtraplatform.features.gml.domain.WfsConnector; import de.ii.xtraplatform.features.gml.domain.XMLNamespaceNormalizer; @@ -131,7 +129,6 @@ public class FeatureProviderWfs private FeatureQueryEncoderWfs queryTransformer; private AggregateStatsReader aggregateStatsReader; - private FeatureStorePathParser pathParser; @AssistedInject public FeatureProviderWfs( @@ -159,8 +156,6 @@ public FeatureProviderWfs( @Override protected boolean onStartup() throws InterruptedException { - this.pathParser = createPathParser(getData().getConnectionInfo()); - boolean success = super.onStartup(); if (!success) { @@ -190,11 +185,6 @@ protected Map> getSourceSchemas() { return types; } - private static FeatureStorePathParser createPathParser( - ConnectionInfoWfsHttp connectionInfoWfsHttp) { - return new FeatureStorePathParserWfs(connectionInfoWfsHttp.getNamespaces()); - } - @Override public FeatureProviderWfsData getData() { return (FeatureProviderWfsData) super.getData(); @@ -328,7 +318,6 @@ public Optional getSpatialExtent(String typeName) { .join(); } catch (Throwable e) { // continue - boolean br = true; } return Optional.empty(); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsAuto.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsAuto.java index ecfa97c2f..ec7466b75 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsAuto.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsAuto.java @@ -42,7 +42,7 @@ public FeatureProviderWfsAuto(WfsClientBasicFactory clientFactory) { @Override public Map check(T entityData) { - return null; + return Map.of(); } @Override diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsFactory.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsFactory.java index 306216c4d..28f88921c 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsFactory.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureProviderWfsFactory.java @@ -114,9 +114,11 @@ public EntityData hydrateData(EntityData entityData) { try { if (data.isAuto()) { - LOGGER.info( - "Feature provider with id '{}' is in auto mode, generating configuration ...", - data.getId()); + if (LOGGER.isInfoEnabled()) { + LOGGER.info( + "Feature provider with id '{}' is in auto mode, generating configuration ...", + data.getId()); + } Map> types = featureProviderWfsAuto.analyze(data); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureQueryEncoderWfs.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureQueryEncoderWfs.java index 8ec8d33a8..a33ebeb95 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureQueryEncoderWfs.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureQueryEncoderWfs.java @@ -33,13 +33,9 @@ import java.net.URI; import java.util.Map; import javax.xml.namespace.QName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class FeatureQueryEncoderWfs implements FeatureQueryEncoder { - private static final Logger LOGGER = LoggerFactory.getLogger(FeatureQueryEncoderWfs.class); - private final Map featureSchemas; private final XMLNamespaceNormalizer namespaceNormalizer; private final WfsRequestEncoder wfsRequestEncoder; @@ -71,8 +67,7 @@ public FeatureQueryEncoderWfs( connectionInfo.getNamespaces(), urls); this.nativeCrs = nativeCrs; - this.filterEncoder = - new FilterEncoderWfs(nativeCrs, crsTransformerFactory, cql, namespaceNormalizer); + this.filterEncoder = new FilterEncoderWfs(nativeCrs, crsTransformerFactory, cql); } // TODO: add cql2 classes @@ -127,7 +122,7 @@ GetFeature encodeGetFeature( return encodeGetFeature( query, featureTypeName, featureSchemas.get(query.getType()), additionalQueryParameters); } catch (CqlParseException e) { - throw new IllegalArgumentException("Filter is invalid", e.getCause()); + throw new IllegalArgumentException("Filter is invalid", e); } } @@ -139,8 +134,7 @@ private GetFeature encodeGetFeature( FeatureQuery query, QName featureTypeName, FeatureSchema featureSchema, - Map additionalQueryParameters) - throws CqlParseException { + Map additionalQueryParameters) { final String featureTypeNameFull = namespaceNormalizer.getQualifiedName( featureTypeName.getNamespaceURI(), featureTypeName.getLocalPart()); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureStorePathParserWfs.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureStorePathParserWfs.java index dc157402a..30cf44066 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureStorePathParserWfs.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureStorePathParserWfs.java @@ -14,11 +14,14 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; public class FeatureStorePathParserWfs implements FeatureStorePathParser { - public FeatureStorePathParserWfs(Map namespaces) {} + public FeatureStorePathParserWfs(Map namespaces) { + Objects.requireNonNull(namespaces); + } @Override public List parse(FeatureSchema schema) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureTokenDecoderGml.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureTokenDecoderGml.java index 8ecd5e0e6..c3c5d5f3e 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureTokenDecoderGml.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FeatureTokenDecoderGml.java @@ -20,7 +20,9 @@ import de.ii.xtraplatform.features.gml.domain.GeometryDecoderGml; import de.ii.xtraplatform.features.gml.domain.XMLNamespaceNormalizer; import de.ii.xtraplatform.geometries.domain.Geometry; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -34,6 +36,7 @@ /** * @author zahnen */ +@SuppressWarnings("PMD.TooManyMethods") public class FeatureTokenDecoderGml extends FeatureTokenDecoder< byte[], FeatureSchema, SchemaMapping, ModifiableContext> { @@ -45,19 +48,26 @@ public class FeatureTokenDecoderGml private final FeatureQuery featureQuery; private final Map mappings; private final List featureTypes; - private final StringBuilder buffer; private final GmlMultiplicityTracker multiplicityTracker; private final boolean passThrough; private final GeometryDecoderGml geometryDecoder; - - private boolean isBuffering; - private int depth = 0; - private int featureDepth = 0; - private boolean inFeature = false; - private boolean inGeometry = false; - private Optional crs = Optional.empty(); - private OptionalInt srsDimension = OptionalInt.empty(); - private ModifiableContext context; + private final ParsingState state; + + private final class ParsingState { + private boolean buffering; + private int depth; + private int featureDepth; + private boolean inFeature; + private boolean inGeometry; + private Optional crs = Optional.empty(); + private OptionalInt srsDimension = OptionalInt.empty(); + private ModifiableContext context; + private final List bufferParts = new ArrayList<>(); + + private void resetBuffer() { + this.bufferParts.clear(); + } + } public FeatureTokenDecoderGml( Map namespaces, @@ -66,26 +76,27 @@ public FeatureTokenDecoderGml( FeatureQuery query, Map mappings, boolean passThrough) { + super(); this.namespaceNormalizer = new XMLNamespaceNormalizer(namespaces); this.featureSchema = featureSchema; this.featureQuery = query; this.mappings = mappings; this.featureTypes = featureTypes; - this.buffer = new StringBuilder(); this.multiplicityTracker = new GmlMultiplicityTracker(); this.passThrough = passThrough; this.geometryDecoder = new GeometryDecoderGml(); + this.state = new ParsingState(); try { this.parser = new InputFactoryImpl().createAsyncFor(new byte[0]); } catch (XMLStreamException e) { - throw new IllegalStateException("Could not create GML decoder: " + e.getMessage()); + throw new IllegalStateException("Could not create GML decoder: " + e.getMessage(), e); } } @Override protected void init() { - this.context = + this.state.context = createContext() .setType(featureSchema.getName()) .setMappings(mappings) @@ -103,7 +114,7 @@ public void onPush(byte[] bytes) { } // for unit tests - void parse(String data) throws Exception { + void parse(String data) { byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8); feedInput(dataBytes); cleanup(); @@ -123,9 +134,11 @@ private void feedInput(byte[] data) { } // TODO: single feature or collection + @SuppressWarnings("PMD.CyclomaticComplexity") protected boolean advanceParser() { boolean feedMeMore = false; + ModifiableContext context = state.context; try { if (!parser.hasNext()) { @@ -141,223 +154,19 @@ protected boolean advanceParser() { break; case XMLStreamConstants.END_DOCUMENT: - // completeStage(); break; case XMLStreamConstants.START_ELEMENT: - if (geometryDecoder.isWaitingForInput()) { - // continue decoding the geometry - Optional> optGeometry = - geometryDecoder.continueDecoding( - parser, crs, srsDimension, parser.getLocalName(), null); - if (optGeometry.isPresent()) { - context.setGeometry(optGeometry.get()); - getDownstream().onGeometry(context); - } else { - // Still waiting for more input to decode the geometry - break; - } - break; - } - if (depth == 0) { - OptionalLong numberMatched; - OptionalLong numberReturned; - try { - numberReturned = - OptionalLong.of(Long.parseLong(parser.getAttributeValue(null, "numberReturned"))); - } catch (NumberFormatException e) { - numberReturned = OptionalLong.empty(); - } - try { - numberMatched = - OptionalLong.of(Long.parseLong(parser.getAttributeValue(null, "numberMatched"))); - } catch (NumberFormatException e) { - numberMatched = OptionalLong.empty(); - } - - context.metadata().numberReturned(numberReturned); - context.metadata().numberMatched(numberMatched); - - if (numberReturned.orElse(0) == 1 && numberMatched.orElse(1) == 1) { - context.metadata().isSingleFeature(true); - } - - context.additionalInfo().clear(); - for (int i = 0; i < parser.getAttributeCount(); i++) { - context.putAdditionalInfo( - namespaceNormalizer.getQualifiedName( - parser.getAttributeNamespace(i), parser.getAttributeLocalName(i)), - parser.getAttributeValue(i)); - } - - getDownstream().onStart(context); - } else if ("Envelope".equals(parser.getLocalName()) && depth == 2) { - String srsName = parser.getAttributeValue(null, "srsName"); - if (srsName != null && !srsName.isEmpty()) { - try { - crs = Optional.of(EpsgCrs.fromString(srsName)); - } catch (IllegalArgumentException e) { - crs = Optional.empty(); - } - } else { - crs = Optional.empty(); - } - try { - srsDimension = - OptionalInt.of(Integer.parseInt(parser.getAttributeValue(null, "srsDimension"))); - } catch (NumberFormatException e) { - srsDimension = OptionalInt.empty(); - } - } else if (matchesFeatureType(parser.getNamespaceURI(), parser.getLocalName()) - || matchesFeatureType(parser.getLocalName())) { - inFeature = true; - featureDepth = depth; - - context.additionalInfo().clear(); - for (int i = 0; i < parser.getAttributeCount(); i++) { - context.putAdditionalInfo( - namespaceNormalizer.getQualifiedName( - parser.getAttributeNamespace(i), parser.getAttributeLocalName(i)), - parser.getAttributeValue(i)); - } - - context - .pathTracker() - .track( - namespaceNormalizer.getQualifiedName( - parser.getNamespaceURI(), parser.getLocalName())); - - getDownstream().onFeatureStart(context); - - if (context.additionalInfo().containsKey("gml:id") && !passThrough) { - context.pathTracker().track("gml:@id"); - context.setValue(context.additionalInfo().get("gml:id")); - context.setValueType(Type.STRING); - getDownstream().onValue(context); - } - } else if (inFeature) { - context - .pathTracker() - .track( - namespaceNormalizer.getQualifiedName( - parser.getNamespaceURI(), parser.getLocalName()), - depth - featureDepth); - multiplicityTracker.track(context.pathTracker().asList()); - - context.additionalInfo().clear(); - for (int i = 0; i < parser.getAttributeCount(); i++) { - context.putAdditionalInfo( - namespaceNormalizer.getQualifiedName( - parser.getAttributeNamespace(i), parser.getAttributeLocalName(i)), - parser.getAttributeValue(i)); - } - - context.setIndexes( - multiplicityTracker.getMultiplicitiesForPath(context.pathTracker().asList())); - - if (context.schema().filter(FeatureSchema::isSpatial).isPresent()) { - this.inGeometry = true; - Optional> optGeometry = geometryDecoder.decode(parser, crs, srsDimension); - // Was the geometry decoded completely? If not, the rest will be buffered before - // decoding is continued... - if (optGeometry.isPresent()) { - context.setGeometry(optGeometry.get()); - getDownstream().onGeometry(context); - } else { - feedMeMore = true; - } - } else if (context.schema().filter(FeatureSchema::isObject).isPresent()) { - if (context.schema().filter(FeatureSchema::isArray).isPresent() - && context.index() == 1) { - getDownstream().onArrayStart(context); - } - getDownstream().onObjectStart(context); - } else if (passThrough) { - getDownstream().onObjectStart(context); - } - } - depth += 1; - - if (inFeature - && depth > featureDepth + 1 - && !inGeometry - && context.schema().filter(FeatureSchema::isObject).isPresent()) { - context - .additionalInfo() - .forEach( - (prop, value) -> { - context.pathTracker().track(prop.replace(":", ":@"), depth - featureDepth); - multiplicityTracker.track(context.pathTracker().asList()); - context.setIndexes( - multiplicityTracker.getMultiplicitiesForPath( - context.pathTracker().asList())); - context.setValue(value); - context.setValueType(Type.STRING); - getDownstream().onValue(context); - }); - } + feedMeMore = handleStartElement(context); break; case XMLStreamConstants.END_ELEMENT: - if (isBuffering) { - this.isBuffering = false; - if (geometryDecoder.isWaitingForInput()) { - // continue decoding the geometry with the new buffered input - Optional> optGeometry = - geometryDecoder.continueDecoding( - parser, crs, srsDimension, parser.getLocalName(), buffer.toString()); - buffer.setLength(0); - if (optGeometry.isPresent()) { - context.setGeometry(optGeometry.get()); - getDownstream().onGeometry(context); - } - break; - } else if (!buffer.isEmpty()) { - context.setValue(buffer.toString()); - getDownstream().onValue(context); - buffer.setLength(0); - } - } else if (geometryDecoder.isWaitingForInput()) { - // continue decoding the geometry - Optional> optGeometry = - geometryDecoder.continueDecoding( - parser, crs, srsDimension, parser.getLocalName(), ""); - if (optGeometry.isPresent()) { - context.setGeometry(optGeometry.get()); - getDownstream().onGeometry(context); - } - break; - } - - depth -= 1; - if (depth == 0) { - getDownstream().onEnd(context); - } else if (matchesFeatureType(parser.getLocalName())) { - inFeature = false; - getDownstream().onFeatureEnd(context); - multiplicityTracker.reset(); - } else if (inFeature) { - if (context.schema().filter(FeatureSchema::isSpatial).isPresent()) { - this.inGeometry = false; - } else if (context.schema().filter(FeatureSchema::isObject).isPresent()) { - getDownstream().onObjectEnd(context); - } else if (passThrough) { - getDownstream().onObjectEnd(context); - } - } - - context.pathTracker().track(depth - featureDepth); - + handleEndElement(context); break; case XMLStreamConstants.CHARACTERS: - if (inFeature) { - if (!parser.isWhiteSpace()) { - this.isBuffering = true; - buffer.append(parser.getText()); - } - } + handleCharacters(); break; // Do not support DTD, SPACE, NAMESPACE, NOTATION_DECLARATION, ENTITY_DECLARATION, @@ -373,6 +182,234 @@ protected boolean advanceParser() { return feedMeMore; } + @SuppressWarnings({ + "PMD.NcssCount", + "PMD.CognitiveComplexity", + "PMD.CyclomaticComplexity", + "PMD.NPathComplexity" + }) + private boolean handleStartElement(ModifiableContext context) + throws XMLStreamException, IOException { + if (geometryDecoder.isWaitingForInput()) { + // continue decoding the geometry + Optional> optGeometry = + geometryDecoder.continueDecoding( + parser, state.crs, state.srsDimension, parser.getLocalName(), null); + if (optGeometry.isPresent()) { + context.setGeometry(optGeometry.get()); + getDownstream().onGeometry(context); + } + // Still waiting for more input or just decoded - either way, done with this element + return false; + } + + boolean feedMeMore = false; + if (state.depth == 0) { + OptionalLong numberMatched; + OptionalLong numberReturned; + try { + numberReturned = + OptionalLong.of(Long.parseLong(parser.getAttributeValue(null, "numberReturned"))); + } catch (NumberFormatException e) { + numberReturned = OptionalLong.empty(); + } + try { + numberMatched = + OptionalLong.of(Long.parseLong(parser.getAttributeValue(null, "numberMatched"))); + } catch (NumberFormatException e) { + numberMatched = OptionalLong.empty(); + } + + context.metadata().numberReturned(numberReturned); + context.metadata().numberMatched(numberMatched); + + if (numberReturned.orElse(0) == 1 && numberMatched.orElse(1) == 1) { + context.metadata().isSingleFeature(true); + } + + context.additionalInfo().clear(); + for (int i = 0; i < parser.getAttributeCount(); i++) { + context.putAdditionalInfo( + namespaceNormalizer.getQualifiedName( + parser.getAttributeNamespace(i), parser.getAttributeLocalName(i)), + parser.getAttributeValue(i)); + } + + getDownstream().onStart(context); + } else if ("Envelope".equals(parser.getLocalName()) && state.depth == 2) { + String srsName = parser.getAttributeValue(null, "srsName"); + if (srsName != null && !srsName.isEmpty()) { + try { + state.crs = Optional.of(EpsgCrs.fromString(srsName)); + } catch (IllegalArgumentException e) { + state.crs = Optional.empty(); + } + } else { + state.crs = Optional.empty(); + } + try { + state.srsDimension = + OptionalInt.of(Integer.parseInt(parser.getAttributeValue(null, "srsDimension"))); + } catch (NumberFormatException e) { + state.srsDimension = OptionalInt.empty(); + } + } else if (matchesFeatureType(parser.getNamespaceURI(), parser.getLocalName()) + || matchesFeatureType(parser.getLocalName())) { + state.inFeature = true; + state.featureDepth = state.depth; + + context.additionalInfo().clear(); + for (int i = 0; i < parser.getAttributeCount(); i++) { + context.putAdditionalInfo( + namespaceNormalizer.getQualifiedName( + parser.getAttributeNamespace(i), parser.getAttributeLocalName(i)), + parser.getAttributeValue(i)); + } + + context + .pathTracker() + .track( + namespaceNormalizer.getQualifiedName( + parser.getNamespaceURI(), parser.getLocalName())); + + getDownstream().onFeatureStart(context); + + if (context.additionalInfo().containsKey("gml:id") && !passThrough) { + context.pathTracker().track("gml:@id"); + context.setValue(context.additionalInfo().get("gml:id")); + context.setValueType(Type.STRING); + getDownstream().onValue(context); + } + } else if (state.inFeature) { + context + .pathTracker() + .track( + namespaceNormalizer.getQualifiedName(parser.getNamespaceURI(), parser.getLocalName()), + state.depth - state.featureDepth); + multiplicityTracker.track(context.pathTracker().asList()); + + context.additionalInfo().clear(); + for (int i = 0; i < parser.getAttributeCount(); i++) { + context.putAdditionalInfo( + namespaceNormalizer.getQualifiedName( + parser.getAttributeNamespace(i), parser.getAttributeLocalName(i)), + parser.getAttributeValue(i)); + } + + context.setIndexes( + multiplicityTracker.getMultiplicitiesForPath(context.pathTracker().asList())); + + if (context.schema().filter(FeatureSchema::isSpatial).isPresent()) { + state.inGeometry = true; + Optional> optGeometry = + geometryDecoder.decode(parser, state.crs, state.srsDimension); + // Was the geometry decoded completely? If not, the rest will be buffered before + // decoding is continued... + if (optGeometry.isPresent()) { + context.setGeometry(optGeometry.get()); + getDownstream().onGeometry(context); + } else { + feedMeMore = true; + } + } else if (context.schema().filter(FeatureSchema::isObject).isPresent()) { + if (context.schema().filter(FeatureSchema::isArray).isPresent() && context.index() == 1) { + getDownstream().onArrayStart(context); + } + getDownstream().onObjectStart(context); + } else if (passThrough) { + getDownstream().onObjectStart(context); + } + } + + state.depth += 1; + + if (state.inFeature + && state.depth > state.featureDepth + 1 + && !state.inGeometry + && context.schema().filter(FeatureSchema::isObject).isPresent()) { + context + .additionalInfo() + .forEach( + (prop, value) -> { + context + .pathTracker() + .track(prop.replace(":", ":@"), state.depth - state.featureDepth); + multiplicityTracker.track(context.pathTracker().asList()); + context.setIndexes( + multiplicityTracker.getMultiplicitiesForPath(context.pathTracker().asList())); + context.setValue(value); + context.setValueType(Type.STRING); + getDownstream().onValue(context); + }); + } + + return feedMeMore; + } + + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CyclomaticComplexity"}) + private void handleEndElement(ModifiableContext context) + throws XMLStreamException, IOException { + if (state.buffering) { + state.buffering = false; + if (geometryDecoder.isWaitingForInput()) { + // continue decoding the geometry with the new buffered input + Optional> optGeometry = + geometryDecoder.continueDecoding( + parser, + state.crs, + state.srsDimension, + parser.getLocalName(), + String.join("", state.bufferParts)); + state.resetBuffer(); + if (optGeometry.isPresent()) { + context.setGeometry(optGeometry.get()); + getDownstream().onGeometry(context); + } + return; + } else if (!state.bufferParts.isEmpty()) { + context.setValue(String.join("", state.bufferParts)); + getDownstream().onValue(context); + state.resetBuffer(); + } + } else if (geometryDecoder.isWaitingForInput()) { + // continue decoding the geometry + Optional> optGeometry = + geometryDecoder.continueDecoding( + parser, state.crs, state.srsDimension, parser.getLocalName(), ""); + if (optGeometry.isPresent()) { + context.setGeometry(optGeometry.get()); + getDownstream().onGeometry(context); + } + return; + } + + state.depth -= 1; + if (state.depth == 0) { + getDownstream().onEnd(context); + } else if (matchesFeatureType(parser.getLocalName())) { + state.inFeature = false; + getDownstream().onFeatureEnd(context); + multiplicityTracker.reset(); + } else if (state.inFeature) { + if (context.schema().filter(FeatureSchema::isSpatial).isPresent()) { + state.inGeometry = false; + } else if (context.schema().filter(FeatureSchema::isObject).isPresent()) { + getDownstream().onObjectEnd(context); + } else if (passThrough) { + getDownstream().onObjectEnd(context); + } + } + + context.pathTracker().track(state.depth - state.featureDepth); + } + + private void handleCharacters() { + if (state.inFeature && !parser.isWhiteSpace()) { + state.buffering = true; + state.bufferParts.add(parser.getText()); + } + } + boolean matchesFeatureType(final String namespace, final String localName) { return featureTypes.stream() .anyMatch( diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FilterEncoderWfs.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FilterEncoderWfs.java index 3e433cb36..4e62a162a 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FilterEncoderWfs.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/FilterEncoderWfs.java @@ -51,7 +51,6 @@ import de.ii.xtraplatform.crs.domain.CrsTransformerFactory; import de.ii.xtraplatform.crs.domain.EpsgCrs; import de.ii.xtraplatform.features.domain.FeatureSchema; -import de.ii.xtraplatform.features.gml.domain.XMLNamespaceNormalizer; import de.ii.xtraplatform.features.gml.infra.fes.FesAnd; import de.ii.xtraplatform.features.gml.infra.fes.FesBBox; import de.ii.xtraplatform.features.gml.infra.fes.FesDuring; @@ -76,29 +75,19 @@ import java.util.Objects; import java.util.Optional; import java.util.function.BiFunction; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.threeten.extra.Interval; public class FilterEncoderWfs { - private static final Logger LOGGER = LoggerFactory.getLogger(FilterEncoderWfs.class); - private final Cql cql; private final EpsgCrs nativeCrs; private final CrsTransformerFactory crsTransformerFactory; - private final XMLNamespaceNormalizer namespaceNormalizer; BiFunction, Optional, List> coordinatesTransformer; - public FilterEncoderWfs( - EpsgCrs nativeCrs, - CrsTransformerFactory crsTransformerFactory, - Cql cql, - XMLNamespaceNormalizer namespaceNormalizer) { + public FilterEncoderWfs(EpsgCrs nativeCrs, CrsTransformerFactory crsTransformerFactory, Cql cql) { this.nativeCrs = nativeCrs; this.crsTransformerFactory = crsTransformerFactory; this.cql = cql; - this.namespaceNormalizer = namespaceNormalizer; this.coordinatesTransformer = this::transformCoordinatesIfNecessary; } @@ -110,34 +99,31 @@ public FesFilter encode(Cql2Expression filter, FeatureSchema schema) { private List transformCoordinatesIfNecessary( List coordinates, Optional sourceCrs) { - - if (sourceCrs.isPresent() && !Objects.equals(sourceCrs.get(), nativeCrs)) { - Optional transformer = - crsTransformerFactory.getTransformer(sourceCrs.get(), nativeCrs, true); - if (transformer.isPresent()) { - double[] transformed = - transformer.get().transform(Doubles.toArray(coordinates), coordinates.size() / 2, 2); - if (Objects.isNull(transformed)) { - throw new IllegalArgumentException( - String.format( - "Filter is invalid. Coordinates cannot be transformed: %s", coordinates)); - } - - return Doubles.asList(transformed); - } + if (sourceCrs.isEmpty() || Objects.equals(sourceCrs.get(), nativeCrs)) { + return coordinates; + } + Optional transformer = + crsTransformerFactory.getTransformer(sourceCrs.get(), nativeCrs, true); + if (transformer.isEmpty()) { + return coordinates; + } + double[] transformed = + transformer.get().transform(Doubles.toArray(coordinates), coordinates.size() / 2, 2); + if (Objects.isNull(transformed)) { + throw new IllegalArgumentException( + String.format("Filter is invalid. Coordinates cannot be transformed: %s", coordinates)); } - return coordinates; + return Doubles.asList(transformed); } // TODO: reverse FeatureSchema for nested mappings? private Optional getPrefixedPropertyName(FeatureSchema schema, String property) { + String normalizedProperty = property.replace(ID_PLACEHOLDER, "id"); return schema.getProperties().stream() .filter( featureProperty -> Objects.nonNull(featureProperty.getName()) - && Objects.equals( - featureProperty.getName().toLowerCase(), - property.replaceAll(ID_PLACEHOLDER, "id").toLowerCase())) + && featureProperty.getName().equalsIgnoreCase(normalizedProperty)) .map(FeatureSchema::getSourcePath) .filter(Optional::isPresent) .map(Optional::get) @@ -151,6 +137,7 @@ private Optional getPrefixedPropertyName(FeatureSchema schema, String pr }); } + @SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods"}) class CqlToFes implements CqlVisitor { private final FeatureSchema schema; @@ -178,6 +165,7 @@ public FesExpression visit(LogicalOperation logicalOperation, List children) { if (scalarOperation instanceof Eq) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/GmlMultiplicityTracker.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/GmlMultiplicityTracker.java index 4b683236f..f68e9ce82 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/GmlMultiplicityTracker.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/GmlMultiplicityTracker.java @@ -13,15 +13,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author zahnen */ public class GmlMultiplicityTracker { - private static final Logger LOGGER = LoggerFactory.getLogger(GmlMultiplicityTracker.class); private static final Joiner JOINER = Joiner.on('.'); private final Map currentMultiplicities; diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/WfsRequestEncoder.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/WfsRequestEncoder.java index 60c0e360a..6f965d7a6 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/WfsRequestEncoder.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/app/WfsRequestEncoder.java @@ -22,8 +22,6 @@ import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import org.apache.hc.core5.net.URIBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; /** @@ -32,11 +30,9 @@ // TODO: merge into FeatureQueryEncoderWfs public class WfsRequestEncoder { - private static final Logger LOGGER = LoggerFactory.getLogger(WfsRequestEncoder.class); - - private Map> urls; - private Versions versions; - private XMLNamespaceNormalizer nsStore; + private final Map> urls; + private final Versions versions; + private final XMLNamespaceNormalizer nsStore; public WfsRequestEncoder( String version, diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java index 6605e6d7a..a5e3e944b 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java @@ -40,6 +40,7 @@ import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; +@SuppressWarnings("PMD.CyclomaticComplexity") public class GeometryDecoderGml extends AbstractGeometryDecoder { // In principle, we could support more GML geometry types, currently only the most common ones are From 1976d61244fbea717980484c36bbf9d7ed06e5b0 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Tue, 26 May 2026 11:15:55 +0200 Subject: [PATCH 2/4] pmd warnings --- .../gml/domain/GeometryDecoderGml.java | 121 +++++++++++------- .../gml/domain/GeometryEncoderGml.java | 17 +-- 2 files changed, 79 insertions(+), 59 deletions(-) diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java index a5e3e944b..60cf65569 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryDecoderGml.java @@ -43,6 +43,12 @@ @SuppressWarnings("PMD.CyclomaticComplexity") public class GeometryDecoderGml extends AbstractGeometryDecoder { + private static final String ELEMENT_SUFFIX = "> element."; + + private boolean waitingForInput; + private boolean waitingForGeometry = true; + private PartialGeometry currentGeometry; + // In principle, we could support more GML geometry types, currently only the most common ones are // supported. However, GML decoding is currently only relevant for un-maintained WFS feature // providers. @@ -59,20 +65,14 @@ public class GeometryDecoderGml extends AbstractGeometryDecoder { new ImmutableList.Builder().add("posList").add("pos").add("coordinates").build(); static class PartialGeometry { - PartialGeometry parent = null; + PartialGeometry parent; Deque children = new ArrayDeque<>(); - boolean isComplete = false; - Geometry geometry = null; - double[] coordinates = null; - StringBuilder textBuffer = new StringBuilder(); + boolean isComplete; + Geometry geometry; + double[] coordinates; + String textBuffer = ""; } - private boolean waitingForInput = false; - private boolean waitingForGeometry = true; - private PartialGeometry currentGeometry = null; - - public GeometryDecoderGml() {} - public Optional> decode( AsyncXMLStreamReader parser, Optional crs, @@ -81,13 +81,19 @@ public Optional> decode( return decode(parser, crs, srsDimension, false); } + @SuppressWarnings({ + "PMD.NcssCount", + "PMD.CognitiveComplexity", + "PMD.NPathComplexity", + "PMD.AvoidInstantiatingObjectsInLoops", + "PMD.NullAssignment" + }) public Optional> decode( AsyncXMLStreamReader parser, Optional defaultCrs, OptionalInt srsDimension, boolean useCurrentEvent) throws XMLStreamException, IOException { - String localName; waitingForInput = false; boolean doNotAdvance = useCurrentEvent; while (doNotAdvance || parser.hasNext()) { @@ -98,7 +104,7 @@ public Optional> decode( waitingForInput = true; return Optional.empty(); case XMLStreamConstants.START_ELEMENT: - localName = parser.getLocalName(); + String startLocalName = parser.getLocalName(); if (waitingForGeometry) { Optional crs = getCrsFromSrsName(parser).or(() -> defaultCrs); Axes axes = @@ -106,7 +112,7 @@ public Optional> decode( ? Axes.XY : Axes.XYZ; Geometry geom = - switch (localName) { + switch (startLocalName) { case "Point" -> ImmutablePoint.builder() .crs(crs) .value(Position.empty(axes)) @@ -129,7 +135,8 @@ public Optional> decode( .crs(crs) .axes(axes) .build(); - default -> throw new IOException("Unsupported GML geometry type: " + localName); + default -> throw new IOException( + "Unsupported GML geometry type: " + startLocalName); }; if (currentGeometry == null) { currentGeometry = new PartialGeometry(); @@ -141,49 +148,58 @@ public Optional> decode( } currentGeometry.geometry = geom; waitingForGeometry = false; - } else if (GEOMETRY_COORDINATES.contains(localName)) { + } else if (GEOMETRY_COORDINATES.contains(startLocalName)) { if (currentGeometry == null) { throw new IllegalStateException( - "No geometry started before element."); + "No geometry started before element cannot be added to a completed geometry."); + " element."); + "No geometry started before element cannot be added to a completed geometry."); + " element."); + "No geometry started before element."); + "Geometry already completed for { var builder = ImmutableMultiPoint.builder().from((MultiPoint) currentGeometry.geometry); @@ -209,11 +225,14 @@ public Optional> decode( } currentGeometry.geometry = builder.build(); } + default -> { + // no-op + } } currentGeometry.isComplete = true; if (currentGeometry.geometry.isEmpty()) { throw new IllegalStateException( - "Geometry is empty for element."); + "Geometry is empty for > decode( break; case XMLStreamConstants.CHARACTERS: break; + default: + break; } } throw new IOException("Unexpected end of XML stream, no complete geometry found."); } - private void handleCoordinates(String localName, double[] coords) { + @SuppressWarnings("PMD.NullAssignment") + private void handleCoordinates(String localName, double... coords) { Geometry geom = currentGeometry.geometry; GeometryType geomType = geom.getType(); Axes axes = geom.getAxes(); @@ -319,21 +341,21 @@ public Optional> continueDecoding( if (GEOMETRY_COORDINATES.contains(localName)) { if (currentGeometry == null) { throw new IllegalStateException( - "No geometry started before element."); + "No geometry started before element cannot be added to a completed geometry."); + " getCrsFromSrsName(AsyncXMLStreamReader parser) { String srsName = parser.getAttributeValue(null, "srsName"); if (srsName != null) { if (srsName.startsWith("urn:ogc:def:crs:EPSG::")) { - String code = srsName.substring(srsName.lastIndexOf(":") + 1); + String code = srsName.substring(srsName.lastIndexOf(':') + 1); try { return Optional.of(EpsgCrs.of(Integer.parseInt(code))); } catch (Exception e) { // ignore, fallback to default } } else if (srsName.startsWith("http://www.opengis.net/def/crs/EPSG/0/")) { - String code = srsName.substring(srsName.lastIndexOf("/") + 1); + String code = srsName.substring(srsName.lastIndexOf('/') + 1); try { return Optional.of(EpsgCrs.of(Integer.parseInt(code))); } catch (Exception e) { // ignore, fallback to default } - } else if (srsName.equals("http://www.opengis.net/def/crs/OGC/0/CRS84") - || srsName.equals("http://www.opengis.net/def/crs/OGC/1.3/CRS84") - || srsName.equals("urn:ogc:def:crs:OGC:1.3:CRS84")) { + } else if ("http://www.opengis.net/def/crs/OGC/0/CRS84".equals(srsName) + || "http://www.opengis.net/def/crs/OGC/1.3/CRS84".equals(srsName) + || "urn:ogc:def:crs:OGC:1.3:CRS84".equals(srsName)) { return Optional.of(OgcCrs.CRS84); - } else if (srsName.equals("http://www.opengis.net/def/crs/OGC/0/CRS84h") - || srsName.equals("urn:ogc:def:crs:OGC::CRS84h")) { + } else if ("http://www.opengis.net/def/crs/OGC/0/CRS84h".equals(srsName) + || "urn:ogc:def:crs:OGC::CRS84h".equals(srsName)) { return Optional.of(OgcCrs.CRS84h); } } @@ -416,9 +439,9 @@ private double[] parseCoordinates( int event = parser.next(); if (event == AsyncXMLStreamReader.EVENT_INCOMPLETE) { waitingForInput = true; - currentGeometry.textBuffer = new StringBuilder(text); + currentGeometry.textBuffer = text.toString(); // keep current state and resume processing when more input is available - return null; + return new double[0]; } else if (event == XMLStreamConstants.CHARACTERS) { text.append(parser.getText()); } else if (event == XMLStreamConstants.END_ELEMENT && tagName.equals(parser.getLocalName())) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java index 64a715f52..9e89a806e 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java @@ -61,9 +61,6 @@ public class GeometryEncoderGml implements GeometryVisitor { private static final String MULTI_POLYGON = "MultiPolygon"; private static final String SOLID = "Solid"; private static final String SHELL = "Shell"; - // these will be needed for the AdV LoD2 CityGML profile - private static final String COMPOSITE_SURFACE = "CompositeSurface"; - private static final String COMPOSITE_CURVE = "CompositeCurve"; private static final String POS = "pos"; private static final String POS_LIST = "posList"; private static final String COORDINATES = "coordinates"; @@ -132,7 +129,7 @@ public enum Options { private final Optional encodeAsSegmentOrPatch; private final Optional encodeAsEmbeddedGeometry; private final GmlVersion version; - private int nextGmlId = 0; + private int nextGmlId; private String srsName; public GeometryEncoderGml(StringBuilder builder) { @@ -140,7 +137,7 @@ public GeometryEncoderGml(StringBuilder builder) { this.gmlPrefix = Optional.of("gml"); this.gmlIdPrefix = "geom_"; this.options = Set.of(); - this.precision = null; + this.precision = new int[0]; this.encodeAsSegmentOrPatch = Optional.of( new GeometryEncoderGml( @@ -154,7 +151,7 @@ public GeometryEncoderGml(StringBuilder builder) { Optional.of( new GeometryEncoderGml( builder, GmlVersion.GML32, Set.of(), this.gmlPrefix, Optional.empty(), List.of())); - this.srsName = null; + this.srsName = ""; this.version = GmlVersion.GML32; } @@ -203,14 +200,14 @@ public GeometryEncoderGml( this.precision = precision.stream().anyMatch(v -> v > 0) ? precision.stream().mapToInt(v -> v).toArray() - : null; - this.srsName = null; + : new int[0]; + this.srsName = ""; this.version = version; } @Override public Optional initAndCheckGeometry(Geometry geometry) { - if (srsName == null) { + if (srsName.isEmpty()) { srsName = geometry .getCrs() @@ -304,7 +301,7 @@ private void writeCoordinates(double[] coordinates, Axes axes) { write(SPACE); } } - if (precision != null && j < precision.length && precision[j] > 0) { + if (j < precision.length && precision[j] > 0) { write( BigDecimal.valueOf(coordinates[i * dimensionWithoutM + j]) .setScale(precision[j], RoundingMode.HALF_UP)); From 9cf2a9ad33e10eeb2532843d182820b7056945d8 Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Wed, 3 Jun 2026 18:35:58 +0200 Subject: [PATCH 3/4] pmd warnings --- .../gml/domain/GeometryEncoderGml.java | 47 +++++++++++-------- .../features/gml/domain/GmlGeometryType.java | 3 +- .../features/gml/domain/WfsClientBasic.java | 2 +- .../gml/domain/XMLNamespaceNormalizer.java | 3 -- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java index 9e89a806e..4e5e8abd4 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java @@ -34,6 +34,12 @@ import java.util.Optional; import java.util.Set; +@SuppressWarnings({ + "PMD.GodClass", + "PMD.CyclomaticComplexity", + "PMD.TooManyMethods", + "PMD.AvoidStringBufferField" +}) public class GeometryEncoderGml implements GeometryVisitor { public static final String SPACE = " "; @@ -288,6 +294,7 @@ private void writeEndTag(String tagName) { write(CLOSE); } + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CyclomaticComplexity"}) private void writeCoordinates(double[] coordinates, Axes axes) { int dimensionWithoutM = axes == Axes.XY || axes == Axes.XYM ? 2 : 3; for (int i = 0; i < coordinates.length / axes.size(); i++) { @@ -313,31 +320,31 @@ private void writeCoordinates(double[] coordinates, Axes axes) { } private void writePosition(double[] coordinates, Axes axes) { - if (version != GmlVersion.GML21) { + if (version == GmlVersion.GML21) { + writeStartTagProperty(COORDINATES); + } else { if (options.contains(Options.WITH_SRS_DIMENSION)) { writeStartTagProperty(POS, Map.of("srsDimension", String.valueOf(axes.size()))); } else { writeStartTagProperty(POS); } - } else { - writeStartTagProperty(COORDINATES); } writeCoordinates(coordinates, axes); - writeEndTag(version != GmlVersion.GML21 ? POS : COORDINATES); + writeEndTag(version == GmlVersion.GML21 ? COORDINATES : POS); } private void writePositionList(double[] coordinates, Axes axes) { - if (version != GmlVersion.GML21) { + if (version == GmlVersion.GML21) { + writeStartTagProperty(COORDINATES); + } else { if (options.contains(Options.WITH_SRS_DIMENSION)) { writeStartTagProperty(POS_LIST, Map.of("srsDimension", String.valueOf(axes.size()))); } else { writeStartTagProperty(POS_LIST); } - } else { - writeStartTagProperty(COORDINATES); } writeCoordinates(coordinates, axes); - writeEndTag(version != GmlVersion.GML21 ? POS_LIST : COORDINATES); + writeEndTag(version == GmlVersion.GML21 ? COORDINATES : POS_LIST); } @Override @@ -401,14 +408,14 @@ private void writeCircularString(CircularString geometry, boolean asSegment) { @Override public Void visit(MultiLineString geometry) { - writeStartTagObject(version != GmlVersion.GML21 ? MULTI_CURVE : MULTI_LINE_STRING, false); + writeStartTagObject(version == GmlVersion.GML21 ? MULTI_LINE_STRING : MULTI_CURVE, false); for (int i = 0; i < geometry.getNumGeometries(); i++) { LineString lineString = geometry.getValue().get(i); - writeStartTagProperty(version != GmlVersion.GML21 ? CURVE_MEMBER : LINE_STRING_MEMBER); + writeStartTagProperty(version == GmlVersion.GML21 ? LINE_STRING_MEMBER : CURVE_MEMBER); lineString.accept(encodeAsEmbeddedGeometry.orElse(this)); - writeEndTag(version != GmlVersion.GML21 ? CURVE_MEMBER : LINE_STRING_MEMBER); + writeEndTag(version == GmlVersion.GML21 ? LINE_STRING_MEMBER : CURVE_MEMBER); } - writeEndTag(version != GmlVersion.GML21 ? MULTI_CURVE : MULTI_LINE_STRING); + writeEndTag(version == GmlVersion.GML21 ? MULTI_LINE_STRING : MULTI_CURVE); return null; } @@ -423,17 +430,17 @@ public Void visit(Polygon geometry) { for (int i = 0; i < geometry.getNumRings(); i++) { LineString ring = geometry.getValue().get(i); if (i == 0) { - writeStartTagProperty(version != GmlVersion.GML21 ? EXTERIOR : OUTER_BOUNDARY_IS); + writeStartTagProperty(version == GmlVersion.GML21 ? OUTER_BOUNDARY_IS : EXTERIOR); } else { - writeStartTagProperty(version != GmlVersion.GML21 ? INTERIOR : INNER_BOUNDARY_IS); + writeStartTagProperty(version == GmlVersion.GML21 ? INNER_BOUNDARY_IS : INTERIOR); } writeStartTagObject(LINEAR_RING, true); writePositionList(ring.getValue().getCoordinates(), geometry.getAxes()); writeEndTag(LINEAR_RING); if (i == 0) { - writeEndTag(version != GmlVersion.GML21 ? EXTERIOR : OUTER_BOUNDARY_IS); + writeEndTag(version == GmlVersion.GML21 ? OUTER_BOUNDARY_IS : EXTERIOR); } else { - writeEndTag(version != GmlVersion.GML21 ? INTERIOR : INNER_BOUNDARY_IS); + writeEndTag(version == GmlVersion.GML21 ? INNER_BOUNDARY_IS : INTERIOR); } } if (asPatch) { @@ -446,14 +453,14 @@ public Void visit(Polygon geometry) { @Override public Void visit(MultiPolygon geometry) { - writeStartTagObject(version != GmlVersion.GML21 ? MULTI_SURFACE : MULTI_POLYGON, false); + writeStartTagObject(version == GmlVersion.GML21 ? MULTI_POLYGON : MULTI_SURFACE, false); for (int i = 0; i < geometry.getNumGeometries(); i++) { Polygon polygon = geometry.getValue().get(i); - writeStartTagProperty(version != GmlVersion.GML21 ? SURFACE_MEMBER : POLYGON_MEMBER); + writeStartTagProperty(version == GmlVersion.GML21 ? POLYGON_MEMBER : SURFACE_MEMBER); polygon.accept(encodeAsEmbeddedGeometry.orElse(this)); - writeEndTag(version != GmlVersion.GML21 ? SURFACE_MEMBER : POLYGON_MEMBER); + writeEndTag(version == GmlVersion.GML21 ? POLYGON_MEMBER : SURFACE_MEMBER); } - writeEndTag(version != GmlVersion.GML21 ? MULTI_SURFACE : MULTI_POLYGON); + writeEndTag(version == GmlVersion.GML21 ? MULTI_POLYGON : MULTI_SURFACE); return null; } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java index ffe8acd8d..529ed6d71 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java @@ -45,8 +45,7 @@ public String toString() { public static GmlGeometryType fromString(String type) { for (GmlGeometryType v : GmlGeometryType.values()) { if (v.toString().equals(type) - || (v.elementStringRepresentation != null - && v.elementStringRepresentation.equals(type))) { + || v.elementStringRepresentation != null && v.elementStringRepresentation.equals(type)) { return v; } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/WfsClientBasic.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/WfsClientBasic.java index a41c920d7..d0af2c346 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/WfsClientBasic.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/WfsClientBasic.java @@ -13,7 +13,7 @@ import java.util.Optional; public interface WfsClientBasic { - InputStream runWfsOperation(final WfsOperation operation); + InputStream runWfsOperation(WfsOperation operation); Optional getMetadata(); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java index 30db0d65a..9f887abf2 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java @@ -13,15 +13,12 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.namespace.QName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author fischer */ public class XMLNamespaceNormalizer { - private static final Logger LOGGER = LoggerFactory.getLogger(XMLNamespaceNormalizer.class); private Map namespaces; private int nscount; private int shortcount; From 207cff6aca6ea8b5703614d57f7f3ad36625399f Mon Sep 17 00:00:00 2001 From: "p.zahnen" Date: Fri, 5 Jun 2026 16:08:02 +0200 Subject: [PATCH 4/4] pmd warnings --- .../gml/domain/GeometryEncoderGml.java | 1 + .../features/gml/domain/GmlGeometryType.java | 1 + .../gml/domain/XMLNamespaceNormalizer.java | 30 +-- .../features/gml/infra/GMLSchemaParser.java | 91 ++++---- .../features/gml/infra/OGCEntityResolver.java | 74 ++++--- .../gml/infra/WFSCapabilitiesParser.java | 194 ++++++++++-------- .../gml/infra/WfsCapabilitiesAnalyzer.java | 27 +-- .../infra/WfsClientBasicFactoryDefault.java | 2 +- .../features/gml/infra/WfsConnectorHttp.java | 20 +- .../features/gml/infra/WfsSchemaAnalyzer.java | 20 +- .../features/gml/infra/WfsSchemaCrawler.java | 34 ++- .../features/gml/infra/fes/FesAnd.java | 7 +- .../features/gml/infra/fes/FesBBox.java | 7 +- .../features/gml/infra/fes/FesDuring.java | 7 +- .../features/gml/infra/fes/FesEnvelope.java | 3 +- .../features/gml/infra/fes/FesExpression.java | 2 +- .../features/gml/infra/fes/FesFilter.java | 62 +++--- .../features/gml/infra/fes/FesLiteral.java | 3 +- .../features/gml/infra/fes/FesNot.java | 5 +- .../features/gml/infra/fes/FesOr.java | 7 +- .../gml/infra/fes/FesPolygonExpression.java | 25 +-- .../gml/infra/fes/FesPropertyIsEqualTo.java | 7 +- .../infra/fes/FesPropertyIsGreaterThan.java | 7 +- .../gml/infra/fes/FesPropertyIsLessThan.java | 7 +- .../gml/infra/fes/FesPropertyIsLike.java | 7 +- .../gml/infra/fes/FesPropertyIsNull.java | 5 +- .../features/gml/infra/fes/FesResourceId.java | 7 +- .../gml/infra/fes/FesTemporalLiteral.java | 6 +- .../gml/infra/fes/FesValueReference.java | 2 +- .../features/gml/infra/fes/Geometry.java | 3 +- .../features/gml/infra/fes/Polygon.java | 8 +- .../features/gml/infra/req/CSW.java | 10 +- .../gml/infra/req/DescribeFeatureType.java | 2 - .../features/gml/infra/req/FES.java | 15 +- .../features/gml/infra/req/GML.java | 13 +- .../gml/infra/req/GetCapabilities.java | 15 +- .../features/gml/infra/req/GetFeature.java | 28 ++- .../gml/infra/req/GetFeatureBuilder.java | 6 +- .../features/gml/infra/req/OWS.java | 8 +- .../gml/infra/req/VersionedVocabulary.java | 1 + .../features/gml/infra/req/Versions.java | 5 +- .../features/gml/infra/req/WFS.java | 22 +- .../features/gml/infra/req/WfsQuery.java | 21 +- .../features/gml/infra/xml/XMLDocument.java | 2 +- .../gml/infra/xml/XMLPathTracker.java | 22 +- ...stractFeatureProviderMetadataConsumer.java | 2 +- .../features/domain/BoundingBoxStrings.java | 39 ++++ .../FeatureProviderMetadataConsumer.java | 3 +- ...oggingFeatureProviderMetadataConsumer.java | 9 +- .../MultiFeatureProviderMetadataConsumer.java | 4 +- 50 files changed, 498 insertions(+), 410 deletions(-) create mode 100644 xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/BoundingBoxStrings.java diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java index 4e5e8abd4..5dbc5aeed 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GeometryEncoderGml.java @@ -420,6 +420,7 @@ public Void visit(MultiLineString geometry) { } @Override + @SuppressWarnings("PMD.CognitiveComplexity") public Void visit(Polygon geometry) { boolean asPatch = options.contains(Options.POLYGON_AS_PATCH); if (asPatch) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java index 529ed6d71..b55d0b229 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/GmlGeometryType.java @@ -61,6 +61,7 @@ public static boolean contains(String type) { return false; } + @SuppressWarnings("PMD.CyclomaticComplexity") public GeometryType toSimpleFeatureGeometry() { return switch (this) { case POINT -> GeometryType.POINT; diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java index 9f887abf2..acb5b6359 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/domain/XMLNamespaceNormalizer.java @@ -17,6 +17,7 @@ /** * @author fischer */ +@SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods"}) public class XMLNamespaceNormalizer { private Map namespaces; @@ -80,13 +81,15 @@ public void addNamespace(String prefix, String namespaceURI, boolean overwritePr addNamespace(prefix, namespaceURI); } + @SuppressWarnings("PMD.CyclomaticComplexity") public void addNamespace(String prefix, String namespaceURI) { + String effectivePrefix = prefix; - if (namespaces.containsKey(prefix)) { - prefix += "x"; + if (namespaces.containsKey(effectivePrefix)) { + effectivePrefix += "x"; } - if (prefix != null && prefix.isEmpty()) { + if (effectivePrefix != null && effectivePrefix.isEmpty()) { // defaultNamespaceURI = namespaceURI; // prefix = defaultNamespacePRE; // LOGGER.debug("Added Default-Namespace: {}, {}", prefix, namespaceURI); @@ -98,14 +101,16 @@ public void addNamespace(String prefix, String namespaceURI) { if (namespaceURI.startsWith("http://www.opengis.net/gml")) { namespaces.put("gml", namespaceURI); // LOGGER.debug("Added gml Namespace: {}, {}", "gml", namespaceURI); - } else if (!namespaces.containsValue(namespaceURI) && prefix != null) { - namespaces.put(prefix, namespaceURI); - // LOGGER.debug("Added Namespace: {}, {}", prefix, namespaceURI); + } else if (!namespaces.containsValue(namespaceURI) && effectivePrefix != null) { + namespaces.put(effectivePrefix, namespaceURI); + // LOGGER.debug("Added Namespace: {}, {}", effectivePrefix, namespaceURI); } } - if (prefix != null && prefix.length() > 5 && !shortNamespaces.containsValue(namespaceURI)) { - String pre = prefix.substring(0, 5) + shortcount++; + if (effectivePrefix != null + && effectivePrefix.length() > 5 + && !shortNamespaces.containsValue(namespaceURI)) { + String pre = effectivePrefix.substring(0, 5) + shortcount++; shortNamespaces.put(pre, namespaceURI); } } @@ -137,12 +142,13 @@ public String getDefaultNamespacePRE() { */ public String convertToShortForm(String longform) { + String shortForm = longform; for (Map.Entry ns : namespaces.entrySet()) { if (ns != null && !ns.getValue().isEmpty()) { - longform = longform.replace(ns.getValue(), this.getNamespacePrefix(ns.getValue())); + shortForm = shortForm.replace(ns.getValue(), this.getNamespacePrefix(ns.getValue())); } } - return longform; + return shortForm; } /* @@ -163,7 +169,7 @@ private String extractNamespaceURI(String qn) { } */ public String getLocalName(String qn) { - return qn.substring(qn.lastIndexOf(":") + 1); + return qn.substring(qn.lastIndexOf(':') + 1); } public String getQualifiedName(String lqn) { @@ -193,7 +199,7 @@ public String generateNamespaceDeclaration(String prefix) { public String extractURI(String qn) { if (qn.contains(":")) { - return qn.substring(0, qn.lastIndexOf(":")); + return qn.substring(0, qn.lastIndexOf(':')); } else { return ""; } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/GMLSchemaParser.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/GMLSchemaParser.java index f6a927d2d..265393a5a 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/GMLSchemaParser.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/GMLSchemaParser.java @@ -19,7 +19,6 @@ import com.sun.xml.xsom.parser.XSOMParser; import de.ii.xtraplatform.features.domain.FeatureProviderSchemaConsumer; import de.ii.xtraplatform.features.gml.infra.req.GML; -import de.ii.xtraplatform.features.gml.infra.xml.XMLPathTracker; import java.io.InputStream; import java.net.URI; import java.util.ArrayList; @@ -41,11 +40,11 @@ /** * @author zahnen */ +@SuppressWarnings("PMD.GodClass") public class GMLSchemaParser { private static final Logger LOGGER = LoggerFactory.getLogger(GMLSchemaParser.class); private final List analyzers; - private final XMLPathTracker currentPath; private final List abstractObjectDecl; private final List abstractFeatureDecl; private final Map namespaces; @@ -65,12 +64,12 @@ public GMLSchemaParser( Map namespaces, EntityResolver entityResolver) { this.analyzers = analyzers; - this.currentPath = new XMLPathTracker(); - this.abstractObjectDecl = new ArrayList(); - this.abstractFeatureDecl = new ArrayList(); + this.abstractObjectDecl = new ArrayList<>(); + this.abstractFeatureDecl = new ArrayList<>(); this.baseURI = baseURI; this.namespaces = namespaces; this.entityResolver = entityResolver; + this.complexTypes = new HashSet<>(); } public void parse( @@ -101,6 +100,12 @@ private void parse( parse(is, elements, true, tracker); } + @SuppressWarnings({ + "PMD.NcssCount", + "PMD.CognitiveComplexity", + "PMD.CyclomaticComplexity", + "PMD.NPathComplexity" + }) private void parse( InputSource is, Map> elements, @@ -161,9 +166,11 @@ private void parse( // and Schema // in this case we search in the targetNamespace of the Schema if (schema == null && lax) { - LOGGER.info( - "Schema for Namespace '{}' not found, searching in targetNamespace schema instead. ", - ns.getKey()); + if (LOGGER.isInfoEnabled()) { + LOGGER.info( + "Schema for Namespace '{}' not found, searching in targetNamespace schema instead. ", + ns.getKey()); + } // looks as if the schema for the targetNamespace of the document is always second in the // list @@ -197,14 +204,7 @@ private void parse( 0); } } - XSParticle particle = elem.getType().asComplexType().getContentType().asParticle(); - if (particle != null) { - XSTerm term = particle.getTerm(); - if (term.isModelGroup()) { - complexTypes = new HashSet(); - parseGroup(term.asModelGroup(), 1, false, i -> {}); - } - } + parseRootElement(elem); } } } @@ -216,7 +216,8 @@ private void parse( throw new IllegalStateException( String.format( "The GML application schema provided by the WFS imports schema '%s', but that schema cannot be accessed. A valid GML application schema is required to determine the layers of the proxy service and its characteristics.. Please contact the WFS provider to correct the schema error.", - ex.getCause().getMessage())); + ex.getCause().getMessage()), + ex); } String msg = ex.toString(); @@ -229,10 +230,24 @@ private void parse( throw new IllegalStateException( "The GML application schema provided by the WFS is invalid. A valid GML application schema is required to determine the layers of the proxy service and its characteristics. Please contact the WFS provider to correct the schema error. \n" - + msgex); + + msgex, + ex); } } + private void parseRootElement(XSElementDecl elem) { + XSParticle particle = elem.getType().asComplexType().getContentType().asParticle(); + if (particle == null) { + return; + } + XSTerm term = particle.getTerm(); + if (!term.isModelGroup()) { + return; + } + complexTypes.clear(); + parseGroup(term.asModelGroup(), 1, false, i -> {}); + } + private void track( Consumer>> tracker, String type, @@ -257,7 +272,7 @@ private void parseGroup( // reset already visited complex types for every first level property of the featuretype, // meaning for every new path that should not contain recursion if (depth == 2) { - complexTypes = new HashSet(); + complexTypes.clear(); } XSParticle[] particles = xsModelGroup.getChildren(); @@ -283,6 +298,12 @@ private void parseGroup( } } + @SuppressWarnings({ + "PMD.NcssCount", + "PMD.CognitiveComplexity", + "PMD.CyclomaticComplexity", + "PMD.NPathComplexity" + }) private void parseElementDecl( XSElementDecl decl, long minOccurs, @@ -291,17 +312,10 @@ private void parseElementDecl( boolean isParentMultible, Consumer onFeature) { - String propertyName = null; - XSType propertyType = null; boolean isObject = false; boolean isFeature = false; - propertyName = decl.getName(); - - String typeName = decl.getType().getBaseType().getName(); - String typeName0 = decl.getType().getName(); - - propertyType = decl.getType(); + XSType propertyType = decl.getType(); if (decl.getType().getName() != null) { XSElementDecl decl0 = decl.getSubstAffiliation(); @@ -330,13 +344,11 @@ private void parseElementDecl( decl0 = decl0.getSubstAffiliation(); } - if (gcoObjectType != null) { - if (propertyType.isDerivedFrom(gcoObjectType)) { - isObject = true; - } + if (gcoObjectType != null && propertyType.isDerivedFrom(gcoObjectType)) { + isObject = true; } - } else if (!decl.getType().getBaseType().getName().equals("anyType")) { + } else if (!"anyType".equals(decl.getType().getBaseType().getName())) { propertyType = decl.getType().getBaseType(); } @@ -346,6 +358,8 @@ private void parseElementDecl( return; } + String propertyName = decl.getName(); + String propertyTypeName = propertyType.getName(); if (propertyType.isSimpleType()) { @@ -451,21 +465,16 @@ private void parseElementDecl( private void parseComplexType( XSComplexType type, int depth, boolean isParenMultiple, Consumer onFeature) { - if (type != null) { + if (type != null && complexTypes.add(type.getTargetNamespace() + ":" + type.getName())) { /*for (XSAttributeUse att : elem.getAttributeUses()) { LOGGER.debug(" - attribute {}, required: {}, type: {}, ns: {}", att.getDecl().getName(), att.isRequired(), att.getDecl().getType().getName(), att.getDecl().getTargetNamespace()); analyzer.analyzeAttribute(att.getDecl().getTargetNamespace(), att.getDecl().getName(), att.getDecl().getType().getName(), att.isRequired()); }*/ // stop analyzing if the complex type already occurred in this path to avoid recursion - if (complexTypes.add(type.getTargetNamespace() + ":" + type.getName())) { - XSParticle particle = type.getContentType().asParticle(); - if (particle != null) { - XSTerm term = particle.getTerm(); - if (term.isModelGroup()) { - parseGroup(term.asModelGroup(), depth, isParenMultiple, onFeature); - } - } + XSParticle particle = type.getContentType().asParticle(); + if (particle != null && particle.getTerm().isModelGroup()) { + parseGroup(particle.getTerm().asModelGroup(), depth, isParenMultiple, onFeature); } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/OGCEntityResolver.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/OGCEntityResolver.java index b4da37261..eb4a67941 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/OGCEntityResolver.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/OGCEntityResolver.java @@ -35,9 +35,9 @@ public class OGCEntityResolver implements EntityResolver { private static final Logger LOGGER = LoggerFactory.getLogger(OGCEntityResolver.class); - private Map uris = new HashMap(); + private final Map uris = new HashMap<>(); private CloseableHttpClient untrustedSslHttpClient; - private boolean useBasicAuth = false; + private final boolean useBasicAuth; private String user; private String password; @@ -49,38 +49,42 @@ public OGCEntityResolver( this.useBasicAuth = true; } - public OGCEntityResolver() {} + public OGCEntityResolver() { + this.useBasicAuth = false; + } @Override + @SuppressWarnings({ + "PMD.NcssCount", + "PMD.CognitiveComplexity", + "PMD.CyclomaticComplexity", + "PMD.NPathComplexity" + }) public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { // TODO: temporary basic auth hack // protected schema files if (systemId != null && systemId.startsWith("https://") && useBasicAuth) { - CloseableHttpResponse response = null; LOGGER.debug("resolving protected schema: {}", systemId); - try { - HttpGet httpGet = new HttpGet(systemId); + HttpGet httpGet = new HttpGet(systemId); - String basic_auth = new String(Base64.encodeBase64((user + ":" + password).getBytes())); - httpGet.addHeader("Authorization", "Basic " + basic_auth); + String basicAuth = new String(Base64.encodeBase64((user + ":" + password).getBytes())); + httpGet.addHeader("Authorization", "Basic " + basicAuth); - response = untrustedSslHttpClient.execute(httpGet, new BasicHttpContext()); + try (CloseableHttpResponse response = + untrustedSslHttpClient.execute(httpGet, new BasicHttpContext())) { String stringFromStream = CharStreams.toString(new InputStreamReader(response.getEntity().getContent(), "UTF-8")); InputSource is = new InputSource(new StringReader(stringFromStream)); is.setSystemId(systemId); + EntityUtils.consumeQuietly(response.getEntity()); return is; } catch (IOException ex) { - ex.printStackTrace(); - throw new IllegalStateException("Error parsing application schema. " + ex.getMessage()); - } finally { - if (response != null) { - EntityUtils.consumeQuietly(response.getEntity()); - } + LOGGER.error("Error parsing application schema.", ex); + throw new IllegalStateException("Error parsing application schema. " + ex.getMessage(), ex); } } @@ -115,6 +119,8 @@ public InputSource resolveEntity(String publicId, String systemId) "http://www.aixm.aero/gallery/content/public/schema/5.1/AIXM_Features.xsd"); } break; + default: + break; } } @@ -146,21 +152,9 @@ public InputSource resolveEntity(String publicId, String systemId) } // A4I workarounds - if (systemId.contains("/exts/InspireFeatureDownload/service")) { - String url = systemId; - // workaround for A4I 10.1 SP1 (Patch1) blank encoding bug in GET parameters - if (url.contains("OUTPUT_FORMAT=")) { - int start = url.indexOf("OUTPUT_FORMAT=") + 13; - int end = url.indexOf("&", start); - String out = url.substring(start, end).replaceAll("%20", ""); - url = url.substring(0, start) + out + url.substring(end); - } - - if (!url.equals(systemId)) { - LOGGER.debug("original systemId: {}", systemId); - LOGGER.debug("changed systemId: {}", url); - return new InputSource(url); - } + InputSource a4i = handleA4IWorkaround(systemId); + if (a4i != null) { + return a4i; } } @@ -177,6 +171,26 @@ public InputSource resolveEntity(String publicId, String systemId) return null; } + private InputSource handleA4IWorkaround(String systemId) { + if (!systemId.contains("/exts/InspireFeatureDownload/service")) { + return null; + } + String url = systemId; + // workaround for A4I 10.1 SP1 (Patch1) blank encoding bug in GET parameters + if (url.contains("OUTPUT_FORMAT=")) { + int start = url.indexOf("OUTPUT_FORMAT=") + 13; + int end = url.indexOf('&', start); + String out = url.substring(start, end).replaceAll("%20", ""); + url = url.substring(0, start) + out + url.substring(end); + } + if (url.equals(systemId)) { + return null; + } + LOGGER.debug("original systemId: {}", systemId); + LOGGER.debug("changed systemId: {}", url); + return new InputSource(url); + } + private InputSource getSchemaFromBundle(String publicId, String schemaPath) throws IOException { URL url = Resources.getResource(OGCEntityResolver.class, schemaPath); InputSource is = new InputSource(url.openStream()); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WFSCapabilitiesParser.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WFSCapabilitiesParser.java index 446c41406..313a63b72 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WFSCapabilitiesParser.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WFSCapabilitiesParser.java @@ -7,6 +7,7 @@ */ package de.ii.xtraplatform.features.gml.infra; +import de.ii.xtraplatform.features.domain.BoundingBoxStrings; import de.ii.xtraplatform.features.domain.FeatureProviderMetadataConsumer; import de.ii.xtraplatform.features.gml.infra.req.OWS; import de.ii.xtraplatform.features.gml.infra.req.XLINK; @@ -21,6 +22,7 @@ /** * @author zahnen */ +@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.TooManyMethods"}) public class WFSCapabilitiesParser { private final FeatureProviderMetadataConsumer metadataConsumer; @@ -45,6 +47,7 @@ public void parse(InputStream inputStream) { } } + @SuppressWarnings("PMD.CyclomaticComplexity") public void parse(InputSource is) { SMInputCursor root = null; @@ -79,6 +82,8 @@ public void parse(InputSource is) { case FEATURE_TYPE_LIST: parseFeatureTypeList(capabilitiesChild); break; + default: + break; } capabilitiesChild = capabilitiesChild.advance(); @@ -125,11 +130,9 @@ private boolean checkForExceptionReport(SMInputCursor cursor) throws XMLStreamEx while (exceptionReportChild.readerAccessible()) { - switch (OWS.findKey(exceptionReportChild.getLocalName())) { - case EXCEPTION: - parseException(exceptionReportChild); - reportChildFound = true; - break; + if (OWS.findKey(exceptionReportChild.getLocalName()) == OWS.VOCABULARY.EXCEPTION) { + parseException(exceptionReportChild); + reportChildFound = true; } exceptionReportChild = exceptionReportChild.advance(); @@ -161,10 +164,8 @@ private void parseException(SMInputCursor cursor) throws XMLStreamException { while (exceptionChild.readerAccessible()) { - switch (OWS.findKey(exceptionChild.getLocalName())) { - case EXCEPTION_TEXT: - metadataConsumer.analyzeFailed(exceptionCode, exceptionChild.collectDescendantText()); - break; + if (OWS.findKey(exceptionChild.getLocalName()) == OWS.VOCABULARY.EXCEPTION_TEXT) { + metadataConsumer.analyzeFailed(exceptionCode, exceptionChild.collectDescendantText()); } exceptionChild = exceptionChild.advance(); @@ -204,6 +205,8 @@ private void parseServiceIdentification(SMInputCursor cursor) throws XMLStreamEx case SERVICE_TYPE_VERSION: metadataConsumer.analyzeVersion(serviceIdentificationChild.collectDescendantText()); break; + default: + break; } serviceIdentificationChild = serviceIdentificationChild.advance(); @@ -247,6 +250,8 @@ private void parseServiceProvider(SMInputCursor cursor) throws XMLStreamExceptio case SERVICE_CONTACT: parseServiceContact(serviceProviderChild); break; + default: + break; } serviceProviderChild = serviceProviderChild.advance(); @@ -277,6 +282,8 @@ private void parseServiceContact(SMInputCursor cursor) throws XMLStreamException case ROLE: metadataConsumer.analyzeServiceContactRole(serviceContactChild.collectDescendantText()); break; + default: + break; } serviceContactChild = serviceContactChild.advance(); @@ -308,6 +315,8 @@ private void parseContactInfo(SMInputCursor cursor) throws XMLStreamException { metadataConsumer.analyzeServiceContactInstructions( contactInfoChild.collectDescendantText()); break; + default: + break; } contactInfoChild = contactInfoChild.advance(); @@ -319,13 +328,11 @@ private void parsePhone(SMInputCursor cursor) throws XMLStreamException { while (phoneChild.readerAccessible()) { - switch (OWS.findKey(phoneChild.getLocalName())) { - case VOICE: - metadataConsumer.analyzeServiceContactPhone(phoneChild.collectDescendantText()); - break; - case FACSIMILE: - metadataConsumer.analyzeServiceContactFacsimile(phoneChild.collectDescendantText()); - break; + OWS.VOCABULARY phoneKey = OWS.findKey(phoneChild.getLocalName()); + if (phoneKey == OWS.VOCABULARY.VOICE) { + metadataConsumer.analyzeServiceContactPhone(phoneChild.collectDescendantText()); + } else if (phoneKey == OWS.VOCABULARY.FACSIMILE) { + metadataConsumer.analyzeServiceContactFacsimile(phoneChild.collectDescendantText()); } phoneChild = phoneChild.advance(); @@ -357,6 +364,8 @@ private void parseAddress(SMInputCursor cursor) throws XMLStreamException { case EMAIL: metadataConsumer.analyzeServiceContactEmail(addressChild.collectDescendantText()); break; + default: + break; } addressChild = addressChild.advance(); @@ -382,6 +391,8 @@ private void parseOperationsMetadata(SMInputCursor cursor) throws XMLStreamExcep case EXTENDED_CAPABILITIES: parseExtendedCapabilities(operationsMetadataChild); break; + default: + break; } operationsMetadataChild = operationsMetadataChild.advance(); @@ -398,14 +409,14 @@ private void parseOperation(SMInputCursor cursor) throws XMLStreamException { } if (wfsOperation == OWS.OPERATION.NONE) { - cursor = cursor.childElementCursor().advance(); + SMInputCursor childCursor = cursor.childElementCursor().advance(); - while (cursor.readerAccessible()) { - if (OWS.OPERATION.fromString(cursor.getLocalName()) != OWS.OPERATION.NONE) { - parseOperation(cursor); + while (childCursor.readerAccessible()) { + if (OWS.OPERATION.fromString(childCursor.getLocalName()) != OWS.OPERATION.NONE) { + parseOperation(childCursor); } - cursor = cursor.advance(); + childCursor = childCursor.advance(); } return; @@ -419,23 +430,7 @@ private void parseOperation(SMInputCursor cursor) throws XMLStreamException { switch (OWS.findKey(operationChild.getLocalName())) { case DCP: - SMInputCursor dcpChild = operationChild.descendantElementCursor().advance(); - - while (dcpChild.readerAccessible()) { - if (dcpChild.getCurrEvent() == SMEvent.START_ELEMENT) { - switch (OWS.findKey(dcpChild.getLocalName())) { - case GET: - metadataConsumer.analyzeOperationGetUrl( - wfsOperation.toString(), parseUrl(dcpChild)); - break; - case POST: - metadataConsumer.analyzeOperationPostUrl( - wfsOperation.toString(), parseUrl(dcpChild)); - break; - } - } - dcpChild = dcpChild.advance(); - } + parseDcp(wfsOperation, operationChild); break; case PARAMETER: parseParameterOrConstraint(wfsOperation, false, operationChild); @@ -452,6 +447,8 @@ private void parseOperation(SMInputCursor cursor) throws XMLStreamException { operationChild.getAttrValue( XLINK.getNS(XLINK.VERSION.DEFAULT), XLINK.getWord(XLINK.VOCABULARY.HREF))); break; + default: + break; } operationChild = operationChild.advance(); @@ -459,6 +456,23 @@ private void parseOperation(SMInputCursor cursor) throws XMLStreamException { } } + private void parseDcp(OWS.OPERATION wfsOperation, SMInputCursor operationChild) + throws XMLStreamException { + SMInputCursor dcpChild = operationChild.descendantElementCursor().advance(); + + while (dcpChild.readerAccessible()) { + if (dcpChild.getCurrEvent() == SMEvent.START_ELEMENT) { + OWS.VOCABULARY dcpKey = OWS.findKey(dcpChild.getLocalName()); + if (dcpKey == OWS.VOCABULARY.GET) { + metadataConsumer.analyzeOperationGetUrl(wfsOperation.toString(), parseUrl(dcpChild)); + } else if (dcpKey == OWS.VOCABULARY.POST) { + metadataConsumer.analyzeOperationPostUrl(wfsOperation.toString(), parseUrl(dcpChild)); + } + } + dcpChild = dcpChild.advance(); + } + } + private String parseUrl(SMInputCursor cursor) throws XMLStreamException { String url = cursor.getAttrValue( @@ -469,6 +483,7 @@ private String parseUrl(SMInputCursor cursor) throws XMLStreamException { return url; } + @SuppressWarnings("PMD.CognitiveComplexity") private void parseParameterOrConstraint( OWS.OPERATION operation, boolean isConstraint, SMInputCursor cursor) throws XMLStreamException { @@ -482,21 +497,19 @@ private void parseParameterOrConstraint( while (parameterChild.readerAccessible()) { if (parameterChild.getCurrEvent() == SMEvent.START_ELEMENT) { - switch (OWS.findKey(parameterChild.getLocalName())) { - case VALUE: - case DEFAULT_VALUE: - if (isConstraint) { - metadataConsumer.analyzeOperationConstraint( - operation.toString(), - parameterName.toString(), - parameterChild.collectDescendantText()); - } else { - metadataConsumer.analyzeOperationParameter( - operation.toString(), - parameterName.toString(), - parameterChild.collectDescendantText()); - } - break; + OWS.VOCABULARY paramKey = OWS.findKey(parameterChild.getLocalName()); + if (paramKey == OWS.VOCABULARY.VALUE || paramKey == OWS.VOCABULARY.DEFAULT_VALUE) { + if (isConstraint) { + metadataConsumer.analyzeOperationConstraint( + operation.toString(), + parameterName.toString(), + parameterChild.collectDescendantText()); + } else { + metadataConsumer.analyzeOperationParameter( + operation.toString(), + parameterName.toString(), + parameterChild.collectDescendantText()); + } } } @@ -531,38 +544,42 @@ private void parseExtendedCapabilities(SMInputCursor cursor) throws XMLStreamExc while (extendedCapabilitiesChild.readerAccessible()) { - switch (OWS.findKey(extendedCapabilitiesChild.getLocalName())) { - case EXTENDED_CAPABILITIES: - SMInputCursor extendedCapabilitiesChild2 = - extendedCapabilitiesChild.childElementCursor().advance(); + if (OWS.findKey(extendedCapabilitiesChild.getLocalName()) + == OWS.VOCABULARY.EXTENDED_CAPABILITIES) { + parseExtendedCapabilitiesInner(extendedCapabilitiesChild); + } - while (extendedCapabilitiesChild2.readerAccessible()) { + extendedCapabilitiesChild = extendedCapabilitiesChild.advance(); + } + } - switch (OWS.findKey(extendedCapabilitiesChild2.getLocalName())) { - case INSPIRE_METADATA_URL: - SMInputCursor inspireMetadataChild = - extendedCapabilitiesChild2.childElementCursor().advance(); + private void parseExtendedCapabilitiesInner(SMInputCursor extendedCapabilitiesChild) + throws XMLStreamException { + SMInputCursor extendedCapabilitiesChild2 = + extendedCapabilitiesChild.childElementCursor().advance(); - while (inspireMetadataChild.readerAccessible()) { + while (extendedCapabilitiesChild2.readerAccessible()) { - switch (OWS.findKey(inspireMetadataChild.getLocalName())) { - case INSPIRE_URL: - metadataConsumer.analyzeInspireMetadataUrl( - inspireMetadataChild.collectDescendantText()); - break; - } + if (OWS.findKey(extendedCapabilitiesChild2.getLocalName()) + == OWS.VOCABULARY.INSPIRE_METADATA_URL) { + parseInspireMetadataUrl(extendedCapabilitiesChild2); + } - inspireMetadataChild = inspireMetadataChild.advance(); - } - break; - } + extendedCapabilitiesChild2 = extendedCapabilitiesChild2.advance(); + } + } - extendedCapabilitiesChild2 = extendedCapabilitiesChild2.advance(); - } - break; + private void parseInspireMetadataUrl(SMInputCursor extendedCapabilitiesChild2) + throws XMLStreamException { + SMInputCursor inspireMetadataChild = extendedCapabilitiesChild2.childElementCursor().advance(); + + while (inspireMetadataChild.readerAccessible()) { + + if (OWS.findKey(inspireMetadataChild.getLocalName()) == OWS.VOCABULARY.INSPIRE_URL) { + metadataConsumer.analyzeInspireMetadataUrl(inspireMetadataChild.collectDescendantText()); } - extendedCapabilitiesChild = extendedCapabilitiesChild.advance(); + inspireMetadataChild = inspireMetadataChild.advance(); } } @@ -571,10 +588,8 @@ private void parseFeatureTypeList(SMInputCursor cursor) throws XMLStreamExceptio while (featureTypeListChild.readerAccessible()) { - switch (OWS.findKey(featureTypeListChild.getLocalName())) { - case FEATURE_TYPE: - parseFeatureType(featureTypeListChild); - break; + if (OWS.findKey(featureTypeListChild.getLocalName()) == OWS.VOCABULARY.FEATURE_TYPE) { + parseFeatureType(featureTypeListChild); } featureTypeListChild = featureTypeListChild.advance(); @@ -622,6 +637,8 @@ private void parseFeatureType(SMInputCursor cursor) throws XMLStreamException { case METADATA_URL: parseMetadataUrl(featureTypeName, featureTypeChild); break; + default: + break; } featureTypeChild = featureTypeChild.advance(); @@ -645,13 +662,11 @@ private void parseBoundingBox(String featureTypeName, SMInputCursor cursor) while (bboxChild.readerAccessible()) { - switch (OWS.findKey(bboxChild.getLocalName())) { - case LOWER_CORNER: - lowerCorner = bboxChild.getElemStringValue().trim().split(" "); - break; - case UPPER_CORNER: - upperCorner = bboxChild.getElemStringValue().trim().split(" "); - break; + OWS.VOCABULARY bboxKey = OWS.findKey(bboxChild.getLocalName()); + if (bboxKey == OWS.VOCABULARY.LOWER_CORNER) { + lowerCorner = bboxChild.getElemStringValue().trim().split(" "); + } else if (bboxKey == OWS.VOCABULARY.UPPER_CORNER) { + upperCorner = bboxChild.getElemStringValue().trim().split(" "); } bboxChild = bboxChild.advance(); @@ -668,7 +683,8 @@ private void parseBoundingBox(String featureTypeName, SMInputCursor cursor) } } - metadataConsumer.analyzeFeatureTypeBoundingBox(featureTypeName, xmin, ymin, xmax, ymax); + metadataConsumer.analyzeFeatureTypeBoundingBox( + featureTypeName, new BoundingBoxStrings(xmin, ymin, xmax, ymax)); } private void parseMetadataUrl(String featureTypeName, SMInputCursor cursor) diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsCapabilitiesAnalyzer.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsCapabilitiesAnalyzer.java index 1a97a1132..061d5359e 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsCapabilitiesAnalyzer.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsCapabilitiesAnalyzer.java @@ -11,13 +11,16 @@ import de.ii.xtraplatform.crs.domain.BoundingBox; import de.ii.xtraplatform.crs.domain.OgcCrs; import de.ii.xtraplatform.features.domain.AbstractFeatureProviderMetadataConsumer; +import de.ii.xtraplatform.features.domain.BoundingBoxStrings; import de.ii.xtraplatform.features.domain.ImmutableMetadata; import de.ii.xtraplatform.features.domain.Metadata; import de.ii.xtraplatform.features.gml.domain.XMLNamespaceNormalizer; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import java.util.Objects; +@SuppressWarnings("PMD.TooManyMethods") public class WfsCapabilitiesAnalyzer extends AbstractFeatureProviderMetadataConsumer { private final XMLNamespaceNormalizer namespaceNormalizer; @@ -26,6 +29,7 @@ public class WfsCapabilitiesAnalyzer extends AbstractFeatureProviderMetadataCons private String lastVersion; public WfsCapabilitiesAnalyzer() { + super(); this.namespaceNormalizer = new XMLNamespaceNormalizer(); this.metadata = new ImmutableMetadata.Builder(); this.usedShortNames = new ArrayList<>(); @@ -62,14 +66,13 @@ public void analyzeFeatureTypeDefaultCrs(String featureTypeName, String crs) { } @Override - public void analyzeFeatureTypeBoundingBox( - String featureTypeName, String xmin, String ymin, String xmax, String ymax) { + public void analyzeFeatureTypeBoundingBox(String featureTypeName, BoundingBoxStrings bbox) { BoundingBox boundingBox = BoundingBox.of( - Double.parseDouble(xmin), - Double.parseDouble(ymin), - Double.parseDouble(xmax), - Double.parseDouble(ymax), + Double.parseDouble(bbox.getXmin()), + Double.parseDouble(bbox.getYmin()), + Double.parseDouble(bbox.getXmax()), + Double.parseDouble(bbox.getYmax()), OgcCrs.CRS84); metadata.putFeatureTypesBoundingBox( @@ -109,8 +112,7 @@ public void analyzeFees(String fees) { @Override public void analyzeAccessConstraints(String accessConstraints) { - if (!Strings.isNullOrEmpty(accessConstraints) - && !Objects.equals(accessConstraints.toLowerCase(), "none")) { + if (!Strings.isNullOrEmpty(accessConstraints) && !"none".equalsIgnoreCase(accessConstraints)) { metadata.accessConstraints(accessConstraints); } } @@ -141,16 +143,17 @@ public void analyzeServiceContactOnlineResource(String onlineResource) { public static String getShortFeatureTypeId( String prefixedName, XMLNamespaceNormalizer namespaceNormalizer) { - return namespaceNormalizer.getLocalName(prefixedName).toLowerCase(); + return namespaceNormalizer.getLocalName(prefixedName).toLowerCase(Locale.ROOT); } public static String getLongFeatureTypeId( String prefixedName, XMLNamespaceNormalizer namespaceNormalizer) { - if (!prefixedName.contains(":")) + if (!prefixedName.contains(":")) { return getShortFeatureTypeId(prefixedName, namespaceNormalizer); + } return String.format( "%s_%s", - namespaceNormalizer.extractPrefix(prefixedName).toLowerCase(), - namespaceNormalizer.getLocalName(prefixedName).toLowerCase()); + namespaceNormalizer.extractPrefix(prefixedName).toLowerCase(Locale.ROOT), + namespaceNormalizer.getLocalName(prefixedName).toLowerCase(Locale.ROOT)); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsClientBasicFactoryDefault.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsClientBasicFactoryDefault.java index 727abdfb7..0a6d80cef 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsClientBasicFactoryDefault.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsClientBasicFactoryDefault.java @@ -48,7 +48,7 @@ public WfsClientBasic create( @Override public void dispose(WfsClientBasic wfsClient) { if (wfsClient instanceof WfsConnector) { - connectorFactory.disposeConnector(((WfsConnector) wfsClient)); + connectorFactory.disposeConnector((WfsConnector) wfsClient); } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsConnectorHttp.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsConnectorHttp.java index 78049c645..cd19d689f 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsConnectorHttp.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsConnectorHttp.java @@ -28,16 +28,16 @@ import de.ii.xtraplatform.streams.domain.Reactive; import de.ii.xtraplatform.web.domain.Http; import de.ii.xtraplatform.web.domain.HttpClient; +import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Optional; import org.apache.hc.core5.net.URIBuilder; import org.codehaus.staxmate.SMInputFactory; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * @author zahnen @@ -46,18 +46,17 @@ public class WfsConnectorHttp extends AbstractVolatile implements WfsConnector { public static final String CONNECTOR_TYPE = "HTTP"; - private static final Logger LOGGER = LoggerFactory.getLogger(WfsConnectorHttp.class); - private static final SMInputFactory staxFactory = new SMInputFactory(new InputFactoryImpl()); + private static final SMInputFactory STAX_FACTORY = new SMInputFactory(new InputFactoryImpl()); private final HttpClient httpClient; private final WfsRequestEncoder wfsRequestEncoder; - private final boolean useHttpPost; private final Optional metadata; private Optional connectionError; private final String providerId; private final ConnectionInfoWfsHttp connectionInfo; @AssistedInject + @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") WfsConnectorHttp( Http http, VolatileRegistry volatileRegistry, @@ -65,7 +64,6 @@ public class WfsConnectorHttp extends AbstractVolatile implements WfsConnector { @Assisted ConnectionInfoWfsHttp connectionInfo) { // TODO super(volatileRegistry); - this.useHttpPost = connectionInfo.getMethod() == ConnectionInfoWfsHttp.METHOD.POST; Map> urls = ImmutableMap.of( @@ -110,7 +108,6 @@ public class WfsConnectorHttp extends AbstractVolatile implements WfsConnector { super(null); httpClient = null; wfsRequestEncoder = null; - useHttpPost = false; metadata = Optional.empty(); providerId = null; connectionInfo = null; @@ -122,7 +119,7 @@ public static URI parseAndCleanWfsUrl(URI inUri) { if (inUri.getQuery() != null && !inUri.getQuery().isEmpty()) { for (String inParam : inUri.getQuery().split("&")) { String[] param = inParam.split("="); - if (!WFS.hasKVPKey(param[0].toUpperCase())) { + if (!WFS.hasKVPKey(param[0].toUpperCase(Locale.ROOT))) { outUri.addParameter(param[0], param[1]); } } @@ -150,17 +147,16 @@ public void start() { public void stop() {} private Optional crawlMetadata() { - try { - InputStream inputStream = runWfsOperation(new GetCapabilities()); + try (InputStream inputStream = runWfsOperation(new GetCapabilities())) { WfsCapabilitiesAnalyzer metadataConsumer = new WfsCapabilitiesAnalyzer(); WFSCapabilitiesParser gmlSchemaParser = - new WFSCapabilitiesParser(metadataConsumer, staxFactory); + new WFSCapabilitiesParser(metadataConsumer, STAX_FACTORY); gmlSchemaParser.parse(inputStream); this.connectionError = Optional.empty(); return Optional.of(metadataConsumer.getMetadata()); - } catch (Throwable e) { + } catch (IOException | RuntimeException e) { this.connectionError = Optional.of(e); } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaAnalyzer.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaAnalyzer.java index f436ffd3e..5062d5863 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaAnalyzer.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaAnalyzer.java @@ -26,6 +26,7 @@ import java.util.Set; import javax.xml.namespace.QName; +@SuppressWarnings("PMD.GodClass") class WfsSchemaAnalyzer implements FeatureProviderSchemaConsumer { public static final String GML_NS_URI = GML.getNS(GML.VERSION._2_1_1); @@ -80,7 +81,6 @@ public void analyzeNamespace(String uri) { @Override public void analyzeFeatureType(String nsUri, String localName) { - String currentPrefixedName = namespaceNormalizer.getQualifiedName(nsUri, localName); QName currentQualifiedName = namespaceNormalizer.getQName(nsUri, localName); mappedPaths.clear(); @@ -92,6 +92,7 @@ public void analyzeFeatureType(String nsUri, String localName) { return; } + String currentPrefixedName = namespaceNormalizer.getQualifiedName(nsUri, localName); String currentLocalName = typeIds.get(currentQualifiedName); this.skip = false; @@ -99,6 +100,7 @@ public void analyzeFeatureType(String nsUri, String localName) { } @Override + @SuppressWarnings("PMD.CyclomaticComplexity") public void analyzeAttribute( String nsUri, String localName, String type, boolean required, int depth) { // only first level gml:ids @@ -110,8 +112,7 @@ public void analyzeAttribute( namespaceNormalizer.getNamespacePrefix(nsUri), "@" + localName, depth + 1, false); if (depth == 0 - && ((localName.equals("id") && nsUri.startsWith(GML_NS_URI)) || localName.equals("fid"))) { - String path = currentPath.toString(); + && ("id".equals(localName) && nsUri.startsWith(GML_NS_URI) || "fid".equals(localName))) { // if (!isPathMapped(path)) { mappingBuilder.addValue( "id", currentPath.asList(), FeatureSchema.Type.STRING, FeatureSchema.Role.ID); @@ -128,6 +129,7 @@ public void analyzeAttribute( } @Override + @SuppressWarnings("PMD.CyclomaticComplexity") public void analyzeProperty( String nsUri, String localName, @@ -142,15 +144,14 @@ public void analyzeProperty( String path = currentPath.toString(); // skip first level gml properties - if ((nsUri.startsWith(GML_NS_URI) + if (nsUri.startsWith(GML_NS_URI) && (path.startsWith(namespaceNormalizer.getNamespacePrefix(nsUri) + ":") - || mappingBuilder.getPrev().filter(FeatureSchema::isSpatial).isPresent())) + || mappingBuilder.getPrev().filter(FeatureSchema::isSpatial).isPresent()) || skip) { return; } boolean isMultiple = maxOccurs > 1 || maxOccurs == -1; - boolean isRequired = minOccurs > 0; // if (!isPathMapped(path)) { Optional propertyType = @@ -162,7 +163,7 @@ public void analyzeProperty( if (propertyType.isPresent()) { String fieldNameGml = currentPath.toFieldNameGml(); - if (fieldNameGml.equals("id")) { + if ("id".equals(fieldNameGml)) { fieldNameGml = "_id_"; } @@ -203,7 +204,7 @@ private Optional getPropertyType( boolean isObject, int pathLength) { boolean isObj = - ((isComplex || isObject) && pathLength % 2 == 0) || Objects.equals(type, "ReferenceType"); + (isComplex || isObject) && pathLength % 2 == 0 || Objects.equals(type, "ReferenceType"); if ((isMultiple || isParentMultiple) && isObj) { return Optional.of(FeatureSchema.Type.OBJECT_ARRAY); @@ -246,6 +247,7 @@ public void analyzeSuccess() { }*/ } + @SuppressWarnings("PMD.CyclomaticComplexity") private FeatureSchema.Type getFeatureSchemaType(GmlType dataType) { switch (dataType) { case BOOLEAN: @@ -276,7 +278,7 @@ private boolean isPathMapped(String path) { return false; } - String parent = path.substring(0, path.lastIndexOf("/")); + String parent = path.substring(0, path.lastIndexOf('/')); for (String mappedPath : mappedPaths) { if (parent.equals(mappedPath)) { return true; diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaCrawler.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaCrawler.java index 1506d8701..83e9e7aa4 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaCrawler.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/WfsSchemaCrawler.java @@ -19,7 +19,6 @@ import de.ii.xtraplatform.features.gml.infra.req.DescribeFeatureType; import java.io.InputStream; import java.net.URI; -import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -28,13 +27,10 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import javax.xml.namespace.QName; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class WfsSchemaCrawler { - private static final Logger LOGGER = LoggerFactory.getLogger(WfsSchemaCrawler.class); - private WfsClientBasic wfsClient; + private final WfsClientBasic wfsClient; private final ConnectionInfoWfsHttp connectionInfo; public WfsSchemaCrawler(WfsClientBasic wfsClient, ConnectionInfoWfsHttp connectionInfo) { @@ -116,23 +112,21 @@ private void analyzeFeatureTypesWithDescribeFeatureType( Consumer>> tracker) { URI baseUri = connectionInfo.getUri(); - InputStream inputStream = wfsClient.runWfsOperation(new DescribeFeatureType()); - - GMLSchemaParser gmlSchemaParser = - new GMLSchemaParser(ImmutableList.of(schemaConsumer), baseUri, namespaces); - gmlSchemaParser.parse(inputStream, featureTypesByNamespace, tracker); + try (InputStream inputStream = wfsClient.runWfsOperation(new DescribeFeatureType())) { + GMLSchemaParser gmlSchemaParser = + new GMLSchemaParser(ImmutableList.of(schemaConsumer), baseUri, namespaces); + gmlSchemaParser.parse(inputStream, featureTypesByNamespace, tracker); + } catch (java.io.IOException e) { + throw new IllegalStateException("Error reading DescribeFeatureType response", e); + } } private Map> getSupportedFeatureTypesPerNamespace(List featureTypes) { - Map> featureTypesPerNamespace = new LinkedHashMap<>(); - - for (QName featureType : featureTypes) { - if (!featureTypesPerNamespace.containsKey(featureType.getNamespaceURI())) { - featureTypesPerNamespace.put(featureType.getNamespaceURI(), new ArrayList<>()); - } - featureTypesPerNamespace.get(featureType.getNamespaceURI()).add(featureType.getLocalPart()); - } - - return featureTypesPerNamespace; + return featureTypes.stream() + .collect( + Collectors.groupingBy( + QName::getNamespaceURI, + LinkedHashMap::new, + Collectors.mapping(QName::getLocalPart, Collectors.toList()))); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesAnd.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesAnd.java index 9ea0a2412..7831b6abe 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesAnd.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesAnd.java @@ -20,13 +20,14 @@ public class FesAnd extends FesExpression { private final List operands; public FesAnd(List operands) { + super(); this.operands = operands; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { if (operands.size() == 1) { - operands.get(0).toXML(version, e, doc); + operands.get(0).appendXml(version, e, doc); } else if (operands.size() > 1) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = @@ -34,7 +35,7 @@ public void toXML(FES.VERSION version, Element e, XMLDocument doc) { e.appendChild(ex); for (FesExpression expr : operands) { - expr.toXML(version, ex, doc); + expr.appendXml(version, ex, doc); } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesBBox.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesBBox.java index fca362730..c44b7876a 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesBBox.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesBBox.java @@ -14,6 +14,7 @@ import de.ii.xtraplatform.features.gml.infra.req.FES.VERSION; import de.ii.xtraplatform.features.gml.infra.req.GML; import de.ii.xtraplatform.features.gml.infra.xml.XMLDocument; +import java.util.Locale; import java.util.Map; import org.w3c.dom.Element; @@ -23,12 +24,13 @@ public class FesBBox extends FesExpression { private final String geometryPath; public FesBBox(BoundingBox env, String geometryPath) { + super(); this.geometryPath = geometryPath; this.env = env; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { // LOGGER.debug("BBOX {} {}", FES.getNS(version), FES.getQN(version, FES.VOCABULARY.BBOX)); doc.addNamespace(FES.getNS(version), FES.getPR(version)); @@ -92,6 +94,7 @@ public Map toKVP(VERSION version, XMLNamespaceNormalizer nsStore String bbox = min + "," + max; bbox += "," + env.getEpsgCrs().toSimpleString(); - return ImmutableMap.of(FES.getWord(version, FES.VOCABULARY.BBOX).toUpperCase(), bbox); + return ImmutableMap.of( + FES.getWord(version, FES.VOCABULARY.BBOX).toUpperCase(Locale.ROOT), bbox); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesDuring.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesDuring.java index 5bd94b189..7435733a3 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesDuring.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesDuring.java @@ -18,16 +18,17 @@ public class FesDuring extends FesExpression { private final FesTemporalLiteral right; public FesDuring(FesValueReference left, FesTemporalLiteral right) { + super(); this.left = left; this.right = right; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, VOCABULARY.DURING)); e.appendChild(ex); - left.toXML(version, ex, doc); - right.toXML(version, ex, doc); + left.appendXml(version, ex, doc); + right.appendXml(version, ex, doc); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesEnvelope.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesEnvelope.java index e7b3a5804..05ec69ec3 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesEnvelope.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesEnvelope.java @@ -17,6 +17,7 @@ public class FesEnvelope extends FesExpression { private final BoundingBox boundingBox; public FesEnvelope(BoundingBox boundingBox) { + super(); this.boundingBox = boundingBox; } @@ -25,5 +26,5 @@ public BoundingBox getBoundingBox() { } @Override - public void toXML(VERSION version, Element e, XMLDocument doc) {} + public void appendXml(VERSION version, Element e, XMLDocument doc) {} } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesExpression.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesExpression.java index 441fa295e..369341618 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesExpression.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesExpression.java @@ -16,7 +16,7 @@ public abstract class FesExpression { - public abstract void toXML(FES.VERSION version, Element e, XMLDocument doc); + public abstract void appendXml(FES.VERSION version, Element e, XMLDocument doc); public Map toKVP(FES.VERSION version, XMLNamespaceNormalizer nsStore) { return ImmutableMap.of(); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesFilter.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesFilter.java index 83a685d62..2eaa63ac1 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesFilter.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesFilter.java @@ -27,11 +27,12 @@ public class FesFilter extends FesExpression { private final List expressions; public FesFilter(List expressions) { + super(); this.expressions = expressions; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { if (expressions.isEmpty()) { return; @@ -43,7 +44,7 @@ public void toXML(FES.VERSION version, Element e, XMLDocument doc) { doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.FILTER)); for (FesExpression expr : expressions) { - expr.toXML(version, ex, doc); + expr.appendXml(version, ex, doc); } if (ex.getChildNodes().getLength() > 0) { @@ -52,6 +53,7 @@ public void toXML(FES.VERSION version, Element e, XMLDocument doc) { } @Override + @SuppressWarnings({"PMD.CognitiveComplexity", "PMD.CyclomaticComplexity"}) public Map toKVP(VERSION version, XMLNamespaceNormalizer nsStore) { // check if the first level expression is BBOX try { @@ -75,41 +77,41 @@ public Map toKVP(VERSION version, XMLNamespaceNormalizer nsStore // ignore } - if (expressions.get(0) != null) { - try { - XMLDocumentFactory documentFactory = new XMLDocumentFactory(nsStore); - XMLDocument doc = documentFactory.newDocument(); - doc.addNamespace(FES.getNS(version), FES.getPR(version)); - Element e = - doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.FILTER)); - doc.appendChild(e); - - expressions.get(0).toXML(version, e, doc); + if (expressions.get(0) == null) { + return ImmutableMap.of(); + } - if (e.hasChildNodes()) { + try { + XMLDocumentFactory documentFactory = new XMLDocumentFactory(nsStore); + XMLDocument doc = documentFactory.newDocument(); + doc.addNamespace(FES.getNS(version), FES.getPR(version)); + Element e = + doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.FILTER)); + doc.appendChild(e); - // attach the namespace(s) for the PropertyName value - for (String uri : nsStore.xgetNamespaceUris()) { - e.setAttribute("xmlns:" + uri + "", nsStore.getNamespaceURI(uri)); - } + expressions.get(0).appendXml(version, e, doc); - String filter = doc.toString(false); - filter = - filter.replace("", ""); + if (!e.hasChildNodes()) { + return ImmutableMap.of(); + } - if (LOGGER.isDebugEnabled()) { - LOGGER.debug("FES filter: {}", filter); - } + // attach the namespace(s) for the PropertyName value + for (String uri : nsStore.xgetNamespaceUris()) { + e.setAttribute("xmlns:" + uri, nsStore.getNamespaceURI(uri)); + } - filter = "(" + filter + ")"; + String filter = doc.toString(false); + filter = filter.replace("", ""); - return ImmutableMap.of("FILTER", filter); - } - } catch (ParserConfigurationException e) { - throw new IllegalStateException(e); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("FES filter: {}", filter); } - } - return ImmutableMap.of(); + filter = "(" + filter + ")"; + + return ImmutableMap.of("FILTER", filter); + } catch (ParserConfigurationException e) { + throw new IllegalStateException(e); + } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesLiteral.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesLiteral.java index 920a072a2..2c0978e16 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesLiteral.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesLiteral.java @@ -17,6 +17,7 @@ public class FesLiteral extends FesExpression { protected final String value; public FesLiteral(String value) { + super(); this.value = value; } @@ -25,7 +26,7 @@ public String getValue() { } @Override - public void toXML(VERSION version, Element e, XMLDocument doc) { + public void appendXml(VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.LITERAL)); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesNot.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesNot.java index 4d15b30f4..2c63d9e9a 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesNot.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesNot.java @@ -17,17 +17,18 @@ public class FesNot extends FesExpression { private final List operands; public FesNot(List operands) { + super(); this.operands = operands; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.NOT)); e.appendChild(ex); for (FesExpression expr : operands) { - expr.toXML(version, ex, doc); + expr.appendXml(version, ex, doc); } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesOr.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesOr.java index d30d6452d..bb8246a98 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesOr.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesOr.java @@ -17,20 +17,21 @@ public class FesOr extends FesExpression { private final List operands; public FesOr(List operands) { + super(); this.operands = operands; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { if (operands.size() == 1) { - operands.get(0).toXML(version, e, doc); + operands.get(0).appendXml(version, e, doc); } else if (operands.size() > 1) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.OR)); e.appendChild(ex); for (FesExpression expr : operands) { - expr.toXML(version, ex, doc); + expr.appendXml(version, ex, doc); } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPolygonExpression.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPolygonExpression.java index d89609ce0..3a06188b1 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPolygonExpression.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPolygonExpression.java @@ -11,21 +11,22 @@ import de.ii.xtraplatform.features.gml.infra.req.GML; import de.ii.xtraplatform.features.gml.infra.xml.XMLDocument; import java.util.List; -import java.util.Map; import org.w3c.dom.Element; public class FesPolygonExpression extends FesExpression { - private Polygon poly; - private String geometryPath; + private final Polygon poly; + private final String geometryPath; public FesPolygonExpression(Polygon env, String geometryPath) { + super(); this.geometryPath = geometryPath; this.poly = env; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element intersects = @@ -78,7 +79,7 @@ public void toXML(FES.VERSION version, Element e, XMLDocument doc) { for (List ring : rings) { for (Double d : ring) { c.append(d); - c.append(" "); + c.append(' '); } } @@ -89,18 +90,4 @@ public void toXML(FES.VERSION version, Element e, XMLDocument doc) { poslist.setTextContent(c.toString()); } } - - public void toKVP(FES.VERSION version, Map params) { - - /* - String min = env.getXmin() + "," + env.getYmin(); - String max = env.getXmax() + "," + env.getYmax(); - String bbox = min+","+max; - - if( !env.getSpatialReference().getWkidString().equals("4326")) { - bbox += ","+env.getSpatialReference().getEPSGCode(); - } - params.put(FES.getWord(version, FES.VOCABULARY.BBOX).toUpperCase(), bbox); - */ - } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsEqualTo.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsEqualTo.java index 546bd9556..81198377c 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsEqualTo.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsEqualTo.java @@ -17,17 +17,18 @@ public class FesPropertyIsEqualTo extends FesExpression { private final FesLiteral right; public FesPropertyIsEqualTo(FesLiteral left, FesLiteral right) { + super(); this.left = left; this.right = right; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.EQUAL)); e.appendChild(ex); - left.toXML(version, ex, doc); - right.toXML(version, ex, doc); + left.appendXml(version, ex, doc); + right.appendXml(version, ex, doc); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsGreaterThan.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsGreaterThan.java index 489e53823..260ecbe4e 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsGreaterThan.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsGreaterThan.java @@ -17,17 +17,18 @@ public class FesPropertyIsGreaterThan extends FesExpression { private final FesLiteral right; public FesPropertyIsGreaterThan(FesLiteral left, FesLiteral right) { + super(); this.left = left; this.right = right; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.GREATER)); e.appendChild(ex); - left.toXML(version, ex, doc); - right.toXML(version, ex, doc); + left.appendXml(version, ex, doc); + right.appendXml(version, ex, doc); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLessThan.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLessThan.java index 7398824f6..ff48f64c5 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLessThan.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLessThan.java @@ -17,16 +17,17 @@ public class FesPropertyIsLessThan extends FesExpression { private final FesLiteral right; public FesPropertyIsLessThan(FesLiteral left, FesLiteral right) { + super(); this.left = left; this.right = right; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.LESS)); e.appendChild(ex); - left.toXML(version, ex, doc); - right.toXML(version, ex, doc); + left.appendXml(version, ex, doc); + right.appendXml(version, ex, doc); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLike.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLike.java index e9dd7c568..7acb8c4cd 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLike.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsLike.java @@ -22,6 +22,7 @@ public class FesPropertyIsLike extends FesExpression { private String escapeChar; public FesPropertyIsLike(FesLiteral left, FesLiteral right) { + super(); this.left = replaceWildCard(left); this.right = replaceWildCard(right); @@ -43,7 +44,7 @@ public void setEscapeChar(String escapeChar) { } @Override - public void toXML(VERSION version, Element e, XMLDocument doc) { + public void appendXml(VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.LIKE)); @@ -54,8 +55,8 @@ public void toXML(VERSION version, Element e, XMLDocument doc) { e.appendChild(ex); - left.toXML(version, ex, doc); - right.toXML(version, ex, doc); + left.appendXml(version, ex, doc); + right.appendXml(version, ex, doc); } private static FesLiteral replaceWildCard(FesLiteral literal) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsNull.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsNull.java index 7bf8c03ac..94e7b6f35 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsNull.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesPropertyIsNull.java @@ -16,15 +16,16 @@ public class FesPropertyIsNull extends FesExpression { private final FesLiteral arg; public FesPropertyIsNull(FesLiteral arg) { + super(); this.arg = arg; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.ISNULL)); e.appendChild(ex); - arg.toXML(version, ex, doc); + arg.appendXml(version, ex, doc); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesResourceId.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesResourceId.java index 5a3666cf4..42e78726a 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesResourceId.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesResourceId.java @@ -11,6 +11,7 @@ import de.ii.xtraplatform.features.gml.domain.XMLNamespaceNormalizer; import de.ii.xtraplatform.features.gml.infra.req.FES; import de.ii.xtraplatform.features.gml.infra.xml.XMLDocument; +import java.util.Locale; import java.util.Map; import org.w3c.dom.Element; @@ -19,11 +20,12 @@ public class FesResourceId extends FesExpression { private final String id; public FesResourceId(String id) { + super(); this.id = id; } @Override - public void toXML(FES.VERSION version, Element e, XMLDocument doc) { + public void appendXml(FES.VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS(FES.getNS(version), FES.getWord(version, FES.VOCABULARY.RESOURCEID)); @@ -37,6 +39,7 @@ public void toXML(FES.VERSION version, Element e, XMLDocument doc) { @Override public Map toKVP(FES.VERSION version, XMLNamespaceNormalizer nsStore) { - return ImmutableMap.of(FES.getWord(version, FES.VOCABULARY.RESOURCEID_KVP).toUpperCase(), id); + return ImmutableMap.of( + FES.getWord(version, FES.VOCABULARY.RESOURCEID_KVP).toUpperCase(Locale.ROOT), id); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesTemporalLiteral.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesTemporalLiteral.java index 3c7ba8fac..fe93d3c20 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesTemporalLiteral.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesTemporalLiteral.java @@ -21,13 +21,17 @@ public class FesTemporalLiteral extends FesExpression { protected final String beginPosition; protected final String endPosition; + @SuppressWarnings("PMD.NullAssignment") public FesTemporalLiteral(String position) { + super(); this.position = position; this.beginPosition = null; this.endPosition = null; } + @SuppressWarnings("PMD.NullAssignment") public FesTemporalLiteral(String beginPosition, String endPosition) { + super(); this.position = null; this.beginPosition = beginPosition; this.endPosition = endPosition; @@ -42,7 +46,7 @@ public FesLiteral toInstantLiteral() { } @Override - public void toXML(VERSION version, Element e, XMLDocument doc) { + public void appendXml(VERSION version, Element e, XMLDocument doc) { GML.VERSION gmlVersion = version.getGmlVersion(); doc.addNamespace(FES.getNS(version), FES.getPR(version)); doc.addNamespace(GML.getNS(gmlVersion), GML.getPR(gmlVersion)); diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesValueReference.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesValueReference.java index 3465e2ab6..eefaad9f4 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesValueReference.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/FesValueReference.java @@ -19,7 +19,7 @@ public FesValueReference(String value) { } @Override - public void toXML(VERSION version, Element e, XMLDocument doc) { + public void appendXml(VERSION version, Element e, XMLDocument doc) { doc.addNamespace(FES.getNS(version), FES.getPR(version)); Element ex = doc.createElementNS( diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Geometry.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Geometry.java index e97435ad0..c277f0ce1 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Geometry.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Geometry.java @@ -12,13 +12,14 @@ /** * @author fischer */ +@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") public abstract class Geometry { protected EpsgCrs crs; protected double[] coordinates; public double[] getCoordinates() { - return coordinates; + return coordinates == null ? null : coordinates.clone(); } public EpsgCrs getCrs() { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Polygon.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Polygon.java index 03670a8a3..042ace9c0 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Polygon.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/fes/Polygon.java @@ -17,11 +17,13 @@ public class Polygon extends Geometry { private List>> rings; - public Polygon() {} + public Polygon() { + super(); + } public Polygon(double[] coordinates, EpsgCrs sr) { this(); - this.coordinates = coordinates; + this.coordinates = coordinates.clone(); this.crs = sr; } @@ -41,7 +43,7 @@ public List>> getRings() { return rings; } - private static double[] parseCoordinates(String[] coordinates) { + private static double[] parseCoordinates(String... coordinates) { double[] doubleCoordinates = new double[coordinates.length]; for (int i = 0; i < coordinates.length; i++) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/CSW.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/CSW.java index e4aeff2f6..eb0eb4d50 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/CSW.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/CSW.java @@ -10,12 +10,14 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.Locale; import java.util.Map; import org.apache.hc.core5.net.URIBuilder; /** * @author zahnen */ +@SuppressWarnings("PMD.FieldNamingConventions") public class CSW extends VersionedVocabulary { public enum VERSION { @@ -25,7 +27,7 @@ public enum VERSION { private final String stringRepresentation; private final FES.VERSION filterVersion; - private VERSION(String stringRepresentation, FES.VERSION filterVersion) { + VERSION(String stringRepresentation, FES.VERSION filterVersion) { this.stringRepresentation = stringRepresentation; this.filterVersion = filterVersion; } @@ -81,7 +83,7 @@ public enum OPERATION { NONE(""); private final String stringRepresentation; - private OPERATION(String stringRepresentation) { + OPERATION(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } @@ -105,7 +107,7 @@ public enum METHOD { POST("POST"); private final String stringRepresentation; - private METHOD(String stringRepresentation) { + METHOD(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } @@ -259,7 +261,7 @@ public static String cleanUrl(String url) { if (inUri.getQuery() != null && !inUri.getQuery().isEmpty()) { for (String inParam : inUri.getQuery().split("&")) { String[] param = inParam.split("="); - if (!CSW.hasKVPKey(param[0].toUpperCase())) { + if (!CSW.hasKVPKey(param[0].toUpperCase(Locale.ROOT))) { outUri.addParameter(param[0], param[1]); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/DescribeFeatureType.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/DescribeFeatureType.java index 31dcfc5fb..4db71e707 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/DescribeFeatureType.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/DescribeFeatureType.java @@ -18,8 +18,6 @@ */ public class DescribeFeatureType implements WfsOperation { - public DescribeFeatureType() {} - @Override public WFS.OPERATION getOperation() { return WFS.OPERATION.DESCRIBE_FEATURE_TYPE; diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/FES.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/FES.java index fa04f0a09..4e987e078 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/FES.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/FES.java @@ -10,6 +10,7 @@ /** * @author zahnen */ +@SuppressWarnings("PMD.FieldNamingConventions") public class FES extends VersionedVocabulary { public enum VERSION { @@ -20,7 +21,7 @@ public enum VERSION { private final String stringRepresentation; private final GML.VERSION gmlVersion; - private VERSION(String stringRepresentation, GML.VERSION gmlVersion) { + VERSION(String stringRepresentation, GML.VERSION gmlVersion) { this.stringRepresentation = stringRepresentation; this.gmlVersion = gmlVersion; } @@ -44,19 +45,11 @@ public static VERSION fromString(String version) { } public boolean isGreaterOrEqual(FES.VERSION other) { - if (this.compareTo(other) >= 0) { - return true; - } else { - return false; - } + return this.compareTo(other) >= 0; } public boolean isEqual(FES.VERSION other) { - if (this.compareTo(other) == 0) { - return true; - } else { - return false; - } + return this.compareTo(other) == 0; } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GML.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GML.java index ea6ed71c7..691f6a05c 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GML.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GML.java @@ -10,6 +10,7 @@ /** * @author zahnen */ +@SuppressWarnings("PMD.FieldNamingConventions") public class GML extends VersionedVocabulary { public enum VERSION { @@ -22,7 +23,7 @@ public enum VERSION { private final String stringRepresentation; - private VERSION(String stringRepresentation) { + VERSION(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } @@ -42,15 +43,15 @@ public static VERSION fromString(String version) { public static VERSION fromOutputFormatString(String value) { - value = value.toLowerCase(); + String normalized = value.toLowerCase(java.util.Locale.ROOT); - if (value.contains("gml2")) { + if (normalized.contains("gml2")) { return VERSION._2_1_1; - } else if (value.contains("text/xml") && value.contains("subtype=gml/3.1.1")) { + } else if (normalized.contains("text/xml") && normalized.contains("subtype=gml/3.1.1")) { return VERSION._3_1_1; - } else if (value.contains("text/xml") && value.contains("subtype=gml/3.2.1")) { + } else if (normalized.contains("text/xml") && normalized.contains("subtype=gml/3.2.1")) { return VERSION._3_2_1_OLD; - } else if (value.contains("application/gml+xml") && value.contains("version=3.2")) { + } else if (normalized.contains("application/gml+xml") && normalized.contains("version=3.2")) { return VERSION._3_2_1; } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetCapabilities.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetCapabilities.java index 902975c69..68bb73be4 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetCapabilities.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetCapabilities.java @@ -18,14 +18,15 @@ */ public class GetCapabilities implements WfsOperation { - private final WFS.VERSION m_version; + private final WFS.VERSION version; + @SuppressWarnings("PMD.NullAssignment") public GetCapabilities() { - m_version = null; + this.version = null; } public GetCapabilities(WFS.VERSION version) { - m_version = version; + this.version = version; } @Override @@ -46,8 +47,8 @@ public XMLDocument asXml(XMLDocumentFactory documentFactory, Versions versions) WFS.getNS(versions.getWfsVersion()), getOperationName(versions.getWfsVersion())); doc.appendChild(oper); - if (m_version != null) { - oper.setAttribute(WFS.getWord(m_version, WFS.VOCABULARY.VERSION), m_version.toString()); + if (version != null) { + oper.setAttribute(WFS.getWord(version, WFS.VOCABULARY.VERSION), version.toString()); } oper.setAttribute("service", "WFS"); @@ -62,8 +63,8 @@ public Map asKvp(XMLDocumentFactory documentFactory, Versions ve builder.put("REQUEST", this.getOperation().toString()); builder.put("SERVICE", "WFS"); - if (m_version != null) { - builder.put("VERSION", m_version.toString()); + if (version != null) { + builder.put("VERSION", version.toString()); } else if (versions.getWfsVersion() != null) { builder.put("VERSION", versions.getWfsVersion().toString()); } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeature.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeature.java index e8f85a528..4385d8a5c 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeature.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeature.java @@ -12,11 +12,10 @@ import de.ii.xtraplatform.features.gml.infra.xml.XMLDocumentFactory; import java.io.IOException; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.stream.Collectors; import javax.xml.transform.TransformerException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -24,24 +23,22 @@ * @author zahnen */ public class GetFeature implements WfsOperation { - enum RESULT_TYPE { + enum ResultType { RESULT, HITS } - private static final Logger LOGGER = LoggerFactory.getLogger(GetFeature.class); - private final List query; private final Integer count; private final Integer startIndex; - private final RESULT_TYPE resultType; + private final ResultType resultType; private final Map additionalOperationParameters; public GetFeature( List query, Integer count, Integer startIndex, - RESULT_TYPE resultType, + ResultType resultType, Map additionalOperationParameters) { this.query = query; this.count = count; @@ -78,10 +75,10 @@ public XMLDocument asXml(XMLDocumentFactory documentFactory, Versions versions) String.valueOf(startIndex)); } - if (this.resultType == RESULT_TYPE.HITS) { + if (this.resultType == ResultType.HITS) { operation.setAttribute( WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.RESULT_TYPE), - String.valueOf(RESULT_TYPE.HITS).toLowerCase()); + String.valueOf(ResultType.HITS).toLowerCase(Locale.ROOT)); } if (versions.getGmlVersion() != null && versions.getWfsVersion() != null) { @@ -119,25 +116,26 @@ public Map asKvp(XMLDocumentFactory documentFactory, Versions ve // WFS.VOCABULARY.OUTPUT_FORMAT).toUpperCase(), GML.getWord(versions.getGmlVersion(), // GML.VOCABULARY.OUTPUTFORMAT_VALUE)); builder.put( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.VERSION).toUpperCase(), + WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.VERSION).toUpperCase(Locale.ROOT), versions.getWfsVersion().toString()); if (this.count != null) { builder.put( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.COUNT).toUpperCase(), + WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.COUNT).toUpperCase(Locale.ROOT), String.valueOf(count)); } if (this.startIndex != null && versions.getWfsVersion().isGreaterOrEqual(WFS.VERSION._2_0_0)) { builder.put( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.STARTINDEX).toUpperCase(), + WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.STARTINDEX).toUpperCase(Locale.ROOT), String.valueOf(startIndex)); } - if (this.resultType == RESULT_TYPE.HITS) { + if (this.resultType == ResultType.HITS) { builder.put( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.RESULT_TYPE).toUpperCase(), - String.valueOf(RESULT_TYPE.HITS).toLowerCase()); + WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.RESULT_TYPE) + .toUpperCase(Locale.ROOT), + String.valueOf(ResultType.HITS).toLowerCase(Locale.ROOT)); } if (!additionalOperationParameters.isEmpty()) { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeatureBuilder.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeatureBuilder.java index f67ea87d3..f406b7357 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeatureBuilder.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/GetFeatureBuilder.java @@ -9,7 +9,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import de.ii.xtraplatform.features.gml.infra.req.GetFeature.RESULT_TYPE; +import de.ii.xtraplatform.features.gml.infra.req.GetFeature.ResultType; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -20,7 +20,7 @@ public class GetFeatureBuilder { private Integer count; private Integer startIndex; private boolean hitsOnly; - private Map additionalOperationParameters; + private final Map additionalOperationParameters; public GetFeatureBuilder() { this.queries = new ArrayList<>(); @@ -58,7 +58,7 @@ public GetFeature build() { ImmutableList.copyOf(queries), count, startIndex, - hitsOnly ? RESULT_TYPE.HITS : RESULT_TYPE.RESULT, + hitsOnly ? ResultType.HITS : ResultType.RESULT, ImmutableMap.copyOf(additionalOperationParameters)); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/OWS.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/OWS.java index 46d8b023f..948befa4f 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/OWS.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/OWS.java @@ -12,6 +12,7 @@ /** * @author fischer */ +@SuppressWarnings("PMD.FieldNamingConventions") public class OWS extends VersionedVocabulary { public enum VERSION { @@ -22,8 +23,7 @@ public enum VERSION { private final FES.VERSION filterVersion; private final GML.VERSION gmlVersion; - private VERSION( - String stringRepresentation, FES.VERSION filterVersion, GML.VERSION gmlVersion) { + VERSION(String stringRepresentation, FES.VERSION filterVersion, GML.VERSION gmlVersion) { this.stringRepresentation = stringRepresentation; this.filterVersion = filterVersion; this.gmlVersion = gmlVersion; @@ -69,7 +69,7 @@ public enum OPERATION { NONE(""); private final String stringRepresentation; - private OPERATION(String stringRepresentation) { + OPERATION(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } @@ -93,7 +93,7 @@ public enum METHOD { POST("POST"); private final String stringRepresentation; - private METHOD(String stringRepresentation) { + METHOD(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/VersionedVocabulary.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/VersionedVocabulary.java index 3f74dc985..c1fe79a76 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/VersionedVocabulary.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/VersionedVocabulary.java @@ -13,6 +13,7 @@ /** * @author zahnen */ +@SuppressWarnings({"PMD.UseUtilityClass", "PMD.FieldNamingConventions"}) public class VersionedVocabulary { public enum NAMESPACE { diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/Versions.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/Versions.java index 9ae0eb9d5..f18e32416 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/Versions.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/Versions.java @@ -12,9 +12,10 @@ /** * @author fischer */ +@SuppressWarnings("PMD.DataClass") public class Versions { - GML.VERSION gmlVersion = null; - WFS.VERSION wfsVersion = null; + GML.VERSION gmlVersion; + WFS.VERSION wfsVersion; public Versions() {} diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WFS.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WFS.java index f03f3b598..182071dd7 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WFS.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WFS.java @@ -12,14 +12,20 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.Locale; import java.util.Map; import org.apache.hc.core5.net.URIBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author fischer */ +@SuppressWarnings("PMD.FieldNamingConventions") public class WFS extends VersionedVocabulary { + private static final Logger LOGGER = LoggerFactory.getLogger(WFS.class); + public enum VERSION { _1_0_0("1.0.0", FES.VERSION._1_0_0, GML.VERSION._2_1_1), _1_1_0("1.1.0", FES.VERSION._1_1_0, GML.VERSION._3_1_1), @@ -28,8 +34,7 @@ public enum VERSION { private final FES.VERSION filterVersion; private final GML.VERSION gmlVersion; - private VERSION( - String stringRepresentation, FES.VERSION filterVersion, GML.VERSION gmlVersion) { + VERSION(String stringRepresentation, FES.VERSION filterVersion, GML.VERSION gmlVersion) { this.stringRepresentation = stringRepresentation; this.filterVersion = filterVersion; this.gmlVersion = gmlVersion; @@ -94,7 +99,7 @@ public enum OPERATION { NONE(""); private final String stringRepresentation; - private OPERATION(String stringRepresentation) { + OPERATION(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } @@ -118,7 +123,7 @@ public enum METHOD { POST("POST"); private final String stringRepresentation; - private METHOD(String stringRepresentation) { + METHOD(String stringRepresentation) { this.stringRepresentation = stringRepresentation; } @@ -350,9 +355,12 @@ public static String cleanUrl(String url) { if (inUri.getQuery() != null && !inUri.getQuery().isEmpty()) { for (String inParam : inUri.getQuery().split("&")) { String[] param = inParam.split("="); - if (!WFS.hasKVPKey(param[0].toUpperCase())) { - if (param.length >= 2) outUri.addParameter(param[0], param[1]); - else System.out.println("SINGLE " + param[0]); + if (!WFS.hasKVPKey(param[0].toUpperCase(Locale.ROOT))) { + if (param.length >= 2) { + outUri.addParameter(param[0], param[1]); + } else { + LOGGER.debug("SINGLE {}", param[0]); + } } } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WfsQuery.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WfsQuery.java index 8211541c2..764f29452 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WfsQuery.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/req/WfsQuery.java @@ -14,18 +14,15 @@ import de.ii.xtraplatform.features.gml.infra.xml.XMLDocument; import java.io.IOException; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; import javax.xml.transform.TransformerException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.w3c.dom.Element; import org.xml.sax.SAXException; public class WfsQuery { - private static final Logger LOGGER = LoggerFactory.getLogger(WfsQuery.class); - private final List typeNames; private final Optional filter; private final EpsgCrs crs; @@ -49,16 +46,14 @@ public Element asXml(XMLDocument document, Versions versions) // final Node node = // document.adoptDocument(FILTER_ENCODERS.get(versions.getWfsVersion()).encode(filter.get(0))); // query.appendChild(node); - filter.get().toXML(versions.getWfsVersion().getFilterVersion(), query, document); + filter.get().appendXml(versions.getWfsVersion().getFilterVersion(), query, document); } query.setAttribute( WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.TYPENAMES), getTypeNames()); if (this.crs != null) { - query.setAttribute( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.SRSNAME), - getCrs(versions.getWfsVersion())); + query.setAttribute(WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.SRSNAME), getCrs()); } return query; @@ -69,13 +64,13 @@ public Map asKvp(XMLDocument document, Versions versions) final ImmutableMap.Builder builder = ImmutableMap.builder(); builder.put( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.TYPENAMES).toUpperCase(), + WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.TYPENAMES).toUpperCase(Locale.ROOT), getTypeNames()); - if (getCrs(versions.getWfsVersion()) != null) { + if (getCrs() != null) { builder.put( - WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.SRSNAME).toUpperCase(), - getCrs(versions.getWfsVersion())); + WFS.getWord(versions.getWfsVersion(), WFS.VOCABULARY.SRSNAME).toUpperCase(Locale.ROOT), + getCrs()); } if (filter.isPresent()) { @@ -93,7 +88,7 @@ private String getTypeNames() { return Joiner.on(',').skipNulls().join(typeNames); } - private String getCrs(WFS.VERSION version) { + private String getCrs() { if (this.crs != null) { return crs.toSimpleString(); } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLDocument.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLDocument.java index 644bacc85..67ed17f30 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLDocument.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLDocument.java @@ -69,7 +69,7 @@ public Element createElementNS(String namespace, String localName) { public void done() { for (String uri : nsn.xgetNamespaceUris()) { - this.doc.getDocumentElement().setAttribute("xmlns:" + uri + "", nsn.getNamespaceURI(uri)); + this.doc.getDocumentElement().setAttribute("xmlns:" + uri, nsn.getNamespaceURI(uri)); } } diff --git a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLPathTracker.java b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLPathTracker.java index 15c0edd3e..e83a87859 100644 --- a/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLPathTracker.java +++ b/xtraplatform-features-gml/src/main/java/de/ii/xtraplatform/features/gml/infra/xml/XMLPathTracker.java @@ -8,7 +8,6 @@ package de.ii.xtraplatform.features.gml.infra.xml; import com.google.common.base.Joiner; -import de.ii.xtraplatform.features.gml.domain.XMLNamespaceNormalizer; import java.util.ArrayList; import java.util.List; @@ -16,13 +15,11 @@ * @author zahnen */ public class XMLPathTracker { - private List localPath; - private List path; - private List noObjectPath; - private XMLNamespaceNormalizer nsStore; + private final List localPath; + private final List path; + private final List noObjectPath; private final Joiner joiner; private final Joiner dotJoiner; - private final StringBuilder stringBuilder; private boolean multiple; @@ -33,12 +30,6 @@ public XMLPathTracker() { this.noObjectPath = new ArrayList<>(); this.joiner = Joiner.on('/').skipNulls(); this.dotJoiner = Joiner.on('.').skipNulls(); - this.stringBuilder = new StringBuilder(); - } - - public XMLPathTracker(XMLNamespaceNormalizer nsStore) { - this(); - this.nsStore = nsStore; } public void track(int depth) { @@ -69,7 +60,9 @@ private void shorten(final int depth) { public void track(String nsuri, String localName, boolean isMultiple) { localPath.add(localName); - if (nsuri != null && localName != null) path.add(nsuri + ":" + localName); + if (nsuri != null && localName != null) { + path.add(nsuri + ":" + localName); + } if (localName != null && (!Character.isUpperCase(localName.charAt(0)) || noObjectPath.isEmpty())) { noObjectPath.add(localName + (isMultiple ? "[]" : "")); @@ -96,8 +89,7 @@ public String toFieldNameGml() { @Override public String toString() { - stringBuilder.setLength(0); - return joiner.appendTo(stringBuilder, path).toString(); + return joiner.join(path); } public String toLocalPath() { diff --git a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/AbstractFeatureProviderMetadataConsumer.java b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/AbstractFeatureProviderMetadataConsumer.java index e2223bf8c..7b07dc3a6 100644 --- a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/AbstractFeatureProviderMetadataConsumer.java +++ b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/AbstractFeatureProviderMetadataConsumer.java @@ -127,7 +127,7 @@ public void analyzeFeatureTypeKeywords(String featureTypeName, String... keyword @Override public void analyzeFeatureTypeBoundingBox( - String featureTypeName, String xmin, String ymin, String xmax, String ymax) {} + String featureTypeName, BoundingBoxStrings boundingBox) {} @Override public void analyzeFeatureTypeDefaultCrs(String featureTypeName, String crs) {} diff --git a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/BoundingBoxStrings.java b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/BoundingBoxStrings.java new file mode 100644 index 000000000..d1fbeb996 --- /dev/null +++ b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/BoundingBoxStrings.java @@ -0,0 +1,39 @@ +/* + * Copyright 2026 interactive instruments GmbH + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package de.ii.xtraplatform.features.domain; + +public final class BoundingBoxStrings { + + private final String xmin; + private final String ymin; + private final String xmax; + private final String ymax; + + public BoundingBoxStrings(String xmin, String ymin, String xmax, String ymax) { + this.xmin = xmin; + this.ymin = ymin; + this.xmax = xmax; + this.ymax = ymax; + } + + public String getXmin() { + return xmin; + } + + public String getYmin() { + return ymin; + } + + public String getXmax() { + return xmax; + } + + public String getYmax() { + return ymax; + } +} diff --git a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/FeatureProviderMetadataConsumer.java b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/FeatureProviderMetadataConsumer.java index ee5d40834..7db076627 100644 --- a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/FeatureProviderMetadataConsumer.java +++ b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/FeatureProviderMetadataConsumer.java @@ -88,8 +88,7 @@ public interface FeatureProviderMetadataConsumer { void analyzeFeatureTypeKeywords(String featureTypeName, String... keywords); - void analyzeFeatureTypeBoundingBox( - String featureTypeName, String xmin, String ymin, String xmax, String ymax); + void analyzeFeatureTypeBoundingBox(String featureTypeName, BoundingBoxStrings boundingBox); void analyzeFeatureTypeDefaultCrs(String featureTypeName, String crs); diff --git a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/LoggingFeatureProviderMetadataConsumer.java b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/LoggingFeatureProviderMetadataConsumer.java index 436a498ae..74fe4a9ef 100644 --- a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/LoggingFeatureProviderMetadataConsumer.java +++ b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/LoggingFeatureProviderMetadataConsumer.java @@ -210,9 +210,14 @@ public void analyzeFeatureTypeKeywords(String featureTypeName, String... keyword @Override public void analyzeFeatureTypeBoundingBox( - String featureTypeName, String xmin, String ymin, String xmax, String ymax) { + String featureTypeName, BoundingBoxStrings boundingBox) { LOGGER.debug( - "analyzeFeatureTypeBoundingBox {} {} {} {} {}", featureTypeName, xmin, ymin, xmax, ymax); + "analyzeFeatureTypeBoundingBox {} {} {} {} {}", + featureTypeName, + boundingBox.getXmin(), + boundingBox.getYmin(), + boundingBox.getXmax(), + boundingBox.getYmax()); } @Override diff --git a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/MultiFeatureProviderMetadataConsumer.java b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/MultiFeatureProviderMetadataConsumer.java index 8507f3ad6..62277e302 100644 --- a/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/MultiFeatureProviderMetadataConsumer.java +++ b/xtraplatform-features/src/main/java/de/ii/xtraplatform/features/domain/MultiFeatureProviderMetadataConsumer.java @@ -286,9 +286,9 @@ public void analyzeFeatureTypeKeywords(String featureTypeName, String... keyword @Override public void analyzeFeatureTypeBoundingBox( - String featureTypeName, String xmin, String ymin, String xmax, String ymax) { + String featureTypeName, BoundingBoxStrings boundingBox) { for (FeatureProviderMetadataConsumer analyzer : analyzers) { - analyzer.analyzeFeatureTypeBoundingBox(featureTypeName, xmin, ymin, xmax, ymax); + analyzer.analyzeFeatureTypeBoundingBox(featureTypeName, boundingBox); } }