diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java
new file mode 100644
index 0000000..1d4fc32
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java
@@ -0,0 +1,82 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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;
+
+import it.geosolutions.geoserver.rest.manager.GeoServerRESTAbstractManager;
+import it.geosolutions.geoserver.rest.manager.GeoServerRESTDatastoreManager;
+
+import java.net.URL;
+
+/**
+ * The single entry point to all of geoserver-manager functionality.
+ *
+ * Instance this one, and use getters to use different components. These are:
+ *
+ * - getReader() simple, high-level access methods.
+ *
- getPublisher() simple, high-level pubhish methods.
+ *
- getFooManager, full-fledged management of catalog objects.
+ *
+ * @author Oscar Fonts
+ */
+public class GeoServerRESTManager extends GeoServerRESTAbstractManager {
+
+ private final GeoServerRESTPublisher publisher;
+ private final GeoServerRESTReader reader;
+
+ private final GeoServerRESTDatastoreManager datastoreManager;
+
+ /**
+ * Default constructor.
+ *
+ * Indicates connection parameters to remote GeoServer instance.
+ *
+ * @param restURL GeoServer REST API endpoint
+ * @param username GeoServer REST API authorized username
+ * @param password GeoServer REST API password for the former username
+ */
+ public GeoServerRESTManager(URL restURL, String username, String password) {
+ super(restURL, username, password);
+
+ // Internal publisher and reader, provide simple access methods.
+ publisher = new GeoServerRESTPublisher(restURL.toString(), username, password);
+ reader = new GeoServerRESTReader(restURL, username, password);
+
+ // Classes for fine-grained management of catalog components.
+ datastoreManager = new GeoServerRESTDatastoreManager(restURL, username, password);
+ }
+
+ public GeoServerRESTPublisher getPublisher() {
+ return publisher;
+ }
+
+ public GeoServerRESTReader getReader() {
+ return reader;
+ }
+
+ public GeoServerRESTDatastoreManager getDatastoreManager() {
+ return datastoreManager;
+ }
+
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java
index d827dd2..d2b0d87 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java
@@ -30,11 +30,11 @@ import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem;
import it.geosolutions.geoserver.rest.encoder.GSBackupEncoder;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.GSNamespaceEncoder;
-import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder;
import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy;
import it.geosolutions.geoserver.rest.encoder.GSWorkspaceEncoder;
import it.geosolutions.geoserver.rest.encoder.coverage.GSCoverageEncoder;
+import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import java.io.File;
@@ -655,20 +655,20 @@ public class GeoServerRESTPublisher {
}
/**
- * The file, url, and external endpoints are used to specify the method that
- * is used to upload the file.
- *
- * The file method is used to directly upload a file from a local source.
+ * The {@code file}, {@code url}, and {@code external} endpoints are used to specify
+ * the method that is used to upload the file.
+ *
+ * - The {@code file} method is used to directly upload a file from a local source.
* The body of the request is the file itself.
*
- * The url method is used to indirectly upload a file from an remote source.
+ *
- The {@code url} method is used to indirectly upload a file from an remote source.
* The body of the request is a url pointing to the file to upload. This url
* must be visible from the server.
*
- * The external method is used to forgo upload and use an existing file on
+ *
- The {@code external} method is used to forgo upload and use an existing file on
* the server. The body of the request is the absolute path to the existing
* file.
- *
+ *
* @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
*
*/
@@ -677,7 +677,7 @@ public class GeoServerRESTPublisher {
}
// ==========================================================================
- // === DATASTORE
+ // === DATASTORES
// ==========================================================================
/**
@@ -693,6 +693,8 @@ public class GeoServerRESTPublisher {
*
* @return true if the PostGIS datastore has been successfully
* created, false otherwise
+ * @deprecated Will be deleted in next version 1.5.x.
+ * Use {@link GeoServerRESTDatastoreManager} instead.
*/
public boolean createPostGISDatastore(String workspace,
GSPostGISDatastoreEncoder datastoreEncoder) {
@@ -706,7 +708,7 @@ public class GeoServerRESTPublisher {
// ==========================================================================
// === SHAPEFILES
// ==========================================================================
-
+
/**
* Publish a zipped shapefile.
* The defaultCRS will be set to EPSG:4326.
@@ -896,6 +898,57 @@ public class GeoServerRESTPublisher {
return publishShp(workspace, storename, params, layername, UploadMethod.file, zipFile.toURI(), srs, ProjectionPolicy.NONE,null);
}
+
+
+ /**
+ * Publish a collection of shapefiles.
+ *
+ * It will automatically create the store and publish each shapefile as a layer.
+ *
+ * @param workspace the name of the workspace to use
+ * @param storeName the name of the store to create
+ * @param resource the shapefile collection. It can be:
+ * - A path to a directory containing shapefiles in the server.
+ *
- A local zip file containing shapefiles that will be uploaded.
+ *
- A URL pointing to a shapefile collection in the wild web (not tested).
+ * @return {@code true} if publication successful.
+ * @throws FileNotFoundException if the specified zip file does not exist.
+ */
+ public boolean publishShpCollection(String workspace, String storeName, URI resource)
+ throws FileNotFoundException {
+
+ // Deduce upload method & mime type from resource syntax.
+ UploadMethod method = null;
+ String mime = null;
+ if (resource.getScheme().equals("file") || resource.isAbsolute() == false) {
+ File f = new File(resource);
+ if (f.exists() && f.isFile() && f.toString().endsWith(".zip")) {
+ method = UploadMethod.file;
+ mime = "application/zip";
+ } else if (f.isDirectory()) {
+ method = UploadMethod.external;
+ mime = "text/plain";
+ }
+ } else {
+ try {
+ if(resource.toURL() != null) {
+ method = UploadMethod.url;
+ mime = "text/plain";
+ }
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException("Resource is not recognized as a zip file, or a directory, or a valid URL", e);
+ }
+ }
+
+ // Create store, upload data, and publish layers
+ return createStore(
+ workspace, DataStoreType.datastores,
+ storeName, method,
+ DataStoreExtension.shp,
+ mime, resource,
+ ParameterConfigure.ALL,
+ new NameValuePair[0]);
+ }
/**
* @param workspace
diff --git a/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java b/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java
index 143418a..dd7d527 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java
@@ -54,7 +54,7 @@ import org.slf4j.LoggerFactory;
/**
* Low level HTTP utilities.
*/
-class HTTPUtils {
+public class HTTPUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(HTTPUtils.class);
/**
diff --git a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTDataStore.java b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTDataStore.java
index 22c24f0..52904d7 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTDataStore.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTDataStore.java
@@ -26,7 +26,11 @@
package it.geosolutions.geoserver.rest.decoder;
import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
+
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+
import org.jdom.Element;
/**
@@ -108,15 +112,44 @@ public class RESTDataStore {
public String getName() {
return dsElem.getChildText("name");
}
+
+ public String getStoreType() {
+ return dsElem.getChildText("type");
+ }
+
+ public String getDescription() {
+ return dsElem.getChildText("description");
+ }
+ public boolean isEnabled() {
+ return Boolean.parseBoolean(dsElem.getChildText("enabled"));
+ }
+
public String getWorkspaceName() {
return dsElem.getChild("workspace").getChildText("name");
}
-
- protected String getConnectionParameter(String paramName) {
+
+ public Map getConnectionParameters() {
Element elConnparm = dsElem.getChild("connectionParameters");
if (elConnparm != null) {
- for (Element entry : (List) elConnparm.getChildren("entry")) {
+ @SuppressWarnings("unchecked")
+ List elements = (List)elConnparm.getChildren("entry");
+ Map params = new HashMap(elements.size());
+ for (Element element : elements) {
+ String key = element.getAttributeValue("key");
+ String value = element.getTextTrim();
+ params.put(key, value);
+ }
+ return params;
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected String getConnectionParameter(String paramName) {
+ Element elConnparm = dsElem.getChild("connectionParameters");
+ if (elConnparm != null) {
+ for (Element entry : (List) elConnparm.getChildren("entry")) {
String key = entry.getAttributeValue("key");
if (paramName.equals(key)) {
return entry.getTextTrim();
@@ -126,7 +159,7 @@ public class RESTDataStore {
return null;
}
-
+
public DBType getType() {
return DBType.get(getConnectionParameter("dbtype"));
}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSPostGISDatastoreEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSPostGISDatastoreEncoder.java
index 1db6613..0d85ff0 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSPostGISDatastoreEncoder.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSPostGISDatastoreEncoder.java
@@ -34,6 +34,9 @@ import it.geosolutions.geoserver.rest.encoder.utils.PropertyXMLEncoder;
* @author Eric Grosso
* @author ETj
* @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
+ *
+ * @deprecated Will be removed in next version 1.5.x.
+ * Use {@link it.geosolutions.geoserver.rest.encoder.datastore.GSPostGISDatastoreEncoder} instead.
*/
public class GSPostGISDatastoreEncoder extends PropertyXMLEncoder {
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSAbstractDatastoreEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSAbstractDatastoreEncoder.java
new file mode 100644
index 0000000..f957810
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSAbstractDatastoreEncoder.java
@@ -0,0 +1,146 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.datastore;
+
+import java.util.Map;
+
+import it.geosolutions.geoserver.rest.decoder.RESTDataStore;
+import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
+import it.geosolutions.geoserver.rest.encoder.utils.NestedElementEncoder;
+import it.geosolutions.geoserver.rest.encoder.utils.PropertyXMLEncoder;
+
+/**
+ * Generic Datastore encoder.
+ *
+ * Provides getters and setters for parameters common to all Datastores,
+ * an internal placeholder for specific connection parameters, and
+ * a constructor to read parameters from a {@link RESTDataStore}.
+ *
+ * @author Oscar Fonts
+ */
+public abstract class GSAbstractDatastoreEncoder extends PropertyXMLEncoder {
+
+ final static String ROOT = "dataStore";
+
+ NestedElementEncoder connectionParameters = new NestedElementEncoder("connectionParameters");
+
+ GSAbstractDatastoreEncoder(String storeName) {
+ super(ROOT);
+ // Add mandatory parameter
+ ensureValidName(storeName);
+ setName(storeName);
+
+ // Add connection parameters
+ addContent(connectionParameters.getRoot());
+ }
+
+ /**
+ * Create a {@value #TYPE} datastore encoder from a store read from server.
+ *
+ * @param store The existing store.
+ * @throws IllegalArgumentException if store type or mandatory parameters are not valid
+ */
+ GSAbstractDatastoreEncoder(RESTDataStore store) {
+ this(store.getName());
+
+ // Match datastore type
+ ensureValidType(store.getStoreType());
+ setType(store.getStoreType());
+
+ // Copy store parameters
+ setDescription(store.getDescription());
+ setEnabled(store.isEnabled());
+
+ // Copy connection parameters - bulk
+ Map params = store.getConnectionParameters();
+ for(String key : params.keySet()) {
+ connectionParameters.set(key, params.get(key));
+ }
+ }
+
+ void setType(String type) {
+ set("type", type);
+ }
+
+ public String getType() {
+ return ElementUtils.contains(getRoot(), "type").getTextTrim();
+ }
+
+ public void setName(String name) {
+ ensureValidName(name);
+ set("name", name);
+ }
+
+ public String getName() {
+ return ElementUtils.contains(getRoot(), "name").getTextTrim();
+ }
+
+ public void setDescription(String description) {
+ set("description", description);
+ }
+
+ public String getDescription() {
+ return ElementUtils.contains(getRoot(), "description").getTextTrim();
+ }
+
+ public void setEnabled(boolean enabled) {
+ set("enabled", Boolean.toString(enabled));
+ }
+
+ public boolean getEnabled() {
+ return Boolean.parseBoolean(ElementUtils.contains(getRoot(), "enabled").getTextTrim());
+ }
+
+ /**
+ * Check name validity.
+ *
+ * @param name the name
+ * @throws IllegalArgumentException if name is null or empty
+ */
+ void ensureValidName(String name) {
+ if (name == null || name.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Store name cannot be null or empty");
+ }
+ }
+
+ /**
+ * Check type validity.
+ *
+ * @param type the type.
+ * @throws IllegalArgumentException if type is not {@value #TYPE}
+ */
+ void ensureValidType(String type) {
+ if (!type.equals(getValidType())) {
+ throw new IllegalArgumentException(
+ "The store type '"+ type +"' is not valid");
+ }
+ }
+
+ /**
+ * The type of the implementing datastore.
+ */
+ abstract String getValidType();
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSDirectoryOfShapefilesDatastoreEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSDirectoryOfShapefilesDatastoreEncoder.java
new file mode 100644
index 0000000..eae422e
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSDirectoryOfShapefilesDatastoreEncoder.java
@@ -0,0 +1,68 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.datastore;
+
+import it.geosolutions.geoserver.rest.decoder.RESTDataStore;
+
+import java.net.URL;
+
+/**
+ * Encoder for a {@value #TYPE} datastore.
+ *
+ * @author Oscar Fonts
+ */
+public class GSDirectoryOfShapefilesDatastoreEncoder extends GSShapefileDatastoreEncoder {
+
+ static final String TYPE = "Directory of spatial files (shapefiles)";
+
+ /**
+ * Create a {@value #TYPE} datastore with default connection parameters,
+ * given a store name and a url (the store location).
+ *
+ * @param name New datastore name
+ * @param url The shapefile location in the server, relative to $GEOSERVER_DATA_DIR.
+ */
+ public GSDirectoryOfShapefilesDatastoreEncoder(String name, URL url) {
+ super(name, url);
+ setType(TYPE);
+ }
+
+ /**
+ * Create a {@value #TYPE} datastore encoder from an existing store read from server.
+ *
+ * @param store The existing store.
+ * @throws IllegalArgumentException if store type or mandatory parameters are not valid
+ */
+ public GSDirectoryOfShapefilesDatastoreEncoder(RESTDataStore store) {
+ super(store);
+ }
+
+ /**
+ * @return {@value #TYPE}
+ */
+ String getValidType() {
+ return TYPE;
+ }
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSPostGISDatastoreEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSPostGISDatastoreEncoder.java
new file mode 100644
index 0000000..19978ee
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSPostGISDatastoreEncoder.java
@@ -0,0 +1,147 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.datastore;
+
+/**
+ * Encoder for a {@value #TYPE} datastore.
+ *
+ * @author Eric Grosso
+ * @author ETj
+ * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it
+ * @author Oscar Fonts
+ */
+public class GSPostGISDatastoreEncoder extends GSAbstractDatastoreEncoder {
+
+ static final String TYPE = "PostGIS";
+
+ static final int DEFAULT_MIN_CONNECTIONS = 1;
+ static final int DEFAULT_MAX_CONNECTIONS = 10;
+ static final int DEFAULT_FETCH_SIZE = 1000;
+ static final int DEFAULT_CONNECTION_TIMEOUT = 20;
+ static final boolean DEFAULT_LOOSE_BBOX = true;
+ static final boolean DEFAULT_PREPARED_STATEMENTS = false;
+ static final int DEFAULT_MAX_OPEN_PREPARED_STATEMENTS = 50;
+
+ public GSPostGISDatastoreEncoder(String name) {
+ super(name);
+
+ // Set mandatory parameter
+ setType(TYPE);
+ setDatabaseType("postgis");
+
+ // Set default values
+ setMinConnections(DEFAULT_MIN_CONNECTIONS);
+ setMaxConnections(DEFAULT_MAX_CONNECTIONS);
+ setFetchSize(DEFAULT_FETCH_SIZE);
+ setConnectionTimeout(DEFAULT_CONNECTION_TIMEOUT);
+ setLooseBBox(DEFAULT_LOOSE_BBOX);
+ setPreparedStatements(DEFAULT_PREPARED_STATEMENTS);
+ setMaxOpenPreparedStatements(DEFAULT_MAX_OPEN_PREPARED_STATEMENTS);
+
+ }
+
+ public void setNamespace(String namespace) {
+ connectionParameters.set("namespace", namespace);
+ }
+
+ public void setHost(String host) {
+ connectionParameters.set("host", host);
+ }
+
+ public void setPort(int port) {
+ connectionParameters.set("port", Integer.toString(port));
+ }
+
+ public void setDatabase(String database) {
+ connectionParameters.set("database", database);
+ }
+
+ public void setSchema(String schema) {
+ connectionParameters.set("schema", schema);
+ }
+
+ public void setUser(String user) {
+ connectionParameters.set("user", user);
+ }
+
+ public void setPassword(String password) {
+ connectionParameters.set("passwd", password);
+ }
+
+ public void setDatabaseType(String dbtype) {
+ connectionParameters.set("dbtype", dbtype);
+ }
+
+ public void setJndiReferenceName(String jndiReferenceName) {
+ connectionParameters.set("jndiReferenceName", jndiReferenceName);
+ }
+
+ public void setExposePrimaryKeys(boolean exposePrimaryKeys) {
+ connectionParameters.set("Expose primary keys", Boolean.toString(exposePrimaryKeys));
+ }
+
+ public void setMaxConnections(int maxConnections) {
+ connectionParameters.set("max connections", Integer.toString(maxConnections));
+ }
+
+ public void setMinConnections(int minConnections) {
+ connectionParameters.set("min connections", Integer.toString(minConnections));
+ }
+
+ public void setFetchSize(int fetchSize) {
+ connectionParameters.set("fetch size", Integer.toString(fetchSize));
+ }
+
+ public void setConnectionTimeout(int seconds) {
+ connectionParameters.set("Connection timeout", Integer.toString(seconds));
+ }
+
+ public void setValidateConnections(boolean validateConnections) {
+ connectionParameters.set("validate connections", Boolean.toString(validateConnections));
+ }
+
+ public void setPrimaryKeyMetadataTable(String primaryKeyMetadataTable) {
+ connectionParameters.set("Primary key metadata table", primaryKeyMetadataTable);
+ }
+
+ public void setLooseBBox(boolean looseBBox) {
+ connectionParameters.set("Loose bbox", Boolean.toString(looseBBox));
+ }
+
+ public void setPreparedStatements(boolean preparedStatements) {
+ connectionParameters.set("preparedStatements", Boolean.toString(preparedStatements));
+ }
+
+ public void setMaxOpenPreparedStatements(int maxOpenPreparedStatements) {
+ connectionParameters.set("Max open prepared statements", Integer.toString(maxOpenPreparedStatements));
+ }
+
+ /**
+ * @return {@value #TYPE}
+ */
+ String getValidType() {
+ return TYPE;
+ }
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSShapefileDatastoreEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSShapefileDatastoreEncoder.java
new file mode 100644
index 0000000..3a9d949
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/datastore/GSShapefileDatastoreEncoder.java
@@ -0,0 +1,163 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.datastore;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.nio.charset.Charset;
+
+import it.geosolutions.geoserver.rest.decoder.RESTDataStore;
+import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
+
+/**
+ * Encoder for a {@value #TYPE} datastore.
+ *
+ * @author Oscar Fonts
+ */
+public class GSShapefileDatastoreEncoder extends GSAbstractDatastoreEncoder {
+
+ static final String TYPE = "Shapefile";
+
+ final static boolean DEFAULT_ENABLED = true;
+ final static String DEFAULT_CHARSET = "ISO-8859-1";
+ final static boolean DEFAULT_CREATE_SPATIAL_INDEX = true;
+ final static boolean DEFAULT_MEMORY_MAPPED_BUFFER = false;
+ final static boolean DEFAULT_CACHE_AND_REUSE_MEMORY_MAPS = true;
+
+ /**
+ * Create a {@value #TYPE} datastore with default connection parameters,
+ * given a store name and a url (the store location).
+ *
+ * The following default connection parameters are set:
+ *
+ * - enabled: {@value #DEFAULT_ENABLED}
+ *
- charset: {@value #DEFAULT_CHARSET}
+ *
- create spatial index: {@value #DEFAULT_CREATE_SPATIAL_INDEX}
+ *
- memory mapped buffer: {@value #DEFAULT_MEMORY_MAPPED_BUFFER}
+ *
- cache and reuse memory maps: {@value #DEFAULT_CACHE_AND_REUSE_MEMORY_MAPS}
+ *
+ *
+ * @param name New datastore name
+ * @param url The shapefile location in the server, relative to $GEOSERVER_DATA_DIR.
+ */
+ public GSShapefileDatastoreEncoder(String name, URL url) {
+ // Set fixed values
+ super(name);
+ setType(TYPE);
+
+ // Set mandatory parameter
+ ensureValidURL(url);
+ setUrl(url);
+
+ // Set default values
+ setEnabled(DEFAULT_ENABLED);
+ setCharset(Charset.forName(DEFAULT_CHARSET));
+ setCreateSpatialIndex(DEFAULT_CREATE_SPATIAL_INDEX);
+ setMemoryMappedBuffer(DEFAULT_MEMORY_MAPPED_BUFFER);
+ setCacheAndReuseMemoryMaps(DEFAULT_CACHE_AND_REUSE_MEMORY_MAPS);
+ }
+
+ /**
+ * Create a {@value #TYPE} datastore encoder from an existing store read from server.
+ *
+ * @param store The existing store.
+ * @throws IllegalArgumentException if store type or mandatory parameters are not valid
+ */
+ public GSShapefileDatastoreEncoder(RESTDataStore store) {
+ super(store);
+
+ // Check mandatory parameter validity
+ try {
+ ensureValidURL(new URL(store.getConnectionParameters().get("url")));
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException("Shapefile store URL is malformed", e);
+ }
+ }
+
+ public void setUrl(URL url) {
+ ensureValidURL(url);
+ connectionParameters.set("url", url.toString());
+ }
+
+ public URL getUrl() {
+ try {
+ return new URL(ElementUtils.contains(connectionParameters.getRoot(), "description").getTextTrim());
+ } catch (MalformedURLException e) {
+ return null;
+ }
+ }
+
+ public void setCharset(Charset charset) {
+ connectionParameters.set("charset", charset.name());
+ }
+
+ public Charset getCharset() {
+ return Charset.forName(ElementUtils.contains(connectionParameters.getRoot(), "charset").getTextTrim());
+ }
+
+ public void setCreateSpatialIndex(boolean createSpatialIndex) {
+ connectionParameters.set("create spatial index", Boolean.toString(createSpatialIndex));
+ }
+
+ public boolean getCreateSpatialIndex() {
+ return Boolean.parseBoolean(ElementUtils.contains(connectionParameters.getRoot(), "create spatial index").getTextTrim());
+ }
+
+ public void setMemoryMappedBuffer(boolean memoryMappedBuffer) {
+ connectionParameters.set("memory mapped buffer", Boolean.toString(memoryMappedBuffer));
+ }
+
+ public boolean getMemoryMappedBuffer() {
+ return Boolean.parseBoolean(ElementUtils.contains(connectionParameters.getRoot(), "memory mapped buffer").getTextTrim());
+ }
+
+ public void setCacheAndReuseMemoryMaps(boolean cacheAndReuseMemoryMaps) {
+ connectionParameters.set("cache and reuse memory maps", Boolean.toString(cacheAndReuseMemoryMaps));
+ }
+
+ public boolean getCacheAndReuseMemoryMaps() {
+ return Boolean.parseBoolean(ElementUtils.contains(connectionParameters.getRoot(), "cache and reuse memory maps").getTextTrim());
+ }
+
+ /**
+ * Check url validity.
+ *
+ * @param url the url
+ * @throws IllegalArgumentException if url is null or empty
+ */
+ private static void ensureValidURL(URL url) {
+ if (url == null || url.toString().isEmpty()) {
+ throw new IllegalArgumentException(
+ "Shapefile store URL cannot be null or empty");
+ }
+ }
+
+ /**
+ * @return {@value #TYPE}
+ */
+ String getValidType() {
+ return TYPE;
+ }
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/utils/NestedElementEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/utils/NestedElementEncoder.java
index aaf97d8..a72dee4 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/encoder/utils/NestedElementEncoder.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/utils/NestedElementEncoder.java
@@ -155,7 +155,7 @@ public class NestedElementEncoder extends XmlElement {
// if some previous similar object is found
final Element search;
if ((search = ElementUtils.contains(getRoot(), new NestedElementFilter(
- getRoot(), key, value))) != null) {
+ getRoot(), key, null))) != null) {
// remove it
ElementUtils.remove(getRoot(), search);
}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTAbstractManager.java b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTAbstractManager.java
new file mode 100644
index 0000000..6fc3464
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTAbstractManager.java
@@ -0,0 +1,55 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.manager;
+
+import java.net.URL;
+
+/**
+ * Abstract manager, common functionality and interface
+ * for all GeoServerRESTFooManager classes.
+ *
+ * @author Oscar Fonts
+ */
+public abstract class GeoServerRESTAbstractManager {
+
+ protected final URL restURL;
+ protected final String gsuser;
+ protected final String gspass;
+
+ /**
+ * Default constructor.
+ *
+ * Indicates connection parameters to remote GeoServer instance.
+ *
+ * @param restURL GeoServer REST API endpoint
+ * @param username GeoServer REST API authorized username
+ * @param password GeoServer REST API password for the former username
+ */
+ public GeoServerRESTAbstractManager(URL restURL, String username, String password) {
+ this.restURL = restURL;
+ this.gsuser = username;
+ this.gspass = password;
+ }
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTDatastoreManager.java b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTDatastoreManager.java
new file mode 100644
index 0000000..36572be
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTDatastoreManager.java
@@ -0,0 +1,92 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.manager;
+
+import it.geosolutions.geoserver.rest.HTTPUtils;
+import it.geosolutions.geoserver.rest.encoder.datastore.GSAbstractDatastoreEncoder;
+
+import java.net.URL;
+
+/**
+ * Manage datastores.
+ *
+ * To pass connection parameters, use the encoders derived from
+ * {@link GSAbstractDatastoreEncoder}.
+ *
+ * @author Oscar Fonts
+ */
+public class GeoServerRESTDatastoreManager extends GeoServerRESTAbstractManager {
+
+ /**
+ * Default constructor.
+ *
+ * @param restURL GeoServer REST API endpoint
+ * @param username GeoServer REST API authorized username
+ * @param password GeoServer REST API password for the former username
+ */
+ public GeoServerRESTDatastoreManager(URL restURL, String username, String password) {
+ super(restURL, username, password);
+ }
+
+ /**
+ * Create a datastore.
+ *
+ * @param workspace
+ * Name of the workspace to contain the datastore. This will also
+ * be the prefix of any layer names contained in the datastore.
+ * @param datastore
+ * the set of parameters to be set to the datastore (including
+ * connection parameters).
+ * @return true if the datastore has been successfully
+ * created, false otherwise
+ */
+
+ public boolean create(String workspace, GSAbstractDatastoreEncoder datastore) {
+ String sUrl = restURL + "/rest/workspaces/" + workspace
+ + "/datastores/";
+ String xml = datastore.toString();
+ String result = HTTPUtils.postXml(sUrl, xml, gsuser, gspass);
+ return result != null;
+ }
+
+ /**
+ * Update a datastore.
+ *
+ * @param workspace
+ * Name of the workspace that contains the datastore.
+ * @param datastore
+ * the set of parameters to be set to the datastore (including
+ * connection parameters).
+ * @return true if the datastore has been successfully
+ * updated, false otherwise
+ */
+ public boolean update(String workspace, GSAbstractDatastoreEncoder datastore) {
+ String sUrl = restURL + "/rest/workspaces/" + workspace
+ + "/datastores/" + datastore.getName();
+ String xml = datastore.toString();
+ String result = HTTPUtils.putXml(sUrl, xml, gsuser, gspass);
+ return result != null;
+ }
+}
diff --git a/src/test/java/it/geosolutions/geoserver/rest/manager/GeoserverRESTDatastoreManagerTest.java b/src/test/java/it/geosolutions/geoserver/rest/manager/GeoserverRESTDatastoreManagerTest.java
new file mode 100644
index 0000000..98af5f6
--- /dev/null
+++ b/src/test/java/it/geosolutions/geoserver/rest/manager/GeoserverRESTDatastoreManagerTest.java
@@ -0,0 +1,137 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.manager;
+
+import org.junit.Test;
+
+import java.net.URL;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+import it.geosolutions.geoserver.rest.GeoServerRESTManager;
+import it.geosolutions.geoserver.rest.GeoserverRESTTest;
+import it.geosolutions.geoserver.rest.decoder.RESTDataStore;
+import it.geosolutions.geoserver.rest.encoder.datastore.GSAbstractDatastoreEncoder;
+import it.geosolutions.geoserver.rest.encoder.datastore.GSShapefileDatastoreEncoder;
+import it.geosolutions.geoserver.rest.encoder.datastore.GSDirectoryOfShapefilesDatastoreEncoder;
+
+/**
+ * Test datastore handling (create, read and update):
+ *
+ * - Tests all the constructors and setters from
+ * {@link GSDirectoryOfShapefilesDatastoreEncoder} and parent classes
+ * ({@link GSShapefileDatastoreEncoder}, {@link GSAbstractDatastoreEncoder}).
+ *
+ *
- Tests constructors and getters from {@link RESTDataStore} (reader).
+ *
+ *
- Tests {@link GeoServerRESTDatastoreManager} create and update methods.
+ *
+ * The sequence is:
+ *
+ * - Create a DirectoryOfShapefilesDatastoreEncoder, with default parameters.
+ *
- Publish via GeoServerRESTDatastoreManager.create.
+ *
- Read the datastore from server.
+ *
- Test all parameter values.
+ *
- Create a new Encoder from it.
+ *
- Change all datastore parameter to non-default ones.
+ *
- Update via GeoServerRESTDatastoreManager.update.
+ *
- Read again.
+ *
- Test all new values.
+ *
+ *
+ * @author Oscar Fonts
+ */
+public class GeoserverRESTDatastoreManagerTest extends GeoserverRESTTest {
+
+ public final GeoServerRESTManager manager;
+
+ private static final String WS_NAME = DEFAULT_WS;
+ private static final String DS_NAME = "testCreateDatastore";
+ private static final String DS_DESCRIPTION = "A description";
+ private static URL LOCATION_1;
+ private static URL LOCATION_2;
+
+ public GeoserverRESTDatastoreManagerTest(String testName) throws Exception {
+ super(testName);
+ manager = new GeoServerRESTManager(new URL(RESTURL), RESTUSER, RESTPW);
+
+ LOCATION_1 = new URL("file:data/1");
+ LOCATION_2 = new URL("file:data/2");
+ }
+
+ @Test
+ public void test() throws Exception {
+ if (!enabled()) {
+ return;
+ }
+
+ // Delete all resources except styles
+ deleteAllWorkspacesRecursively();
+
+ // Create workspace
+ assertTrue(publisher.createWorkspace(WS_NAME));
+
+ // Create a directory of spatial files with default parameters
+ GSDirectoryOfShapefilesDatastoreEncoder create = new GSDirectoryOfShapefilesDatastoreEncoder(DS_NAME, LOCATION_1);
+ assertTrue(manager.getDatastoreManager().create(WS_NAME, create));
+
+ // Read the store from server; check all parameter values
+ RESTDataStore read = reader.getDatastore(WS_NAME, DS_NAME);
+ assertEquals(read.getName(), DS_NAME);
+ assertEquals(read.getWorkspaceName(), WS_NAME);
+ assertEquals(read.isEnabled(), true);
+
+ Map connParams = read.getConnectionParameters();
+ assertEquals(connParams.get("url"), LOCATION_1.toString());
+ assertEquals(connParams.get("charset"), "ISO-8859-1");
+ assertEquals(connParams.get("create spatial index"), "true");
+ assertEquals(connParams.get("memory mapped buffer"), "false");
+ assertEquals(connParams.get("cache and reuse memory maps"), "true");
+
+ // Change all parameter to non-default values
+ GSDirectoryOfShapefilesDatastoreEncoder update = new GSDirectoryOfShapefilesDatastoreEncoder(read);
+ update.setDescription(DS_DESCRIPTION);
+ update.setEnabled(false);
+ update.setUrl(LOCATION_2);
+ update.setCharset(Charset.forName("UTF-8"));
+ update.setCreateSpatialIndex(false);
+ update.setMemoryMappedBuffer(true);
+ update.setCacheAndReuseMemoryMaps(false);
+
+ //update the store
+ assertTrue(manager.getDatastoreManager().update(WS_NAME, update));
+
+ // Read again, check that all parameters have changed
+ read = reader.getDatastore(WS_NAME, DS_NAME);
+ assertEquals(read.getWorkspaceName(), WS_NAME);
+ assertEquals(read.isEnabled(), false);
+ connParams = read.getConnectionParameters();
+ assertEquals(connParams.get("url"), LOCATION_2.toString());
+ assertEquals(connParams.get("charset"), "UTF-8");
+ assertEquals(connParams.get("create spatial index"), "false");
+ assertEquals(connParams.get("memory mapped buffer"), "true");
+ assertEquals(connParams.get("cache and reuse memory maps"), "false");
+ }
+}
diff --git a/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTPublishShpCollectionTest.java b/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTPublishShpCollectionTest.java
new file mode 100644
index 0000000..8463bbe
--- /dev/null
+++ b/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTPublishShpCollectionTest.java
@@ -0,0 +1,85 @@
+/*
+ * GeoServer-Manager - Simple Manager Library for GeoServer
+ *
+ * Copyright (C) 2007,2012 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.publisher;
+
+import org.junit.Test;
+import java.net.URI;
+import java.util.List;
+import org.springframework.core.io.ClassPathResource;
+
+import it.geosolutions.geoserver.rest.GeoserverRESTTest;
+
+/**
+ * @author Oscar Fonts
+ */
+public class GeoserverRESTPublishShpCollectionTest extends GeoserverRESTTest {
+
+ final String workspace = DEFAULT_WS;
+ final String storeName = "testshpcollection";
+
+ public GeoserverRESTPublishShpCollectionTest(String testName) {
+ super(testName);
+ }
+
+ @Test
+ public void testLocalZip() throws Exception {
+ if (!enabled()) {
+ return;
+ }
+
+ URI location = new ClassPathResource("testdata/multipleshp.zip").getFile().toURI();
+ test(location);
+ }
+
+ @Test
+ public void testExternalDir() throws Exception {
+ if (!enabled()) {
+ return;
+ }
+
+ URI location = new ClassPathResource("testdata/multipleshapefiles").getFile().toURI();
+ test(location);
+ }
+
+ void test(URI location) throws Exception {
+
+ // Delete all resources except styles
+ deleteAllWorkspacesRecursively();
+
+ // Create workspace
+ assertTrue(publisher.createWorkspace(workspace));
+
+ // Publish shp collection
+ assertTrue(publisher.publishShpCollection(workspace, storeName, location));
+
+ String storeType = reader.getDatastore(workspace, storeName).getStoreType();
+ assertEquals(storeType, "Shapefile");
+
+ // Test published layer names
+ List layers = reader.getLayers().getNames();
+ assertTrue(layers.contains("cities"));
+ assertTrue(layers.contains("boundaries"));
+ }
+}
diff --git a/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTShapeTest.java b/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTShapeTest.java
index 8859d92..3f3ebfa 100644
--- a/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTShapeTest.java
+++ b/src/test/java/it/geosolutions/geoserver/rest/publisher/GeoserverRESTShapeTest.java
@@ -166,11 +166,12 @@ public class GeoserverRESTShapeTest extends GeoserverRESTTest {
String ns = "geosolutions";
String storeName = "resttestshp";
String layerName = "cities";
+ final String styleName = "restteststyle";
File zipFile = new ClassPathResource("testdata/resttestshp.zip").getFile();
publisher.removeDatastore(DEFAULT_WS, storeName,true);
+ publisher.removeStyle(styleName);
- final String styleName = "restteststyle";
File sldFile = new ClassPathResource("testdata/restteststyle.sld").getFile();
// insert style
diff --git a/src/test/resources/testdata/multipleshapefiles/boundaries.dbf b/src/test/resources/testdata/multipleshapefiles/boundaries.dbf
new file mode 100644
index 0000000..b245a5e
Binary files /dev/null and b/src/test/resources/testdata/multipleshapefiles/boundaries.dbf differ
diff --git a/src/test/resources/testdata/multipleshapefiles/boundaries.prj b/src/test/resources/testdata/multipleshapefiles/boundaries.prj
new file mode 100644
index 0000000..7a70628
--- /dev/null
+++ b/src/test/resources/testdata/multipleshapefiles/boundaries.prj
@@ -0,0 +1 @@
+GEOGCS["GCS_WGS_1984",DATUM["WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]
diff --git a/src/test/resources/testdata/multipleshapefiles/boundaries.shp b/src/test/resources/testdata/multipleshapefiles/boundaries.shp
new file mode 100644
index 0000000..85957fa
Binary files /dev/null and b/src/test/resources/testdata/multipleshapefiles/boundaries.shp differ
diff --git a/src/test/resources/testdata/multipleshapefiles/cities.dbf b/src/test/resources/testdata/multipleshapefiles/cities.dbf
new file mode 100644
index 0000000..6b53516
Binary files /dev/null and b/src/test/resources/testdata/multipleshapefiles/cities.dbf differ
diff --git a/src/test/resources/testdata/multipleshapefiles/cities.prj b/src/test/resources/testdata/multipleshapefiles/cities.prj
new file mode 100644
index 0000000..c0c0792
Binary files /dev/null and b/src/test/resources/testdata/multipleshapefiles/cities.prj differ
diff --git a/src/test/resources/testdata/multipleshapefiles/cities.shp b/src/test/resources/testdata/multipleshapefiles/cities.shp
new file mode 100644
index 0000000..54fd672
Binary files /dev/null and b/src/test/resources/testdata/multipleshapefiles/cities.shp differ
diff --git a/src/test/resources/testdata/multipleshp.zip b/src/test/resources/testdata/multipleshp.zip
new file mode 100644
index 0000000..6a58512
Binary files /dev/null and b/src/test/resources/testdata/multipleshp.zip differ
diff --git a/src/test/resources/testdata/shapefile/cities.shx b/src/test/resources/testdata/shapefile/cities.shx
deleted file mode 100644
index 6817e44..0000000
Binary files a/src/test/resources/testdata/shapefile/cities.shx and /dev/null differ