ingo@1: /*
ingo@1: * Copyright (c) 2010 by Intevation GmbH
ingo@1: *
ingo@1: * This program is free software under the LGPL (>=v2.1)
ingo@1: * Read the file LGPL.txt coming with the software for details
ingo@1: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@1: */
ingo@1: package de.intevation.artifacts.httpclient.http;
ingo@1:
ingo@1: import java.io.InputStream;
ingo@1: import java.io.IOException;
ingo@1: import java.io.OutputStream;
ingo@1:
ingo@1: import org.apache.log4j.Logger;
ingo@1:
ingo@1: import org.restlet.Client;
ingo@1: import org.restlet.Request;
ingo@1: import org.restlet.Response;
ingo@1: import org.restlet.data.MediaType;
ingo@1: import org.restlet.data.Method;
ingo@1: import org.restlet.data.Protocol;
ingo@1: import org.restlet.data.Status;
ingo@1: import org.restlet.ext.xml.DomRepresentation;
ingo@1: import org.restlet.representation.Representation;
ingo@1:
ingo@1: import org.w3c.dom.Document;
ingo@1:
ingo@1: import de.intevation.artifacts.httpclient.exceptions.ConnectionException;
ingo@1: import de.intevation.artifacts.httpclient.http.response.DocumentResponseHandler;
ingo@1: import de.intevation.artifacts.httpclient.http.response.ResponseHandler;
ingo@1: import de.intevation.artifacts.httpclient.http.response.StreamResponseHandler;
ingo@1: import de.intevation.artifacts.httpclient.objects.Artifact;
ingo@1: import de.intevation.artifacts.httpclient.objects.ArtifactFactory;
ingo@1: import de.intevation.artifacts.httpclient.utils.ArtifactProtocolUtils;
ingo@2: import de.intevation.artifacts.httpclient.utils.ArtifactCreator;
ingo@2:
ingo@1:
ingo@1: /**
ingo@1: * @author Ingo Weinzierl
ingo@1: */
ingo@1: public class HttpClientImpl implements HttpClient {
ingo@1:
ingo@1: private static final Logger logger = Logger.getLogger(HttpClient.class);
ingo@1:
ingo@4: /** The URL part of the resource to list the existing users of the server.*/
ingo@4: public static final String PATH_LIST_USERS = "/list-users";
ingo@4:
ingo@7: /** The URL part of the resource to list the Collections owned by a specific
ingo@7: * user.*/
ingo@7: public static final String PATH_USER_COLLECTIONS = "/list-collections";
ingo@7:
ingo@5: /** The URL part of the resource to call a specific service.*/
ingo@5: public static final String PATH_SERVICE = "/service";
ingo@5:
ingo@3: /** The URL path of the resource to create new artifact collections.*/
ingo@3: public static final String PATH_CREATE_COLLECTION = "/create-collection";
ingo@3:
ingo@6: /** The URL path of the resource to work with an artifact collections.*/
ingo@6: public static final String PATH_ACTION_COLLECTION = "/collection";
ingo@6:
ingo@1: private String serverUrl;
ingo@1:
ingo@1:
ingo@1: public HttpClientImpl(String serverUrl) {
ingo@1: this.serverUrl = serverUrl;
ingo@1: }
ingo@1:
ingo@1:
ingo@1: @Override
ingo@1: public ArtifactFactory[] getArtifactFactories()
ingo@1: throws ConnectionException
ingo@1: {
ingo@1: ResponseHandler handler = new DocumentResponseHandler();
ingo@1:
ingo@1: try {
ingo@1: String url = serverUrl + "/factories";
ingo@1: Document result = (Document) handler.handle(doGet(url));
ingo@1:
ingo@1: return ArtifactProtocolUtils.extractArtifactFactories(result);
ingo@1: }
ingo@1: catch (IOException ioe) {
ingo@1: throw new ConnectionException(
ingo@1: "Connection to server failed. No Factories recieved.");
ingo@1: }
ingo@1: }
ingo@1:
ingo@1:
ingo@2: /**
ingo@2: * This method creates a new artifact in the artifact server and returns
ingo@2: * this artifact. The new artifact is created using creator. If no
ingo@2: * {@link ArtifactCreator} is given (null), an {@link Artifact} is returned.
ingo@2: *
ingo@2: * @param doc The CREATE document.
ingo@2: * @param creator The {@link ArtifactCreator} that is used to extract the
ingo@2: * new artifact from response document of the server.
ingo@2: *
ingo@2: * @return the new artifact.
ingo@2: */
ingo@1: @Override
ingo@2: public Object create(Document doc, ArtifactCreator creator)
ingo@2: throws ConnectionException
ingo@2: {
ingo@1: ResponseHandler handler = new DocumentResponseHandler();
ingo@1:
ingo@1: try {
ingo@1: String url = serverUrl + "/create";
ingo@1: Document result = (Document) handler.handle(doPost(url, doc));
ingo@1:
ingo@2: return creator == null
ingo@2: ? ArtifactProtocolUtils.extractArtifact(result)
ingo@2: : creator.create(result);
ingo@1: }
ingo@1: catch (IOException ioe) {
ingo@1: throw new ConnectionException(
ingo@1: "Connection to server failed. No Artifact created.");
ingo@1: }
ingo@1: }
ingo@1:
ingo@1:
ingo@1: @Override
ingo@1: public Object describe(
ingo@1: Artifact artifact,
ingo@1: Document doc,
ingo@1: ResponseHandler handler)
ingo@1: throws ConnectionException
ingo@1: {
ingo@1: try {
ingo@1: String url = serverUrl + "/artifact/" + artifact.getUuid();
ingo@1: return handler.handle(doPost(url, doc));
ingo@1: }
ingo@1: catch (IOException ioe) {
ingo@1: throw new ConnectionException(
ingo@1: "Connection to server failed: " + ioe.getMessage());
ingo@1: }
ingo@1: }
ingo@1:
ingo@1:
ingo@1: @Override
ingo@1: public Object feed(Artifact artifact, Document doc, ResponseHandler handler)
ingo@1: throws ConnectionException
ingo@1: {
ingo@1: try {
ingo@1: String url = serverUrl + "/artifact/" + artifact.getUuid();
ingo@1: Document result = (Document) handler.handle(doPost(url, doc));
ingo@1:
ingo@1: return result;
ingo@1: }
ingo@1: catch (IOException ioe) {
ingo@1: throw new ConnectionException(
ingo@1: "Connection to server failed: " + ioe.getMessage());
ingo@1: }
ingo@1: }
ingo@1:
ingo@1:
ingo@1: @Override
ingo@1: public Object advance(Artifact artifact, Document doc, ResponseHandler handler)
ingo@1: throws ConnectionException
ingo@1: {
ingo@1: try {
ingo@1: String url = serverUrl + "/artifact/" + artifact.getUuid();
ingo@1: Document result = (Document) handler.handle(doPost(url, doc));
ingo@1:
ingo@1: return result;
ingo@1: }
ingo@1: catch (IOException ioe) {
ingo@1: throw new ConnectionException(
ingo@1: "Connection to server failed: " + ioe.getMessage());
ingo@1: }
ingo@1: }
ingo@1:
ingo@1:
ingo@1: @Override
ingo@1: public void out(
ingo@1: Artifact artifact,
ingo@1: Document doc,
ingo@1: String target,
ingo@1: OutputStream out)
ingo@1: throws ConnectionException
ingo@1: {
ingo@1: try {
ingo@1: String url =
ingo@1: serverUrl
ingo@1: + "/artifact/"
ingo@1: + artifact.getUuid()
ingo@1: + "/" + target;
ingo@1:
ingo@1: ResponseHandler handler = new StreamResponseHandler();
ingo@1:
ingo@1: InputStream stream = (InputStream) handler.handle(doPost(url, doc));
ingo@1:
ingo@1: byte[] b = new byte[4096];
ingo@1: int i = -1;
ingo@1: while ((i = stream.read(b)) > 0) {
ingo@1: out.write(b, 0, i);
ingo@1: }
ingo@1: }
ingo@1: catch (IOException ioe) {
ingo@1: throw new ConnectionException(
ingo@1: "Connection to server failed: " + ioe.getMessage());
ingo@1: }
ingo@1: }
ingo@1:
ingo@1:
ingo@1: private Response doPost(String url, Document body) throws IOException {
ingo@1: logger.info("Start HTTP-POST request to: "+ url);
ingo@1:
ingo@1: Client client = new Client(Protocol.HTTP);
ingo@1: Request request = new Request(Method.POST, url);
ingo@1:
ingo@1: Representation representation = new DomRepresentation(
ingo@1: MediaType.APPLICATION_XML,
ingo@1: body);
ingo@1:
ingo@1: request.setEntity(representation);
ingo@1: Response response = client.handle(request);
ingo@1:
ingo@1: Status status = response.getStatus();
ingo@1: if (status.getCode() != 200) {
ingo@1: logger.error("Response status: " + status.getCode());
ingo@1: throw new IOException(status.getDescription());
ingo@1: }
ingo@1:
ingo@1: return response;
ingo@1: }
ingo@1:
ingo@1:
ingo@1: private Response doGet(String url) throws IOException {
ingo@1: logger.info("Start HTTP-POST request to: "+ url);
ingo@1:
ingo@1: Client client = new Client(Protocol.HTTP);
ingo@1: Request request = new Request(Method.GET, url);
ingo@1:
ingo@1: Response response = client.handle(request);
ingo@1:
ingo@1: Status status = response.getStatus();
ingo@1: if (status.getCode() != 200) {
ingo@1: logger.error("Response status: " + status.getCode());
ingo@1: throw new IOException(status.getDescription());
ingo@1: }
ingo@1:
ingo@1: return response;
ingo@1: }
ingo@4:
ingo@4:
ingo@6: //==============================
ingo@6: // Collection API
ingo@6: //==============================
ingo@6:
ingo@6: /**
ingo@6: * This method triggers the artifact servers resource to create a new
ingo@6: * artifact collection.
ingo@6: *
ingo@6: * @param create The CREATE document for the collection.
ingo@6: * @param ownerId The uuid of the creator.
ingo@6: * @param handler The handler that is used to create the result object.
ingo@6: *
ingo@6: * @return a result object created by handler.
ingo@6: */
ingo@6: public Object createCollection(
ingo@6: Document create,
ingo@6: String ownerId,
ingo@6: ResponseHandler handler)
ingo@6: throws ConnectionException
ingo@6: {
ingo@6: String url = serverUrl + PATH_CREATE_COLLECTION + "/" + ownerId;
ingo@6:
ingo@6: try {
ingo@6: return handler.handle(doPost(url, create));
ingo@6: }
ingo@6: catch (IOException ioe) {
ingo@6: throw new ConnectionException(ioe.getMessage(), ioe);
ingo@6: }
ingo@6: }
ingo@6:
ingo@6:
ingo@6: /**
ingo@6: * This method might be used to trigger a collection specific action. The
ingo@6: * action that is executed depends on the document actionDoc.
ingo@6: *
ingo@6: * @param actionDoc The document that describes the action to be executed.
ingo@6: * @param uuid The uuid of the collection.
ingo@6: * @param handler The handler that is used to create the result object.
ingo@6: *
ingo@6: * @return a result object created by handler.
ingo@6: */
ingo@6: public Object doCollectionAction(
ingo@6: Document actionDoc,
ingo@6: String uuid,
ingo@6: ResponseHandler handler)
ingo@6: throws ConnectionException
ingo@6: {
ingo@6: String url = serverUrl + PATH_ACTION_COLLECTION + "/" + uuid;
ingo@6:
ingo@6: try {
ingo@6: return handler.handle(doPost(url, actionDoc));
ingo@6: }
ingo@6: catch (IOException ioe) {
ingo@6: throw new ConnectionException(ioe.getMessage(), ioe);
ingo@6: }
ingo@6: }
ingo@6:
ingo@6:
ingo@4: /*******************************
ingo@5: * Service API
ingo@5: *******************************/
ingo@5:
ingo@5: public Document callService(String url, String service, Document input)
ingo@5: throws ConnectionException
ingo@5: {
ingo@5: logger.info("Start service call to '" + service + "'");
ingo@5:
ingo@5: DocumentResponseHandler handler = new DocumentResponseHandler();
ingo@5:
ingo@5: try {
ingo@5: String serverUrl = url + PATH_SERVICE + "/" + service;
ingo@5: return (Document) handler.handle(doPost(serverUrl, input));
ingo@5: }
ingo@5: catch (IOException ioe) {
ingo@5: throw new ConnectionException(
ingo@5: "Connection to server failed: " + ioe.getMessage());
ingo@5: }
ingo@5: }
ingo@5:
ingo@5:
ingo@5: /*******************************
ingo@4: * Users API
ingo@4: *******************************/
ingo@5:
ingo@4: public Document listUsers()
ingo@4: throws ConnectionException
ingo@4: {
ingo@4: ResponseHandler handler = new DocumentResponseHandler();
ingo@4: String url = serverUrl + PATH_LIST_USERS;
ingo@4:
ingo@4: try {
ingo@4: return (Document) handler.handle(doGet(url));
ingo@4: }
ingo@4: catch (IOException ioe) {
ingo@4: throw new ConnectionException(ioe.getMessage(), ioe);
ingo@4: }
ingo@4: }
ingo@7:
ingo@7:
ingo@7: public Document listUserCollections(String userid)
ingo@7: throws ConnectionException
ingo@7: {
ingo@7: ResponseHandler handler = new DocumentResponseHandler();
ingo@7:
ingo@7: String url = serverUrl + PATH_USER_COLLECTIONS + "/" + userid;
ingo@7:
ingo@7: try {
ingo@7: return (Document) handler.handle(doGet(url));
ingo@7: }
ingo@7: catch (IOException ioe) {
ingo@7: throw new ConnectionException(ioe.getMessage(), ioe);
ingo@7: }
ingo@7: }
ingo@1: }
ingo@1: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: