# HG changeset patch # User Ingo Weinzierl # Date 1299078634 0 # Node ID e986e32bc7d45db60dafcd689e9b86026f9a2bab # Parent 5d40faf1484d41ee57527bc722b7ead717c49bde Added a Rest resource that handles operations specific to a collection. artifacts/trunk@1367 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 5d40faf1484d -r e986e32bc7d4 ChangeLog --- a/ChangeLog Wed Mar 02 13:31:59 2011 +0000 +++ b/ChangeLog Wed Mar 02 15:10:34 2011 +0000 @@ -1,3 +1,11 @@ +2011-03-02 Ingo Weinzierl + + * artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CollectionResource.java: + New. A Rest resource that handles operations for a specific collection. + + * artifact-database/src/main/java/de/intevation/artifactdatabase/rest/RestApp.java: + Added the CollectionResource. + 2011-03-02 Ingo Weinzierl * artifact-database/src/main/java/de/intevation/artifactdatabase/rest/ListCollectionsResource.java: diff -r 5d40faf1484d -r e986e32bc7d4 artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CollectionResource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/CollectionResource.java Wed Mar 02 15:10:34 2011 +0000 @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2011 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ +package de.intevation.artifactdatabase.rest; + +import de.intevation.artifacts.ArtifactDatabase; +import de.intevation.artifacts.ArtifactDatabaseException; +import de.intevation.artifacts.CallMeta; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; + +import java.io.IOException; + +import org.apache.log4j.Logger; + +import org.restlet.data.MediaType; +import org.restlet.data.Status; +import org.restlet.ext.xml.DomRepresentation; +import org.restlet.representation.EmptyRepresentation; +import org.restlet.representation.Representation; +import org.restlet.Request; +import org.restlet.Response; + +import org.w3c.dom.Document; + + +/** + * @author Ingo Weinzierl + */ +public class CollectionResource +extends BaseResource +{ + /** The logger that is used in this class.*/ + private static Logger logger = Logger.getLogger(CollectionResource.class); + + /** server URL where to reach the resource.*/ + public static final String PATH = "/collection/{uuid}"; + + /** + * XPath to figure out the type of action (feed, advance) via the + * incoming POST request. + */ + public static final String XPATH_ACTION = "/art:action/art:type/@name"; + + /** + * XPath to figure out the identifier of the artifact described in the + * action. + */ + public static final String XPATH_ARTIFACT = + "/art:action/art:type/art:artifact/@uuid"; + + /** Error message if no action was given.*/ + public static final String NO_ACTION_MSG = "no action given"; + + /** Error message if a unknown action was given.*/ + public static final String NO_SUCH_ACTION_MSG = "no such action"; + + /** Action name for deleting a collection.*/ + public static final String ACTION_DELETE = "delete"; + + /** Action name for retrieving the attributes of an artifact stored in the + * collection.*/ + public static final String ACTION_GET_ATTRIBUTE = "getattribute"; + + /** Action name for setting the attribute for an artifact stored in the + * collection.*/ + public static final String ACTION_SET_ATTRIBUTE = "setattribute"; + + /** Action name for adding a new artifact to the collection.*/ + public static final String ACTION_ADD_ARTIFACT = "addartifact"; + + /** Action name for removing an artifact from the collection.*/ + public static final String ACTION_REMOVE_ARTIFACT = "removeartifact"; + + /** Action name for listing the artifacts of the collection.*/ + public static final String ACTION_LIST_ARTIFACTS = "listartifacts"; + + + /** + * Method to figure out which POST action was triggered and perform this + * operation on the collection specified by 'identifier' and found in the + * artifact database 'db'. + * + * @param identifier The identifier of the collection. + * @param action The action to be performed. + * @param source The input document to further parameterize the operation. + * @param db The artifact database where to find the collection. + * + * @return The representation produced by the performed action. + */ + protected Representation dispatch( + String identifier, + String action, + Document source, + ArtifactDatabase db + ) { + Document out = null; + + try { + CallMeta meta = getCallMeta(); + + if (action.equals(ACTION_DELETE)) { + logger.info("Delete collection '" + identifier + "'"); + out = db.deleteCollection(identifier, getCallMeta()); + } + else if (action.equals(ACTION_ADD_ARTIFACT)) { + String art = getArtifactIdentifier(source); + + logger.info("Add artifact '" + art + "' to collection."); + out = db.addCollectionArtifact(identifier, art, meta); + } + else if (action.equals(ACTION_REMOVE_ARTIFACT)) { + String art = getArtifactIdentifier(source); + + logger.info("Remove artifact '" + art + "' from collection."); + out = db.removeCollectionArtifact(identifier, art, meta); + } + else if (action.equals(ACTION_LIST_ARTIFACTS)) { + logger.info("List artifacts of collection '" + identifier +"'"); + out = db.listCollectionArtifacts(identifier, meta); + } + else if (action.equals(ACTION_SET_ATTRIBUTE)) { + String art = getArtifactIdentifier(source); + + logger.info("Set attribute for artifact '" + art + "'"); + out = db.setCollectionAttribute(identifier, art, source, meta); + } + else if (action.equals(ACTION_GET_ATTRIBUTE)) { + String art = getArtifactIdentifier(source); + + logger.info("Retrieve attribute of artifact '" + art + "'"); + out = db.getCollectionAttribute(identifier, art, meta); + } + else { + throw new ArtifactDatabaseException(NO_SUCH_ACTION_MSG); + } + } + catch (ArtifactDatabaseException adbe) { + logger.warn(adbe.getLocalizedMessage(), adbe); + + Response response = getResponse(); + response.setStatus( + Status.CLIENT_ERROR_BAD_REQUEST, adbe.getMessage()); + return new EmptyRepresentation(); + } + + return new DomRepresentation(MediaType.APPLICATION_XML, out); + } + + + @Override + protected Representation innerPost(Representation requestRepr) { + Document input = null; + try { + DomRepresentation in = new DomRepresentation(requestRepr); + in.setNamespaceAware(true); + input = in.getDocument(); + } + catch (IOException ioe) { + logger.error(ioe.getLocalizedMessage(), ioe); + + Response response = getResponse(); + response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, ioe); + return new EmptyRepresentation(); + } + + String action = XMLUtils.xpathString( + input, XPATH_ACTION, ArtifactNamespaceContext.INSTANCE); + + if (action == null || action.length() == 0) { + Response response = getResponse(); + response.setStatus( + Status.CLIENT_ERROR_BAD_REQUEST, NO_ACTION_MSG); + return new EmptyRepresentation(); + } + + Request request = getRequest(); + + String identifier = (String) request.getAttributes().get("uuid"); + + ArtifactDatabase db = getArtifactDatabase(); + + return dispatch(identifier, action, input, db); + } + + + /** + * Retrieves the identifier of the artifact used in the action. + * + * @param source The incoming document that describes the operation. + * + * @return the uuid of the artifact described in the document. + */ + protected String getArtifactIdentifier(Document source) { + return XMLUtils.xpathString( + source, XPATH_ARTIFACT, ArtifactNamespaceContext.INSTANCE); + } +} diff -r 5d40faf1484d -r e986e32bc7d4 artifact-database/src/main/java/de/intevation/artifactdatabase/rest/RestApp.java --- a/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/RestApp.java Wed Mar 02 13:31:59 2011 +0000 +++ b/artifact-database/src/main/java/de/intevation/artifactdatabase/rest/RestApp.java Wed Mar 02 15:10:34 2011 +0000 @@ -80,6 +80,8 @@ CreateCollectionResource.PATH, CreateCollectionResource.class); router.attach( ListCollectionsResource.PATH, ListCollectionsResource.class); + router.attach( + CollectionResource.PATH, CollectionResource.class); return router; }