/* (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.wcs2_0.util; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.logging.Logger; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.NamespaceInfo; import org.geoserver.catalog.ResourceInfo; import org.geoserver.catalog.PublishedType; import org.geoserver.wcs2_0.exception.WCS20Exception; import org.geotools.util.MapEntry; import org.geotools.util.logging.Logging; /** * De/encode a workspace and a resource name into a single string. * <p/> * Some external formats do not allow to use semicolons in some strings. * This class offers methods to encode and decode workspace and names into a single string * without using semicolons. * <p/> * We simply use a "__" as separator. This should reduce the conflicts with existing underscores. * This encoding is not unique, so the {@link #decode(java.lang.String) decode} method * return a list of possible workspace,name combinations. You'll need to check which workspace * is really existing. * <p/> * You may use the {@link #getLayer(org.geoserver.catalog.Catalog, java.lang.String) getLayer()} method * to just retrieve the matching layers. * * @author ETj (etj at geo-solutions.it) */ public class NCNameResourceCodec { protected static Logger LOGGER = Logging.getLogger(NCNameResourceCodec.class); private final static String DELIMITER = "__"; public static String encode(ResourceInfo resource) { return encode(resource.getNamespace().getPrefix(), resource.getName()); } public static String encode(String workspaceName, String resourceName) { return workspaceName + DELIMITER + resourceName; } public static LayerInfo getCoverage(Catalog catalog, String encodedCoverageId) throws WCS20Exception { List<LayerInfo> layers = NCNameResourceCodec.getLayers(catalog, encodedCoverageId); if(layers == null) return null; LayerInfo ret = null; for (LayerInfo layer : layers) { if (layer != null && layer.getType() == PublishedType.RASTER) { if(ret == null) { ret = layer; } else { LOGGER.warning("Multiple coverages found for NSName '" + encodedCoverageId + "': " + ret.prefixedName() + " is selected, " + layer.prefixedName() + " will be ignored"); } } } return ret; } /** * Search in the catalog the Layers matching the encoded id. * <p/> * * @return A possibly empty list of the matching layers, or null if the encoded id could not be decoded. */ public static List<LayerInfo> getLayers(Catalog catalog, String encodedResourceId) { List<MapEntry<String, String>> decodedList = decode(encodedResourceId); if(decodedList.isEmpty()) { LOGGER.info("Could not decode id '"+encodedResourceId+"'"); return null; } List<LayerInfo> ret = new ArrayList<LayerInfo>(); LOGGER.info(" Examining encoded name " + encodedResourceId); for (MapEntry<String, String> mapEntry : decodedList) { String namespace = mapEntry.getKey(); String covName = mapEntry.getValue(); if (namespace == null || namespace.isEmpty()) { LOGGER.info(" Checking coverage name " + covName); LayerInfo layer = catalog.getLayerByName(covName); if (layer != null) { LOGGER.info(" - Collecting layer " + layer.prefixedName()); ret.add(layer); } else { LOGGER.info(" - Ignoring layer " + covName); } } else { LOGGER.info(" Checking pair " + namespace + " : " + covName); String fullName = namespace + ":" + covName; NamespaceInfo nsInfo = catalog.getNamespaceByPrefix(namespace); if (nsInfo != null) { LOGGER.info(" - Namespace found " + namespace); LayerInfo layer = catalog.getLayerByName(fullName); if (layer != null) { LOGGER.info(" - Collecting layer " + layer.prefixedName()); ret.add(layer); } else { LOGGER.info(" - Ignoring layer " + fullName); } } else { LOGGER.info(" - Namespace not found " + namespace); } } } return ret; } /** * * @return a List of possible workspace/name pairs, possibly empty if the input could not be decoded; */ public static List<MapEntry<String,String>> decode(String qualifiedName) { int lastPos = qualifiedName.lastIndexOf(DELIMITER); List<MapEntry<String,String>> ret = new ArrayList<MapEntry<String, String>>(); if (lastPos == -1) { ret.add(new MapEntry<String, String>(null, qualifiedName)); return ret; } while (lastPos > -1) { String ws = qualifiedName.substring(0, lastPos); String name = qualifiedName.substring(lastPos+DELIMITER.length()); ret.add(new MapEntry<String, String>(ws, name)); lastPos = qualifiedName.lastIndexOf(DELIMITER, lastPos-1); } return ret; } }