package org.geoserver.wms;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.ProjectionPolicy;
import org.geoserver.catalog.ResourcePool;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.impl.CatalogImpl;
import org.geoserver.catalog.impl.DataStoreInfoImpl;
import org.geoserver.catalog.impl.FeatureTypeInfoImpl;
import org.geoserver.catalog.impl.LayerInfoImpl;
import org.geoserver.catalog.impl.NamespaceInfoImpl;
import org.geoserver.catalog.impl.StyleInfoImpl;
import org.geoserver.catalog.impl.WorkspaceInfoImpl;
import org.geoserver.config.GeoServer;
import org.geoserver.config.impl.GeoServerImpl;
import org.geoserver.config.impl.GeoServerInfoImpl;
import org.geoserver.platform.ServiceException;
import org.geotools.data.DataStore;
import org.geotools.data.DataUtilities;
import org.geotools.data.FeatureStore;
import org.geotools.data.memory.MemoryDataStore;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geometry.jts.ReferencedEnvelope;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.styling.Style;
import org.geotools.styling.StyleFactory;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.vfny.geoserver.wms.GetMapProducer;
import org.vfny.geoserver.wms.RasterMapProducer;
import org.vfny.geoserver.wms.WMSMapContext;
import org.vfny.geoserver.wms.WmsException;
import org.vfny.geoserver.wms.requests.GetMapRequest;
import org.vfny.geoserver.wms.responses.GetMapResponse;
import com.mockrunner.mock.web.MockHttpServletRequest;
import com.mockrunner.mock.web.MockHttpSession;
import com.mockrunner.mock.web.MockServletContext;
import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.ParseException;
/**
* WMS tests utility class to set up a mocked up catalog and geoserver environment so unit tests
* does not depend on a fully configured geoserver instance, and also they run fast due to no data
* directory set up required.
*
* @author Gabriel Roldan
* @version $Id: WMSMockData.java 13762 2009-12-09 02:22:13Z jdeolive $
*/
public class WMSMockData {
/**
* Namespace used for the resources in this test suite
*/
public static final String TEST_NAMESPACE = "http://geoserver.org";
private CatalogImpl catalog;
private MemoryDataStore dataStore;
private DataStoreInfo dataStoreInfo;
private NamespaceInfoImpl namespaceInfo;
private WorkspaceInfoImpl workspaceInfo;
private StyleInfoImpl defaultStyle;
private GetMapProducer mockMapProducer;
private GeoServer mockGeoServer;
private WMS mockWMS;
@SuppressWarnings("deprecation")
public void setUp() throws Exception {
mockMapProducer = new DummyRasterMapProducer();
catalog = new CatalogImpl();
namespaceInfo = new NamespaceInfoImpl();
namespaceInfo.setId("testNs");
namespaceInfo.setPrefix("geos");
namespaceInfo.setURI(TEST_NAMESPACE);
catalog.add(namespaceInfo);
workspaceInfo = new WorkspaceInfoImpl();
catalog.setDefaultWorkspace(workspaceInfo);
defaultStyle = new StyleInfoImpl(catalog) {
/**
* Override so it does not try to load a file from disk
*/
@Override
public Style getStyle() throws IOException {
StyleFactory styleFactory = CommonFactoryFinder.getStyleFactory(null);
Style style = styleFactory.createStyle();
style.setName("Default Style");
return style;
}
};
defaultStyle.setFilename("defaultStyleFileName");
defaultStyle.setId("defaultStyleId");
defaultStyle.setName("defaultStyleName");
catalog.add(defaultStyle);
// coverageStoreInfo = new CoverageStoreInfoImpl(catalog);
// coverageInfo = new CoverageInfoImpl(catalog);
// coverageLayerInfo = new LayerInfoImpl();
// // setUpBasicTestCoverage(coverageStoreInfo, coverageInfo, coverageLayerInfo);
//
// coverageInfoOldApi = new CoverageInfo(coverageLayerInfo, catalog);
dataStoreInfo = new DataStoreInfoImpl(catalog);
dataStoreInfo.setName("mockDataStore");
dataStoreInfo.setEnabled(true);
dataStoreInfo.setWorkspace(workspaceInfo);
dataStore = new MemoryDataStore();
ResourcePool resourcePool = new ResourcePool(catalog) {
@Override
public DataStore getDataStore(DataStoreInfo info) throws IOException {
return dataStore;
}
};
catalog.setResourcePool(resourcePool);
mockGeoServer = new GeoServerImpl();
mockGeoServer.setCatalog(catalog);
GeoServerInfoImpl geoserverInfo = new GeoServerInfoImpl(mockGeoServer);
geoserverInfo.setId("geoserver");
mockGeoServer.setGlobal(geoserverInfo);
WMSInfoImpl wmsInfo = new WMSInfoImpl();
wmsInfo.setId("wms");
wmsInfo.setName("WMS");
wmsInfo.setEnabled(true);
mockGeoServer.add(wmsInfo);
mockWMS = new WMS(mockGeoServer);
}
/**
* This dummy producer adds no functionality to DefaultRasterMapProducer, just implements a void
* formatImageOutputStream
*
* @author Gabriel Roldan
* @version $Id: WMSMockData.java 13762 2009-12-09 02:22:13Z jdeolive $
*/
public static class DummyRasterMapProducer implements RasterMapProducer {
public static final String MIME_TYPE = "image/dummy";
public WMSMapContext mapContext;
public boolean abortCalled;
public boolean produceMapCalled;
public String outputFormat;
public boolean writeToCalled;
public void formatImageOutputStream(RenderedImage image, OutputStream outStream)
throws WmsException, IOException {
// do nothing
}
public RenderedImage getImage() {
// do nothing
return null;
}
public void abort() {
this.abortCalled = true;
}
public String getContentDisposition() {
// do nothing
return null;
}
public String getContentType() throws IllegalStateException {
return MIME_TYPE;
}
public String getOutputFormat() {
return MIME_TYPE;
}
public void setMapContext(WMSMapContext mapContext) {
this.mapContext = mapContext;
}
public WMSMapContext getMapContext() {
return mapContext;
}
public Set<String> getOutputFormatNames() {
return Collections.singleton(MIME_TYPE);
}
public void produceMap() throws WmsException {
this.produceMapCalled = true;
}
public void setOutputFormat(String format) {
this.outputFormat = format;
}
public void writeTo(OutputStream out) throws ServiceException, IOException {
this.writeToCalled = true;
}
}
public StyleInfo getDefaultStyle() {
return defaultStyle;
}
public GetMapRequest createRequest() {
GetMapRequest request;
request = new GetMapRequest(mockWMS);
request.setFormat(DummyRasterMapProducer.MIME_TYPE);
request.setWidth(512);
request.setHeight(256);
Envelope envelope = new Envelope(-180, 180, -90, 90);
request.setBbox(envelope);
request.setSRS("EPSG:4326");
request.setCrs(DefaultGeographicCRS.WGS84);
try {
request.setStyles(Collections.singletonList(defaultStyle.getStyle()));
} catch (IOException e) {
throw new RuntimeException("shouldn't happen", e);
}
request.setRawKvp(new HashMap<String, Serializable>());
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
request.setHttpServletRequest(servletRequest);
MockHttpSession session = new MockHttpSession();
servletRequest.setSession(session);
MockServletContext context = new MockServletContext();
session.setupServletContext(context);
return request;
}
public GetMapResponse createResponse() {
return createResponse(Collections.singletonList(mockMapProducer));
}
public GetMapResponse createResponse(List<GetMapProducer> availableProducers) {
GetMapResponse getMap;
getMap = new GetMapResponse(availableProducers);
return getMap;
}
/**
* Creates a vector layer with associated FeatureType in the internal MemoryDataStore with the
* given type and two attributes: name:String and geom:geometryType
*/
public MapLayerInfo addFeatureTypeLayer(final String name,
Class<? extends Geometry> geometryType) throws IOException {
org.geoserver.catalog.FeatureTypeInfo featureTypeInfo = new FeatureTypeInfoImpl(catalog);
featureTypeInfo.setName(name);
featureTypeInfo.setNativeName(name);
featureTypeInfo.setEnabled(true);
final DefaultGeographicCRS wgs84 = DefaultGeographicCRS.WGS84;
ReferencedEnvelope bbox = new ReferencedEnvelope(-180, 180, -90, 90, wgs84);
featureTypeInfo.setLatLonBoundingBox(bbox);
featureTypeInfo.setNamespace(namespaceInfo);
featureTypeInfo.setNativeBoundingBox(bbox);
featureTypeInfo.setNativeCRS(wgs84);
featureTypeInfo.setSRS("EPSG:4326");
featureTypeInfo.setProjectionPolicy(ProjectionPolicy.FORCE_DECLARED);
featureTypeInfo.setStore(dataStoreInfo);
catalog.add(featureTypeInfo);
LayerInfo layerInfo = new LayerInfoImpl();
layerInfo.setResource(featureTypeInfo);
layerInfo.setName(name);
layerInfo.setEnabled(true);
layerInfo.setDefaultStyle(defaultStyle);
layerInfo.setType(LayerInfo.Type.VECTOR);
catalog.add(layerInfo);
SimpleFeatureTypeBuilder ftb = new SimpleFeatureTypeBuilder();
ftb.setNamespaceURI(TEST_NAMESPACE);
ftb.setName(name);
ftb.add("name", String.class);
ftb.add("geom", geometryType, wgs84);
SimpleFeatureType featureType = ftb.buildFeatureType();
dataStore.createSchema(featureType);
return new MapLayerInfo(layerInfo);
}
public SimpleFeature addFeature(final SimpleFeatureType featureType, final Object[] values)
throws IOException, ParseException {
FeatureStore<SimpleFeatureType, SimpleFeature> fs;
fs = (FeatureStore<SimpleFeatureType, SimpleFeature>) dataStore
.getFeatureSource(featureType.getName());
SimpleFeatureBuilder sfb = new SimpleFeatureBuilder(featureType);
sfb.addAll(values);
SimpleFeature feature = sfb.buildFeature(null);
fs.addFeatures(DataUtilities.collection(feature));
return feature;
}
}