X-Git-Url: https://git.argeo.org/?a=blobdiff_plain;f=org.argeo.app.geo%2Fsrc%2Forg%2Fargeo%2Fapp%2Fgeo%2Fhttp%2FWfsHttpHandler.java;h=c9a1e85c8c5867708b773a2b3d1345b6cad92090;hb=6e13b9416a5fd1f5477eb7233f86d3eacbb88c55;hp=5897d567095865c4ac87019b9c7a775ec4f8a1c7;hpb=efda92d76cd7ccce3925763bf95f68d7927ac5c7;p=gpl%2Fargeo-suite.git 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 5897d56..c9a1e85 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 @@ -13,6 +13,8 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; import javax.xml.namespace.QName; @@ -36,6 +38,15 @@ import org.argeo.cms.acr.json.AcrJsonUtils; import org.argeo.cms.http.HttpHeader; import org.argeo.cms.http.server.HttpServerUtils; import org.argeo.cms.util.LangUtils; +import org.geotools.api.feature.GeometryAttribute; +import org.geotools.api.feature.simple.SimpleFeature; +import org.geotools.api.feature.simple.SimpleFeatureType; +import org.geotools.api.feature.type.AttributeDescriptor; +import org.geotools.api.feature.type.Name; +import org.geotools.api.referencing.FactoryException; +import org.geotools.api.referencing.crs.CoordinateReferenceSystem; +import org.geotools.api.referencing.operation.MathTransform; +import org.geotools.api.referencing.operation.TransformException; import org.geotools.feature.DefaultFeatureCollection; import org.geotools.feature.NameImpl; import org.geotools.feature.simple.SimpleFeatureBuilder; @@ -48,15 +59,6 @@ import org.locationtech.jts.geom.Envelope; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Point; import org.locationtech.jts.geom.Polygon; -import org.opengis.feature.GeometryAttribute; -import org.opengis.feature.simple.SimpleFeature; -import org.opengis.feature.simple.SimpleFeatureType; -import org.opengis.feature.type.AttributeDescriptor; -import org.opengis.feature.type.Name; -import org.opengis.referencing.FactoryException; -import org.opengis.referencing.crs.CoordinateReferenceSystem; -import org.opengis.referencing.operation.MathTransform; -import org.opengis.referencing.operation.TransformException; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; @@ -80,6 +82,24 @@ public class WfsHttpHandler implements HttpHandler { @Override public void handle(HttpExchange exchange) throws IOException { String path = HttpServerUtils.subPath(exchange); + + // content path + final String pathToUse; + int lastSlash = path.lastIndexOf('/'); + 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; + } + ContentSession session = HttpServerUtils.getContentSession(contentRepository, exchange); // Content content = session.get(path); @@ -92,7 +112,8 @@ public class WfsHttpHandler implements HttpHandler { outputFormat = "application/json"; } String bboxStr = getKvpParameter(parameters, BBOX); - log.debug(bboxStr); + if (log.isTraceEnabled()) + log.trace(bboxStr); final Envelope bbox; if (bboxStr != null) { String srs; @@ -127,16 +148,31 @@ public class WfsHttpHandler implements HttpHandler { bbox = null; } - switch (outputFormat) { - case "application/json" -> { - exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/json"); + // response headers + exchange.getResponseHeaders().set(HttpHeader.DATE.getHeaderName(), Long.toString(System.currentTimeMillis())); + + if (fileName != null) { + exchange.getResponseHeaders().set(HttpHeader.CONTENT_DISPOSITION.getHeaderName(), + HttpHeader.ATTACHMENT + ";" + HttpHeader.FILENAME + "=\"" + fileName + "\""); + } - case "GML3" -> { + + // content type + if (zipped) { + exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/zip"); + + } else { + switch (outputFormat) { + case "application/json" -> { + exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/json"); + } + case "GML3" -> { // exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/gml+xml"); - exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/xml"); - } + exchange.getResponseHeaders().set(HttpHeader.CONTENT_TYPE.getHeaderName(), "application/xml"); + } - default -> throw new IllegalArgumentException("Unexpected value: " + outputFormat); + default -> throw new IllegalArgumentException("Unexpected value: " + outputFormat); + } } List typeNames = new ArrayList<>(); @@ -155,9 +191,9 @@ public class WfsHttpHandler implements HttpHandler { // QUERY Stream res = session.search((search) -> { if (cql != null) { - CqlUtils.filter(search.from(path), cql); + CqlUtils.filter(search.from(pathToUse), cql); } else { - search.from(path); + search.from(pathToUse); } for (QName typeName : typeNames) { FeatureAdapter featureAdapter = featureAdapters.get(typeName); @@ -188,7 +224,13 @@ public class WfsHttpHandler implements HttpHandler { exchange.sendResponseHeaders(200, 0); final int BUFFER_SIZE = 100 * 1024; - try (BufferedOutputStream out = new BufferedOutputStream(exchange.getResponseBody(), BUFFER_SIZE)) { + try (OutputStream out = zipped ? new ZipOutputStream(exchange.getResponseBody()) + : new BufferedOutputStream(exchange.getResponseBody(), BUFFER_SIZE)) { + if (out instanceof ZipOutputStream zipOut) { + String unzippedFileName = fileName.substring(0, fileName.length() - ".zip".length()); + zipOut.putNextEntry(new ZipEntry(unzippedFileName)); + } + if ("GML3".equals(outputFormat)) { encodeCollectionAsGML(res, out); } else if ("application/json".equals(outputFormat)) {