/** * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * @author Gabriel Roldan, Boundless Spatial Inc, Copyright 2015 */ package org.geowebcache.s3; import static com.google.common.base.Preconditions.checkNotNull; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import org.geowebcache.GeoWebCacheException; import org.geowebcache.filter.parameters.ParametersUtils; import org.geowebcache.layer.TileLayer; import org.geowebcache.layer.TileLayerDispatcher; import org.geowebcache.mime.MimeException; import org.geowebcache.mime.MimeType; import org.geowebcache.storage.TileObject; import org.geowebcache.storage.TileRange; import com.google.common.base.Throwables; final class TMSKeyBuilder { /** * Key format, comprised of * {@code <prefix>/<layer name>/<gridset id>/<format id>/<parameters hash>/<z>/<x>/<y>.<extension>} */ private static final String TILE_FORMAT = "%s/%s/%s/%s/%s/%d/%d/%d.%s"; /** * Coordinates prefix: {@code <prefix>/<layer name>/<gridset id>/<format id>/<parameters hash>/} */ private static final String COORDINATES_PREFIX_FORMAT = "%s/%s/%s/%s/%s/"; /** * Layer prefix format, comprised of {@code <prefix>/<layer name>/} */ private static final String LAYER_PREFIX_FORMAT = "%s/%s/"; /** * layer + gridset prefix format, comprised of {@code <prefix>/<layer name>/<gridset id>/} */ private static final String GRIDSET_PREFIX_FORMAT = "%s/%s/%s/"; public static final String LAYER_METADATA_OBJECT_NAME = "metadata.properties"; public static final String PARAMETERS_METADATA_OBJECT_PREFIX = "parameters-"; public static final String PARAMETERS_METADATA_OBJECT_NAME = PARAMETERS_METADATA_OBJECT_PREFIX+"%s.properties"; private static final String LAYER_METADATA_FORMAT = "%s/%s/" + LAYER_METADATA_OBJECT_NAME; private static final String PARAMETERS_METADATA_FORMAT = "%s/%s/" + PARAMETERS_METADATA_OBJECT_NAME; private static final String PARAMETERS_METADATA_PREFIX_FORMAT = "%s/%s/" + PARAMETERS_METADATA_OBJECT_PREFIX; private String prefix; private TileLayerDispatcher layers; public TMSKeyBuilder(final String prefix, TileLayerDispatcher layers) { this.prefix = prefix; this.layers = layers; } public String layerId(String layerName) { TileLayer layer; try { layer = layers.getTileLayer(layerName); } catch (GeoWebCacheException e) { throw Throwables.propagate(e); } return layer.getId(); } public Set<String> layerGridsets(String layerName) { TileLayer layer; try { layer = layers.getTileLayer(layerName); } catch (GeoWebCacheException e) { throw Throwables.propagate(e); } return layer.getGridSubsets(); } public Set<String> layerFormats(String layerName) { TileLayer layer; try { layer = layers.getTileLayer(layerName); } catch (GeoWebCacheException e) { throw Throwables.propagate(e); } return layer.getMimeTypes().stream() .map(MimeType::getFileExtension) .collect(Collectors.toSet()); } public String forTile(TileObject obj) { checkNotNull(obj.getLayerName()); checkNotNull(obj.getGridSetId()); checkNotNull(obj.getBlobFormat()); checkNotNull(obj.getXYZ()); String layer = layerId(obj.getLayerName()); String gridset = obj.getGridSetId(); String shortFormat; String parametersId = obj.getParametersId(); if (parametersId == null) { Map<String, String> parameters = obj.getParameters(); parametersId = ParametersUtils.getId(parameters); if (parametersId == null) { parametersId = "default"; } else { obj.setParametersId(parametersId); } } Long x = Long.valueOf(obj.getXYZ()[0]); Long y = Long.valueOf(obj.getXYZ()[1]); Long z = Long.valueOf(obj.getXYZ()[2]); String extension; try { String format = obj.getBlobFormat(); MimeType mimeType = MimeType.createFromFormat(format); shortFormat = mimeType.getFileExtension();// png, png8, png24, etc extension = mimeType.getInternalName();// png, jpeg, etc } catch (MimeException e) { throw Throwables.propagate(e); } String key = String.format(TILE_FORMAT, prefix, layer, gridset, shortFormat, parametersId, z, x, y, extension); return key; } public String forLayer(final String layerName) { String layerId = layerId(layerName); return String.format(LAYER_PREFIX_FORMAT, prefix, layerId); } public String forGridset(final String layerName, final String gridsetId) { String layerId = layerId(layerName); return String.format(GRIDSET_PREFIX_FORMAT, prefix, layerId, gridsetId); } public Set<String> forParameters(final String layerName, final String parametersId) { String layerId = layerId(layerName); return layerGridsets(layerName).stream() .flatMap(gridsetId -> layerFormats(layerName).stream() .map(format -> String.format(COORDINATES_PREFIX_FORMAT, prefix, layerId, gridsetId, format, parametersId))) .collect(Collectors.toSet()); } public String layerMetadata(final String layerName) { String layerId = layerId(layerName); return String.format(LAYER_METADATA_FORMAT, prefix, layerId); } public String parametersMetadata(final String layerName, final String parametersId) { String layerId = layerId(layerName); return String.format(PARAMETERS_METADATA_FORMAT, prefix, layerId, parametersId); } public String parametersMetadataPrefix(final String layerName) { String layerId = layerId(layerName); return String.format(PARAMETERS_METADATA_PREFIX_FORMAT, prefix, layerId); } /** * @return the key prefix up to the coordinates (i.e. * {@code "<prefix>/<layer>/<gridset>/<format>/<parametersId>"}) */ public String coordinatesPrefix(TileRange obj) { checkNotNull(obj.getLayerName()); checkNotNull(obj.getGridSetId()); checkNotNull(obj.getMimeType()); String layer = layerId(obj.getLayerName()); String gridset = obj.getGridSetId(); MimeType mimeType = obj.getMimeType(); String shortFormat; String parametersId = obj.getParametersId(); if (parametersId == null) { Map<String, String> parameters = obj.getParameters(); parametersId = ParametersUtils.getId(parameters); if (parametersId == null) { parametersId = "default"; } else { obj.setParametersId(parametersId); } } shortFormat = mimeType.getFileExtension();// png, png8, png24, etc String key = String.format(COORDINATES_PREFIX_FORMAT, prefix, layer, gridset, shortFormat, parametersId); return key; } public String pendingDeletes() { return String.format("%s/%s", prefix, "_pending_deletes.properties"); } }