/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2001 - 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.gwc.layer; import static org.geoserver.gwc.GWC.*; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; import org.geoserver.catalog.CatalogInfo; import org.geoserver.catalog.CoverageInfo; import org.geoserver.catalog.FeatureTypeInfo; import org.geoserver.catalog.LayerGroupInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.PublishedInfo; import org.geoserver.catalog.ResourceInfo; import org.geoserver.gwc.config.GWCConfig; import org.geowebcache.config.XMLGridSubset; import org.geowebcache.filter.parameters.FloatParameterFilter; import org.geowebcache.filter.parameters.ParameterFilter; import org.geowebcache.filter.parameters.RegexParameterFilter; import org.geowebcache.filter.parameters.StringParameterFilter; /** * Utility methods for manipulating {@link GeoServerTileLayerInfo}s */ public class TileLayerInfoUtil { /** * Creates a cached tile layer from the given Layer or Layer Group * @param info a Layerinfo or LayerGroupInfo * @param defaults default configuration * */ public static GeoServerTileLayerInfo loadOrCreate(final CatalogInfo info, final GWCConfig defaults) { if (info instanceof LayerInfo) { return loadOrCreate((LayerInfo) info, defaults); } if (info instanceof LayerGroupInfo) { return loadOrCreate((LayerGroupInfo) info, defaults); } throw new IllegalArgumentException(); } /** * Creates a cached tile layer from the given Layer Group * @param info the layer group to cache * @param defaults default configuration * */ public static GeoServerTileLayerInfoImpl loadOrCreate(final LayerGroupInfo groupInfo, final GWCConfig defaults) { GeoServerTileLayerInfoImpl info = LegacyTileLayerInfoLoader.load(groupInfo); if (info == null) { info = create(defaults); checkAutomaticStyles(groupInfo, info); } info.setName(tileLayerName(groupInfo)); info.setId(groupInfo.getId()); return info; } /** * Creates a cached tile layer from the given Layer * @param info the layer to cache * @param defaults default configuration * */ public static GeoServerTileLayerInfoImpl loadOrCreate(final LayerInfo layerInfo, final GWCConfig defaults) { GeoServerTileLayerInfoImpl info = LegacyTileLayerInfoLoader.load(layerInfo); if (info == null) { info = create(defaults); final ResourceInfo resource = layerInfo.getResource(); if (resource instanceof FeatureTypeInfo) { info.getMimeFormats().clear(); info.getMimeFormats().addAll(defaults.getDefaultVectorCacheFormats()); } else if (resource instanceof CoverageInfo) { info.getMimeFormats().clear(); info.getMimeFormats().addAll(defaults.getDefaultCoverageCacheFormats()); } checkAutomaticStyles(layerInfo, info); } info.setName(tileLayerName(layerInfo)); info.setId(layerInfo.getId()); return info; } // FIXME I think this only needs to be package visible for the tests to work. /** * Creates a default tile layer info based on the global defaults, public only for unit testing * purposes. */ public static GeoServerTileLayerInfoImpl create(GWCConfig defaults) { GeoServerTileLayerInfoImpl info = new GeoServerTileLayerInfoImpl(); info.setEnabled(defaults.isCacheLayersByDefault()); info.setAutoCacheStyles(defaults.isCacheNonDefaultStyles()); for (String gsetId : defaults.getDefaultCachingGridSetIds()) { XMLGridSubset subset = new XMLGridSubset(); subset.setGridSetName(gsetId); info.getGridSubsets().add(subset); } info.getMimeFormats().addAll(defaults.getDefaultOtherCacheFormats()); info.setGutter(defaults.getGutter()); info.setMetaTilingX(defaults.getMetaTilingX()); info.setMetaTilingY(defaults.getMetaTilingY()); info.setInMemoryCached(true); return info; } public static void addAutoStyleParameterFilter(final LayerInfo layer, GeoServerTileLayerInfo layerInfo){ StyleParameterFilter filter = new StyleParameterFilter(); filter.setLayer(layer); layerInfo.removeParameterFilter("STYLES"); layerInfo.getParameterFilters().add(filter); } /** * If the layer is configured for automatic style updates of its Style parameter filter, do so. * @param layer The GeoServer layer * @param layerInfo The GeoWebCache layer */ public static void checkAutomaticStyles(final PublishedInfo published, GeoServerTileLayerInfo layerInfo) { if (published instanceof LayerInfo) { checkAutomaticStyles((LayerInfo) published, layerInfo); } else if (published instanceof LayerGroupInfo) { checkAutomaticStyles((LayerGroupInfo) published, layerInfo); } else { throw new IllegalArgumentException( "Do not know how to handle this kind of PublishedInfo: " + published); } } /** * If the layer is configured for automatic style updates of its Style parameter filter, do so. * * @param layer The GeoServer layer * @param layerInfo The GeoWebCache layer */ public static void checkAutomaticStyles(final LayerInfo layer, GeoServerTileLayerInfo layerInfo) { ParameterFilter filter = layerInfo.getParameterFilter("STYLES"); // Update the filter with the latest available styles if it's a style filter if(filter!=null && filter instanceof StyleParameterFilter) { ((StyleParameterFilter) filter).setLayer(layer); } } /** * If the layer is configured for automatic style updates of its Style parameter filter, do so. * @param layer The GeoServer layer group * @param layerInfo The GeoWebCache layer */ public static void checkAutomaticStyles(final LayerGroupInfo layer, GeoServerTileLayerInfo layerInfo) { ParameterFilter filter = layerInfo.getParameterFilter("STYLES"); // Remove the filter as groups shouldn't have auto-updating styles if(filter!=null && filter instanceof StyleParameterFilter) { layerInfo.removeParameterFilter("STYLES"); } } /** * Find a parameter filter by key from a set of filters. * @param paramName * @param parameterFilters * * @deprecated */ public static ParameterFilter findParameterFilter(final String paramName, Set<ParameterFilter> parameterFilters) { if (parameterFilters == null || parameterFilters.size() == 0) { return null; } for (ParameterFilter pf : parameterFilters) { if (paramName.equalsIgnoreCase(pf.getKey())) { return pf; } } return null; } /** * Set the styles which should be cached on a layer * @param info * @param defaultStyle * @param cachedStyles */ public static void setCachedStyles(GeoServerTileLayerInfo info, String defaultStyle, Set<String> cachedStyles) { StyleParameterFilter filter = (StyleParameterFilter) info.getParameterFilter("STYLES"); if(filter==null) filter = new StyleParameterFilter(); filter.setDefaultValue(defaultStyle); filter.setStyles(cachedStyles); info.addParameterFilter(filter); } /** * Replace a filter with a new {@link StringParameterFilter}. * @param tileLayerInfo layer to update the filter on * @param paramKey key for the parameter * @param createParam create a new filter if there is none to replace for the specified key * @param defaultValue default value * @param allowedValues legal values for the parameter */ public static void updateStringParameterFilter(final GeoServerTileLayerInfo tileLayerInfo, final String paramKey, boolean createParam, final String defaultValue, final String... allowedValues) { Set<String> validValues = new HashSet<String>(); if (allowedValues != null) { validValues.addAll(Arrays.asList(allowedValues)); } updateStringParameterFilter(tileLayerInfo, paramKey, createParam, defaultValue, validValues); } /** * Add a {@link StringParameterFilter} to the layer, replacing any existing filter for the same parameter. * @param tileLayerInfo layer to update the filter on * @param paramKey key for the parameter * @param createParam create a new filter if there is none to replace for the specified key * @param defaultValue default value * @param allowedValues legal values for the parameter */ public static void updateStringParameterFilter(final GeoServerTileLayerInfo tileLayerInfo, final String paramKey, boolean createParam, final String defaultValue, final Set<String> allowedValues) { createParam |= tileLayerInfo.removeParameterFilter(paramKey); if (createParam && allowedValues != null && allowedValues.size() > 0) { // make sure default value is among the list of allowed values Set<String> values = new TreeSet<String>(allowedValues); StringParameterFilter stringListFilter = new StringParameterFilter(); stringListFilter.setKey(paramKey); stringListFilter.setDefaultValue(defaultValue == null ? "" : defaultValue); values.addAll(stringListFilter.getValues()); stringListFilter.setValues(new ArrayList<String>(values)); tileLayerInfo.addParameterFilter(stringListFilter); } } /** * Remove a parameter filter from a layer * @param tileLayerInfo the layer * @param paramKey the key of the parameter filter * @return true if a parameter matched and was removed, false otherwise * @deprecated */ public static boolean removeParameterFilter(final GeoServerTileLayerInfo tileLayerInfo, final String paramKey) { return tileLayerInfo.removeParameterFilter(paramKey); } /** * Add a {@link RegexpParameterFilter} set accept anything, replacing any existing filter for the same parameter. * @param tileLayerInfo layer to update the filter on * @param paramKey key for the parameter * @param createParam create a new filter if there is none to replace for the specified key */ public static void updateAcceptAllRegExParameterFilter( final GeoServerTileLayerInfo tileLayerInfo, final String paramKey, boolean createParam) { createParam |= tileLayerInfo.removeParameterFilter(paramKey); if (createParam) { RegexParameterFilter filter = new RegexParameterFilter(); filter.setKey(paramKey); filter.setDefaultValue(""); filter.setRegex(".*"); tileLayerInfo.addParameterFilter(filter); } } /** * Add a {@link FloatParameterFilter} set accept anything, replacing any existing filter for the same parameter. * @param tileLayerInfo layer to update the filter on * @param paramKey key for the parameter * @param createParam create a new filter if there is none to replace for the specified key */ public static void updateAcceptAllFloatParameterFilter(final GeoServerTileLayerInfo tileLayerInfo, final String paramKey, boolean createParam) { createParam |= tileLayerInfo.removeParameterFilter(paramKey); if (createParam) { FloatParameterFilter filter = new FloatParameterFilter(); filter.setKey(paramKey); filter.setDefaultValue(""); tileLayerInfo.addParameterFilter(filter); } } }