ingo@100: /*
ingo@100: * Copyright (c) 2010 by Intevation GmbH
ingo@100: *
ingo@100: * This program is free software under the LGPL (>=v2.1)
ingo@100: * Read the file LGPL.txt coming with the software for details
ingo@100: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@100: */
ingo@100:
sascha@27: package de.intevation.artifactdatabase.rest;
sascha@27:
sascha@207: import de.intevation.artifacts.common.utils.XMLUtils;
sascha@27:
sascha@93: import de.intevation.artifacts.Artifact;
sascha@93: import de.intevation.artifacts.ArtifactDatabase;
sascha@93: import de.intevation.artifacts.ArtifactDatabaseException;
sascha@93: import de.intevation.artifacts.ArtifactNamespaceContext;
sascha@93:
sascha@93: import java.io.IOException;
sascha@93:
sascha@93: import org.apache.log4j.Logger;
sascha@93:
ingo@101: import org.restlet.Request;
ingo@101: import org.restlet.Response;
ingo@101:
sascha@93: import org.restlet.data.MediaType;
sascha@93: import org.restlet.data.Status;
sascha@27:
sascha@27: import org.restlet.ext.xml.DomRepresentation;
sascha@27:
sascha@93: import org.restlet.representation.EmptyRepresentation;
sascha@93: import org.restlet.representation.Representation;
sascha@27:
sascha@93: import org.restlet.resource.ResourceException;
sascha@27:
sascha@27: import org.w3c.dom.Document;
sascha@27:
sascha@27: /**
sascha@88: * Resource to expose the core artifact methods
sascha@88: * (describe, feed and advance) via REST.
sascha@88: *
sascha@88: *
sascha@88: * - describe() is modelled via GET.
sascha@88: * - advance() and feed() are modelled via POST.
sascha@88: *
sascha@77: * @author Sascha L. Teichmann
sascha@27: */
sascha@27: public class ArtifactResource
sascha@40: extends BaseResource
sascha@27: {
sascha@27: private static Logger logger = Logger.getLogger(ArtifactResource.class);
sascha@27:
sascha@88: /**
sascha@88: * XPath to figure out the type of action (feed, advance) via the
sascha@88: * incoming POST request.
sascha@88: */
ingo@64: public static final String XPATH_ACTION = "/art:action/art:type/@name";
sascha@28:
sascha@88: /**
sascha@88: * server URL where to reach the resource.
sascha@88: */
sascha@27: public static final String PATH = "/artifact/{uuid}";
sascha@27:
sascha@88: /**
sascha@88: * Error message if no action was given.
sascha@88: */
sascha@28: public static final String NO_ACTION_MESSAGE = "no action given";
sascha@88:
sascha@88: /**
sascha@88: * Error message if a unknown action was given.
sascha@88: */
sascha@28: public static final String NO_SUCH_ACTION_MESSAGE = "no such action";
sascha@28:
sascha@88: /**
sascha@88: * Error message if the requested artifact was not found in
sascha@88: * the artifact database.
sascha@88: */
sascha@27: public static final String NO_ARTIFACT_FOUND = "Artifact not found";
sascha@27:
sascha@88: /**
sascha@88: * Action name 'advance'.
sascha@88: */
sascha@55: public static final String ADVANCE = "advance";
sascha@88: /**
sascha@88: * Action name 'feed'.
sascha@88: */
sascha@55: public static final String FEED = "feed";
sascha@88: /**
sascha@88: * Action name 'describe'.
sascha@88: */
sascha@55: public static final String DESCRIBE = "describe";
sascha@28:
sascha@88: @Override
sascha@40: protected Representation innerGet()
sascha@40: throws ResourceException
sascha@40: {
sascha@27: Request request = getRequest();
sascha@27:
sascha@27: String identifier = (String)request.getAttributes().get("uuid");
sascha@27:
sascha@27: if (logger.isDebugEnabled()) {
sascha@27: logger.debug("looking for artifact id '" + identifier + "'");
sascha@27: }
sascha@27:
sascha@27: ArtifactDatabase db = (ArtifactDatabase)getContext()
sascha@27: .getAttributes().get("database");
sascha@27:
sascha@32: try {
sascha@32: return new DomRepresentation(
sascha@32: MediaType.APPLICATION_XML,
sascha@55: db.describe(identifier, null, getCallMeta()));
sascha@32: }
sascha@32: catch (ArtifactDatabaseException adbe) {
sascha@35: logger.warn(adbe.getLocalizedMessage(), adbe);
sascha@32: Response response = getResponse();
sascha@32: response.setStatus(
sascha@32: Status.CLIENT_ERROR_NOT_FOUND, adbe.getMessage());
sascha@32: return new EmptyRepresentation();
sascha@32: }
sascha@32: }
sascha@27:
sascha@88: /**
sascha@88: * Method to figure out which POST action (feed or advance) was
sascha@88: * triggered and perform this operation on the artifact specified
sascha@88: * by 'identifier' and found in the artifact database 'db'
sascha@88: * @param identifier The identifier of the artifact.
sascha@88: * @param action The action to be performed.
sascha@88: * @param source The input document to further parameterize the
sascha@88: * operation.
sascha@88: * @param db The artifact database where to find the artifact.
sascha@89: * @return The representation produced by the performed action.
sascha@88: */
sascha@32: protected Representation dispatch(
sascha@32: String identifier,
sascha@32: String action,
sascha@32: Document source,
sascha@32: ArtifactDatabase db
sascha@32: ) {
sascha@32: Document out = null;
sascha@32:
sascha@32: try {
sascha@32: if (action.equals(FEED)) {
sascha@48: out = db.feed(identifier, source, getCallMeta());
sascha@32: }
sascha@32: else if (action.equals(ADVANCE)) {
sascha@48: out = db.advance(identifier, source, getCallMeta());
sascha@32: }
sascha@55: else if (action.equals(DESCRIBE)) {
sascha@55: out = db.describe(identifier, source, getCallMeta());
sascha@55: }
sascha@32: else {
sascha@32: throw new ArtifactDatabaseException(NO_SUCH_ACTION_MESSAGE);
sascha@32: }
sascha@32: }
sascha@32: catch (ArtifactDatabaseException adbe) {
sascha@35: logger.warn(adbe.getLocalizedMessage(), adbe);
sascha@27: Response response = getResponse();
sascha@32: response.setStatus(
sascha@32: Status.CLIENT_ERROR_BAD_REQUEST, adbe.getMessage());
sascha@27: return new EmptyRepresentation();
sascha@27: }
sascha@27:
sascha@32: return new DomRepresentation(MediaType.APPLICATION_XML, out);
sascha@27: }
sascha@27:
sascha@88: @Override
sascha@40: protected Representation innerPost(Representation requestRepr) {
sascha@28:
sascha@28: Document inputDocument = null;
sascha@28: try {
sascha@28: DomRepresentation input = new DomRepresentation(requestRepr);
ingo@64: input.setNamespaceAware(true);
sascha@28: inputDocument = input.getDocument();
sascha@28: }
sascha@28: catch (IOException ioe) {
sascha@28: logger.error(ioe.getMessage());
sascha@28: Response response = getResponse();
sascha@28: response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST, ioe);
sascha@28: return new EmptyRepresentation();
sascha@28: }
sascha@28:
sascha@28: String action = XMLUtils.xpathString(
sascha@28: inputDocument,
sascha@28: XPATH_ACTION,
sascha@28: ArtifactNamespaceContext.INSTANCE);
sascha@28:
sascha@28: if (action == null || action.length() == 0) {
sascha@28: Response response = getResponse();
sascha@32: response.setStatus(
sascha@32: Status.CLIENT_ERROR_BAD_REQUEST, NO_ACTION_MESSAGE);
sascha@28: return new EmptyRepresentation();
sascha@28: }
sascha@28:
sascha@40: Request request = getRequest();
sascha@40:
sascha@28: String identifier = (String)request.getAttributes().get("uuid");
sascha@28:
sascha@28: ArtifactDatabase db = (ArtifactDatabase)getContext()
sascha@28: .getAttributes().get("database");
sascha@28:
sascha@32: return dispatch(identifier, action, inputDocument, db);
sascha@27: }
sascha@27: }
sascha@88: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :