/* (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.tileLayerName;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataMap;
import org.geotools.util.logging.Logging;
import org.geowebcache.config.XMLGridSubset;
/**
* Backwards (<= 2.1.3) compatible {@link GeoServerTileLayerInfoImpl} loader.
*
* @author groldan
*
*/
public class LegacyTileLayerInfoLoader {
private static final Logger LOGGER = Logging.getLogger(LegacyTileLayerInfoLoader.class);
public static final String CONFIG_KEY_ENABLED = "GWC.enabled";
public static final String CONFIG_KEY_GUTTER = "GWC.gutter";
public static final String CONFIG_KEY_GRIDSETS = "GWC.gridSets";
public static final String CONFIG_KEY_METATILING_X = "GWC.metaTilingX";
public static final String CONFIG_KEY_METATILING_Y = "GWC.metaTilingY";
public static final String CONFIG_KEY_FORMATS = "GWC.cacheFormats";
public static final String CONFIG_KEY_AUTO_CACHE_STYLES = "GWC.autoCacheStyles";
public static final String CONFIG_KEY_CACHED_STYLES = "GWC.cachedNonDefaultStyles";
public static final String CONFIG_KEY_IN_MEMORY_CACHED = "GWC.inMemoryUncached";
public static final String[] _ALL_KEYS = { CONFIG_KEY_ENABLED, CONFIG_KEY_GUTTER,
CONFIG_KEY_GRIDSETS, CONFIG_KEY_METATILING_X, CONFIG_KEY_METATILING_Y,
CONFIG_KEY_FORMATS, CONFIG_KEY_AUTO_CACHE_STYLES, CONFIG_KEY_CACHED_STYLES,
CONFIG_KEY_IN_MEMORY_CACHED };
public static GeoServerTileLayerInfoImpl load(final LayerInfo layer) {
MetadataMap metadataMap = layer.getMetadata();
if (!hasTileLayerDef(metadataMap)) {
return null;
}
GeoServerTileLayerInfoImpl tileLayerInfo = load(metadataMap);
if (metadataMap.containsKey(CONFIG_KEY_CACHED_STYLES)) {
final String defaultStyle = layer.getDefaultStyle() == null ? "" : layer
.getDefaultStyle().prefixedName();
String cachedStylesStr = metadataMap.get(CONFIG_KEY_CACHED_STYLES, String.class);
Set<String> cachedStyles = unmarshalSet(cachedStylesStr);
TileLayerInfoUtil.setCachedStyles(tileLayerInfo, defaultStyle, cachedStyles);
}
TileLayerInfoUtil.checkAutomaticStyles(layer, tileLayerInfo);
tileLayerInfo.setName(tileLayerName(layer));
tileLayerInfo.setId(layer.getId());
return tileLayerInfo;
}
public static boolean hasTileLayerDef(MetadataMap metadataMap) {
return metadataMap.containsKey(CONFIG_KEY_ENABLED);
}
public static GeoServerTileLayerInfoImpl load(final LayerGroupInfo layerGroup) {
MetadataMap metadataMap = layerGroup.getMetadata();
if (!hasTileLayerDef(metadataMap)) {
return null;
}
GeoServerTileLayerInfoImpl tileLayerInfo = load(metadataMap);
if (tileLayerInfo != null) {
tileLayerInfo.setName(tileLayerName(layerGroup));
tileLayerInfo.setId(layerGroup.getId());
}
TileLayerInfoUtil.checkAutomaticStyles(layerGroup, tileLayerInfo);
return tileLayerInfo;
}
private static GeoServerTileLayerInfoImpl load(final MetadataMap metadataMap) {
GeoServerTileLayerInfoImpl info = new GeoServerTileLayerInfoImpl();
// whether the config needs to be saved
final boolean enabled = metadataMap.get(CONFIG_KEY_ENABLED, Boolean.class).booleanValue();
info.setEnabled(enabled);
int gutter = metadataMap.get(CONFIG_KEY_GUTTER, Integer.class).intValue();
info.setGutter(gutter);
String gridsets = metadataMap.get(CONFIG_KEY_GRIDSETS, String.class);
Set<XMLGridSubset> gridSetIds = unmarshalGridSubsets(gridsets);
info.getGridSubsets().addAll(gridSetIds);
int metaTilingX = metadataMap.get(CONFIG_KEY_METATILING_X, Integer.class).intValue();
info.setMetaTilingX(metaTilingX);
int metaTilingY = metadataMap.get(CONFIG_KEY_METATILING_Y, Integer.class).intValue();
info.setMetaTilingY(metaTilingY);
if (metadataMap.containsKey(CONFIG_KEY_FORMATS)) {
String mimeFormatsStr = metadataMap.get(CONFIG_KEY_FORMATS, String.class);
Set<String> mimeFormats = unmarshalSet(mimeFormatsStr);
info.getMimeFormats().addAll(mimeFormats);
}
if (metadataMap.containsKey(CONFIG_KEY_AUTO_CACHE_STYLES)) {
boolean autoCacheStyles = metadataMap.get(CONFIG_KEY_AUTO_CACHE_STYLES, Boolean.class)
.booleanValue();
info.setAutoCacheStyles(autoCacheStyles);
}
if(metadataMap.containsKey(CONFIG_KEY_IN_MEMORY_CACHED)){
boolean inMemoryCached = metadataMap.get(CONFIG_KEY_IN_MEMORY_CACHED, Boolean.class);
info.setInMemoryCached(inMemoryCached);
}
return info;
}
private static Set<String> unmarshalSet(final String listStr) {
Set<String> unmarshalled = new HashSet<String>(Arrays.asList(listStr.split(",")));
return unmarshalled;
}
private static String marshalList(final Collection<String> list) {
StringBuilder sb = new StringBuilder();
for (Iterator<String> i = list.iterator(); i.hasNext();) {
sb.append(i.next());
if (i.hasNext()) {
sb.append(",");
}
}
return sb.toString();
}
/**
* @param gridSubsetsStr
* comma separated list of epsg codes (usually just {@code EPSG:900913,EPSG:4326}
* @return the list of parsed grid subsets from the argument JSON array
* @throws IllegalArgumentException
* if {@code str} can't be parsed to a JSONArray
*/
private static Set<XMLGridSubset> unmarshalGridSubsets(String gridSubsetsStr)
throws IllegalArgumentException {
Set<XMLGridSubset> gridSubsets = new HashSet<XMLGridSubset>();
// backwards compatibility check for when str comes in as "EPSG:XXX,EPSG:YYY"
String[] epsgCodes = gridSubsetsStr.split(",");
for (String code : epsgCodes) {
if (code.trim().length() == 0) {
continue;
}
try {
XMLGridSubset xmlGridSubset = new XMLGridSubset();
xmlGridSubset.setGridSetName(code);
gridSubsets.add(xmlGridSubset);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "Invalid GridSubset list: " + gridSubsetsStr);
}
}
gridSubsets.remove(null);
return gridSubsets;
}
public static void clear(MetadataMap metadata) {
if (metadata != null) {
for (String key : LegacyTileLayerInfoLoader._ALL_KEYS) {
metadata.remove(key);
}
}
}
/**
* Saves a tile layer info into the given metadata map using the old legacy metadata elements.
* For unit testing only.
*
* @param source
* @param metadata
*/
public static void save(GeoServerTileLayerInfo source, MetadataMap metadata) {
final boolean enabled = source.isEnabled();
final int gutter = source.getGutter();
final Set<XMLGridSubset> cachedGridSubsets = source.getGridSubsets();
final int metaTilingX = source.getMetaTilingX();
final int metaTilingY = source.getMetaTilingY();
final Set<String> mimeFormats = source.getMimeFormats();
final Boolean autoCacheStyles = source.isAutoCacheStyles();
final Set<String> cachedStyles = source.cachedStyles();
final boolean inMemoryCached = source.isInMemoryCached();
metadata.put(CONFIG_KEY_ENABLED, Boolean.valueOf(enabled));
metadata.put(CONFIG_KEY_GUTTER, Integer.valueOf(gutter));
Collection<String> subsetNames = new ArrayList<String>();
for (XMLGridSubset s : cachedGridSubsets) {
subsetNames.add(s.getGridSetName());
}
metadata.put(CONFIG_KEY_GRIDSETS, marshalList(subsetNames));
metadata.put(CONFIG_KEY_METATILING_X, Integer.valueOf(metaTilingX));
metadata.put(CONFIG_KEY_METATILING_Y, Integer.valueOf(metaTilingY));
metadata.put(CONFIG_KEY_FORMATS, marshalList(mimeFormats));
metadata.put(CONFIG_KEY_AUTO_CACHE_STYLES, autoCacheStyles);
metadata.put(CONFIG_KEY_IN_MEMORY_CACHED, inMemoryCached);
if (cachedStyles.size() > 0) {
metadata.put(CONFIG_KEY_CACHED_STYLES, marshalList(cachedStyles));
} else {
metadata.remove(CONFIG_KEY_CACHED_STYLES);
}
}
}