diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java
index f18e4bc..97255fa 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTManager.java
@@ -26,6 +26,7 @@ package it.geosolutions.geoserver.rest;
import it.geosolutions.geoserver.rest.manager.GeoServerRESTAbstractManager;
import it.geosolutions.geoserver.rest.manager.GeoServerRESTStoreManager;
+import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredGridCoverageReaderManager;
import java.net.MalformedURLException;
import java.net.URL;
@@ -50,6 +51,8 @@ public class GeoServerRESTManager extends GeoServerRESTAbstractManager {
private final GeoServerRESTReader reader;
private final GeoServerRESTStoreManager store;
+
+ private final GeoServerRESTStructuredGridCoverageReaderManager structuredGridCoverageReader;
/**
* Default constructor.
@@ -69,6 +72,7 @@ public class GeoServerRESTManager extends GeoServerRESTAbstractManager {
// Internal publisher and reader, provide simple access methods.
publisher = new GeoServerRESTPublisher(restURL.toString(), username, password);
reader = new GeoServerRESTReader(restURL, username, password);
+ structuredGridCoverageReader = new GeoServerRESTStructuredGridCoverageReaderManager(restURL, username, password);
store = new GeoServerRESTStoreManager(restURL, gsuser, gspass);
}
@@ -84,4 +88,8 @@ public class GeoServerRESTManager extends GeoServerRESTAbstractManager {
return store;
}
+ public GeoServerRESTStructuredGridCoverageReaderManager getStructuredGridCoverageReader() {
+ return structuredGridCoverageReader;
+ }
+
}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java
index 9b703ce..5eb3dfc 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java
@@ -26,6 +26,7 @@ package it.geosolutions.geoserver.rest;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageList;
import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
import it.geosolutions.geoserver.rest.decoder.utils.NameLinkElem;
import it.geosolutions.geoserver.rest.encoder.GSBackupEncoder;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
@@ -37,9 +38,11 @@ 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.feature.GSFeatureTypeEncoder;
+import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredGridCoverageReaderManager;
import java.io.File;
import java.io.FileNotFoundException;
+import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
@@ -2537,7 +2540,7 @@ public class GeoServerRESTPublisher {
*
* configured - Only setup or configured feature types are returned. This is the default value. available - Only unconfigured feature types
* (not yet setup) but are available from the specified datastore will be returned. available_with_geom - Same as available but only
- * includes feature types that have a geometry attribute. all - The union of configured and available.
+ * includes feature types that have a geometry granule. all - The union of configured and available.
*
*
* @return true if success
@@ -2647,4 +2650,94 @@ public class GeoServerRESTPublisher {
return URLEncoder.encode(s);
// }
}
+
+ // ==> StructuredCoverageGridReader
+
+ /**
+ * Create a store or harvest the coverage from the provided external path.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param format the format of the file to upload
+ * @param the absolut path to the file to upload
+ *
+ * @return true if the call succeeds or false otherwise.
+ */
+ public boolean createOrHarvestExternal(String workspace, String coverageStore, String format, String path) {
+ try {
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(restURL), gsuser, gspass);
+ return manager.createOrHarvestExternal(workspace, coverageStore, format, path);
+ } catch (IllegalArgumentException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ } catch (MalformedURLException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Remove a granule from a structured coverage by id.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param coverage the name of the target coverage from which we are going to remove
+ * @param filter the absolute path to the file to upload
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public boolean removeGranuleById(final String workspace, String coverageStore, String coverage, String granuleId) {
+ try {
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(restURL), gsuser, gspass);
+ return manager.removeGranuleById(workspace, coverageStore, coverage, granuleId);
+ } catch (IllegalArgumentException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ } catch (MalformedURLException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ }
+ return false;
+ }
+ /**
+ * Remove granules from a structured coverage, by providing a CQL filter.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param coverage the name of the target coverage from which we are going to remove
+ * @param filter the absolute path to the file to upload
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public boolean removeGranulesByCQL(final String workspace, String coverageStore,String coverage, String filter) throws UnsupportedEncodingException{
+ try {
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(restURL), gsuser, gspass);
+ return manager.removeGranulesByCQL(workspace, coverageStore, coverage, filter);
+ } catch (IllegalArgumentException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ } catch (MalformedURLException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ }
+ return false;
+
+ }
+
}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java
index 0cf9846..05c1dcf 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java
@@ -39,13 +39,16 @@ import it.geosolutions.geoserver.rest.decoder.RESTLayerList;
import it.geosolutions.geoserver.rest.decoder.RESTNamespace;
import it.geosolutions.geoserver.rest.decoder.RESTNamespaceList;
import it.geosolutions.geoserver.rest.decoder.RESTResource;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema;
import it.geosolutions.geoserver.rest.decoder.RESTStyleList;
import it.geosolutions.geoserver.rest.decoder.RESTWorkspaceList;
+import it.geosolutions.geoserver.rest.manager.GeoServerRESTStructuredGridCoverageReaderManager;
+import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -575,4 +578,99 @@ public class GeoServerRESTReader {
return names;
}
+ /**
+ * Get information about a granule for a structured coverage.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param format the format of the file to upload
+ * @param the absolute path to the file to upload
+ * @param id the ID of the granule to get information for
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public RESTStructuredCoverageGranulesList getGranuleById(final String workspace,
+ String coverageStore, String coverage, String id) throws MalformedURLException,
+ UnsupportedEncodingException {
+ try {
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(baseurl), username, password);
+ return manager.getGranuleById(workspace, coverageStore, coverage, id);
+ } catch (IllegalArgumentException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ } catch (MalformedURLException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get information about the schema of the index for a structured coverage.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param format the format of the file to upload
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public RESTStructuredCoverageIndexSchema getGranuleIndexSchema(final String workspace, String coverageStore, String coverage) throws MalformedURLException {
+ try {
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(baseurl), username, password);
+ return manager.getGranuleIndexSchema(workspace, coverageStore, coverage);
+ } catch (IllegalArgumentException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ } catch (MalformedURLException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get information about the granules for a coverage with optional filter and paging.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param coverage the name of the target coverage
+ * @param filter the format of the file to upload, can be null to include all the granules
+ * @param offset the start page, can be null or an integer
+ * @param limit the dimension of the page, can be null or a positive integer
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public RESTStructuredCoverageGranulesList getGranules(final String workspace, String coverageStore, String coverage, String filter, Integer offset, Integer limit)
+ throws MalformedURLException, UnsupportedEncodingException {
+ try {
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(baseurl), username, password);
+ return manager.getGranules(workspace, coverageStore, coverage, filter, offset, limit);
+ } catch (IllegalArgumentException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ } catch (MalformedURLException e) {
+ if(LOGGER.isInfoEnabled()){
+ LOGGER.info(e.getLocalizedMessage(),e);
+ }
+ }
+ return null;
+ }
+
}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java b/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java
index a08da22..ad8e2d0 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/HTTPUtils.java
@@ -336,7 +336,7 @@ public class HTTPUtils {
InputStream is = httpMethod.getResponseBodyAsStream();
response = IOUtils.toString(is);
IOUtils.closeQuietly(is);
- if (response.trim().equals("")) { // sometimes gs rest fails
+ if (response.trim().equals("")) {
if (LOGGER.isDebugEnabled())
LOGGER
.debug("ResponseBody is empty (this may be not an error since we just performed a DELETE call)");
@@ -467,14 +467,14 @@ public class HTTPUtils {
/**
* @param str a string array
- * @return create a StringBuffer appending all the passed arguments
+ * @return create a StringBuilder appending all the passed arguments
*/
- public static StringBuffer append(String ... str){
+ public static StringBuilder append(String ... str){
if (str==null){
return null;
}
- StringBuffer buf=new StringBuffer();
+ StringBuilder buf=new StringBuilder();
for (String s: str){
if (s!=null)
buf.append(s);
@@ -488,12 +488,12 @@ public class HTTPUtils {
* @param str strings to append
* @return the base URL with parameters attached
*/
- public static StringBuffer append(URL base, String ... str){
+ public static StringBuilder append(URL base, String ... str){
if (str==null){
return append(base.toString());
}
- StringBuffer buf=new StringBuffer(base.toString());
+ StringBuilder buf=new StringBuilder(base.toString());
for (String s: str){
if (s!=null)
buf.append(s);
diff --git a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java
index 04b8316..2e14e65 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTCoverageStore.java
@@ -76,15 +76,23 @@ public class RESTCoverageStore {
return new RESTCoverageStore(pb);
else
return null;
- }
+ }
- public String getName() {
- return cs.getChildText("name");
- }
+ public String getName() {
+ return cs.getChildText("name");
+ }
- public String getWorkspaceName() {
- return cs.getChild("workspace").getChildText("name");
- }
+ public String getWorkspaceName() {
+ return cs.getChild("workspace").getChildText("name");
+ }
+
+ public String getURL() {
+ return cs.getChildText("url");
+ }
+
+ public String getType() {
+ return cs.getChildText("type");
+ }
public String toString() {
StringBuilder sb = new StringBuilder(getClass().getSimpleName())
diff --git a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTStructuredCoverageGranulesList.java b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTStructuredCoverageGranulesList.java
new file mode 100644
index 0000000..80d612a
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTStructuredCoverageGranulesList.java
@@ -0,0 +1,230 @@
+/*
+ * 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.decoder;
+
+import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jdom.Element;
+import org.jdom.Namespace;
+
+/**
+ * This decode turns index format for a GeoServer StructuredGridCoverageReader into something
+ * useful, giving access to the definition of the single attributes.
+ *
+ *
This is the XML REST representation: + *
+ {@code
+
+
+
+
+
+
+ 5.0
+ 45.0
+
+
+ 14.875
+ 50.9375
+
+
+
+
+
+
+
+
+
+ 5.0,45.0 5.0,50.9375 14.875,50.9375 14.875,45.0 5.0,45.0
+
+
+
+
+ ..\\polyphemus\\polyphemus_20130302.nc
+ 672
+ 2013-03-01T23:00:00Z
+ 10.0
+ 2013-03-01T23:00:00Z
+ 2013-04-08T05:40:29.061Z
+
+
+
+
+}
+ * @author Simone Giannecchini, GeoSolutions SAS
+ *
+ */
+public class RESTStructuredCoverageGranulesList implements IterableThis is the XML REST representation: + *
+ {@code
+
+
+
+
+
+
+ 5.0,45.0 5.0,50.9375 14.875,50.9375 14.875,45.0 5.0,45.0
+
+
+
+
+ polyphemus_20130301.nc
+ 672
+ 2013-02-28T23:00:00Z
+ 10.0
+ 2013-02-28T23:00:00Z
+ 2013-04-08T06:18:41.597Z
+
+
+
+ * @author Simone Giannecchini, GeoSolutions SAS
+ *
+ */
+ public static class RESTStructuredCoverageGranule {
+
+ protected final Element granule;
+
+ private final String fid;
+
+ private final List children;
+
+ @SuppressWarnings("unchecked")
+ public RESTStructuredCoverageGranule(Element elem) {
+ if(!elem.getName().equals("featureMember")){
+ throw new IllegalStateException("Root element should be gml:featureMember for a granule");
+ }
+ Element feature = (Element) elem.getChildren().get(0);
+ if(feature==null){
+ throw new IllegalStateException("Unable to find feature element for this granule");
+ }
+ this.granule = feature;
+ this.fid=granule.getAttribute("fid").getValue();
+ this.children=granule.getChildren();
+
+ }
+
+ public String getAttributeByName(String name) {
+ return granule.getChildTextTrim(name,null);
+ }
+
+ public String getAttributeByIndex(int index) {
+ return children.get(index).getValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator getAttributesIterator() {
+ return granule.getChildren().iterator();
+ }
+
+ /**
+ * @return the fid
+ */
+ public String getFid() {
+ return fid;
+ }
+ }
+
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTStructuredCoverageIndexSchema.java b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTStructuredCoverageIndexSchema.java
new file mode 100644
index 0000000..b19e0e6
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTStructuredCoverageIndexSchema.java
@@ -0,0 +1,212 @@
+/*
+ * 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.decoder;
+
+import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jdom.Element;
+
+/**
+ * This decode turns index format for a GeoServer StructuredGridCoverageReader into something
+ * useful, giving access to the definition of the single attributes.
+ *
+ * This is the XML REST representation:
+ *
+ {@code
+
+
+
+
+ the_geom
+ 0
+ 1
+ true
+ com.vividsolutions.jts.geom.Polygon
+
+
+ location
+ 0
+ 1
+ true
+ java.lang.String
+
+
+ imageindex
+ 0
+ 1
+ true
+ java.lang.Integer
+
+
+ time
+ 0
+ 1
+ true
+ java.sql.Timestamp
+
+
+ elevation
+ 0
+ 1
+ true
+ java.lang.Double
+
+
+ fileDate
+ 0
+ 1
+ true
+ java.sql.Timestamp
+
+
+ updated
+ 0
+ 1
+ true
+ java.sql.Timestamp
+
+
+
+
+}
+ * @author Simone Giannecchini, GeoSolutions SAS
+ *
+ */
+public class RESTStructuredCoverageIndexSchema implements Iterable {
+
+ private final List attributeList;
+
+ /**
+ * @param list
+ */
+ @SuppressWarnings("unchecked")
+ protected RESTStructuredCoverageIndexSchema(Element schema) {
+
+ // check ordering of elements
+ if(!schema.getName().equals("Schema")){
+ throw new IllegalStateException("Root element should be Schema");
+ }
+ Element attributes = schema.getChild("attributes");
+ if(attributes==null){
+ throw new IllegalStateException("Root element should be Schema");
+ }
+
+ List tmpList = new ArrayList();
+ for(Element el : (List)attributes.getChildren()){
+ tmpList.add(new RESTStructuredCoverageIndexAttribute(el));
+ }
+ attributeList = Collections.unmodifiableList(tmpList);
+ }
+
+ public static RESTStructuredCoverageIndexSchema build(String response) {
+ if(response == null)
+ return null;
+
+ Element pb = JDOMBuilder.buildElement(response);
+ if(pb != null){
+ return new RESTStructuredCoverageIndexSchema(pb);
+ } else {
+ return null;
+ }
+ }
+
+ public int size() {
+ return attributeList.size();
+ }
+
+ public boolean isEmpty() {
+ return attributeList.isEmpty();
+ }
+
+ public RESTStructuredCoverageIndexAttribute get(int index) {
+ return attributeList.get(index);
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Iterable#iterator()
+ */
+ @Override
+ public Iterator iterator() {
+ return attributeList.iterator();
+ }
+
+ /**
+ * Generic granule of the index.
+ *
+ * This is the XML REST representation:
+ *
+ {@code
+
+ the_geom
+ 0
+ 1
+ true
+ com.vividsolutions.jts.geom.Polygon
+
+ * @author Simone Giannecchini, GeoSolutions SAS
+ *
+ */
+ public static class RESTStructuredCoverageIndexAttribute {
+ protected final Element attribute;
+
+ public RESTStructuredCoverageIndexAttribute(Element elem) {
+ this.attribute = elem;
+ }
+
+ public String getName() {
+ return attribute.getChildTextTrim("name");
+ }
+
+ public String getMinOccurs() {
+ return attribute.getChildTextTrim("minOccurs");
+ }
+
+ public String getMaxOccurs() {
+ return attribute.getChildTextTrim("maxOccurs");
+ }
+
+ public String getNillable() {
+ return attribute.getChildTextTrim("nillable");
+ }
+
+ public String getBinding() {
+ return attribute.getChildTextTrim("binding");
+ }
+
+ @Override
+ public String toString() {
+ return "RESTStructuredCoverageGranule [getName()=" + getName()
+ + ", getMinOccurs()=" + getMinOccurs() + ", getMaxOccurs()=" + getMaxOccurs()
+ + ", getNillable()=" + getNillable() + ", getBinding()=" + getBinding() + "]";
+ }
+
+ }
+
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStoreManager.java b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStoreManager.java
index 34dad05..5aad7be 100644
--- a/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStoreManager.java
+++ b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStoreManager.java
@@ -107,7 +107,7 @@ public class GeoServerRESTStoreManager extends GeoServerRESTAbstractManager {
// if (workspace.isEmpty() || storename.isEmpty())
// throw new IllegalArgumentException("Arguments may not be empty!");
- final StringBuffer url=HTTPUtils.append(restURL,"/rest/workspaces/",workspace,"/", store.getStoreType().toString(), "/",store.getName());
+ final StringBuilder url=HTTPUtils.append(restURL,"/rest/workspaces/",workspace,"/", store.getStoreType().toString(), "/",store.getName());
if (recurse)
url.append("?recurse=true");
final URL deleteStore = new URL(url.toString());
diff --git a/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStructuredGridCoverageReaderManager.java b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStructuredGridCoverageReaderManager.java
new file mode 100644
index 0000000..5440f2b
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTStructuredGridCoverageReaderManager.java
@@ -0,0 +1,350 @@
+/*
+ * 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.GeoServerRESTPublisher.UploadMethod;
+import it.geosolutions.geoserver.rest.HTTPUtils;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema;
+
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLEncoder;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manage GeoTools StructuredGridCoverageReader. It allows to create a store from a file or harvest
+ * the coverages contained in a file, to delete granules from an existing coverage and eventually
+ * to get information about the granules inside a StructuredGridCoverageReader.
+ *
+ * @author Simone Giannecchini, GeoSolutions
+ */
+public class GeoServerRESTStructuredGridCoverageReaderManager extends GeoServerRESTAbstractManager {
+
+ /**
+ * Default logger
+ */
+ private final static Logger LOGGER = LoggerFactory.getLogger(GeoServerRESTStructuredGridCoverageReaderManager.class);
+
+ /**
+ * 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
+ * @throws IllegalArgumentException
+ */
+ public GeoServerRESTStructuredGridCoverageReaderManager(URL restURL, String username, String password) throws IllegalArgumentException, MalformedURLException{
+ super(restURL, username, password);
+ }
+
+ /**
+ * Create a store or harvest the coverage from the provided external path.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param format the format of the file to upload
+ * @param the absolut path to the file to upload
+ *
+ * @return true if the call succeeds or false otherwise.
+ */
+ public boolean createOrHarvestExternal(String workspace, String coverageStore, String format, String path) {
+ // checks
+ checkString(workspace);
+ checkString(coverageStore);
+ checkString(format);
+ checkString(path);
+
+ // create URL
+ String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/",coverageStore,"/",UploadMethod.EXTERNAL.toString(),".", format).toString();
+
+ // POST request
+ String result = HTTPUtils.post(sUrl, "file:/"+path, "text/plain", gsuser, gspass);
+ return result != null;
+ }
+
+ /**
+ * Check the provided string for not being null or empty.
+ *
+ *
+ * It throws an exception in case the string is either null or empty.
+ *
+ * @param string the {@link String} to be checked
+ */
+ private static void checkString(String string) {
+ if(string==null){
+ throw new NullPointerException("Provided string is is null!");
+ }
+ if(string.length()<=0){
+ throw new IllegalArgumentException("Provided string is is empty!");
+ }
+
+ }
+
+ /**
+ * Remove granules from a structured coverage, by providing a CQL filter.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param coverage the name of the target coverage from which we are going to remove
+ * @param filter the absolute path to the file to upload
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public boolean removeGranulesByCQL(final String workspace, String coverageStore,String coverage, String filter) throws UnsupportedEncodingException{
+ // checks
+ checkString(workspace);
+ checkString(coverage);
+ checkString(filter);
+ checkString(coverageStore);
+
+ // does it exist?
+ RESTStructuredCoverageGranulesList granulesList=null;
+ try {
+ granulesList = getGranules(workspace, coverageStore, coverageStore, filter, null, 1);
+ } catch (MalformedURLException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ } catch (UnsupportedEncodingException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ }
+ if (granulesList == null||granulesList.isEmpty()) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace("Granules for filter: "+filter+ " does not exist for coverage "+coverage);
+ }
+ return true; // nothing to remove
+ }
+
+ // method
+ String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores", "/",coverageStore,"/coverages/",coverage,"/index/granules?filter=",URLEncoder.encode(filter, "UTF-8")).toString();
+ if(!HTTPUtils.delete(sUrl, gsuser, gspass)){
+ return false;
+ }
+
+ // does it exist?
+ granulesList=null;
+ try {
+ granulesList = getGranules(workspace, coverageStore, coverageStore, filter, null, 1);
+ } catch (MalformedURLException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ } catch (UnsupportedEncodingException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ }
+ if (granulesList == null||granulesList.isEmpty()) {
+ return true; // nothing to remove
+ }
+ return false;
+ }
+
+ /**
+ * Remove a granule from a structured coverage by id.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param coverage the name of the target coverage from which we are going to remove
+ * @param filter the absolute path to the file to upload
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public boolean removeGranuleById(final String workspace, String coverageStore, String coverage, String granuleId) {
+ // checks
+ checkString(workspace);
+ checkString(coverage);
+ checkString(granuleId);
+ checkString(coverageStore);
+
+ // does it exist?
+ RESTStructuredCoverageGranulesList granule=null;
+ try {
+ granule = getGranuleById(workspace, coverageStore, coverage, granuleId);
+ } catch (MalformedURLException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ } catch (UnsupportedEncodingException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ }
+ if (granule == null) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace("Granule for id: "+granuleId+ " does not exist for coverage "+coverage);
+ }
+ return true; // nothing to remove
+ }
+
+ // delete
+ String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores",
+ "/", coverageStore, "/coverages/", coverage, "/index/granules/", granuleId)
+ .toString();
+ if(!HTTPUtils.delete(sUrl, gsuser, gspass)){
+ return false;
+ }
+
+ // has it been canceled?
+ // does it exist?
+ granule=null;
+ try {
+ granule = getGranuleById(workspace, coverageStore, coverage, granuleId);
+ } catch (MalformedURLException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ } catch (UnsupportedEncodingException e) {
+ if(LOGGER.isTraceEnabled()){
+ LOGGER.trace(e.getMessage(), e);
+ }
+ }
+ if (granule == null) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get information about the schema of the index for a structured coverage.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param format the format of the file to upload
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public RESTStructuredCoverageIndexSchema getGranuleIndexSchema(final String workspace, String coverageStore, String coverage) throws MalformedURLException {
+ // checks
+ checkString(workspace);
+ checkString(coverage);
+ checkString(coverageStore);
+
+ // create URL and then call it
+ String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/", coverageStore, "/coverages/", coverage, "/index.xml").toString();
+ String result = HTTPUtils.get(sUrl, gsuser, gspass);
+ if (result != null) {
+ return RESTStructuredCoverageIndexSchema.build(result);
+ }
+ return null;
+ }
+
+ /**
+ * Get information about the granules for a coverage with optional filter and paging.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param coverage the name of the target coverage
+ * @param filter the format of the file to upload, can be null to include all the granules
+ * @param offset the start page, can be null or an integer
+ * @param limit the dimension of the page, can be null or a positive integer
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public RESTStructuredCoverageGranulesList getGranules(final String workspace, String coverageStore, String coverage, String filter, Integer offset, Integer limit)
+ throws MalformedURLException, UnsupportedEncodingException {
+ // checks
+ checkString(workspace);
+ checkString(coverage);
+ checkString(coverageStore);
+
+ // method
+ boolean append = false;
+ String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/", coverageStore, "/coverages/", coverage, "/index/granules.xml").toString();
+ if (filter != null && !filter.isEmpty()) {
+ append = true;
+ sUrl = HTTPUtils.append(sUrl, "?filter=", URLEncoder.encode(filter, "UTF-8")).toString();
+ }
+ if (offset != null) {
+ sUrl = HTTPUtils.append(sUrl, append ? "&offset=" : "?offset=", offset.toString()).toString();
+ append = true;
+ }
+ if (limit != null) {
+ sUrl = HTTPUtils.append(sUrl, append ? "&limit=" : "?limit=", limit.toString()).toString();
+ append = true;
+ }
+ String result = HTTPUtils.get(sUrl, gsuser, gspass);
+ if (result != null) {
+ return RESTStructuredCoverageGranulesList.build(result);
+ }
+ return null;
+ }
+
+ /**
+ * Get information about a granule for a structured coverage.
+ *
+ * @param workspace the GeoServer workspace
+ * @param coverageStore the GeoServer coverageStore
+ * @param format the format of the file to upload
+ * @param the absolute path to the file to upload
+ * @param id the ID of the granule to get information for
+ *
+ * @return null in case the call does not succeed, or an instance of {@link RESTStructuredCoverageGranulesList}.
+ *
+ * @throws MalformedURLException
+ * @throws UnsupportedEncodingException
+ */
+ public RESTStructuredCoverageGranulesList getGranuleById(final String workspace,
+ String coverageStore, String coverage, String id) throws MalformedURLException,
+ UnsupportedEncodingException {
+ // checks
+ checkString(workspace);
+ checkString(coverage);
+ checkString(coverageStore);
+ checkString(id);
+ try{
+ Integer.parseInt(id);
+ }catch (NumberFormatException e) {
+ throw new IllegalArgumentException(e);
+ }
+
+ // method
+ String sUrl = HTTPUtils.append(restURL, "/rest/workspaces/", workspace, "/coveragestores/", coverageStore, "/coverages/", coverage, "/index/granules/", id, ".xml").toString();
+ String result = HTTPUtils.get(sUrl, gsuser, gspass);
+ if (result != null) {
+ return RESTStructuredCoverageGranulesList.build(result);
+ }
+ return null;
+ }
+}
diff --git a/src/test/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImageMosaicManagerTest.java b/src/test/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImageMosaicManagerTest.java
new file mode 100644
index 0000000..1634102
--- /dev/null
+++ b/src/test/java/it/geosolutions/geoserver/rest/manager/GeoServerRESTImageMosaicManagerTest.java
@@ -0,0 +1,264 @@
+/*
+ * GeoTools - The Open Source Java GIS Toolkit
+ * http://geotools.org
+ *
+ * (C) 2002-2011, Open Source Geospatial Foundation (OSGeo)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ */
+package it.geosolutions.geoserver.rest.manager;
+
+import it.geosolutions.geoserver.rest.GeoServerRESTReader;
+import it.geosolutions.geoserver.rest.datastore.StoreIntegrationTest;
+import it.geosolutions.geoserver.rest.decoder.RESTCoverageStore;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageGranulesList.RESTStructuredCoverageGranule;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema;
+import it.geosolutions.geoserver.rest.decoder.RESTStructuredCoverageIndexSchema.RESTStructuredCoverageIndexAttribute;
+import it.geosolutions.geoserver.rest.encoder.GSAbstractStoreEncoder;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Iterator;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * In order to test that class, make sure to configure a geoserver with a "mosaic" store.
+ *
+ * 1) take the mosaic.zip archive contained on src/test/resources/testdata.granules
+ * 2) extract it on disk
+ * 3) configure an ImageMosaic store on geoserver (name the store as "mosaic"), use the "it.geosolutions" workspace
+ * 4) configure a layer on that store (name the coverage as "mosaic" again).
+ * 5) on dimensions configuration tab, make sure to enable custom depth and date dimensions.
+ * 6) publish it.
+ *
+ *
+ * @author Simone Giannecchini, simone.giannecchini@geo-solutions.it
+ * @author Daniele Romagnoli, GeoSolutions SAS
+ *
+ */
+public class GeoServerRESTImageMosaicManagerTest extends StoreIntegrationTest {
+
+ private final static Logger LOGGER = LoggerFactory.getLogger(GeoServerRESTImageMosaicManagerTest.class);
+
+ /**
+ * @param ignore
+ * @throws IllegalArgumentException
+ * @throws MalformedURLException
+ */
+ public GeoServerRESTImageMosaicManagerTest()
+ throws IllegalArgumentException, MalformedURLException {
+ super(true);
+ }
+
+ @Override
+ public GSAbstractStoreEncoder getStoreEncoderTest() {
+ return null;
+ }
+
+ @Test
+ public void createAndDelete() throws IllegalArgumentException, MalformedURLException, UnsupportedEncodingException{
+ if (!enabled()) {
+ return;
+ }
+ GeoServerRESTStructuredGridCoverageReaderManager manager =
+ new GeoServerRESTStructuredGridCoverageReaderManager(new URL(RESTURL), RESTUSER, RESTPW);
+ GeoServerRESTReader reader = new GeoServerRESTReader(new URL(RESTURL), RESTUSER, RESTPW);
+
+ // check index format
+ RESTStructuredCoverageIndexSchema indexFormat = manager.getGranuleIndexSchema("it.geosolutions", "mosaic","mosaic");
+ if (indexFormat == null) {
+ if (LOGGER.isWarnEnabled()) {
+ LOGGER.warn("sample coverage hasn't been found. Make sure to configure the layer before running this test");
+ return;
+ }
+ }
+ assertNotNull(indexFormat);
+ assertFalse(indexFormat.isEmpty());
+ assertEquals(5, indexFormat.size());
+ Iterator iterator = indexFormat.iterator();
+ while (iterator.hasNext()) {
+ final RESTStructuredCoverageIndexAttribute element = iterator.next();
+ final String elementName = element.getName();
+ if (elementName.equals("location")) {
+ assertEquals("0", element.getMinOccurs());
+ assertEquals("1", element.getMaxOccurs());
+ assertEquals("true", element.getNillable());
+ assertEquals("java.lang.String", element.getBinding());
+ } else if (elementName.equals("time")) {
+ assertEquals("0", element.getMinOccurs());
+ assertEquals("1", element.getMaxOccurs());
+ assertEquals("true", element.getNillable());
+ assertEquals("java.sql.Timestamp", element.getBinding());
+ } else if (elementName.equals("date")) {
+ assertEquals("0", element.getMinOccurs());
+ assertEquals("1", element.getMaxOccurs());
+ assertEquals("true", element.getNillable());
+ assertEquals("java.lang.String", element.getBinding());
+ } else if (elementName.equals("depth")) {
+ assertEquals("0", element.getMinOccurs());
+ assertEquals("1", element.getMaxOccurs());
+ assertEquals("true", element.getNillable());
+ assertEquals("java.lang.Integer", element.getBinding());
+ }
+ }
+
+ RESTStructuredCoverageGranulesList granulesList = null;
+ RESTStructuredCoverageGranule granule = null;
+ // get some granules by id
+// manager.getGranuleById("it.geosolutions", "mosaic","mosaic","2");
+// assertNotNull(granulesList);
+// assertSame(1, granulesList.size());
+// assertFalse(granulesList.isEmpty());
+// RESTStructuredCoverageGranule granule = granulesList.get(0);
+// assertNotNull(granule);
+// assertEquals(granule.getAttributeByIndex(4), "1250.0");
+// assertEquals(granule.getAttributeByName("elevation"), "1250.0");
+
+
+ // get with paging
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic" , null, 0, 1);
+ assertNotNull(granulesList);
+ assertEquals(1, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic", null, null, 2);
+ assertNotNull(granulesList);
+ assertEquals(2, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic", null, null, null);
+ assertNotNull(granulesList);
+ assertEquals(4, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic", "depth = 100", null, null);
+ assertNotNull(granulesList);
+ assertEquals(2, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic", "depth = 100 AND date='20081101T0000000'", null, null);
+ assertNotNull(granulesList);
+ assertEquals(1, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ // remove by filter
+ final String fileLocation = "NCOM_wattemp_100_20081101T0000000_12.tiff";
+ boolean result = manager.removeGranulesByCQL("it.geosolutions", "mosaic", "mosaic", "location = '" + fileLocation + "'");
+ Assert.assertTrue(result);
+
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic", null, null, null);
+ assertNotNull(granulesList);
+ assertEquals(3, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ // Readding that granule
+ RESTCoverageStore store = reader.getCoverageStore("it.geosolutions", "mosaic");
+ final String urlString = store.getURL();
+ final URL url = new URL(urlString);
+ final File file = urlToFile(url);
+ final String filePath = file.getAbsolutePath();
+
+ // use reflection to get the store URL since coveragestore only returns name and workspace
+ result = manager.createOrHarvestExternal("it.geosolutions", "mosaic", "imagemosaic", filePath + File.separatorChar + fileLocation );
+ Assert.assertTrue(result);
+
+ granulesList = manager.getGranules("it.geosolutions", "mosaic", "mosaic", null, null, null);
+ assertNotNull(granulesList);
+ assertEquals(4, granulesList.size());
+ assertFalse(granulesList.isEmpty());
+ granule = granulesList.get(0);
+ assertNotNull(granule);
+
+ }
+
+
+ /**
+ * This method has been copied from org.geotools.data.DataUtilities
+ *
+ * Takes a URL and converts it to a File. The attempts to deal with Windows UNC format specific
+ * problems, specifically files located on network shares and different drives.
+ *
+ * If the URL.getAuthority() returns null or is empty, then only the url's path property is used
+ * to construct the file. Otherwise, the authority is prefixed before the path.
+ *
+ * It is assumed that url.getProtocol returns "file".
+ *
+ * Authority is the drive or network share the file is located on. Such as "C:", "E:",
+ * "\\fooServer"
+ *
+ * @param url
+ * a URL object that uses protocol "file"
+ * @return a File that corresponds to the URL's location
+ */
+ private static File urlToFile(URL url) {
+ if (!"file".equals(url.getProtocol())) {
+ return null; // not a File URL
+ }
+ String string = url.toExternalForm();
+ if (string.contains("+")) {
+ // this represents an invalid URL created using either
+ // file.toURL(); or
+ // file.toURI().toURL() on a specific version of Java 5 on Mac
+ string = string.replace("+", "%2B");
+ }
+ try {
+ string = URLDecoder.decode(string, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Could not decode the URL to UTF-8 format", e);
+ }
+
+ String path3;
+
+ String simplePrefix = "file:/";
+ String standardPrefix = "file://";
+ String os = System.getProperty("os.name");
+
+ if (os.toUpperCase().contains("WINDOWS") && string.startsWith(standardPrefix)) {
+ // win32: host/share reference
+ path3 = string.substring(standardPrefix.length() - 2);
+ } else if (string.startsWith(standardPrefix)) {
+ path3 = string.substring(standardPrefix.length());
+ } else if (string.startsWith(simplePrefix)) {
+ path3 = string.substring(simplePrefix.length() - 1);
+ } else {
+ String auth = url.getAuthority();
+ String path2 = url.getPath().replace("%20", " ");
+ if (auth != null && !auth.equals("")) {
+ path3 = "//" + auth + path2;
+ } else {
+ path3 = path2;
+ }
+ }
+
+ return new File(path3);
+ }
+
+}
diff --git a/src/test/resources/testdata/granules/mosaic.zip b/src/test/resources/testdata/granules/mosaic.zip
new file mode 100644
index 0000000..138af26
Binary files /dev/null and b/src/test/resources/testdata/granules/mosaic.zip differ