/* (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);
}
}