diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java index 90b00b0..b1cfc11 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java +++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java @@ -29,6 +29,7 @@ import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore; import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem; import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder; 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; @@ -53,6 +54,7 @@ import org.apache.log4j.Logger; * There are no modifiable instance fields, so all the calls are thread-safe. * * @author ETj (etj at geo-solutions.it) + * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it */ public class GeoServerRESTPublisher { @@ -265,7 +267,7 @@ public class GeoServerRESTPublisher { * * @throws IllegalArgumentException * if the sldFile file or name are null or name is empty - * + * */ public boolean updateStyle(final File sldFile, final String name) throws IllegalArgumentException { @@ -344,121 +346,139 @@ public class GeoServerRESTPublisher { } return false; } - - private boolean createDataStore(String workspace, String storeName, - UploadMethod method, DataStoreExtension extension, String mimeType, URI uri, - ParameterConfigure configure, NameValuePair... params) - throws FileNotFoundException, IllegalArgumentException { - return createStore(workspace, DataStoreType.datastores, storeName, method, extension, mimeType, uri, configure, params); - } - - private boolean createCoverageStore(String workspace, String storeName, - UploadMethod method, CoverageStoreExtension extension, String mimeType, URI uri, - ParameterConfigure configure, NameValuePair... params) - throws FileNotFoundException, IllegalArgumentException { - return createStore(workspace, DataStoreType.coveragestores, storeName, method, extension, mimeType, uri, configure, params); - } - /** - * - * @param workspace - * @param dsType - * @param storeName - * @param method - * @param extension - * @param mimeType - * @param uri - * @param configure - * @param params - * @return - * @throws FileNotFoundException - * @throws IllegalArgumentException - */ - private boolean createStore(String workspace, DataStoreType dsType, String storeName, UploadMethod method, Enum extension, - String mimeType, URI uri, ParameterConfigure configure, NameValuePair... params) - throws FileNotFoundException, IllegalArgumentException { - if (workspace==null||dsType==null||storeName==null||method==null|extension==null||mimeType==null||uri==null){ - throw new IllegalArgumentException("Null argument"); - } - StringBuilder sbUrl = new StringBuilder(restURL) - .append("/rest/workspaces/").append(workspace) - .append("/").append(dsType).append("/").append(storeName) - .append("/").append(method).append(".").append(extension); - - if (configure != null) { - sbUrl.append("?configure=").append(configure); - if (params != (NameValuePair[]) null - && !configure.equals(ParameterConfigure.NONE)) { - final String paramString = appendParameters(params); - if (!paramString.isEmpty()) { - sbUrl.append("&").append(paramString); - } - } - } - - - String sentResult =null; + private boolean createDataStore(String workspace, String storeName, + UploadMethod method, DataStoreExtension extension, String mimeType, + URI uri, ParameterConfigure configure, NameValuePair... params) + throws FileNotFoundException, IllegalArgumentException { + return createStore(workspace, DataStoreType.datastores, storeName, + method, extension, mimeType, uri, configure, params); + } - if (method.equals(UploadMethod.file)){ - final File file=new File(uri); - if (!file.exists()) - throw new FileNotFoundException("unable to locate file: "+file); - sentResult = HTTPUtils.put(sbUrl.toString(), file, mimeType, gsuser, gspass); - } else if (method.equals(UploadMethod.external)){ - sentResult = HTTPUtils.put(sbUrl.toString(), uri.toString(), mimeType, gsuser, gspass); - } else if (method.equals(UploadMethod.url)){ - // TODO check - sentResult = HTTPUtils.put(sbUrl.toString(), uri.toString(), mimeType, gsuser, gspass); - } + private boolean createCoverageStore(String workspace, String storeName, + UploadMethod method, CoverageStoreExtension extension, + String mimeType, URI uri, ParameterConfigure configure, + NameValuePair... params) throws FileNotFoundException, + IllegalArgumentException { + return createStore(workspace, DataStoreType.coveragestores, storeName, + method, extension, mimeType, uri, configure, params); + } - if (sentResult != null) { - if (LOGGER.isInfoEnabled()) - LOGGER.info("Store successfully created using ( " + uri + " )"); - return true; - } else { - if (LOGGER.isEnabledFor(Level.ERROR)) - LOGGER.error("Error in creating store using: " + uri); - return false; - } + /** + * + * @param workspace + * @param dsType + * @param storeName + * @param method + * @param extension + * @param mimeType + * @param uri + * @param configure + * @param params + * @return + * @throws FileNotFoundException + * @throws IllegalArgumentException + */ + private boolean createStore(String workspace, DataStoreType dsType, + String storeName, UploadMethod method, Enum extension, + String mimeType, URI uri, ParameterConfigure configure, + NameValuePair... params) throws FileNotFoundException, + IllegalArgumentException { + if (workspace == null || dsType == null || storeName == null + || method == null | extension == null || mimeType == null + || uri == null) { + throw new IllegalArgumentException("Null argument"); + } + StringBuilder sbUrl = new StringBuilder(restURL) + .append("/rest/workspaces/").append(workspace).append("/") + .append(dsType).append("/").append(storeName).append("/") + .append(method).append(".").append(extension); + + if (configure != null) { + sbUrl.append("?configure=").append(configure); + if (params != (NameValuePair[]) null) { + final String paramString = appendParameters(params); + if (!paramString.isEmpty()) { + sbUrl.append("&").append(paramString); + } + } + } + + String sentResult = null; + + if (method.equals(UploadMethod.file)) { + final File file = new File(uri); + if (!file.exists()) + throw new FileNotFoundException("unable to locate file: " + + file); + sentResult = HTTPUtils.put(sbUrl.toString(), file, mimeType, + gsuser, gspass); + } else if (method.equals(UploadMethod.external)) { + sentResult = HTTPUtils.put(sbUrl.toString(), uri.toString(), + mimeType, gsuser, gspass); + } else if (method.equals(UploadMethod.url)) { + // TODO check + sentResult = HTTPUtils.put(sbUrl.toString(), uri.toString(), + mimeType, gsuser, gspass); + } + + if (sentResult != null) { + if (LOGGER.isInfoEnabled()) + LOGGER.info("Store successfully created using ( " + uri + " )"); + return true; + } else { + if (LOGGER.isEnabledFor(Level.ERROR)) + LOGGER.error("Error in creating store using: " + uri); + return false; + } } - /** - * A data store is a source of spatial data that is vector based. It can be - * a file in the case of a Shapefile, a database in the case of PostGIS, or - * a server in the case of a remote Web Feature Service.
- * - * A coverage store is a source of spatial data that is raster based.
- * - * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it - * - */ - public enum DataStoreType{ - coveragestores, - datastores + /** + * A data store is a source of spatial data that is vector based. It can be + * a file in the case of a Shapefile, a database in the case of PostGIS, or + * a server in the case of a remote Web Feature Service.
+ * + * A coverage store is a source of spatial data that is raster based.
+ * + * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it + * + */ + public enum DataStoreType { + coveragestores, datastores; + + public static String getTypeName(DataStoreType type) { + switch (type) { + case coveragestores: + return "coverages.xml"; // Format + case datastores: + return "featuretypes.xml"; + default: + return "coverages.xml"; + } + } } - /** - * 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 body of the request is the file itself. - * - * The 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 server. The body of the request is the absolute path to the existing - * file. - * - * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it - * - */ + + /** + * 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 body of the request is the file itself. + * + * The 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 server. The body of the request is the absolute path to the existing + * file. + * + * @author Carlo Cancellieri - carlo.cancellieri@geo-solutions.it + * + */ public enum UploadMethod { - file, - url, - external + file, url, external } // ========================================================================== @@ -494,21 +514,112 @@ public class GeoServerRESTPublisher { /** * Publish a zipped shapefile.
- * The CRS will be forced to EPSG:4326. + * The defaultCRS will be set to EPSG:4326. + * + * @see {@link #publishShp(String, String, NameValuePair[], String, UploadMethod, URI, String, ProjectionPolicy, String)} * * @param workspace * @param storename * @param layername * @param zipFile * @return true if the operation completed successfully. - * @throws FileNotFoundException + * @throws FileNotFoundException, IllegalArgumentException */ public boolean publishShp(String workspace, String storename, - String layername, File zipFile) throws FileNotFoundException { - return publishShp(workspace, storename, layername, zipFile, "EPSG:4326"); + String datasetname, File zipFile) throws FileNotFoundException, IllegalArgumentException { + return publishShp(workspace, storename, new NameValuePair[0], datasetname,UploadMethod.file, zipFile.toURI(), "EPSG:4326", ProjectionPolicy.NONE,null); } /** + * + * Publish a shapefile.
+ * + * @param workspace + * the name of the workspace to use + * @param storename + * the name of the store to create + * @param storeParams + * parameters to append to the url (can be null).
+ * Accepted parameters are:
+ * + * @param layername + * the name of the layer to configure + * @param method + * {@link UploadMethod} + * @param fileUri + * the uri of the file containing the shapefile.It should be: + * + * @param srs + * the native CRS + * @param policy + * {@link ProjectionPolicy} + * @param defaultStyle + * the default style to set (can be null). + * @return true if success false otherwise + * @throws FileNotFoundException + * if file to upload is not found + * @throws IllegalArgumentException + * if some arguments are null. + */ + public boolean publishShp(String workspace, String storeName, + NameValuePair[] storeParams, String datasetName, UploadMethod method, URI shapefile, + String srs, ProjectionPolicy policy, String defaultStyle) + throws FileNotFoundException, IllegalArgumentException { + if (workspace == null || storeName == null || shapefile == null + || datasetName == null || srs == null || policy == null) + throw new IllegalArgumentException("Unable to run: null parameter"); + // + final String mimeType; + switch (method){ + case external: + mimeType="text/plain"; + break; + case url: // TODO check which mime-type should be used + case file: + mimeType="application/zip"; + break; + default: + mimeType=null; + } + if (!createDataStore(workspace, + (storeName != null) ? storeName : FilenameUtils.getBaseName(shapefile.toString()), + method, DataStoreExtension.shp, mimeType, + shapefile, ParameterConfigure.NONE, storeParams)) { + LOGGER.error("Unable to create data store for shapefile: " + + shapefile); + return false; + } + + // config coverage props (srs) + final GSFeatureTypeEncoder featureTypeEncoder = new GSFeatureTypeEncoder(); + featureTypeEncoder.setName(datasetName); + featureTypeEncoder.setSRS(srs); + featureTypeEncoder.setProjectionPolicy(policy); + + if (!createResource(workspace, DataStoreType.datastores, storeName, + featureTypeEncoder)) { + LOGGER.error("Unable to create a coverage store for coverage: " + + shapefile); + return false; + } + + // config layer props (style, ...) + final GSLayerEncoder layerEncoder = new GSLayerEncoder(); + if (defaultStyle != null && !defaultStyle.isEmpty()) + layerEncoder.setDefaultStyle(defaultStyle); + + return configureLayer(workspace, datasetName, layerEncoder); + } + + /** + * @see {@link #publishShp(String, String, NameValuePair[], String, UploadMethod, URI, String, ProjectionPolicy, String)} + * * Publish a zipped shapefile. * * @param workspace @@ -522,28 +633,16 @@ public class GeoServerRESTPublisher { */ public boolean publishShp(String workspace, String storename, String layerName, File zipFile, String nativeCrs, - String defaultStyle) throws FileNotFoundException { - boolean sent = publishShp(workspace, storename, layerName, zipFile, - nativeCrs); - if (sent) { - - try { - GSLayerEncoder layerEncoder = new GSLayerEncoder(); - layerEncoder.setDefaultStyle(defaultStyle); - configureLayer(workspace, layerName, layerEncoder); - } catch (Exception e) { - LOGGER.warn("Error in publishing shapefile " + e.getMessage(), - e); - sent = false; - } - } - - return sent; + String defaultStyle) throws FileNotFoundException, IllegalArgumentException { + + return publishShp(workspace, storename, (NameValuePair[])null, layerName, UploadMethod.file, zipFile.toURI(), nativeCrs, ProjectionPolicy.NONE,defaultStyle); } /** * Publish a zipped shapefile. * + * @see {@link #publishShp(String, String, NameValuePair[], String, UploadMethod, URI, String, ProjectionPolicy, String)} + * *

* These are the equivalent calls with cUrl: * @@ -559,21 +658,20 @@ public class GeoServerRESTPublisher { * } * * - * {@link #publishShp(String, String, String, File, String, NameValuePair...)} - * * @return true if the operation completed successfully. */ public boolean publishShp(String workspace, String storename, String layername, File zipFile, String srs) throws FileNotFoundException { - return publishShp(workspace, storename, layername, zipFile, srs, - new NameValuePair[0]); + return publishShp(workspace, storename, (NameValuePair[])null, layername, UploadMethod.file, zipFile.toURI(), srs, ProjectionPolicy.NONE,null); } /** * * Publish a zipped shapefile.
* + * @see {@link #publishShp(String, String, NameValuePair[], String, UploadMethod, URI, String, ProjectionPolicy, String)} + * * http://docs.geoserver.org/stable/en/user * /restconfig/rest-config-examples/rest- * config-examples-curl.html#uploading-a-shapefile @@ -595,63 +693,13 @@ public class GeoServerRESTPublisher { *

  • charset used to set the charset
  • * * @return true if success false otherwise - * @throws FileNotFoundException + * @throws FileNotFoundException, IllegalArgumentException */ public boolean publishShp(String workspace, String storename, String layername, File zipFile, String srs, NameValuePair... params) - throws FileNotFoundException { - // build full URL - StringBuilder sbUrl = new StringBuilder(restURL) - .append("/rest/workspaces/").append(workspace) - .append("/datastores/").append(storename).append("/file.shp?"); - - // append parameters - sbUrl.append(appendParameters(params)); - - // if (workspace != null) { - // sbUrl.append("namespace=").append(workspace); - // } - // sbUrl.append("&SRS=4326&SRSHandling=Force"); // hack - - String sentResult = HTTPUtils.put(sbUrl.toString(), zipFile, - "application/zip", gsuser, gspass); - boolean shpSent = sentResult != null; - - if (shpSent) { - LOGGER.info("Zipfile successfully uploaded (layer:" + layername - + " zip:" + zipFile + ")"); - - StringBuilder postUrl = new StringBuilder(restURL) - .append("/rest/workspaces/").append(workspace) - .append("/datastores/").append(storename) - .append("/featuretypes/").append(layername); - - GSFeatureTypeEncoder fte = new GSFeatureTypeEncoder(); - fte.setName(layername); - fte.setSRS(srs); - fte.setProjectionPolicy(ProjectionPolicy.FORCE_DECLARED); - - String configuredResult = HTTPUtils.putXml(postUrl.toString(), - fte.toString(), this.gsuser, this.gspass); - boolean shpConfigured = configuredResult != null; - - if (!shpConfigured) { - LOGGER.warn("Error in configuring " + workspace + ":" - + storename + "/" + layername - + " -- Zipfile was uploaded successfully: " + zipFile); - } else { - LOGGER.info("Shapefile successfully configured (layer:" - + layername + ")"); - } - - return shpConfigured; - - } else { - LOGGER.warn("Error in sending zipfile " + workspace + ":" - + storename + "/" + layername + " " + zipFile); - return false; - } + throws FileNotFoundException, IllegalArgumentException { + return publishShp(workspace, storename, params, layername, UploadMethod.file, zipFile.toURI(), srs, ProjectionPolicy.NONE,null); } /** @@ -661,6 +709,7 @@ public class GeoServerRESTPublisher { * @param srs * @param defaultStyle * @return + * @deprecated will be removed in the next release */ public boolean publishDBLayer(String workspace, String storename, String layername, String srs, String defaultStyle) { @@ -750,8 +799,8 @@ public class GeoServerRESTPublisher { /** * The configure parameter is used to control how the data store is - * configured upon file upload. It can take one of the three values first, - * none, or all. + * configured upon file upload. It can take one of the three values + * first, none, or all. *