/* (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.sequence; import java.util.List; import org.geoserver.kml.KmlEncodingContext; import org.geoserver.kml.decorator.KmlDecoratorFactory.KmlDecorator; import org.geoserver.kml.utils.KMLFeatureAccessor; import org.geoserver.ows.HttpErrorCodeException; import org.geoserver.platform.ServiceException; import org.geoserver.wms.WMSMapContent; import org.geotools.data.simple.SimpleFeatureCollection; import org.geotools.map.FeatureLayer; import org.geotools.map.Layer; import de.micromata.opengis.kml.v_2_2_0.Feature; import de.micromata.opengis.kml.v_2_2_0.Folder; /** * Base class for sequences that create one folder per layer * * @author Andrea Aime - GeoSolutions */ public abstract class AbstractFolderSequenceFactory implements SequenceFactory<Feature> { protected KmlEncodingContext context; protected List<KmlDecorator> decorators; public AbstractFolderSequenceFactory(KmlEncodingContext context) { this.context = context; this.decorators = context.getDecoratorsForClass(Folder.class); } public abstract class AbstractFolderGenerator implements Sequence<Feature> { protected int i = 0; protected int size; public AbstractFolderGenerator() { this.size = context.getMapContent().layers().size(); } @Override public Feature next() { while (i < size) { List<Layer> layers = context.getMapContent().layers(); Layer layer = layers.get(i++); context.setCurrentLayer(layer); // setup the folder and let it be decorated Folder folder = new Folder(); folder.setName(layer.getTitle()); // if it's a feature layer, setup the feature collection for it (some decorators use it) if (layer instanceof FeatureLayer) { try { WMSMapContent mapContent = context.getMapContent(); SimpleFeatureCollection fc = new KMLFeatureAccessor().loadFeatureCollection( layer, mapContent, context.getWms(), mapContent.getScaleDenominator()); context.setCurrentFeatureCollection(fc); } catch (Exception e) { if (e instanceof ServiceException) { throw (ServiceException) e; } else if(e instanceof HttpErrorCodeException) { throw (HttpErrorCodeException) e; } else { throw new ServiceException( "Failed to load vector data during KML generation", e); } } } // have the folder be decorated for (KmlDecorator decorator : decorators) { folder = (Folder) decorator.decorate(folder, context); if (folder == null) { continue; } } encodeFolderContents(layer, folder); return folder; } return null; } /** * Encodes the actual contents of the folder, besides the one generated by decorators * @param layer * @param folder */ protected abstract void encodeFolderContents(Layer layer, Folder folder); } }