+ } else {
+ search.from(path);
+ }
+// search.getWhere().any((f) -> {
+ for (QName typeName : typeNames) {
+ FeatureAdapter featureAdapter = featureAdapters.get(typeName);
+ if (featureAdapter == null)
+ throw new IllegalStateException("No feature adapter found for " + typeName);
+ // f.isContentClass(typeName);
+ featureAdapter.addConstraintsForFeature((AndFilter) search.getWhere(), typeName);
+ }
+// });
+ });
+
+ exchange.sendResponseHeaders(200, 0);
+
+ final int BUFFER_SIZE = 100 * 1024;
+ try (BufferedOutputStream out = new BufferedOutputStream(exchange.getResponseBody(), BUFFER_SIZE)) {
+ if ("GML3".equals(outputFormat)) {
+ encodeCollectionAsGML(res, out);
+ } else if ("application/json".equals(outputFormat)) {
+ encodeCollectionAsGeoJSon(res, out, typeNames);
+ }
+ }
+ }
+
+ /**
+ * Retrieve KVP (keyword-value pairs) parameters, which are lower case, as per
+ * specifications.
+ *
+ * @see https://docs.ogc.org/is/09-025r2/09-025r2.html#19
+ */
+ protected String getKvpParameter(Map<String, List<String>> parameters, String key) {
+ Objects.requireNonNull(key, "KVP key cannot be null");
+ // let's first try the default (CAML case) which should be more efficient
+ List<String> values = parameters.get(key);
+ if (values == null) {
+ // then let's do an ignore case comparison of the key
+ keys: for (String k : parameters.keySet()) {
+ if (key.equalsIgnoreCase(k)) {
+ values = parameters.get(k);
+ break keys;
+ }
+ }
+ }
+ if (values == null) // nothing was found
+ return null;
+ if (values.size() != 1) {
+ // although not completely clear from the standard, we assume keys must be
+ // unique
+ // since lists are defined here
+ // https://docs.ogc.org/is/09-026r2/09-026r2.html#10
+ throw new IllegalArgumentException("Key " + key + " as multiple values");
+ }
+ String value = values.get(0);
+ assert value != null;
+ return value;
+ }
+
+ protected void encodeCollectionAsGeoJSon(Stream<Content> features, OutputStream out, List<QName> typeNames)
+ throws IOException {
+ long begin = System.currentTimeMillis();
+ AtomicLong count = new AtomicLong(0);
+ JsonGenerator generator = Json.createGenerator(out);
+ generator.writeStartObject();
+ generator.write("type", "FeatureCollection");
+ generator.writeStartArray("features");
+ features.forEach((c) -> {
+ // TODO deal with multiple type names
+ FeatureAdapter featureAdapter = null;
+ QName typeName = null;
+ if (!typeNames.isEmpty()) {
+ typeName = typeNames.get(0);
+ featureAdapter = featureAdapters.get(typeName);
+ }
+
+ boolean geometryWritten = false;
+// if (typeName.getLocalPart().equals("fieldSimpleFeature")) {
+// Content area = c.getContent("place.geom.json").orElse(null);
+// if (area != null) {
+// generator.writeStartObject();
+// generator.write("type", "Feature");
+// String featureId = getFeatureId(c);
+// if (featureId != null)
+// generator.write("id", featureId);
+//
+// generator.flush();
+// try (InputStream in = area.open(InputStream.class)) {
+// out.write(",\"geometry\":".getBytes());
+// StreamUtils.copy(in, out);
+// //out.flush();
+// } catch (Exception e) {
+// log.error(c.getPath() + " : " + e.getMessage());
+// } finally {
+// }
+// geometryWritten = true;
+// }else {
+// return;
+// }
+// }
+
+ if (!geometryWritten) {
+
+ Geometry defaultGeometry = featureAdapter != null ? featureAdapter.getDefaultGeometry(c, typeName)
+ : getDefaultGeometry(c);
+ if (defaultGeometry == null)
+ return;
+ generator.writeStartObject();
+ generator.write("type", "Feature");
+ String featureId = getFeatureId(c);
+ if (featureId != null)
+ generator.write("id", featureId);
+
+// GeoJson.writeBBox(generator, defaultGeometry);
+ generator.writeStartObject(GeoJson.GEOMETRY);
+ GeoJson.writeGeometry(generator, defaultGeometry);
+ generator.writeEnd();// geometry object
+ }
+ generator.writeStartObject(GeoJson.PROPERTIES);
+ AcrJsonUtils.writeTimeProperties(generator, c);
+ if (featureAdapter != null)
+ featureAdapter.writeProperties(generator, c, typeName);
+ else
+ writeProperties(generator, c);
+ generator.writeEnd();// properties object
+
+ generator.writeEnd();// feature object
+
+ if (count.incrementAndGet() % 10 == 0)
+ try {
+ out.flush();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ });
+ generator.writeEnd();// features array
+ generator.writeEnd().close();
+
+ log.debug("GeoJSon encoding took " + (System.currentTimeMillis() - begin) + " ms.");
+ }
+
+ protected Geometry getDefaultGeometry(Content content) {
+ if (content.hasContentClass(EntityType.geopoint)) {
+ double latitude = content.get(WGS84PosName.lat, Double.class).get();
+ double longitude = content.get(WGS84PosName.lon, Double.class).get();
+
+ Coordinate coordinate = new Coordinate(longitude, latitude);
+ Point the_geom = JTS.GEOMETRY_FACTORY.createPoint(coordinate);
+ return the_geom;
+ }
+ return null;
+ }
+
+ protected String getFeatureId(Content content) {
+ String uuid = content.attr(LdapAttr.entryUUID);
+ return uuid;
+ }