diff --git a/doc/en/user/source/extensions/mapml/index.rst b/doc/en/user/source/extensions/mapml/index.rst index 8153803757b..adda4c9c962 100644 --- a/doc/en/user/source/extensions/mapml/index.rst +++ b/doc/en/user/source/extensions/mapml/index.rst @@ -286,7 +286,7 @@ The link is generated so that it always work, if the CRS configured for the laye **MapML Output Format** -The output image format for the MapML resource should be specified using the format_options parameter with a key called ``mapml-wms-format``. If provided, the provided mime type must be a valid WMS format specifier. If not provided, it defaults to ``image/png``. +The output image format for the MapML resource should be specified using the format_options parameter with a key called ``mapml-wms-format``. If provided, the provided mime type must be a valid WMS format specifier. If not provided, it defaults to to the format set with the Default Mime Type dropdown under MapML Settings in the Publishing tab of the Edit Layer settings page. Example:: diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLConstants.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLConstants.java index 5dcfb3386b9..b89279f0a44 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLConstants.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLConstants.java @@ -69,9 +69,15 @@ public final class MapMLConstants { /** DIMENSION */ public static final String DIMENSION = "dimension"; + /** DEFAULT MIME TYPE */ + public static final String MIME = "mime"; + /** MAPML_DIMENSION */ public static final String MAPML_DIMENSION = MAPML_PREFIX + DIMENSION; + /** MAPML_DIMENSION */ + public static final String MAPML_MIME = MAPML_PREFIX + MIME; + /** SHARD_LIST */ public static final String SHARD_LIST = "shardList"; diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java index b1fbe07b539..587c27b7674 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLDocumentBuilder.java @@ -108,6 +108,8 @@ public class MapMLDocumentBuilder { public static final String MINIMUM_WIDTH_HEIGHT = "1"; private static final int BYTES_PER_PIXEL_TRANSPARENT = 4; private static final int BYTES_PER_KILOBYTE = 1024; + public static final String DEFAULT_MIME_TYPE = "image/png"; + private final WMS wms; private final GeoServer geoServer; @@ -129,7 +131,7 @@ public class MapMLDocumentBuilder { private String defaultStyle; private String layerTitle; - private String imageFormat; + private String imageFormat = DEFAULT_MIME_TYPE; private String baseUrl; private String baseUrlPattern; private Boolean enableSharding; @@ -326,7 +328,7 @@ public void initialize() throws ServiceException { projType = mapMLLayerMetadata.getProjType(); layerTitle = layerTitlesCommaDelimited; layerMeta = mapMLLayerMetadata.getLayerMeta(); - imageFormat = (String) format.orElse("image/png"); + imageFormat = (String) format.orElse(mapMLLayerMetadata.getDefaultMimeType()); baseUrl = ResponseUtils.baseURL(request); baseUrlPattern = baseUrl; // handle shard config @@ -402,6 +404,7 @@ private MapMLLayerMetadata layersToOneMapMLLayerMetadata(List layers) mapMLLayerMetadata.setQueryable(layersToQueryable(layers)); mapMLLayerMetadata.setLayerLabel(layersToLabel(layers)); mapMLLayerMetadata.setProjType(projType); + mapMLLayerMetadata.setDefaultMimeType(imageFormat); return mapMLLayerMetadata; } @@ -541,6 +544,7 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl String styleName = style != null ? style : ""; String cqlFilter = null; boolean tileLayerExists = false; + String defaultMimeType = DEFAULT_MIME_TYPE; if (isLayerGroup) { layerGroupInfo = (LayerGroupInfo) layer.getPublishedInfo(); if (layerGroupInfo == null) { @@ -558,6 +562,10 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl queryable = !layerGroupInfo.isQueryDisabled(); layerName = layerGroupInfo.getName(); layerTitle = getTitle(layerGroupInfo, layerName); + defaultMimeType = + Optional.ofNullable(layerGroupInfo.getMetadata().get(MapMLConstants.MAPML_MIME)) + .orElse(DEFAULT_MIME_TYPE) + .toString(); } else { layerInfo = (LayerInfo) layer.getPublishedInfo(); resourceInfo = layerInfo.getResource(); @@ -573,6 +581,10 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl layerTitle = getTitle(layerInfo, layerName); // set the actual style name from the layer info if (style == null) styleName = layerInfo.getDefaultStyle().getName(); + defaultMimeType = + Optional.ofNullable(resourceInfo.getMetadata().get(MapMLConstants.MAPML_MIME)) + .orElse(DEFAULT_MIME_TYPE) + .toString(); } ProjType projType = parseProjType(); cqlFilter = cql != null ? cql : ""; @@ -600,7 +612,8 @@ private MapMLLayerMetadata layerToMapMLLayerMetadata(RawLayer layer, String styl tileLayerExists, useTiles, useFeatures, - cqlFilter); + cqlFilter, + defaultMimeType); } /** @@ -1792,7 +1805,7 @@ private String buildGetMap( String formatOptions = MapMLConstants.MAPML_WMS_MIME_TYPE_OPTION + ":" - + escapeHtml4((String) format.orElse("image/png")); + + escapeHtml4((String) format.orElse(imageFormat)); kvp.put("format_options", formatOptions); kvp.put("SERVICE", "WMS"); kvp.put("REQUEST", "GetMap"); @@ -1938,6 +1951,7 @@ static class MapMLLayerMetadata { private ReferencedEnvelope bbbox; private String layerLabel; + private String defaultMimeType; /** * get if the layer uses features @@ -1974,6 +1988,7 @@ public void setUseFeatures(boolean useFeatures) { * @param styleName String * @param tileLayerExists boolean * @param useTiles boolean + * @param defaultMimeType String */ public MapMLLayerMetadata( LayerInfo layerInfo, @@ -1991,7 +2006,8 @@ public MapMLLayerMetadata( boolean tileLayerExists, boolean useTiles, boolean useFeatures, - String cqFilter) { + String cqFilter, + String defaultMimeType) { this.layerInfo = layerInfo; this.bbox = bbox; this.isLayerGroup = isLayerGroup; @@ -2008,6 +2024,7 @@ public MapMLLayerMetadata( this.useTiles = useTiles; this.useFeatures = useFeatures; this.cqlFilter = cqFilter; + this.defaultMimeType = defaultMimeType; } /** Constructor */ @@ -2366,5 +2383,23 @@ public String getCqlFilter() { public void setCqlFilter(String cqlFilter) { this.cqlFilter = cqlFilter; } + + /** + * get the default mime type + * + * @return String + */ + public String getDefaultMimeType() { + return defaultMimeType; + } + + /** + * set the default mime type + * + * @param defaultMimeType String + */ + public void setDefaultMimeType(String defaultMimeType) { + this.defaultMimeType = defaultMimeType; + } } } diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.html b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.html index d64afbdb28f..2f0426d5dc6 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.html +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.html @@ -135,6 +135,21 @@

+
  • +
    + + Default Mimetype + +
      +
    • + + +
    • +
    +
    +
  • diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.java index b18725c2320..f7e9101040d 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerConfigurationPanel.java @@ -4,6 +4,8 @@ */ package org.geoserver.mapml; +import static org.geoserver.mapml.MapMLConstants.MAPML_USE_TILES; + import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; @@ -12,6 +14,10 @@ import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.markup.html.form.CheckBox; import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.ListMultipleChoice; @@ -32,11 +38,16 @@ import org.geoserver.catalog.PublishedType; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.ResourcePool; +import org.geoserver.gwc.GWC; +import org.geoserver.gwc.layer.GeoServerTileLayer; +import org.geoserver.gwc.layer.GeoServerTileLayerInfo; import org.geoserver.web.GeoServerApplication; import org.geoserver.web.publish.PublishedConfigurationPanel; import org.geoserver.web.util.MapModel; import org.geoserver.web.wicket.ParamResourceModel; +import org.geoserver.wms.WMS; import org.geotools.util.logging.Logging; +import org.geowebcache.layer.TileLayer; /** * Resource configuration panel for MapML @@ -48,8 +59,16 @@ public class MapMLLayerConfigurationPanel extends PublishedConfigurationPanel featureCaptionAttributes; + private static final String MIME_PATTERN = "png|jpeg"; + + public static final Pattern mimePattern = + Pattern.compile(MIME_PATTERN, Pattern.CASE_INSENSITIVE); + + DropDownChoice mime; + /** * Adds MapML configuration panel * @@ -80,6 +99,15 @@ public MapMLLayerConfigurationPanel(final String panelId, final IModel(model, MapMLConstants.RESOURCE_METADATA), MapMLConstants.MAPML_USE_TILES); CheckBox useTiles = new CheckBox(MapMLConstants.USE_TILES, useTilesModel); + useTiles.add( + new OnChangeAjaxBehavior() { + @Override + protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) { + ajaxRequestTarget.add(mime); + boolean useTilesChecked = useTiles.getConvertedInput(); + mime.setChoices(getAvailableMimeTypes(model.getObject(), useTilesChecked)); + } + }); add(useTiles); // add the checkbox to select features or not @@ -93,6 +121,15 @@ public MapMLLayerConfigurationPanel(final String panelId, final IModel mimeModel = + new MapModel<>( + new PropertyModel(model, MapMLConstants.RESOURCE_METADATA), + MapMLConstants.MAPML_MIME); + boolean useTilesFromModel = + Boolean.TRUE.equals( + model.getObject() + .getResource() + .getMetadata() + .get(MAPML_USE_TILES, Boolean.class)); + mime = + new DropDownChoice<>( + MapMLConstants.MIME, + mimeModel, + getAvailableMimeTypes(model.getObject(), useTilesFromModel)); + mime.setOutputMarkupId(true); + mime.setNullValid(false); + // if we are using features, we don't use a mime type + if (useFeaturesModel.getObject() != null) { + String useFeaturesString = String.valueOf(useFeaturesModel.getObject()); + boolean useFeaturesBoolean = Boolean.parseBoolean(useFeaturesString); + mime.setEnabled(!useFeaturesBoolean); + } + add(mime); + featureCaptionAttributes = new ListMultipleChoice<>( MapMLConstants.FEATURE_CAPTION_ATTRIBUTES, @@ -147,6 +209,46 @@ public MapMLLayerConfigurationPanel(final String panelId, final IModel getAvailableMimeTypes(PublishedInfo layer, boolean useTiles) { + List mimeTypes = new ArrayList<>(); + if (useTiles) { + GWC gwc = GWC.get(); + if (gwc != null) { + try { + TileLayer tileLayer = gwc.getTileLayerByName(layer.prefixedName()); + // if the useTiles flag is set and the cache is enabled we get cache mime types + if (tileLayer instanceof GeoServerTileLayer && tileLayer.isEnabled()) { + GeoServerTileLayer geoServerTileLayer = (GeoServerTileLayer) tileLayer; + GeoServerTileLayerInfo info = geoServerTileLayer.getInfo(); + mimeTypes.addAll( + info.getMimeFormats().stream() + .filter(mimeType -> mimePattern.matcher(mimeType).find()) + .collect(Collectors.toList())); + return mimeTypes; + } + } catch (IllegalArgumentException e) { + LOGGER.fine("No tile layer found for " + layer.prefixedName()); + } + } + } + // if the useTiles flag is not set or the tile cache is not enabled we get WMS mime types + WMS wms = WMS.get(); + if (wms != null) { + mimeTypes.addAll( + wms.getAllowedMapFormatNames().stream() + .filter(mimeType -> mimePattern.matcher(mimeType).find()) + .collect(Collectors.toList())); + } + + return mimeTypes; + } + /** * @param layer a LayerInfo for the layer * @return a list of strings of dimension names from the layer info diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.html b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.html index 8cb1dcd4375..1ab2d05c414 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.html +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.html @@ -58,8 +58,24 @@

    MapML Settings +
  • +
    + + Default Mimetype + +
      +
    • + + +
    • +
    +
    +
  • - + \ No newline at end of file diff --git a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.java b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.java index ec4f8605be6..597f9db008c 100644 --- a/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.java +++ b/src/extension/mapml/src/main/java/org/geoserver/mapml/MapMLLayerGroupConfigurationPanel.java @@ -5,7 +5,14 @@ package org.geoserver.mapml; +import static org.geoserver.mapml.MapMLConstants.MAPML_USE_TILES; +import static org.geoserver.mapml.MapMLLayerConfigurationPanel.getAvailableMimeTypes; + +import java.util.logging.Logger; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.OnChangeAjaxBehavior; import org.apache.wicket.markup.html.form.CheckBox; +import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.TextField; import org.apache.wicket.model.IModel; import org.apache.wicket.model.PropertyModel; @@ -13,6 +20,7 @@ import org.geoserver.catalog.MetadataMap; import org.geoserver.web.publish.PublishedConfigurationPanel; import org.geoserver.web.util.MapModel; +import org.geotools.util.logging.Logging; /** * LayerGroup configuration panel for MapML @@ -20,8 +28,12 @@ * @author prushforth */ public class MapMLLayerGroupConfigurationPanel extends PublishedConfigurationPanel { + static final Logger LOGGER = Logging.getLogger(MapMLLayerGroupConfigurationPanel.class); private static final long serialVersionUID = 1L; + public static final String METADATA = "metadata"; + + DropDownChoice mime; /** * Adds MapML configuration panel @@ -35,41 +47,64 @@ public MapMLLayerGroupConfigurationPanel( MapModel licenseTitleModel = new MapModel<>( - new PropertyModel(model, "metadata"), "mapml.licenseTitle"); + new PropertyModel(model, METADATA), "mapml.licenseTitle"); TextField licenseTitle = new TextField<>("licenseTitle", licenseTitleModel); add(licenseTitle); MapModel licenseLinkModel = new MapModel<>( - new PropertyModel(model, "metadata"), "mapml.licenseLink"); + new PropertyModel(model, METADATA), "mapml.licenseLink"); TextField licenseLink = new TextField<>("licenseLink", licenseLinkModel); add(licenseLink); // add the checkbox to select tiled or not MapModel useTilesModel = - new MapModel<>(new PropertyModel(model, "metadata"), "mapml.useTiles"); + new MapModel<>(new PropertyModel(model, METADATA), "mapml.useTiles"); CheckBox useTiles = new CheckBox("useTiles", useTilesModel); + useTiles.add( + new OnChangeAjaxBehavior() { + @Override + protected void onUpdate(AjaxRequestTarget ajaxRequestTarget) { + ajaxRequestTarget.add(mime); + boolean useTilesChecked = useTiles.getConvertedInput(); + mime.setChoices(getAvailableMimeTypes(model.getObject(), useTilesChecked)); + } + }); add(useTiles); // add the checkbox to enable sharding or not MapModel enableShardingModel = new MapModel<>( - new PropertyModel(model, "metadata"), "mapml.enableSharding"); + new PropertyModel(model, METADATA), "mapml.enableSharding"); CheckBox enableSharding = new CheckBox("enableSharding", enableShardingModel); add(enableSharding); MapModel shardListModel = - new MapModel<>( - new PropertyModel(model, "metadata"), "mapml.shardList"); + new MapModel<>(new PropertyModel(model, METADATA), "mapml.shardList"); TextField shardList = new TextField<>("shardList", shardListModel); add(shardList); MapModel shardServerPatternModel = new MapModel<>( - new PropertyModel(model, "metadata"), + new PropertyModel(model, METADATA), "mapml.shardServerPattern"); TextField shardServerPattern = new TextField<>("shardServerPattern", shardServerPatternModel); add(shardServerPattern); + + MapModel mimeModel = + new MapModel<>( + new PropertyModel(model, METADATA), MapMLConstants.MAPML_MIME); + boolean useTilesFromModel = + Boolean.TRUE.equals( + model.getObject().getMetadata().get(MAPML_USE_TILES, Boolean.class)); + mime = + new DropDownChoice<>( + MapMLConstants.MIME, + mimeModel, + getAvailableMimeTypes(model.getObject(), useTilesFromModel)); + mime.setOutputMarkupId(true); + mime.setNullValid(false); + add(mime); } } diff --git a/src/extension/mapml/src/main/resources/GeoServerApplication.properties b/src/extension/mapml/src/main/resources/GeoServerApplication.properties index c21f7f0571f..7b4e6bd30b9 100644 --- a/src/extension/mapml/src/main/resources/GeoServerApplication.properties +++ b/src/extension/mapml/src/main/resources/GeoServerApplication.properties @@ -22,7 +22,9 @@ MapMLLayerConfigurationPanel.mapmlEnableSharding=Enable Sharding MapMLLayerConfigurationPanel.mapmlShardList=Shard List (comma separated) MapMLLayerConfigurationPanel.mapmlShardServerPattern=Shard Server Pattern (include {s} as shard placeholder) MapMLLayerConfigurationPanel.mapmlDimensionSection=Dimension Config +MapMLLayerConfigurationPanel.mapmlDefaultMimeSection=Default Mime Type Config MapMLLayerConfigurationPanel.mapmlDimension=Dimension +MapMLLayerConfigurationPanel.mapmlDefaultMime=Default Mime Type MapMLLayerConfigurationPanel.dimension.nullValid=None MapMLLayerConfigurationPanel.mapmlFeatureCaptionSection=Attributes to <featurecaption> mapping MapMLLayerConfigurationPanel.mapmlFeatureCaption=List of attributes @@ -39,6 +41,8 @@ MapMLLayerGroupConfigurationPanel.mapmlShardSection=Sharding Config MapMLLayerGroupConfigurationPanel.mapmlEnableSharding=Enable Sharding MapMLLayerGroupConfigurationPanel.mapmlShardList=Shard List (comma separated) MapMLLayerGroupConfigurationPanel.mapmlShardServerPattern=Shard Server Pattern (include {s} as shard placeholder) +MapMLLayerGroupConfigurationPanel.mapmlDefaultMimeSection=Default Mime Type Config +MapMLLayerGroupConfigurationPanel.mapmlDefaultMime=Default Mime Type MapMLAdminPanel.title=MapML Settings MapMLAdminPanel.mapml=MapML Settings MapMLAdminPanel.multiextent=Represent multi-layer requests as multiple elements diff --git a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLLayerConfigurationPanelTest.java b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLLayerConfigurationPanelTest.java index 2e3c7587a32..29664016919 100644 --- a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLLayerConfigurationPanelTest.java +++ b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLLayerConfigurationPanelTest.java @@ -4,13 +4,19 @@ */ package org.geoserver.mapml; +import static org.geoserver.data.test.MockData.BASIC_POLYGONS; import static org.geoserver.data.test.MockData.PONDS; +import static org.geoserver.mapml.MapMLConstants.MAPML_USE_TILES; import static org.geoserver.web.GeoServerWicketTestSupport.tester; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.HashMap; import java.util.Map; import javax.xml.namespace.QName; +import org.apache.wicket.markup.html.form.DropDownChoice; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.ListMultipleChoice; import org.apache.wicket.model.Model; @@ -18,14 +24,19 @@ import org.geoserver.catalog.LayerInfo; import org.geoserver.data.test.MockData; import org.geoserver.data.test.SystemTestData; +import org.geoserver.gwc.GWC; +import org.geoserver.gwc.layer.GeoServerTileLayer; import org.geoserver.web.ComponentBuilder; import org.geoserver.web.FormTestPage; import org.geoserver.web.GeoServerWicketTestSupport; +import org.geowebcache.layer.TileLayer; +import org.hamcrest.Matchers; import org.junit.Test; /** @author prushforth */ public class MapMLLayerConfigurationPanelTest extends GeoServerWicketTestSupport { static QName MOSAIC = new QName(MockData.SF_URI, "mosaic", MockData.SF_PREFIX); + GeoServerTileLayer tileLayer; @Override protected void setUpTestData(SystemTestData testData) throws Exception { @@ -42,6 +53,7 @@ protected void onSetUp(SystemTestData testData) throws Exception { testData.addRasterLayer( MOSAIC, "raster-filter-test.zip", null, props, SystemTestData.class, getCatalog()); + testData.addVectorLayer(BASIC_POLYGONS, getCatalog()); } @Test @@ -58,6 +70,9 @@ public void testMapMLPanel() { tester.assertComponent("form", Form.class); // check that the attributes dropdown is available tester.assertComponent("form:panel:featurecaptionattributes", ListMultipleChoice.class); + tester.assertComponent("form:panel:mime", DropDownChoice.class); + // check that the mime type pick list is available as expected with vector data + tester.assertEnabled("form:panel:mime"); // check that the "useFeatures" checkbox is enabled as expected with vector data tester.assertEnabled("form:panel:useFeatures"); FormTester ft = tester.newFormTester("form"); @@ -118,6 +133,7 @@ public void testMapMLPanelWithRasterData() { tester.assertComponent("form", Form.class); // check that the "attributes" (works with raster dimensions) dropdown is available tester.assertComponent("form:panel:featurecaptionattributes", ListMultipleChoice.class); + tester.assertComponent("form:panel:mime", DropDownChoice.class); // check that the "useFeatures" checkbox is disabled as expected with raster data tester.assertDisabled("form:panel:useFeatures"); FormTester ft = tester.newFormTester("form"); @@ -162,4 +178,70 @@ public void testMapMLPanelWithRasterData() { // tester.assertModelValue("form:panel:featurecaptionattributes", "[BLUE_BAND]"); tester.assertModelValue("form:panel:featureCaptionTemplate", "This is the ${BLUE_BAND}"); } + + @SuppressWarnings("unchecked") + @Test + public void testMapMLMime() { + // get a test layer and instantiate the model + final LayerInfo layer = getCatalog().getLayerByName(MockData.PONDS.getLocalPart()); + layer.getResource().getMetadata().put(MapMLConstants.MAPML_USE_FEATURES, true); + Model model = new Model<>(layer); + + FormTestPage page = + new FormTestPage( + (ComponentBuilder) id -> new MapMLLayerConfigurationPanel(id, model)); + // let's start the page and check that the components are correctly instantiated + tester.startPage(page); + + tester.assertComponent("form:panel:mime", DropDownChoice.class); + // check that the mime type pick list is disabled when mapML useFeatures is enabled + tester.assertDisabled("form:panel:mime"); + + // check that the "mime" checkbox is disabled as expected when mapML useFeatures is enabled + tester.assertDisabled("form:panel:mime"); + layer.getResource().getMetadata().put(MapMLConstants.MAPML_USE_FEATURES, false); + Model model2 = new Model<>(layer); + page = + new FormTestPage( + (ComponentBuilder) id -> new MapMLLayerConfigurationPanel(id, model2)); + // let's start the page and check that the components are correctly instantiated + tester.startPage(page); + // check that the "mime" checkbox is enabled as expected when mapML useFeatures is disabled + tester.assertEnabled("form:panel:mime"); + DropDownChoice dropDownChoice = + (DropDownChoice) tester.getComponentFromLastRenderedPage("form:panel:mime"); + assertThat( + dropDownChoice.getChoices(), + Matchers.containsInAnyOrder( + "image/png; mode=8bit", + "image/vnd.jpeg-png", + "image/jpeg", + "image/vnd.jpeg-png8", + "image/png", + "image/png8")); + GWC mediator = GWC.get(); + + final String layerName = getLayerId(BASIC_POLYGONS); + LayerInfo layerInfo = getCatalog().getLayerByName(layerName); + assertNotNull(layerInfo); + layerInfo.getResource().getMetadata().put(MapMLConstants.MAPML_USE_FEATURES, false); + layerInfo.getResource().getMetadata().put(MAPML_USE_TILES, true); + + TileLayer tileLayer = mediator.getTileLayerByName(layerName); + assertNotNull(tileLayer); + assertTrue(tileLayer.isEnabled()); + + Model modelTile = new Model<>(layerInfo); + + FormTestPage pageTile = + new FormTestPage( + (ComponentBuilder) id -> new MapMLLayerConfigurationPanel(id, modelTile)); + // let's start the page and check that the components are correctly instantiated + tester.startPage(pageTile); + DropDownChoice dropDownChoiceTile = + (DropDownChoice) tester.getComponentFromLastRenderedPage("form:panel:mime"); + assertThat( + dropDownChoiceTile.getChoices(), + Matchers.containsInAnyOrder("image/jpeg", "image/png")); + } } diff --git a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLTestSupport.java b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLTestSupport.java index 2c97813a430..a94a253cb8f 100644 --- a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLTestSupport.java +++ b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLTestSupport.java @@ -183,7 +183,9 @@ protected MockHttpServletRequest toHttpRequest() throws Exception { String formatOptions = isFeature() ? MapMLConstants.MAPML_FEATURE_FO + ":true" - : MapMLConstants.MAPML_WMS_MIME_TYPE_OPTION + ":image/png"; + : getFormat() != null + ? MapMLConstants.MAPML_WMS_MIME_TYPE_OPTION + ":image/png" + : ""; if (getKvp() != null) { path = "wms"; httpRequest = createRequest(path, getKvp()); diff --git a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMSTest.java b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMSTest.java index 10139b7b986..7441741f979 100644 --- a/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMSTest.java +++ b/src/extension/mapml/src/test/java/org/geoserver/mapml/MapMLWMSTest.java @@ -357,6 +357,63 @@ public void testMapMLMaxImageWidthHeight() throws Exception { response.getContentAsString().contains("ServiceException")); } + @Test + public void testMapMLDefaultMimeType() throws Exception { + GeoServer geoServer = getGeoServer(); + WMSInfo wms = geoServer.getService(WMSInfo.class); + wms.getMetadata().put(MapMLDocumentBuilder.MAPML_MULTILAYER_AS_MULTIEXTENT, Boolean.TRUE); + geoServer.save(wms); + Catalog cat = getCatalog(); + LayerInfo li = cat.getLayerByName(MockData.POLYGONS.getLocalPart()); + li.getResource().getMetadata().put(MAPML_USE_FEATURES, false); + li.getResource().getMetadata().put(MAPML_USE_TILES, false); + li.getResource().getMetadata().put(MapMLConstants.MAPML_MIME, "img/jpeg"); + LayerInfo li2 = cat.getLayerByName(MockData.LINES.getLocalPart()); + li2.getResource().getMetadata().put(MAPML_USE_FEATURES, false); + li2.getResource().getMetadata().put(MAPML_USE_TILES, false); + cat.save(li); + cat.save(li2); + Mapml mapmlExtent = + new MapMLWMSRequest() + .name(MockData.POLYGONS.getLocalPart()) + .srs("EPSG:3857") + .getAsMapML(); + + List extentLinks = + getTypeFromInputOrDataListOrLink( + mapmlExtent.getBody().getExtents().get(0).getInputOrDatalistOrLink(), + Link.class); + List imageLinksForSingle = getLinkByRelType(extentLinks, RelType.IMAGE); + assertTrue( + "Image link tref should contain img/jpeg format despite no format passed into request", + imageLinksForSingle.get(0).getTref().contains("format=img/jpeg")); + Mapml mapmlExtentWithTwo = + new MapMLWMSRequest() + .name( + MockData.POLYGONS.getLocalPart() + + "," + + MockData.LINES.getLocalPart()) + .srs("EPSG:3857") + .getAsMapML(); + List extentLinksOne = + getTypeFromInputOrDataListOrLink( + mapmlExtentWithTwo.getBody().getExtents().get(0).getInputOrDatalistOrLink(), + Link.class); + List imageLinksOne = getLinkByRelType(extentLinksOne, RelType.IMAGE); + assertTrue( + "Image link tref should contain img/jpeg format despite no format passed into request", + imageLinksOne.get(0).getTref().contains("format=img/jpeg")); + List extentLinksTwo = + getTypeFromInputOrDataListOrLink( + mapmlExtentWithTwo.getBody().getExtents().get(1).getInputOrDatalistOrLink(), + Link.class); + List imageLinksTwo = getLinkByRelType(extentLinksTwo, RelType.IMAGE); + assertTrue( + "Image link tref should contain img/jpeg format despite no format passed into request " + + "and no default set in metadata because first requested layer has default set", + imageLinksTwo.get(0).getTref().contains("format=img/jpeg")); + } + @Test public void testMapMLUseFeaturesLinks() throws Exception { GeoServer geoServer = getGeoServer();