diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java index 35bc2f2..f6603bf 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java +++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTPublisher.java @@ -28,6 +28,7 @@ import it.geosolutions.geoserver.rest.decoder.RESTCoverageList; 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.GSNamespaceEncoder; import it.geosolutions.geoserver.rest.encoder.GSPostGISDatastoreEncoder; import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder; import it.geosolutions.geoserver.rest.encoder.GSResourceEncoder.ProjectionPolicy; @@ -110,6 +111,84 @@ public class GeoServerRESTPublisher { final String result = HTTPUtils.postXml(sUrl, wsxml, gsuser, gspass); return result != null; } + + /** + * Create both a workspace and its associated namespace. + * + * Note that this method is equivalent to {@link #createNamespace}. + * + * @param name Name for the new workspace, which will be also its associated namespace prefix. + * @param uri Namespace URI. Cannot be empty. + * @return true if the Workspace and its associated namespace were successfully created. + */ + public boolean createWorkspace(final String name, final URI uri) { + // This is really an alias to createNamespace, as GeoServer + // will automatically create the workspace as well. + return createNamespace(name, uri); + } + + // ========================================================================== + // === NAMESPACES + // ========================================================================== + + /** + * Create a new namespace. GeoServer will automatically create the corresponding workspace. + * + * Prefix and uri are mandatory and cannot be empty. + * If a namespace with the given prefix already exists, it won't be created. + * + * @param prefix The name of the new namespace. + * @param uri The URI of the new namespace. + * @return true if the namespace was successfully created. + * @see GeoServer Documentation + */ + public boolean createNamespace(final String prefix, final URI uri) { + final String sUrl = restURL + "/rest/namespaces"; + final GSNamespaceEncoder nsenc = new GSNamespaceEncoder(prefix, uri); + final String nsxml = nsenc.toString(); + final String result = HTTPUtils.postXml(sUrl, nsxml, gsuser, gspass); + return result != null; + } + + /** + * Update a namespace URI. + * + * Prefix and uri are mandatory and cannot be empty. + * A namespace with the given prefix should exist. + * + * @param prefix The prefix of an existing namespace. + * @param uri The new URI. + * @return true if the namespace was successfully updated. + */ + public boolean updateNamespace(final String prefix, final URI uri) { + final String sUrl = restURL + "/rest/namespaces/"+ encode(prefix); + final GSNamespaceEncoder nsenc = new GSNamespaceEncoder(prefix, uri); + final String nsxml = nsenc.toString(); + final String result = HTTPUtils.put(sUrl, nsxml, "application/xml", gsuser, gspass); + return result != null; + } + + /** + * Remove a given Namespace. It will remove the associated workspace as well. + * + * @param prefix + * The namespace prefix + * @param recurse + * The recurse parameter is used to recursively delete all + * resources contained in the workspace associated with this + * namespace. This includesdata stores, coverage stores, + * feature types, etc... Allowable values for this parameter + * are true or false. The default (safer) value + * is false. + * @return true if the namespace was successfully removed. + */ + public boolean removeNamespace(final String prefix, boolean recurse) { + // Hack: We are instead calling removeWorkspace, as DELETE on + // a namespace will leave associated workspace in an inconsistent + // state. See https://jira.codehaus.org/browse/GEOS-5075 + // TODO switch to namespace when GEOS-5075 is solved + return removeWorkspace(prefix, recurse); + } // ========================================================================== // === STYLES diff --git a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java index 792a54a..bf7075b 100644 --- a/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java +++ b/src/main/java/it/geosolutions/geoserver/rest/GeoServerRESTReader.java @@ -36,6 +36,7 @@ import it.geosolutions.geoserver.rest.decoder.RESTLayer; import it.geosolutions.geoserver.rest.decoder.RESTLayerGroup; import it.geosolutions.geoserver.rest.decoder.RESTLayerGroupList; 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.RESTStyleList; @@ -454,6 +455,25 @@ public class GeoServerRESTReader { //=== NAMESPACES //========================================================================== + /** + * Get a namespace. + * + * @param prefix namespace prefix. + * + * @return a RESTNamespace, or null if couldn't be created. + */ + public RESTNamespace getNamespace(String prefix) { + if (prefix == null || prefix.isEmpty()) { + throw new IllegalArgumentException( + "Namespace prefix cannot be null or empty"); + } + String url = "/rest/namespaces/"+prefix+".xml"; + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("### Getting namespace from " + url); + } + return RESTNamespace.build(load(url)); + } + /** * Get summary info about all Namespaces. * diff --git a/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTNamespace.java b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTNamespace.java new file mode 100644 index 0000000..aa034ea --- /dev/null +++ b/src/main/java/it/geosolutions/geoserver/rest/decoder/RESTNamespace.java @@ -0,0 +1,99 @@ +/* + * 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.decoder; + +import it.geosolutions.geoserver.rest.decoder.utils.JDOMBuilder; + +import org.jdom.Element; +import java.net.URI; + +/** + * Parse namespaces returned as XML REST objects. + * + * This is the XML REST representation: + *
{@code
+
+ topp
+ http://www.openplans.org/topp
+
+
+
+
+ * }
+ *
+ * @author Oscar Fonts
+ */
+public class RESTNamespace {
+ public final static String NAMESPACE="namespace";
+ public final static String PREFIX="prefix";
+ public final static String URI="uri";
+ public final static String FEATURE_TYPES="featureTypes";
+
+ private final Element namespaceElem;
+
+ /**
+ * Build a RESTNamespace from a REST response.
+ *
+ * @param response XML representation of the namespace.
+ * @return a new RESTNamespace, or null if XML could not be parsed.
+ */
+ public static RESTNamespace build(String response) {
+ if(response == null)
+ return null;
+
+ Element pb = JDOMBuilder.buildElement(response);
+ if(pb != null)
+ return new RESTNamespace(pb);
+ else
+ return null;
+ }
+
+ /**
+ * Create a RESTNamespace from a XML element.
+ *
+ * @param elem The jdom XML Element describing a namespace.
+ */
+ public RESTNamespace(Element elem) {
+ this.namespaceElem = elem;
+ }
+
+ /**
+ * Get the namespace prefix
+ *
+ * @return the namespace prefix.
+ */
+ public String getPrefix() {
+ return namespaceElem.getChildText(PREFIX);
+ }
+
+ /**
+ * Get the namespace URI.
+ *
+ * @return the namespace uri.
+ */
+ public URI getURI() {
+ return java.net.URI.create(namespaceElem.getChildText(URI));
+ }
+}
diff --git a/src/main/java/it/geosolutions/geoserver/rest/encoder/GSNamespaceEncoder.java b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSNamespaceEncoder.java
new file mode 100644
index 0000000..d46b1a5
--- /dev/null
+++ b/src/main/java/it/geosolutions/geoserver/rest/encoder/GSNamespaceEncoder.java
@@ -0,0 +1,131 @@
+/*
+ * 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;
+
+import java.net.URI;
+
+import it.geosolutions.geoserver.rest.encoder.utils.ElementUtils;
+import it.geosolutions.geoserver.rest.encoder.utils.PropertyXMLEncoder;
+
+/**
+ * Namespace XML encoder. Namespaces must contain a non empty prefix and a URI:
+ *
+ * + * <namespace> + * <prefix>example</prefix> + * <uri>http://example.com</uri> + * </namespace> + *+ * + * @see GeoServer Documentation + * @author Oscar Fonts + */ +public class GSNamespaceEncoder extends PropertyXMLEncoder { + + public final static String NAMESPACE="namespace"; + public final static String PREFIX="prefix"; + public final static String URI="uri"; + + /** + * Create a namespace XML encoder. + * + * @param prefix the namespace prefix + * @param uri the namespace URI + * @throws IllegalArgumentException if prefix or uri are null or empty + */ + public GSNamespaceEncoder(String prefix, URI uri) { + super(NAMESPACE); + + ensureValidPrefix(prefix); + ensureValidURI(uri); + + add(PREFIX, prefix); + add(URI, uri.toString()); + } + + /** + * Get the namespace prefix. + * @return the prefix + */ + public String getPrefix() { + return ElementUtils.contains(getRoot(), PREFIX).getTextTrim(); + } + + /** + * Change the namespace prefix. + * @param prefix the new prefix + * @throws IllegalArgumentException if prefix is null or empty + */ + public void setPrefix(final String prefix) { + ensureValidPrefix(prefix); + ElementUtils.contains(getRoot(), PREFIX).setText(prefix); + } + + /** + * Get the namespace uri. + * @return the uri + */ + public URI getURI() { + String sUri = ElementUtils.contains(getRoot(), URI).getTextTrim(); + return java.net.URI.create(sUri); + } + + /** + * change the nampespace uri. + * @param URI the new uri + * @throws IllegalArgumentException if uri is null or empty + */ + public void setURI(final URI uri) { + ensureValidURI(uri); + String sUri = uri.toString(); + ElementUtils.contains(getRoot(), URI).setText(sUri); + } + + /** + * Check prefix value. + * + * @param prefix the prefix + * @throws IllegalArgumentException if prefix is null or empty + */ + private static void ensureValidPrefix(String prefix) { + if (prefix == null || prefix.isEmpty()) { + throw new IllegalArgumentException( + "Namespace prefix cannot be null or empty"); + } + } + + /** + * Check uri value. + * + * @param prefix the uri + * @throws IllegalArgumentException if uri is null or empty + */ + private static void ensureValidURI(URI uri) { + if (uri == null || uri.toString().isEmpty()) { + throw new IllegalArgumentException( + "Namespace uri cannot be null or empty"); + } + } +} diff --git a/src/test/java/it/geosolutions/geoserver/rest/GeoserverRESTReaderTest.java b/src/test/java/it/geosolutions/geoserver/rest/GeoserverRESTReaderTest.java index d92739c..773066c 100644 --- a/src/test/java/it/geosolutions/geoserver/rest/GeoserverRESTReaderTest.java +++ b/src/test/java/it/geosolutions/geoserver/rest/GeoserverRESTReaderTest.java @@ -161,7 +161,24 @@ public class GeoserverRESTReaderTest extends GeoserverRESTTest { } System.out.println(); } + + /** + * Test of getWorkspaceNames method, of class GeoServerRESTReader. + */ + public void testGetNamespaceNames() { + if(!enabled()) return; + List