/* (c) 2014 Open Source Geospatial Foundation - all rights reserved * (c) 2013 OpenPlans * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ package org.geoserver.kml.decorator; import java.io.IOException; import org.geoserver.kml.KmlEncodingContext; import org.geoserver.wms.GetMapRequest; import org.geoserver.wms.WMSInfo; import de.micromata.opengis.kml.v_2_2_0.Feature; import de.micromata.opengis.kml.v_2_2_0.Folder; import de.micromata.opengis.kml.v_2_2_0.Link; import de.micromata.opengis.kml.v_2_2_0.NetworkLink; /** * Encodes previous/next network links when paging is used * TODO: move this in GeoSearch, as it references its REST services * * @author Andrea Aime - GeoSolutions */ public class FolderRelativeLinksDecoratorFactory implements KmlDecoratorFactory { @Override public KmlDecorator getDecorator(Class<? extends Feature> featureClass, KmlEncodingContext context) { // this decorator makes sense only for WMS if(!(context.getService() instanceof WMSInfo)) { return null; } // we decorate only the feature collection folders if(!(featureClass.equals(Folder.class))) { return null; } // see if we have to encode relative links GetMapRequest request = context.getRequest(); String relLinks = (String) request.getFormatOptions().get("relLinks"); // Add prev/next links if requested if(request.getMaxFeatures() != null && relLinks != null && relLinks.equalsIgnoreCase("true")) { return new FolderRelativeLinksDecorator(); } else { return null; } } static class FolderRelativeLinksDecorator extends AbstractGeoSearchDecorator { @Override public Feature decorate(Feature feature, KmlEncodingContext context) { // if not a layer link, move on if(context.getCurrentLayer() == null || context.getCurrentFeatureCollection() == null) { return feature; } Folder folder = (Folder) feature; String linkbase = ""; try { linkbase = getFeatureTypeURL(context); linkbase += ".kml"; } catch (IOException ioe) { throw new RuntimeException(ioe); } GetMapRequest request = context.getRequest(); int maxFeatures = request.getMaxFeatures(); int startIndex = (request.getStartIndex() == null) ? 0 : request.getStartIndex().intValue(); int prevStart = startIndex - maxFeatures; int nextStart = startIndex + maxFeatures; // Previous page, if any if (prevStart >= 0) { encodeSequentialNetworkLink(folder, linkbase, prevStart, maxFeatures, "prev", "Previous page"); } // Next page, if potentially any if (context.getCurrentFeatureCollection().size() >= maxFeatures) { encodeSequentialNetworkLink(folder, linkbase, nextStart, maxFeatures, "next", "Next page"); } return folder; } private void encodeSequentialNetworkLink(Folder folder, String linkbase, int start, int maxFeatures, String id, String readableName) { NetworkLink nl = folder.createAndAddNetworkLink(); Link link = nl.createAndSetLink(); link.setHref(linkbase + "?startindex=" + start + "&maxfeatures=" + maxFeatures); nl.setDescription(readableName); nl.setId(id); } } }