From ee54891e28ea7af2623bfaa28bc4a1103bfc7c22 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Fri, 27 Oct 2023 07:58:07 +0200 Subject: [PATCH] Improve WFS --- .../src/org/argeo/app/api/geo/WfsKvp.java | 24 +++++++ .../argeo/app/geo/http/WfsHttpHandler.java | 68 ++++++++++--------- 2 files changed, 61 insertions(+), 31 deletions(-) create mode 100644 org.argeo.app.geo/src/org/argeo/app/api/geo/WfsKvp.java diff --git a/org.argeo.app.geo/src/org/argeo/app/api/geo/WfsKvp.java b/org.argeo.app.geo/src/org/argeo/app/api/geo/WfsKvp.java new file mode 100644 index 0000000..166cdf0 --- /dev/null +++ b/org.argeo.app.geo/src/org/argeo/app/api/geo/WfsKvp.java @@ -0,0 +1,24 @@ +package org.argeo.app.api.geo; + +/** Keys used for WFS KVP (key-value pair) encoding. */ +public enum WfsKvp { + CQL_FILTER("cql_filter"), // + OUTPUT_FORMAT("outputFormat"), // + TYPE_NAMES("typeNames"), // + BBOX("bbox"), // + FORMAT_OPTIONS("format_options"), // + ; + + public final static String FILENAME_ = "filename:"; + + private final String key; + + private WfsKvp(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + +} diff --git a/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java b/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java index 8c143db..59cb97a 100644 --- a/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java +++ b/org.argeo.app.geo/src/org/argeo/app/geo/http/WfsHttpHandler.java @@ -29,6 +29,7 @@ import org.argeo.app.api.EntityName; import org.argeo.app.api.EntityType; import org.argeo.app.api.WGS84PosName; import org.argeo.app.api.geo.FeatureAdapter; +import org.argeo.app.api.geo.WfsKvp; import org.argeo.app.geo.CqlUtils; import org.argeo.app.geo.GeoJson; import org.argeo.app.geo.GeoUtils; @@ -73,47 +74,52 @@ public class WfsHttpHandler implements HttpHandler { private final static CmsLog log = CmsLog.getLog(WfsHttpHandler.class); private ProvidedRepository contentRepository; - // HTTP parameters - final static String OUTPUT_FORMAT = "outputFormat"; - final static String TYPE_NAMES = "typeNames"; - final static String CQL_FILTER = "cql_filter"; - final static String BBOX = "bbox"; - private final Map featureAdapters = new HashMap<>(); @Override public void handle(HttpExchange exchange) throws IOException { + ContentSession session = HttpServerUtils.getContentSession(contentRepository, exchange); + String path = HttpServerUtils.subPath(exchange); // content path - final String pathToUse; - int lastSlash = path.lastIndexOf('/'); + final String pathToUse = path; String fileName = null; - if (lastSlash > 0) { - fileName = path.substring(lastSlash + 1); - } boolean zipped = false; - if (fileName != null) { - pathToUse = path.substring(0, lastSlash); - if (path.endsWith(".zip")) { - zipped = true; - } - } else { - pathToUse = path; - } +// int lastSlash = path.lastIndexOf('/'); +// if (lastSlash > 0) { +// fileName = path.substring(lastSlash + 1); +// } +// if (fileName != null) { +// pathToUse = path.substring(0, lastSlash); +// if (path.endsWith(".zip")) { +// zipped = true; +// } +// } else { +// pathToUse = path; +// } - ContentSession session = HttpServerUtils.getContentSession(contentRepository, exchange); - // Content content = session.get(path); + Map> parameters = HttpServerUtils.parseParameters(exchange); // PARAMETERS - Map> parameters = HttpServerUtils.parseParameters(exchange); - String cql = getKvpParameter(parameters, CQL_FILTER); - String typeNamesStr = getKvpParameter(parameters, TYPE_NAMES); - String outputFormat = getKvpParameter(parameters, OUTPUT_FORMAT); + String cql = getKvpParameter(parameters, WfsKvp.CQL_FILTER); + String typeNamesStr = getKvpParameter(parameters, WfsKvp.TYPE_NAMES); + String outputFormat = getKvpParameter(parameters, WfsKvp.OUTPUT_FORMAT); if (outputFormat == null) { outputFormat = "application/json"; } - String bboxStr = getKvpParameter(parameters, BBOX); + + // TODO deal with multiple + String formatOption = getKvpParameter(parameters, WfsKvp.FORMAT_OPTIONS); + if (formatOption != null) { + if (formatOption.startsWith(WfsKvp.FILENAME_)) + fileName = formatOption.substring(WfsKvp.FILENAME_.length()); + } + if (fileName != null && fileName.endsWith(".zip")) + zipped = true; + + // bbox + String bboxStr = getKvpParameter(parameters, WfsKvp.BBOX); if (log.isTraceEnabled()) log.trace(bboxStr); final Envelope bbox; @@ -250,14 +256,14 @@ public class WfsHttpHandler implements HttpHandler { * * @see https://docs.ogc.org/is/09-025r2/09-025r2.html#19 */ - protected String getKvpParameter(Map> parameters, String key) { + protected String getKvpParameter(Map> parameters, WfsKvp key) { Objects.requireNonNull(key, "KVP key cannot be null"); // let's first try the default (CAML case) which should be more efficient - List values = parameters.get(key); + List values = parameters.get(key.getKey()); if (values == null) { // then let's do an ignore case comparison of the key keys: for (String k : parameters.keySet()) { - if (key.equalsIgnoreCase(k)) { + if (key.getKey().equalsIgnoreCase(k)) { values = parameters.get(k); break keys; } @@ -468,7 +474,7 @@ public class WfsHttpHandler implements HttpHandler { */ public void addFeatureAdapter(FeatureAdapter featureAdapter, Map properties) { - List typeNames = LangUtils.toStringList(properties.get(TYPE_NAMES)); + List typeNames = LangUtils.toStringList(properties.get(WfsKvp.TYPE_NAMES.getKey())); if (typeNames.isEmpty()) { log.warn("FeatureAdapter " + featureAdapter.getClass() + " does not declare type names. Ignoring it..."); return; @@ -481,7 +487,7 @@ public class WfsHttpHandler implements HttpHandler { } public void removeFeatureAdapter(FeatureAdapter featureAdapter, Map properties) { - List typeNames = LangUtils.toStringList(properties.get(TYPE_NAMES)); + List typeNames = LangUtils.toStringList(properties.get(WfsKvp.TYPE_NAMES.getKey())); if (!typeNames.isEmpty()) { // ignore if noe type name declared return; -- 2.30.2