/* (c) 2014 - 2016 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.config.util;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.measure.unit.SI;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.custommonkey.xmlunit.XMLAssert;
import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.CatalogFactory;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.CoverageView;
import org.geoserver.catalog.CoverageView.CompositionType;
import org.geoserver.catalog.CoverageView.CoverageBand;
import org.geoserver.catalog.CoverageView.InputCoverageBand;
import org.geoserver.catalog.DataStoreInfo;
import org.geoserver.catalog.FeatureTypeInfo;
import org.geoserver.catalog.Keyword;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerGroupInfo.Mode;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataMap;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WMSLayerInfo;
import org.geoserver.catalog.WMSStoreInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.CatalogImpl;
import org.geoserver.catalog.impl.CoverageDimensionImpl;
import org.geoserver.catalog.impl.CoverageStoreInfoImpl;
import org.geoserver.catalog.impl.DataStoreInfoImpl;
import org.geoserver.catalog.impl.MetadataLinkInfoImpl;
import org.geoserver.catalog.impl.WMSStoreInfoImpl;
import org.geoserver.config.ContactInfo;
import org.geoserver.config.GeoServerFactory;
import org.geoserver.config.GeoServerInfo;
import org.geoserver.config.LoggingInfo;
import org.geoserver.config.impl.GeoServerImpl;
import org.geoserver.config.impl.ServiceInfoImpl;
import org.geoserver.config.util.XStreamPersister.CRSConverter;
import org.geoserver.config.util.XStreamPersister.SRSConverter;
import org.geotools.jdbc.RegexpValidator;
import org.geotools.jdbc.VirtualTable;
import org.geotools.jdbc.VirtualTableParameter;
import org.geotools.measure.Measure;
import org.geotools.referencing.CRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.referencing.wkt.Formattable;
import org.geotools.referencing.wkt.UnformattableObjectException;
import org.geotools.util.NumberRange;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.thoughtworks.xstream.XStream;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
public class XStreamPersisterTest {
GeoServerFactory factory;
CatalogFactory cfactory;
XStreamPersister persister;
@Before
public void init() {
factory = new GeoServerImpl().getFactory();
persister = new XStreamPersisterFactory().createXMLPersister();
}
@Test
public void testGlobal() throws Exception {
GeoServerInfo g1 = factory.createGlobal();
g1.setAdminPassword( "foo" );
g1.setAdminUsername( "bar" );
g1.setCharset( "ISO-8859-1" );
ContactInfo contact = factory.createContact();
g1.setContact( contact );
contact.setAddress( "123" );
contact.setAddressCity( "Victoria" );
contact.setAddressCountry( "Canada" );
contact.setAddressPostalCode( "V1T3T8");
contact.setAddressState( "BC" );
contact.setAddressType( "house" );
contact.setContactEmail( "bob@acme.org" );
contact.setContactFacsimile("+1 250 123 4567" );
contact.setContactOrganization( "Acme" );
contact.setContactPerson( "Bob" );
contact.setContactPosition( "hacker" );
contact.setContactVoice( "+1 250 765 4321" );
g1.setNumDecimals( 2 );
g1.setOnlineResource( "http://acme.org" );
g1.setProxyBaseUrl( "http://proxy.acme.org" );
g1.setSchemaBaseUrl( "http://schemas.acme.org");
g1.setTitle( "Acme's GeoServer" );
g1.setUpdateSequence( 123 );
g1.setVerbose( true );
g1.setVerboseExceptions( true );
g1.getMetadata().put( "one", new Integer(1) );
g1.getMetadata().put( "two", new Double(2.2) );
ByteArrayOutputStream out = out();
persister.save( g1, out );
GeoServerInfo g2 = persister.load(in(out),GeoServerInfo.class);
assertEquals( g1, g2 );
Document dom = dom( in( out ) );
assertEquals( "global", dom.getDocumentElement().getNodeName() );
}
@Test
public void testLogging() throws Exception {
LoggingInfo logging = factory.createLogging();
logging.setLevel( "CRAZY_LOGGING" );
logging.setLocation( "some/place/geoserver.log" );
logging.setStdOutLogging( true );
ByteArrayOutputStream out = out();
persister.save( logging, out );
LoggingInfo logging2 = persister.load(in(out),LoggingInfo.class);
assertEquals( logging, logging2 );
Document dom = dom( in( out ) );
assertEquals( "logging", dom.getDocumentElement().getNodeName() );
}
@Test
public void testGobalContactDefault() throws Exception {
GeoServerInfo g1 = factory.createGlobal();
ContactInfo contact = factory.createContact();
g1.setContact( contact );
ByteArrayOutputStream out = out();
persister.save(g1, out);
ByteArrayInputStream in = in( out );
Document dom = dom( in );
Element e = (Element) dom.getElementsByTagName( "contact" ).item(0);
e.removeAttribute( "class" );
in = in( dom );
GeoServerInfo g2 = persister.load( in, GeoServerInfo.class );
assertEquals( g1, g2 );
}
static class MyServiceInfo extends ServiceInfoImpl {
String foo;
String getFoo() {
return foo;
}
void setFoo( String foo ) {
this.foo = foo;
}
public boolean equals(Object obj) {
if ( !( obj instanceof MyServiceInfo ) ) {
return false;
}
MyServiceInfo other = (MyServiceInfo) obj;
if ( foo == null ) {
if ( other.foo != null ) {
return false;
}
}
else {
if ( !foo.equals( other.foo ) ) {
return false;
}
}
return super.equals(other);
}
}
@Test
public void testService() throws Exception {
MyServiceInfo s1 = new MyServiceInfo();
s1.setAbstract( "my service abstract" );
s1.setAccessConstraints( "no constraints" );
s1.setCiteCompliant( true );
s1.setEnabled( true );
s1.setFees( "no fees" );
s1.setFoo( "bar" );
s1.setId( "id" );
s1.setMaintainer( "Bob" );
s1.setMetadataLink( factory.createMetadataLink() );
s1.setName( "MS" );
s1.setOnlineResource( "http://acme.org?service=myservice" );
s1.setOutputStrategy("FAST");
s1.setSchemaBaseURL( "http://schemas.acme.org/");
s1.setTitle( "My Service" );
s1.setVerbose(true);
ByteArrayOutputStream out = out();
persister.save( s1, out );
MyServiceInfo s2 = persister.load( in( out ), MyServiceInfo.class );
assertEquals( s1.getAbstract(), s2.getAbstract() );
assertEquals( s1.getAccessConstraints(), s2.getAccessConstraints() );
assertEquals( s1.isCiteCompliant(), s2.isCiteCompliant() );
assertEquals( s1.isEnabled(), s2.isEnabled() );
assertEquals( s1.getFees(), s2.getFees() );
assertEquals( s1.getFoo(), s2.getFoo() );
assertEquals( s1.getId(), s2.getId() );
assertEquals( s1.getMaintainer(), s2.getMaintainer() );
assertEquals( s1.getMetadataLink(), s2.getMetadataLink() );
assertEquals( s1.getName(), s2.getName() );
assertEquals( s1.getOnlineResource( ), s2.getOnlineResource() );
assertEquals( s1.getOutputStrategy(), s2.getOutputStrategy() );
assertEquals( s1.getSchemaBaseURL(), s2.getSchemaBaseURL() );
assertEquals( s1.getTitle(), s2.getTitle() );
assertEquals( s1.isVerbose(), s2.isVerbose() );
}
@Test
public void testServiceOmitGlobal() throws Exception {
MyServiceInfo s1 = new MyServiceInfo();
s1.setGeoServer( new GeoServerImpl() );
ByteArrayOutputStream out = out();
persister.save( s1, out );
MyServiceInfo s2 = persister.load( in( out ), MyServiceInfo.class );
assertNull( s2.getGeoServer() );
}
@Test
public void testServiceCustomAlias() throws Exception {
XStreamPersister p = persister = new XStreamPersisterFactory().createXMLPersister();
p.getXStream().alias( "ms", MyServiceInfo.class );
MyServiceInfo s1 = new MyServiceInfo();
ByteArrayOutputStream out = out();
p.save( s1, out );
Document dom = dom( in( out ) ) ;
assertEquals( "ms", dom.getDocumentElement().getNodeName() );
}
@Test
public void testDataStore() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
DataStoreInfo ds1 = cFactory.createDataStore();
ds1.setName( "bar" );
ds1.setWorkspace( ws );
ByteArrayOutputStream out = out();
persister.save( ds1 , out );
DataStoreInfo ds2 = persister.load( in( out ), DataStoreInfo.class );
assertEquals( "bar", ds2.getName() );
assertNotNull( ds2.getWorkspace() );
assertEquals( "foo", ds2.getWorkspace().getId() );
Document dom = dom( in( out ) );
assertEquals( "dataStore", dom.getDocumentElement().getNodeName() );
}
@Test
public void testDataStoreReferencedByName() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
DataStoreInfo ds1 = cFactory.createDataStore();
ds1.setName( "bar" );
ds1.setWorkspace( ws );
catalog.detach(ds1);
((DataStoreInfoImpl)ds1).setId(null);
ByteArrayOutputStream out = out();
XStreamPersister persister = new XStreamPersisterFactory().createXMLPersister();
persister.setReferenceByName(true);
persister.save( ds1 , out );
DataStoreInfo ds2 = persister.load( in( out ), DataStoreInfo.class );
assertEquals( "bar", ds2.getName() );
assertNotNull( ds2.getWorkspace() );
assertEquals( "foo", ds2.getWorkspace().getId() );
Document dom = dom( in( out ) );
assertEquals( "dataStore", dom.getDocumentElement().getNodeName() );
}
@Test
public void testCoverageStore() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
CoverageStoreInfo cs1 = cFactory.createCoverageStore();
cs1.setName( "bar" );
cs1.setWorkspace( ws );
ByteArrayOutputStream out = out();
persister.save( cs1 , out );
CoverageStoreInfo ds2 = persister.load( in( out ), CoverageStoreInfo.class );
assertEquals( "bar", ds2.getName() );
assertNotNull( ds2.getWorkspace() );
assertEquals( "foo", ds2.getWorkspace().getId() );
Document dom = dom( in( out ) );
assertEquals( "coverageStore", dom.getDocumentElement().getNodeName() );
}
@Test
public void testCoverageStoreReferencedByName() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
CoverageStoreInfo cs1 = cFactory.createCoverageStore();
cs1.setName( "bar" );
cs1.setWorkspace( ws );
catalog.detach(cs1);
((CoverageStoreInfoImpl)cs1).setId(null);
ByteArrayOutputStream out = out();
XStreamPersister persister = new XStreamPersisterFactory().createXMLPersister();
persister.setReferenceByName(true);
persister.save( cs1 , out );
CoverageStoreInfo ds2 = persister.load( in( out ), CoverageStoreInfo.class );
assertEquals( "bar", ds2.getName() );
assertNotNull( ds2.getWorkspace() );
assertEquals( "foo", ds2.getWorkspace().getId() );
Document dom = dom( in( out ) );
assertEquals( "coverageStore", dom.getDocumentElement().getNodeName() );
}
@Test
public void testWMSStore() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
WMSStoreInfo wms1 = cFactory.createWebMapServer();
wms1.setName( "bar" );
wms1.setWorkspace( ws );
wms1.setCapabilitiesURL( "http://fake.host/wms?request=GetCapabilities&service=wms");
ByteArrayOutputStream out = out();
persister.save( wms1, out );
WMSStoreInfo wms2 = persister.load( in( out ), WMSStoreInfo.class );
assertEquals( "bar", wms2.getName() );
assertEquals(WMSStoreInfoImpl.DEFAULT_MAX_CONNECTIONS, wms2.getMaxConnections());
assertEquals(WMSStoreInfoImpl.DEFAULT_CONNECT_TIMEOUT, wms2.getConnectTimeout());
assertEquals(WMSStoreInfoImpl.DEFAULT_READ_TIMEOUT, wms2.getReadTimeout());
assertNotNull( wms2.getWorkspace() );
assertEquals( "foo", wms2.getWorkspace().getId() );
Document dom = dom( in( out ) );
assertEquals( "wmsStore", dom.getDocumentElement().getNodeName() );
}
@Test
public void testWMSStoreReferencedByName() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
WMSStoreInfo wms1 = cFactory.createWebMapServer();
wms1.setName( "bar" );
wms1.setWorkspace( ws );
wms1.setCapabilitiesURL( "http://fake.host/wms?request=GetCapabilities&service=wms");
catalog.detach(wms1);
((WMSStoreInfoImpl)wms1).setId(null);
ByteArrayOutputStream out = out();
XStreamPersister persister = new XStreamPersisterFactory().createXMLPersister();
persister.setReferenceByName(true);
persister.save( wms1, out );
WMSStoreInfo wms2 = persister.load( in( out ), WMSStoreInfo.class );
assertEquals( "bar", wms2.getName() );
assertEquals(WMSStoreInfoImpl.DEFAULT_MAX_CONNECTIONS, wms2.getMaxConnections());
assertEquals(WMSStoreInfoImpl.DEFAULT_CONNECT_TIMEOUT, wms2.getConnectTimeout());
assertEquals(WMSStoreInfoImpl.DEFAULT_READ_TIMEOUT, wms2.getReadTimeout());
assertNotNull( wms2.getWorkspace() );
assertEquals( "foo", wms2.getWorkspace().getId() );
Document dom = dom( in( out ) );
assertEquals( "wmsStore", dom.getDocumentElement().getNodeName() );
}
/**
* Check maxConnections, connectTimeout, and readTimeout, stored as metadata properties in a
* 2.1.3+ configuration are read back as actual properties.
*/
@Test
public void testWMSStoreBackwardsCompatibility() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
WMSStoreInfo wms1 = cFactory.createWebMapServer();
wms1.setName( "bar" );
wms1.setWorkspace( ws );
wms1.setCapabilitiesURL( "http://fake.host/wms?request=GetCapabilities&service=wms");
wms1.getMetadata().put("maxConnections", Integer.valueOf(18));
wms1.getMetadata().put("connectTimeout", Integer.valueOf(25));
wms1.getMetadata().put("readTimeout", Integer.valueOf(78));
ByteArrayOutputStream out = out();
persister.save( wms1, out );
WMSStoreInfo wms2 = persister.load( in( out ), WMSStoreInfo.class );
assertEquals( "bar", wms2.getName() );
assertEquals(18, wms2.getMaxConnections());
assertEquals(25, wms2.getConnectTimeout());
assertEquals(78, wms2.getReadTimeout());
assertNull(wms2.getMetadata().get("maxConnections"));
assertNull(wms2.getMetadata().get("connectTimeout"));
assertNull(wms2.getMetadata().get("readTimeout"));
}
@Test
public void testStyle() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
StyleInfo s1 = cFactory.createStyle();
s1.setName( "foo" );
s1.setFilename( "foo.sld" );
ByteArrayOutputStream out = out();
persister.save( s1, out );
ByteArrayInputStream in = in( out );
StyleInfo s2 = persister.load(in,StyleInfo.class);
assertEquals( s1, s2 );
Document dom = dom( in( out ) );
assertEquals( "style", dom.getDocumentElement().getNodeName() );
}
@Test
@Ignore // why do we want to xstream persist the catalog again?
public void testCatalog() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
DataStoreInfo ds = cFactory.createDataStore();
ds.setWorkspace( ws );
ds.setName( "foo" );
catalog.add( ds );
CoverageStoreInfo cs = cFactory.createCoverageStore();
cs.setWorkspace( ws );
cs.setName( "bar" );
catalog.add( cs );
StyleInfo s = cFactory.createStyle();
s.setName( "style" );
s.setFilename( "style.sld" );
catalog.add(s);
ByteArrayOutputStream out = out();
persister.save( catalog, out );
catalog = persister.load( in(out), Catalog.class );
assertNotNull(catalog);
assertEquals( 1, catalog.getWorkspaces().size() );
assertNotNull( catalog.getDefaultWorkspace() );
ws = catalog.getDefaultWorkspace();
assertEquals( "foo", ws.getName() );
assertEquals( 1, catalog.getNamespaces().size() );
assertNotNull( catalog.getDefaultNamespace() );
ns = catalog.getDefaultNamespace();
assertEquals( "acme", ns.getPrefix() );
assertEquals( "http://acme.org", ns.getURI() );
assertEquals( 1, catalog.getDataStores().size() );
ds = catalog.getDataStores().get( 0 );
assertEquals( "foo", ds.getName() );
assertNotNull( ds.getWorkspace() );
assertEquals( ws, ds.getWorkspace() );
assertEquals( 1, catalog.getCoverageStores().size() );
cs = catalog.getCoverageStores().get( 0 );
assertEquals( "bar", cs.getName() );
assertEquals( ws, cs.getWorkspace() );
assertEquals( 1, catalog.getStyles().size() );
s = catalog.getStyles().get(0);
assertEquals( "style", s.getName() );
assertEquals( "style.sld", s.getFilename() );
}
@Test
public void testFeatureType() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
DataStoreInfo ds = cFactory.createDataStore();
ds.setWorkspace( ws );
ds.setName( "foo" );
catalog.add( ds );
FeatureTypeInfo ft = cFactory.createFeatureType();
ft.setStore( ds );
ft.setNamespace( ns );
ft.setName( "ft" );
ft.setAbstract( "abstract");
ft.setSRS( "EPSG:4326");
ft.setNativeCRS( CRS.decode( "EPSG:4326") );
ft.setLinearizationTolerance(new Measure(10, SI.METER));
ByteArrayOutputStream out = out();
persister.save( ft, out );
persister.setCatalog( catalog );
ft = persister.load( in( out ), FeatureTypeInfo.class );
assertNotNull( ft );
assertEquals( "ft", ft.getName() );
assertEquals( ds, ft.getStore() );
assertEquals( ns, ft.getNamespace() );
assertEquals( "EPSG:4326", ft.getSRS() );
assertEquals( new Measure(10, SI.METER), ft.getLinearizationTolerance() );
assertTrue( CRS.equalsIgnoreMetadata( CRS.decode( "EPSG:4326"), ft.getNativeCRS() ) );
}
@Test
public void testCoverage() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName("foo");
catalog.add(ws);
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix("acme");
ns.setURI("http://acme.org");
catalog.add(ns);
CoverageStoreInfo cs = cFactory.createCoverageStore();
cs.setWorkspace(ws);
cs.setName("foo");
catalog.add(cs);
CoverageInfo cv = cFactory.createCoverage();
cv.setStore(cs);
cv.setNamespace(ns);
cv.setName("cv");
cv.setAbstract("abstract");
cv.setSRS("EPSG:4326");
cv.setNativeCRS(CRS.decode("EPSG:4326"));
cv.getParameters().put("foo", null);
ByteArrayOutputStream out = out();
persister.save(cv, out);
persister.setCatalog(catalog);
cv = persister.load(in(out), CoverageInfo.class);
assertNotNull(cv);
assertEquals("cv", cv.getName());
assertEquals(cs, cv.getStore());
assertEquals(ns, cv.getNamespace());
assertEquals("EPSG:4326", cv.getSRS());
assertTrue(cv.getParameters().containsKey("foo"));
assertNull(cv.getParameters().get("foo"));
assertTrue(CRS.equalsIgnoreMetadata(CRS.decode("EPSG:4326"), cv.getNativeCRS()));
}
@Test
public void testWMSLayer() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
WMSStoreInfo wms = cFactory.createWebMapServer();
wms.setWorkspace( ws );
wms.setName( "foo" );
wms.setCapabilitiesURL( "http://fake.host/wms?request=getCapabilities");
catalog.add( wms );
WMSLayerInfo wl = cFactory.createWMSLayer();
wl.setStore( wms );
wl.setNamespace( ns );
wl.setName( "wmsLayer" );
wl.setAbstract( "abstract");
wl.setSRS( "EPSG:4326");
wl.setNativeCRS( CRS.decode( "EPSG:4326") );
ByteArrayOutputStream out = out();
persister.save( wl, out );
// System.out.println( new String(out.toByteArray()) );
persister.setCatalog( catalog );
wl = persister.load( in( out ), WMSLayerInfo.class );
assertNotNull( wl );
assertEquals( "wmsLayer", wl.getName() );
assertEquals( wms, wl.getStore() );
assertEquals( ns, wl.getNamespace() );
assertEquals( "EPSG:4326", wl.getSRS() );
assertTrue( CRS.equalsIgnoreMetadata( CRS.decode( "EPSG:4326"), wl.getNativeCRS() ) );
Document dom = dom( in( out ) );
assertEquals( "wmsLayer", dom.getDocumentElement().getNodeName() );
}
@Test
public void testLayer() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
DataStoreInfo ds = cFactory.createDataStore();
ds.setWorkspace( ws );
ds.setName( "foo" );
catalog.add( ds );
FeatureTypeInfo ft = cFactory.createFeatureType();
ft.setStore( ds );
ft.setNamespace( ns );
ft.setName( "ft" );
ft.setAbstract( "abstract");
ft.setSRS( "EPSG:4326");
ft.setNativeCRS( CRS.decode( "EPSG:4326") );
catalog.add( ft );
StyleInfo s = cFactory.createStyle();
s.setName( "style" );
s.setFilename( "style.sld" );
catalog.add( s );
LayerInfo l = cFactory.createLayer();
// TODO: reinstate when layer/publish slipt is actually in place
// l.setName( "layer" );
l.setResource( ft );
l.setDefaultStyle( s );
l.getStyles().add(s);
catalog.add( l );
ByteArrayOutputStream out = out();
persister.save( l, out );
persister.setCatalog( catalog );
l = persister.load( in( out ) , LayerInfo.class );
assertEquals( l.getResource().getName(), l.getName() );
assertEquals( ft, l.getResource() );
assertEquals( s, l.getDefaultStyle() );
assertNotNull(l.getStyles());
assertEquals(1, l.getStyles().size());
assertTrue(l.getStyles().contains(s));
}
@Test
public void testLayerGroupInfo() throws Exception {
for (LayerGroupInfo.Mode mode : LayerGroupInfo.Mode.values()) {
testSerializationWithMode(mode);
}
}
private void testSerializationWithMode(Mode mode) throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
LayerGroupInfo group1 = cFactory.createLayerGroup();
group1.setName("foo");
group1.setTitle("foo title");
group1.setAbstract("foo abstract");
group1.setMode(mode);
ByteArrayOutputStream out = out();
persister.save(group1, out);
// print(in(out));
ByteArrayInputStream in = in(out);
LayerGroupInfo group2 = persister.load(in, LayerGroupInfo.class);
assertEquals(group1.getName(), group2.getName());
assertEquals(group1.getTitle(), group2.getTitle());
assertEquals(group1.getAbstract(), group2.getAbstract());
assertEquals(group1.getMode(), group2.getMode());
Document dom = dom(in(out));
assertEquals("layerGroup", dom.getDocumentElement().getNodeName());
}
@Test
public void testLegacyLayerGroupWithoutMode() throws Exception {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<layerGroup>\n" +
"<name>foo</name>\n" +
"<title>foo title</title>\n" +
"<abstractTxt>foo abstract</abstractTxt>\n" +
"<layers>\n" +
"<layer>\n" +
"<id>LayerInfoImpl--570ae188:124761b8d78:-7fb0</id>\n" +
"</layer>\n" +
"</layers>\n" +
"<styles>\n" +
"<style/>\n" +
"</styles>\n" +
"<bounds>\n" +
"<minx>589425.9342365642</minx>\n" +
"<maxx>609518.6719560538</maxx>\n" +
"<miny>4913959.224611808</miny>\n" +
"<maxy>4928082.949945881</maxy>\n" +
"<crs class=\"projected\">EPSG:26713</crs>\n" +
"</bounds>\n" +
"</layerGroup>\n";
LayerGroupInfo group = persister.load(new ByteArrayInputStream(xml.getBytes()), LayerGroupInfo.class);
Assert.assertEquals(LayerGroupInfo.Mode.SINGLE, group.getMode());
Catalog catalog = new CatalogImpl();
Assert.assertTrue(catalog.validate(group, false).isValid());
}
@Test
public void testVirtualTable() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
DataStoreInfo ds = cFactory.createDataStore();
ds.setWorkspace( ws );
ds.setName( "foo" );
catalog.add( ds );
VirtualTable vt = new VirtualTable("riverReduced",
"select a, b, c * %mulparam% \n from table \n where x > 1 %andparam%");
vt.addGeometryMetadatata("geom", LineString.class, 4326);
vt.setPrimaryKeyColumns(Arrays.asList("a", "b"));
vt.addParameter(new VirtualTableParameter("mulparam", "1", new RegexpValidator("\\d+")));
vt.addParameter(new VirtualTableParameter("andparam", null));
FeatureTypeInfo ft = cFactory.createFeatureType();
ft.setStore( ds );
ft.setNamespace( ns );
ft.setName( "ft" );
ft.setAbstract( "abstract");
ft.setSRS( "EPSG:4326");
ft.setNativeCRS( CRS.decode( "EPSG:4326") );
ft.getMetadata().put(FeatureTypeInfo.JDBC_VIRTUAL_TABLE, vt);
catalog.add( ft );
ByteArrayOutputStream out = new ByteArrayOutputStream();
persister.save(ft, out);
// System.out.println(out.toString());
persister.setCatalog( catalog );
ft = persister.load( in( out ) , FeatureTypeInfo.class );
VirtualTable vt2 = (VirtualTable) ft.getMetadata().get(FeatureTypeInfo.JDBC_VIRTUAL_TABLE);
assertNotNull(vt2);
assertEquals(vt, vt2);
}
/**
* Test for GEOS-6052
*/
@Test
public void testVirtualTableMissingEscapeSql() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
DataStoreInfo ds = cFactory.createDataStore();
ds.setWorkspace( ws );
ds.setName( "foo" );
catalog.add( ds );
persister.setCatalog( catalog );
FeatureTypeInfo ft = persister.load( getClass().getResourceAsStream("/org/geoserver/config/virtualtable_error.xml") , FeatureTypeInfo.class );
VirtualTable vt2 = (VirtualTable) ft.getMetadata().get(FeatureTypeInfo.JDBC_VIRTUAL_TABLE);
assertNotNull(vt2);
assertEquals(1,ft.getMetadata().size());
}
/**
* Another Test for GEOS-6052
*/
@Test
public void testVirtualTableMissingEscapeSqlDoesntSkipElements() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix( "acme" );
ns.setURI( "http://acme.org" );
catalog.add( ns );
DataStoreInfo ds = cFactory.createDataStore();
ds.setWorkspace( ws );
ds.setName( "foo" );
catalog.add( ds );
persister.setCatalog( catalog );
FeatureTypeInfo ft = persister.load( getClass().getResourceAsStream("/org/geoserver/config/virtualtable_error_2.xml") , FeatureTypeInfo.class );
VirtualTable vt2 = (VirtualTable) ft.getMetadata().get(FeatureTypeInfo.JDBC_VIRTUAL_TABLE);
assertNotNull(vt2);
assertEquals(1,ft.getMetadata().size());
assertEquals(1, vt2.getGeometries().size());
String geometryName = vt2.getGeometries().iterator().next();
assertEquals("geometry", geometryName);
assertNotNull(vt2.getGeometryType(geometryName));
assertNotNull(vt2.getNativeSrid(geometryName));
}
@Test
public void testCRSConverter() throws Exception {
CoordinateReferenceSystem crs = CRS.decode("EPSG:4326");
CRSConverter c = new CRSConverter();
assertEquals(crs.toWKT(), c.toString(crs));
assertEquals(DefaultGeographicCRS.WGS84.toWKT(), c.toString(DefaultGeographicCRS.WGS84));
CoordinateReferenceSystem crs2 = (CoordinateReferenceSystem) c.fromString(crs.toWKT());
assertTrue(CRS.equalsIgnoreMetadata(crs, crs2));
crs2 = (CoordinateReferenceSystem) c.fromString("EPSG:4326");
assertTrue(CRS.equalsIgnoreMetadata(crs, crs2));
}
@Test
public void testSRSConverter() throws Exception {
CoordinateReferenceSystem crs = CRS.decode("EPSG:4901");
SRSConverter c = new SRSConverter();
assertEquals("EPSG:4901", c.toString(crs));
// definition with odd UOM that won't be matched to the EPSG one
assertFalse("EPSG:4901".equals(
c.toString(CRS.parseWKT("GEOGCS[\"GCS_ATF_Paris\",DATUM[\"D_ATF\",SPHEROID[\"Plessis_1817\",6376523.0,308.64]],PRIMEM[\"Paris\",2.337229166666667],UNIT[\"Grad\",0.01570796326794897]]"))));
}
@Test
public void testCRSConverterInvalidWKT() throws Exception {
CoordinateReferenceSystem crs = CRS.decode("EPSG:3575");
try {
((Formattable)crs).toWKT(2, true);
fail("expected exception");
}
catch(UnformattableObjectException e){
}
String wkt = null;
try {
wkt = new CRSConverter().toString(crs);
}
catch(UnformattableObjectException e) {
fail("Should have thrown exception");
}
CoordinateReferenceSystem crs2 =
(CoordinateReferenceSystem) new CRSConverter().fromString(wkt);
assertTrue(CRS.equalsIgnoreMetadata(crs, crs2));
}
@Test
public void testMultimapConverter() throws Exception {
XStreamPersisterFactory factory = new XStreamPersisterFactory();
XStreamPersister xmlPersister = factory.createXMLPersister();
XStream xs = xmlPersister.getXStream();
Multimap<String, Object> mmap = ArrayListMultimap.create();
mmap.put("one", "abc");
mmap.put("one", new Integer(2));
mmap.put("two", new NumberRange<Integer>(Integer.class, 10, 20));
ByteArrayOutputStream out = new ByteArrayOutputStream();
persister.save(mmap, out);
// print(in(out));
Multimap mmap2 = persister.load(in(out), Multimap.class);
assertEquals(mmap, mmap2);
}
@Test
public void testPersisterCustomization() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName("foo");
ws.getMetadata().put("banana", new SweetBanana("Musa acuminata"));
XStreamPersisterFactory factory = new XStreamPersisterFactory();
factory.addInitializer(new XStreamPersisterInitializer() {
@Override
public void init(XStreamPersister persister) {
persister.getXStream().alias("sweetBanana", SweetBanana.class);
persister.getXStream().aliasAttribute(SweetBanana.class, "scientificName", "name");
persister.registerBreifMapComplexType("sweetBanana", SweetBanana.class);
}
});
XStreamPersister persister = factory.createXMLPersister();
ByteArrayOutputStream out = new ByteArrayOutputStream();
persister.save(ws, out);
WorkspaceInfo ws2 = persister.load(in(out), WorkspaceInfo.class);
assertEquals(ws, ws2);
Document dom = dom(in(out));
// print(in(out));
XMLAssert.assertXpathEvaluatesTo("Musa acuminata",
"/workspace/metadata/entry[@key='banana']/sweetBanana/@name", dom);
}
@Test
public void testCoverageView() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
CoverageInfo coverage = cFactory.createCoverage();
MetadataMap metadata = coverage.getMetadata();
coverage.setName("test");
coverage.setEnabled(true);
coverage.getAlias().add("alias");
coverage.getKeywords().add(new Keyword("key"));
MetadataLinkInfoImpl metadataLink = new MetadataLinkInfoImpl();
metadataLink.setAbout("about");
coverage.getMetadataLinks().add(metadataLink);
CoverageDimensionImpl coverageDimension = new CoverageDimensionImpl("time");
coverageDimension.setNullValues(Collections.singletonList(new Double(0)));
coverage.getDimensions().add(coverageDimension);
coverage.getInterpolationMethods().add("Bilinear");
coverage.getParameters().put("ParameterKey", "ParameterValue");
coverage.getSupportedFormats().add("GEOTIFF");
coverage.getRequestSRS().add("EPSG:4326");
coverage.getResponseSRS().add("EPSG:4326");
final InputCoverageBand band_u = new InputCoverageBand("u-component_of_current_surface", "0");
final CoverageBand outputBand_u = new CoverageBand(Collections.singletonList(band_u),
"u-component_of_current_surface@0", 0, CompositionType.BAND_SELECT);
final InputCoverageBand band_v = new InputCoverageBand("v-component_of_current_surface", "0");
final CoverageBand outputBand_v = new CoverageBand(Collections.singletonList(band_v),
"v-component_of_current_surface@0", 1, CompositionType.BAND_SELECT);
final List<CoverageBand> coverageBands = new ArrayList<CoverageBand>(2);
coverageBands.add(outputBand_u);
coverageBands.add(outputBand_v);
CoverageView coverageView = new CoverageView("regional_currents", coverageBands);
metadata.put("COVERAGE_VIEW", coverageView);
ByteArrayOutputStream out = new ByteArrayOutputStream();
persister.save(coverage, out);
CoverageInfo coverage2 = persister.load(in(out), CoverageInfo.class);
assertEquals(coverage, coverage2);
}
@Test
public void testVirtualTableOrder() throws Exception {
FeatureTypeInfo ft = persister.load( getClass().getResourceAsStream("/org/geoserver/config/virtualtable_order_error.xml") , FeatureTypeInfo.class );
VirtualTable vtc = (VirtualTable) ft.getMetadata().get(FeatureTypeInfo.JDBC_VIRTUAL_TABLE);
assertEquals(vtc.getSql(),"select * from table\n");
assertEquals(vtc.getName(),"sqlview");
}
@SuppressWarnings("serial")
@Test
public void testVirtualTableMultipleGeoms() throws IOException{
Map<String,String> types=new HashMap<String, String>(){{
put("southernmost_point","com.vividsolutions.jts.geom.Geometry");
put("location_polygon","com.vividsolutions.jts.geom.Geometry");
put("centroid","com.vividsolutions.jts.geom.Geometry");
put("northernmost_point","com.vividsolutions.jts.geom.Geometry");
put("easternmost_point","com.vividsolutions.jts.geom.Geometry");
put("location","com.vividsolutions.jts.geom.Geometry");
put("location_original","com.vividsolutions.jts.geom.Geometry");
put("westernmost_point","com.vividsolutions.jts.geom.Geometry");
}};
Map<String,Integer> srids=new HashMap<String, Integer>(){{
put("southernmost_point",4326);
put("location_polygon",3003);
put("centroid",3004);
put("northernmost_point",3857);
put("easternmost_point",4326);
put("location",3003);
put("location_original",3004);
put("westernmost_point",3857);
}};
FeatureTypeInfo ft = persister.load( getClass().getResourceAsStream("/org/geoserver/config/virtualtable_error_GEOS-7400.xml") , FeatureTypeInfo.class );
VirtualTable vt3 = (VirtualTable) ft.getMetadata().get(FeatureTypeInfo.JDBC_VIRTUAL_TABLE);
assertEquals(8, vt3.getGeometries().size());
for(String g:vt3.getGeometries()){
Class<? extends Geometry> geom = vt3.getGeometryType(g);
assertEquals(srids.get(g).intValue(), vt3.getNativeSrid(g));
assertEquals(types.get(g), geom.getName());
}
}
/**
* Test for GEOS-7444.
* Check GridGeometry is correctly unmarshaled when XML elements are
* provided on an different order than the marshaling one
* @throws Exception
*/
@Test
public void testGridGeometry2DConverterUnmarshalling() throws Exception {
Catalog catalog = new CatalogImpl();
CatalogFactory cFactory = catalog.getFactory();
WorkspaceInfo ws = cFactory.createWorkspace();
ws.setName( "foo" );
catalog.add( ws );
NamespaceInfo ns = cFactory.createNamespace();
ns.setPrefix("acme");
ns.setURI("http://acme.org");
catalog.add(ns);
CoverageStoreInfo cs = cFactory.createCoverageStore();
cs.setWorkspace(ws);
cs.setName("coveragestore");
catalog.add(cs);
CoverageInfo cv = cFactory.createCoverage();
cv.setStore(cs);
cv.setNamespace(ns);
cv.setName("coverage");
cv.setAbstract("abstract");
cv.setSRS("EPSG:4326");
cv.setNativeCRS(CRS.decode("EPSG:4326"));
cv.getParameters().put("foo", null);
ByteArrayOutputStream out = out();
persister.save( cv, out );
ByteArrayInputStream in = in( out );
Document dom = dom( in );
Element crs = dom.createElement("crs");
Text t = dom.createTextNode("EPSG:4326");
crs.appendChild(t);
Element high = dom.createElement("high");
t = dom.createTextNode("4029 4029");
high.appendChild(t);
Element low = dom.createElement("low");
t = dom.createTextNode("0 0");
low.appendChild(t);
Element range = dom.createElement("range");
range.appendChild(high);
range.appendChild(low);
Element translateX = dom.createElement("translateX");
t = dom.createTextNode("0");
translateX.appendChild(t);
Element translateY = dom.createElement("translateY");
t = dom.createTextNode("0");
translateY.appendChild(t);
Element scaleX = dom.createElement("scaleX");
t = dom.createTextNode("1");
scaleX.appendChild(t);
Element scaleY = dom.createElement("scaleY");
t = dom.createTextNode("1");
scaleY.appendChild(t);
Element shearX = dom.createElement("shearX");
t = dom.createTextNode("0");
shearX.appendChild(t);
Element shearY = dom.createElement("shearY");
t = dom.createTextNode("0");
shearY.appendChild(t);
Element transform = dom.createElement("transform");
transform.appendChild(translateX);
transform.appendChild(translateY);
transform.appendChild(scaleX);
transform.appendChild(scaleY);
transform.appendChild(shearX);
transform.appendChild(shearY);
Element grid = dom.createElement("grid");
grid.setAttribute("dimension", "2");
grid.appendChild(crs);
grid.appendChild(range);
grid.appendChild(transform);
Element e = (Element) dom.getElementsByTagName( "coverage" ).item(0);
Element params = (Element) dom.getElementsByTagName( "parameters" ).item(0);
e.insertBefore(grid, params);
in = in( dom );
persister.setCatalog( catalog );
cv = persister.load( in, CoverageInfo.class );
assertNotNull( cv );
assertNotNull( cv.getGrid() );
assertNotNull( cv.getGrid().getGridRange() );
assertNotNull( cv.getCRS() );
assertNotNull( cv.getGrid().getGridToCRS() );
assertEquals( cv.getGrid().getGridRange().getLow(0), 0);
}
ByteArrayOutputStream out() {
return new ByteArrayOutputStream();
}
ByteArrayInputStream in( ByteArrayOutputStream in ) {
return new ByteArrayInputStream( in.toByteArray() );
}
ByteArrayInputStream in( Document dom ) throws Exception {
Transformer tx = TransformerFactory.newInstance().newTransformer();
tx.setOutputProperty( OutputKeys.INDENT, "yes" );
ByteArrayOutputStream out = out();
tx.transform( new DOMSource( dom ), new StreamResult( out ) );
return in( out );
}
protected Document dom( InputStream in ) throws ParserConfigurationException, SAXException, IOException {
return
DocumentBuilderFactory.newInstance().newDocumentBuilder().parse( in );
}
protected void print( InputStream in ) throws Exception {
Transformer tx = TransformerFactory.newInstance().newTransformer();
tx.setOutputProperty( OutputKeys.INDENT, "yes" );
tx.transform( new StreamSource( in ), new StreamResult( System.out ) );
}
static class SweetBanana implements Serializable {
String scientificName;
public SweetBanana(String scientificName) {
super();
this.scientificName = scientificName;
}
}
}