From 34bc92a067970c7e4cc4659b33aa8da40a4d065a Mon Sep 17 00:00:00 2001 From: Lyn Elisa Goltz Date: Thu, 6 Aug 2026 09:16:09 +0200 Subject: [PATCH] XPLANBOX-5140 - added vendor specific parameter GFI_TEMPLATE and GfiTemplateProvider to add implementations to resolve resources specified with GFI_TEMPLATE --- .../featureinfo/FeatureInfoParams.java | 29 ++---------- .../TemplateFeatureInfoSerializer.java | 4 +- .../featureinfo/templating/GfiRetriever.java | 47 +++++++++++++++++++ .../templating/GfiTemplateProvider.java | 24 ++++++++++ .../templating/TemplatingUtils.java | 20 +++----- .../protocol/wms/ops/GetFeatureInfo.java | 11 +++++ .../wms/controller/WMSController.java | 2 +- 7 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiRetriever.java create mode 100644 deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiTemplateProvider.java diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java index 8f8b80015d9..9d36d2f63c4 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/FeatureInfoParams.java @@ -52,34 +52,13 @@ Occam Labs UG (haftungsbeschränkt) * * @author Andreas Schmitz */ -public class FeatureInfoParams { - - private Map nsBindings; - - private FeatureCollection featureCollection; - - private String format; - - private boolean withGeometries; - - private String schemaLocation; - - private FeatureType featureType; - - private ICRS crs; - - private final ICRS infoCrs; +public record FeatureInfoParams(Map nsBindings, FeatureCollection featureCollection, String format, + boolean withGeometries, String schemaLocation, FeatureType featureType, ICRS crs, ICRS infoCrs, + String gfiTemplate) { public FeatureInfoParams(Map nsBindings, FeatureCollection col, String format, boolean withGeometries, String schemaLocation, FeatureType type, ICRS crs, ICRS infoCrs) { - this.nsBindings = nsBindings; - this.featureCollection = col; - this.format = format; - this.withGeometries = withGeometries; - this.schemaLocation = schemaLocation; - this.featureType = type; - this.crs = crs; - this.infoCrs = infoCrs; + this(nsBindings, col, format, withGeometries, schemaLocation, type, crs, infoCrs, null); } /** diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializer.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializer.java index 2b8c2c8d271..e84e0381c54 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializer.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/serializing/TemplateFeatureInfoSerializer.java @@ -62,8 +62,8 @@ public TemplateFeatureInfoSerializer(final String fiFile) { @Override public void serialize(FeatureInfoParams params, FeatureInfoContext context) throws IOException, XMLStreamException { - - runTemplate(context.getOutputStream(), fiFile, params.getFeatureCollection(), params.isWithGeometries()); + runTemplate(context.getOutputStream(), fiFile, params.getFeatureCollection(), params.isWithGeometries(), + params.gfiTemplate()); } } diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiRetriever.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiRetriever.java new file mode 100644 index 00000000000..ca4f516af1b --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiRetriever.java @@ -0,0 +1,47 @@ +package org.deegree.featureinfo.templating; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ServiceLoader; + +import org.deegree.featureinfo.FeatureInfoManager; + +/** + * @author Lyn Goltz + */ +public class GfiRetriever { + + private static final ServiceLoader gfiTemplateProviderLoader; + + static { + gfiTemplateProviderLoader = ServiceLoader.load(GfiTemplateProvider.class); + for (GfiTemplateProvider gfiTemplateProvider : gfiTemplateProviderLoader) { + gfiTemplateProvider.init(); + } + } + + /** + * @param gfiFile to retrieve the template from, may be null + * @param gfiTemplateParam the value of the gfiTemplate parameter, may be + * null + * @return the template from the gfiTemplateParam, if available or from the gfiFile if + * not null, if both are null or not available the default + * 'html.gfi' is returned + * @throws FileNotFoundException if the gfiFile could not be found + */ + InputStream retrieveTemplate(String gfiFile, String gfiTemplateParam) throws FileNotFoundException { + if (gfiTemplateParam != null && !gfiTemplateParam.isEmpty()) { + for (GfiTemplateProvider gfiTemplateProvider : gfiTemplateProviderLoader) { + InputStream gfiTemplateFromProvider = gfiTemplateProvider.retrieveTemplate(gfiTemplateParam); + if (gfiTemplateFromProvider != null) + return gfiTemplateFromProvider; + } + } + if (gfiFile == null) { + return FeatureInfoManager.class.getResourceAsStream("html.gfi"); + } + return new FileInputStream(gfiFile); + } + +} diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiTemplateProvider.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiTemplateProvider.java new file mode 100644 index 00000000000..7288412089d --- /dev/null +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/GfiTemplateProvider.java @@ -0,0 +1,24 @@ +package org.deegree.featureinfo.templating; + +import java.io.InputStream; + +/** + * Implementations of this class provides gfi templates from a passed query param. + * + * @author Lyn Goltz + */ +public interface GfiTemplateProvider { + + /** + * Called once to initialize the GfiTemplateProvider + */ + void init(); + + /** + * @param gfiTemplateParam the value of the query param, never null + * @return the content associated to the query param, may be null if not + * retrievable or parseable + */ + InputStream retrieveTemplate(String gfiTemplateParam); + +} diff --git a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/TemplatingUtils.java b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/TemplatingUtils.java index 5eed0fbb08e..884aa9d7ac8 100644 --- a/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/TemplatingUtils.java +++ b/deegree-core/deegree-core-featureinfo/src/main/java/org/deegree/featureinfo/templating/TemplatingUtils.java @@ -43,19 +43,17 @@ Occam Labs UG (haftungsbeschränkt) import static java.util.Collections.singletonList; import static org.slf4j.LoggerFactory.getLogger; -import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import org.antlr.runtime.ANTLRInputStream; import org.antlr.runtime.CharStream; import org.antlr.runtime.CommonTokenStream; import org.deegree.feature.FeatureCollection; -import org.deegree.featureinfo.FeatureInfoManager; import org.deegree.featureinfo.templating.lang.PropertyTemplateCall; import org.slf4j.Logger; @@ -68,18 +66,12 @@ public class TemplatingUtils { private static final Logger LOG = getLogger(TemplatingUtils.class); - public static void runTemplate(OutputStream response, String fiFile, FeatureCollection col, boolean geometries) - throws IOException { - PrintWriter out = new PrintWriter(new OutputStreamWriter(response, "UTF-8")); + public static void runTemplate(OutputStream response, String fiFile, FeatureCollection col, boolean geometries, + String gfiTemplateParam) { + PrintWriter out = new PrintWriter(new OutputStreamWriter(response, StandardCharsets.UTF_8)); try { - InputStream in; - if (fiFile == null) { - in = FeatureInfoManager.class.getResourceAsStream("html.gfi"); - } - else { - in = new FileInputStream(fiFile); - } + InputStream in = new GfiRetriever().retrieveTemplate(fiFile, gfiTemplateParam); CharStream input = new ANTLRInputStream(in); Templating2Lexer lexer = new Templating2Lexer(input); @@ -90,7 +82,7 @@ public static void runTemplate(OutputStream response, String fiFile, FeatureColl StringBuilder sb = new StringBuilder(); new PropertyTemplateCall("start", singletonList("*"), false).eval(sb, defs, col, geometries); - out.println(sb.toString()); + out.println(sb); } catch (Throwable e) { if (fiFile == null) { diff --git a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java index 904a27d8681..9b20df1a9ac 100644 --- a/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java +++ b/deegree-core/deegree-core-protocol/deegree-protocol-wms/src/main/java/org/deegree/protocol/wms/ops/GetFeatureInfo.java @@ -105,6 +105,8 @@ public class GetFeatureInfo extends RequestBase { private double scale; + private String gfiTemplate; + /** * @param map * @param version @@ -332,6 +334,7 @@ private double[] handleCommon(Map map) throws OWSException { returnGeometries = map.get("GEOMETRIES") != null && map.get("GEOMETRIES").equalsIgnoreCase("true"); infoCrs = map.get("INFO_CRS") != null ? CRSManager.getCRSRef(map.get("INFO_CRS")) : null; + gfiTemplate = map.get("GFI_TEMPLATE"); return vals; } @@ -442,6 +445,14 @@ public int getY() { return y; } + /** + * @return the gfi template (vendor specific parameter GFI_TEMPLATE), may be + * null + */ + public String getGfiTemplate() { + return gfiTemplate; + } + /** * @return the original parameter map (might be empty if not constructed via request) */ diff --git a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java index 8e8d22f7814..a5ddf2d06fc 100644 --- a/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java +++ b/deegree-services/deegree-services-wms/src/main/java/org/deegree/services/wms/controller/WMSController.java @@ -957,7 +957,7 @@ private void doGetFeatureInfo(final HttpResponseBuffer response, Version version try { FeatureInfoParams params = new FeatureInfoParams(nsBindings, col, format, geometries, loc, type, crs, - infoCrs); + infoCrs, fi.getGfiTemplate()); featureInfoManager.serializeFeatureInfo(params, new StandardFeatureInfoContext(response)); response.flushBuffer(); }