diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java index 8780c27..3d38c3b 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSResourceEncoder.java @@ -51,6 +51,7 @@ import org.jdom.filter.Filter; public abstract class GSResourceEncoder extends PropertyXMLEncoder { public final static String NAME = "name"; + public final static String NATIVENAME = "nativeName"; public final static String METADATA="metadata"; public final static String KEYWORDS="keywords"; public final static String METADATALINKS="metadataLinks"; @@ -236,6 +237,42 @@ public abstract class GSResourceEncoder return null; } + + /** + * Add the 'nativename' node with a text value from 'name' + * + * + */ + protected void addNativeName(final String nativename) { + add(NATIVENAME, nativename); + } + + + /** + * Set or modify the 'nativename' node with a text value from 'name' + * + * @note if not specified, the nativeName will be set with the value of the + * 'name' node. + * + */ + public void setNativeName(final String nativename) { + set(NATIVENAME, nativename); + } + + + /** + * Get the nativeName + * + * @return + */ + public String getNativeName() { + final Element nameNode = ElementUtils.contains(getRoot(), NATIVENAME, 1); + if (nameNode != null) + return nameNode.getText(); + else + return null; + } + private final static String DESCRIPTION = "description"; /** diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureTypeEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureTypeEncoder.java index d55e528..ff59e84 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureTypeEncoder.java +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureTypeEncoder.java @@ -27,6 +27,7 @@ package it.geosolutions.geoserver.rest.encoder.feature; import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder; import it.geosolutions.geoserver.rest.encoder.metadata.GSFeatureDimensionInfoEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.GSVirtualTableEncoder; import org.jdom.Element; @@ -60,6 +61,34 @@ public class GSFeatureTypeEncoder extends GSResourceEncoder { super.setMetadata(key, dimensionInfo); } + /** + * Add a VirtualTable (SQL View feature type) + * + * @param virtualtable + */ + protected void addMetadataVirtualTable( + final GSVirtualTableEncoder virtualtable) { + super.addMetadata("JDBC_VIRTUAL_TABLE", virtualtable); + } + + /** + * Set a VirtualTable (SQL View feature type) + * + * @param virtualtable + */ + public void setMetadataVirtualTable(final GSVirtualTableEncoder virtualtable) { + super.setMetadata("JDBC_VIRTUAL_TABLE", virtualtable); + } + + /** + * Deletes the VirtualTable metadata + * + * @return true if deleted, false otherwise + */ + public boolean delMetadataVirtualTable() { + return super.delMetadata("JDB_VIRTUAL_TABLE"); + } + /** * delete a keyword from the list * diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/GSVirtualTableEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/GSVirtualTableEncoder.java new file mode 100644 index 0000000..b7c36ee --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/GSVirtualTableEncoder.java @@ -0,0 +1,341 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package it.geosolutions.geoserver.rest.encoder.metadata.virtualtable; + +import java.util.List; + +import org.jdom.Element; +import org.jdom.filter.Filter; + +import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils; +import it.geosolutions.geoserver.rest.encoder.utils.XmlElement; + +/** + * GSVirtualTableEncoder - Encodes a metadata VirtualTable for a GeoServer + * featureType. + * + * Example (based on the example provided in the Geoserver documentation - see + * {@link http://docs.geoserver.org/latest/en/user/data/database/sqlview.html# + * parameterizing-sql-views}): + * + *
+ * {
+ * 	@code
+ * 	// Set-up the vtGeom
+ * 	final VTGeometryEncoder vtGeom = new VTGeometryEncoder();
+ * 	vtGeom.setName("the_geom");
+ * 	vtGeom.setType("MultiPolygon");
+ * 	vtGeom.setSrid("4326");
+ * 
+ * 	// Set-up 2 virtual table parameters
+ * 	final VTParameterEncoder vtParam1 = new VTParameterEncoder("high",
+ * 			"100000000", "^[\\d]+$");
+ * 	final VTParameterEncoder vtParam2 = new VTParameterEncoder("low", "0",
+ * 			"^[\\d]+$");
+ * 
+ * 	// sql
+ * 	String sql = "select gid, state_name, the_geom from pgstates where persons between %low% and %high%";
+ * 
+ * 	// Set-up the virtual table
+ * 	final GSVirtualTableEncoder vte = new GSVirtualTableEncoder();
+ * 	vte.setName("popstates");
+ * 	vte.setSql("select gid, state_name, the_geom from pgstates where persons between %low% and %high%");
+ * 	vte.addKeyColumn("gid");
+ * 	vte.addVirtualTableGeometry(vtGeom);
+ * 	vte.addVirtualTableParameter(vtParam1);
+ * 	vte.addVirtualTableParameter(vtParam2);
+ * }
+ * 
+ * + * For this example, the XML output is: + * + *
+ * {@code
+ * 
+ * 	popstates
+ * 	select gid, state_name, the_geom from pgstates where persons between %low% and %high%
+ * 	
+ * 		the_geom
+ * 		MultiPolygon
+ * 		4326
+ * 	
+ *  gid
+ * 	
+ * 		high
+ * 		100000000
+ * 		^[\d]+$
+ * 	
+ * 	
+ * 		low
+ * 		0
+ * 		^[\d]+$
+ * 	
+ * 
+ * }
+ * 
+ * + * @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | + * emmanuel.blondel@fao.org + * + */ +public class GSVirtualTableEncoder extends XmlElement { + + public final static String NAME = "name"; + public final static String SQL = "sql"; + public final static String KEYCOLUMN = "keyColumn"; + + /** + * Constructs a GSVirtualTableEncoder + */ + public GSVirtualTableEncoder() { + super("virtualTable"); + } + + /** + * Constructs directly a GSVirtualTableEncoder + * + * @param name (required) + * @param sql (required) + * @param keyColumns (optional) + * @param geomEncList (optional for geometryless sql view) + * @param paramEncList (optional) + */ + public GSVirtualTableEncoder(String name, String sql, List keyColumns, + List geomEncList, + List paramEncList){ + super("virtualTable"); + this.setup(name, sql, keyColumns, geomEncList, paramEncList); + } + + /** + * Set-up quickly a GSVirtualTableEncoder + * + * @param name (must be the same as the featureType nativeName) + * @param sql + * @param keyColumns + * @param geomEncList + * @param paramEncList + */ + protected void setup(String name, String sql, List keyColumns, + List geomEncList, + List paramEncList) { + + setName(name); + setSql(sql); + + if (keyColumns != null) { + for (String pk : keyColumns) { + addKeyColumn(pk); + } + } + + if (geomEncList != null) { + for (VTGeometryEncoder geomEnc : geomEncList) { + addVirtualTableGeometry(geomEnc); + } + } + + if (paramEncList != null) { + for(VTParameterEncoder paramEnc : paramEncList){ + addVirtualTableParameter(paramEnc); + } + } + } + + /** + * Add the 'name' node with a text value from 'name' + * + * @note REQUIRED to configure a virtual table + */ + protected void addName(final String name){ + add(NAME, name); + } + + /** + * Set or modify the 'name' node with a text value from 'name' + * + * @note REQUIRED to configure a virtual table + */ + public void setName(final String name) { + set(NAME, name); + } + + /** + * Get the name of the virtual table + * + * @return + */ + public String getName() { + final Element nameNode = ElementUtils.contains(getRoot(), NAME, 1); + if (nameNode != null) + return nameNode.getText(); + else + return null; + } + + /** + * Add the 'sql' node with a text value from 'sql' + * + * @note REQUIRED to configure a virtual table + */ + protected void addSql(final String sql){ + add(SQL, sql); + } + + /** + * Set or modify the 'sql' node with a text value from 'sql' + * + * @note REQUIRED to configure a virtual table + */ + public void setSql(final String sql) { + set(SQL, sql); + } + + /** + * Get the sql query + * + * @return + */ + public String getSql() { + final Element sqlNode = ElementUtils.contains(getRoot(), SQL, 1); + if (sqlNode != null) + return sqlNode.getText(); + else + return null; + } + + /** + * Adds a keyColumn + * + * @param keycolumn + */ + public void addKeyColumn(String keycolumn){ + final Element el = new Element(KEYCOLUMN); + el.setText(keycolumn); + this.getRoot().addContent(el); + } + + /** + * Deletes a keyColumn + * + * @param keycolumn + * @return true if the keycolumn was removed + */ + public boolean delKeyColumn(final String keycolumn){ + final Element el = new Element(KEYCOLUMN); + el.setText(keycolumn); + return (this.getRoot().removeContent(new Filter() { + private static final long serialVersionUID = 1L; + + public boolean matches(Object obj) { + if (((Element) obj).getText().equals(keycolumn)) { + return true; + } + return false; + } + })).size() == 0 ? false : true; + } + + /** + * Adds a geometry to the VirtualTable + * + * @param geomEnc + */ + public void addVirtualTableGeometry(VTGeometryEncoder geomEnc){ + this.getRoot().addContent(geomEnc.getRoot()); + } + + /** + * Adds quickly a geometry to the virtual table + * + * @param name + * @param geometryType + * @param srid + */ + public void addVirtualTableGeometry(String name, String geometryType, String srid){ + final VTGeometryEncoder gEnc = new VTGeometryEncoder(); + gEnc.setup(name, geometryType, srid); + this.getRoot().addContent(gEnc.getRoot()); + } + + /** + * Deletes a geometry from the VirtualTable + * + * @param name + * @return true if the geometry was removed, otherwise false + */ + public boolean delVirtualTableGeometry(String name){ + return (this.getRoot() + .removeContent(VTGeometryEncoder + .getFilterByName(name))).size() == 0 ? false + : true; + } + + /** + * Adds a parameter to the VirtualTable + * + * @param paramEnc + */ + public void addVirtualTableParameter(VTParameterEncoder paramEnc){ + this.getRoot().addContent(paramEnc.getRoot()); + } + + /** + * Adds quickly a parameter to the VirtualTable + * + * @param name + * @param defaultValue + * @param regexpValidator + */ + public void addVirtualTableParameter(String name, String defaultValue, String regexpValidator){ + final VTParameterEncoder pEnc = new VTParameterEncoder(); + pEnc.setup(name, defaultValue, regexpValidator); + this.getRoot().addContent(pEnc.getRoot()); + } + + /** + * Deletes a parameter from the VirtualTable + * + * @param name + * @return + */ + public boolean delVirtualTableParameter(String name){ + return (this.getRoot() + .removeContent(VTParameterEncoder + .getFilterByName(name))).size() == 0 ? false + : true; + } + + + /* + * a method to check either the virtual parameters as specified in the sql + * query map those encoded in VTParameterEncoder, i.e. check the number and + * names of parameters. + */ + public boolean validate() throws IllegalStateException{ + throw new UnsupportedOperationException("not yet implemented"); + } + +} diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTGeometry.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTGeometry.java new file mode 100644 index 0000000..602d352 --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTGeometry.java @@ -0,0 +1,36 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package it.geosolutions.geoserver.rest.encoder.metadata.virtualtable; + +/** + * Enumeration of Virtual Table geometry members + * + * @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | + * emmanuel.blondel@fao.org + * + */ +public enum VTGeometry { + name, type, srid +} diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTGeometryEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTGeometryEncoder.java new file mode 100644 index 0000000..cf85741 --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTGeometryEncoder.java @@ -0,0 +1,247 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package it.geosolutions.geoserver.rest.encoder.metadata.virtualtable; + +import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils; +import it.geosolutions.geoserver.rest.encoder.utils.XmlElement; + +import org.jdom.Element; +import org.jdom.filter.Filter; + +/** + * VTGeometryEncoder - Encodes a metadata VirtualTable geometry for a + * GeoServer featureType, as follows: + * + *
+ * {
+ * 	@code
+ * 	final VTGeometryEncoder vtGeom = new VTGeometryEncoder();
+ * 	vtGeom.setName("the_geom");
+ * 	vtGeom.setType("MultiPolygon");
+ * 	vtGeom.setSrid("4326");
+ * }
+ * 
+ * + * For this example, the XML output is: + * + *
+ * {@code
+ * 
+ * 	the_geom
+ * 	MultiPolygon
+ * 	4326
+ * 
+ * }
+ * 
+ * + * @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | + * emmanuel.blondel@fao.org + * + */ +public class VTGeometryEncoder extends XmlElement { + + /** + * A class to filter the VirtualTable geometries by name + * + */ + private static class filterByName implements Filter { + + final private String key; + + public filterByName(String name) { + this.key = name; + } + + private static final long serialVersionUID = 1L; + + public boolean matches(Object obj) { + Element el = ((Element) obj) + .getChild(VTGeometry.name.toString()); + if (el != null && el.getTextTrim().equals(key)) { + return true; + } + return false; + } + } + + /** + * Get a Filter using the VTGeometry name + * + * @param name + * @return the filter + */ + public static Filter getFilterByName(String name) { + return new filterByName(name); + } + + /** + * Constructs a GSVirtualTableGeomEncoder + * + */ + public VTGeometryEncoder() { + super("geometry"); + } + + /** + * Constructs quickly a VTGeometryEncoder + * + * @param name (required) + * @param geometryType (required) + * @param srid (required) + */ + public VTGeometryEncoder(String name, String geometryType, String srid) { + super("geometry"); + this.setup(name, geometryType, srid); + } + + /** + * Set-up quickly a GSVirtualTableGeomEncoder + * + * @param name + * @param geometryType + * @param srid + */ + protected void setup(String name, String geometryType, String srid) { + setName(name); + setType(geometryType); + setSrid(srid); + } + + /** + * Set a VirtualTable Geometry member + * + * @param type + * @param value + */ + protected void setMember(VTGeometry type, + String value) { + set(type.toString(), value); + } + + /** + * Set a geometry name + * + * @param name + */ + public void setName(String name){ + this.setMember(VTGeometry.name, name); + } + + /** + * Set a geometry type + * + * @param type + */ + public void setType(String type){ + this.setMember(VTGeometry.type, type); + } + + /** + * Set a geometry srid + * + * @param srid + */ + public void setSrid(String srid){ + this.setMember(VTGeometry.srid, srid); + } + + /** + * Deletes a VirtualTableGeometry member + * + * @param type + * @return true if removed, false otherwise + */ + protected boolean delMember(VTGeometry type) { + return ElementUtils.remove(this.getRoot(), this.getRoot().getChild(type.toString())); + } + + /** + * Deletes the name + * + * @return true if removed, false otherwise + */ + public boolean delName(){ + return this.delMember(VTGeometry.name); + } + + /** + * Deletes the type + * + * @return true if removed, false otherwise + */ + public boolean delType(){ + return this.delMember(VTGeometry.type); + } + + /** + * Deletes the srid + * + * @return true if removed, false otherwise + */ + public boolean delSrid(){ + return this.delMember(VTGeometry.srid); + } + + /** + * Get the VirtualTableGeometry member value + * + * @param type + * @return + */ + protected String getMember(VTGeometry type) { + Element el = this.getRoot().getChild(type.toString()); + if (el != null) + return el.getTextTrim(); + else + return null; + } + + /** + * Get the geometry column name + * + * @return + */ + public String getName(){ + return this.getMember(VTGeometry.name); + } + + /** + * Get the geometry column type + * + * @return + */ + public String getType(){ + return this.getMember(VTGeometry.type); + } + + /** + * Get the geometry column srid + * + * @return + */ + public String getSrid(){ + return this.getMember(VTGeometry.srid); + } +} \ No newline at end of file diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTParameter.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTParameter.java new file mode 100644 index 0000000..a454c67 --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTParameter.java @@ -0,0 +1,37 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package it.geosolutions.geoserver.rest.encoder.metadata.virtualtable; + +/** + * Enumeration of SQL View featureType virtual table parameter members + * + * @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | + * emmanuel.blondel@fao.org + * + */ +public enum VTParameter { + name, defaultValue, regexpValidator + +} diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTParameterEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTParameterEncoder.java new file mode 100644 index 0000000..5a2995f --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/metadata/virtualtable/VTParameterEncoder.java @@ -0,0 +1,246 @@ +/* + * GeoServer-Manager - Simple Manager Library for GeoServer + * + * Copyright (C) 2007,2011 GeoSolutions S.A.S. + * http://www.geo-solutions.it + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package it.geosolutions.geoserver.rest.encoder.metadata.virtualtable; + +import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils; +import it.geosolutions.geoserver.rest.encoder.utils.XmlElement; + +import org.jdom.Element; +import org.jdom.filter.Filter; + +/** + * VTParameterEncoder - Encodes a metadata VirtualTable parameter for a + * GeoServer featureType, as follows: + * + *
+ * { @code
+ * 	final VTParameterEncoder vtParam = new VTParameterEncoder();
+ * 	vtParam.setName("fieldname");
+ * 	vtParam.setDefaultValue("default_value");
+ * 	vtParam.setRegexpValidator("^[\\w\\d\\s]+$");
+ * }
+ * 
+ * + * For this example, the XML output is: + * + *
+ * { @code
+ * 
+ * 	fieldname
+ * 	default_value
+ * 	^[\w\d\s]+$
+ * 
+ * }
+ * 
+ * + * @author Emmanuel Blondel - emmanuel.blondel1@gmail.com | + * emmanuel.blondel@fao.org + * + */ +public class VTParameterEncoder extends XmlElement { + + /** + * A class to filter the VirtualTable parameters by name + * + */ + private static class filterByName implements Filter { + + final private String key; + + public filterByName(String name) { + this.key = name; + } + + private static final long serialVersionUID = 1L; + + public boolean matches(Object obj) { + Element el = ((Element) obj) + .getChild(VTParameter.name.toString()); + if (el != null && el.getTextTrim().equals(key)) { + return true; + } + return false; + } + } + + /** + * Get a Filter using the VTParameter name + * + * @param name + * @return the filter + */ + public static Filter getFilterByName(String name) { + return new filterByName(name); + } + + /** + * Constructs a GSVirtualTableParamEncoder + */ + public VTParameterEncoder() { + super("parameter"); + } + + /** + * Constructs quickly a VTParameterEncoder + * + * @param name (required) + * @param defaultValue (required) + * @param regexpValidator (required) + */ + public VTParameterEncoder(String name, String defaultValue, String regexpValidator){ + super("parameter"); + this.setup(name, defaultValue, regexpValidator); + } + + /** + * Set-up quickly a VirtualTable parameter + * + * @param name + * @param defaultValue + * @param regexpValidator + */ + protected void setup(String name, String defaultValue, String regexpValidator) { + setName(name); + setDefaultValue(defaultValue); + setRegexpValidator(regexpValidator); + } + + /** + * Set a VirtualTableParameter member + * + * @param type + * @param value + */ + protected void setMember(VTParameter type, + String value) { + set(type.toString(), value); + } + + /** + * Set the parameter name + * + * @param name + */ + public void setName(String name){ + this.setMember(VTParameter.name, name); + } + + /** + * Set the parameter default value + * + * @param value + */ + public void setDefaultValue(String value){ + this.setMember(VTParameter.defaultValue, value); + } + + /** + * Set the parameter regexp validator + * + * @param validator + */ + public void setRegexpValidator(String validator){ + this.setMember(VTParameter.regexpValidator, validator); + } + + /** + * Deletes a VirtualTableParameter member + * + * @param type + * @return + */ + protected boolean delMember(VTParameter type) { + return ElementUtils.remove(this.getRoot(), this.getRoot().getChild(type.toString())); + } + + /** + * Deletes the name + * + * @return true if removed, false otherwise + */ + public boolean delName(){ + return this.delMember(VTParameter.name); + } + + /** + * Deletes the default value + * + * @return true if removed, false otherwise + */ + public boolean delDefaultValue(){ + return this.delMember(VTParameter.defaultValue); + } + + /** + * Deletes the Regexp validator + * + * @return true if removed, false otherwise + */ + public boolean delRegexpValidator(){ + return this.delMember(VTParameter.regexpValidator); + } + + + /** + * Get a VirtualTableParameter member + * + * @param type + * @return + */ + protected String getMember(VTParameter type) { + Element el = getRoot().getChild(type.toString()); + if (el != null) + return el.getTextTrim(); + else + return null; + } + + /** + * Get the parameter name + * + * @return + */ + public String getName(){ + return this.getMember(VTParameter.name); + } + + /** + * Get the parameter default value + * + * @return + */ + public String getDefaultValue(){ + return this.getMember(VTParameter.defaultValue); + } + + /** + * Get the parameter regexp validator + * + * @return + */ + public String getRegexpValidator(){ + return this.getMember(VTParameter.regexpValidator); + } +} \ No newline at end of file diff --git a/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureEncoderTest.java b/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureEncoderTest.java index fb2172a..019183c 100644 --- a/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureEncoderTest.java +++ b/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSFeatureEncoderTest.java @@ -28,6 +28,9 @@ import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder; import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder.Presentation; import it.geosolutions.geoserver.rest.encoder.metadata.GSDimensionInfoEncoder.PresentationDiscrete; import it.geosolutions.geoserver.rest.encoder.metadata.GSFeatureDimensionInfoEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.GSVirtualTableEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.VTGeometryEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.VTParameterEncoder; import it.geosolutions.geoserver.rest.encoder.metadatalink.GSMetadataLinkInfoEncoder; import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils; import it.geosolutions.geoserver.rest.publisher.GeoserverRESTPublisherTest; @@ -229,4 +232,89 @@ public class GSFeatureEncoderTest extends GeoserverRESTPublisherTest { LOGGER.info("REMOVED"); } + + /** + * Test method for virtual table encoding / SQL view layer integration + * + * Settings information for integration tests + * - test is based on the data used in http://docs.geoserver.org/latest/en/user/data/database/sqlview.html#parameterizing-sql-views + * (states shapefile - available in testdata/states.zip) + * - create a postgis db + * - import the states shapefile (using shp2pgsql or Postgis shapefile uploader) + * - In Geoserver, create a postgis datastore for this DB, with the name "statesdb" + * + */ + @Test + public void testSQLViewIntegration() { + + if (!enabled()) + return; + deleteAll(); + GeoServerRESTPublisher publisher = new GeoServerRESTPublisher(RESTURL, + RESTUSER, RESTPW); + + String storeName = "statesdb"; // name of the datastore setup for tests + String layerName = "my_sqlviewlayer"; + String nativeName = "popstates"; + + GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder(); + fte.setName(layerName); + fte.setNativeName(nativeName); + fte.setTitle("title"); + + fte.addKeyword("keyword1"); + fte.addKeyword("keyword2"); + fte.setNativeCRS("EPSG:4326"); + fte.setDescription("desc"); + fte.setEnabled(true); + + // virtual table + // ------------- + // Set-up the vtGeom + final VTGeometryEncoder vtGeom = new VTGeometryEncoder("the_geom", + "Point", "4326"); + + // Set-up 2 virtual table parameters + final VTParameterEncoder vtParam1 = new VTParameterEncoder("high", + "100000000", "^[\\d]+$"); + final VTParameterEncoder vtParam2 = new VTParameterEncoder("low", "0", + "^[\\d]+$"); + + // sql + String sql = "select gid, state_name, the_geom from pgstates where persons between %low% and %high% and state_abbr = '%state%'"; + + // set-up the virtual table + final GSVirtualTableEncoder vte = new GSVirtualTableEncoder(); + vte.setName(nativeName); + vte.setSql(sql); + vte.addVirtualTableGeometry(vtGeom); + vte.addVirtualTableParameter(vtParam1); + vte.addVirtualTableParameter(vtParam2); + fte.setMetadataVirtualTable(vte); // Set the virtual table + + // modif the vte + vte.delVirtualTableGeometry("the_geom"); + vte.addVirtualTableGeometry("the_geom", "MultiPolygon", "4326"); + + final VTParameterEncoder vtParam3 = new VTParameterEncoder("state", + "FL", "^[\\w\\d\\s]+$"); + vte.addVirtualTableParameter(vtParam3); + vte.addKeyColumn("gid"); + + // Layer encoder + // ------------- + GSLayerEncoder layerEncoder = new GSLayerEncoder(); + layerEncoder.setEnabled(true); + layerEncoder.setQueryable(true); + layerEncoder.setDefaultStyle("polygon"); + + // test insert + // ------------ + publisher.createWorkspace(DEFAULT_WS); + boolean published = publisher.publishDBLayer(DEFAULT_WS, storeName, + fte, layerEncoder); + assertTrue("Successfull publication", published); + assertTrue(existsLayer(layerName)); + + } } diff --git a/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSVirtualTableEncoderTest.java b/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSVirtualTableEncoderTest.java new file mode 100644 index 0000000..f808f1d --- /dev/null +++ b/src/test/java/it/geosolutions/geoserver/rest/encoder/feature/GSVirtualTableEncoderTest.java @@ -0,0 +1,98 @@ +package it.geosolutions.geoserver.rest.encoder.feature; + +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.GSVirtualTableEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.VTGeometryEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.VTParameterEncoder; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.VTGeometry; +import it.geosolutions.geoserver.rest.encoder.metadata.virtualtable.VTParameter; +import it.geosolutions.geoserver.rest.encoder.utils.XmlElement; + +import java.util.Arrays; + +import junit.framework.Assert; + +import org.jdom.Element; +import org.junit.Test; + +/** + * + * @author eblondel + * + */ +public class GSVirtualTableEncoderTest { + + @Test + public void virtualTableTest() { + + // Set-up the vtGeom + final VTGeometryEncoder vtGeom = new VTGeometryEncoder("the_geom", + "MultiPolygon", "4326"); + + // Set-up 2 virtual table parameters + final VTParameterEncoder vtParam1 = new VTParameterEncoder( + "fieldname1", "default_value1", "^[\\w\\d\\s]+$"); + final VTParameterEncoder vtParam2 = new VTParameterEncoder( + "fieldname2", "default_value2", "^[\\w\\d\\s]+$"); + + // sql + String sql = "select the_geom, id, field1, field2 from mytable where field1 = '%fieldname1%' and field2 = '%fieldname2%'"; + + // Set-up the virtual table + final GSVirtualTableEncoder vte = new GSVirtualTableEncoder(); + vte.setName("mysqlview"); + vte.setSql(sql); + vte.addKeyColumn("id"); + vte.addVirtualTableGeometry(vtGeom); + vte.addVirtualTableParameter(vtParam1); + vte.addVirtualTableParameter(vtParam2); + + // TESTS + + Assert.assertEquals("mysqlview", vte.getName()); + Assert.assertEquals(sql, vte.getSql()); + Assert.assertEquals("id", vte.getRoot().getChildText("keyColumn")); + + final Element ge = (Element) vte.getRoot().getChild("geometry"); + Assert.assertEquals("the_geom", + ge.getChildText(VTGeometry.name.toString())); + Assert.assertEquals("MultiPolygon", + ge.getChildText(VTGeometry.type.toString())); + Assert.assertEquals("4326", ge.getChildText(VTGeometry.srid.toString())); + + final Element p1 = (Element) vte.getRoot().getChildren("parameter") + .get(0); + final Element p2 = (Element) vte.getRoot().getChildren("parameter") + .get(1); + Assert.assertEquals("fieldname1", + p1.getChildText(VTParameter.name.toString())); + Assert.assertEquals("default_value1", + p1.getChildText(VTParameter.defaultValue.toString())); + Assert.assertEquals("^[\\w\\d\\s]+$", + p1.getChildText(VTParameter.regexpValidator.toString())); + Assert.assertEquals("fieldname2", + p2.getChildText(VTParameter.name.toString())); + Assert.assertEquals("default_value2", + p2.getChildText(VTParameter.defaultValue.toString())); + Assert.assertEquals("^[\\w\\d\\s]+$", + p2.getChildText(VTParameter.regexpValidator.toString())); + + vte.delKeyColumn("id"); + Assert.assertNull(vte.getRoot().getChildText("keyColumn")); + Assert.assertEquals("mysqlview", vte.getName()); + Assert.assertEquals(sql, vte.getSql()); + + vtGeom.setType("Point"); + vtParam1.setName("newfieldname"); + + Assert.assertEquals("Point", + ((Element) vte.getRoot().getChildren("geometry").get(0)) + .getChildText(VTGeometry.type.toString())); + Assert.assertEquals("newfieldname", ((Element) vte.getRoot() + .getChildren("parameter").get(0)).getChildText(VTParameter.name + .toString())); + + Assert.assertTrue(vtGeom.delSrid()); + Assert.assertTrue(vtParam1.delRegexpValidator()); + } + +} diff --git a/src/test/resources/testdata/states.zip b/src/test/resources/testdata/states.zip new file mode 100644 index 0000000..4865e27 Binary files /dev/null and b/src/test/resources/testdata/states.zip differ