view gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java @ 11:3cb753564552

Integration of the required XSL-Transformation of the Describe-Response of the Artifactdatabase gnv/trunk@90 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 15 Sep 2009 14:19:55 +0000
parents a4cb6d175a6e
children 4ebe57b170d3
line wrap: on
line source
/**
 *
 */
package de.intevation.gnv.artifactdatabase.client;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.log4j.Logger;
import org.restlet.Client;
import org.restlet.data.Method;
import org.restlet.data.Protocol;
import org.restlet.data.Request;
import org.restlet.data.Response;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import de.intevation.gnv.artifactdatabase.client.exception.ArtifactDatabaseClientException;
import de.intevation.gnv.artifactdatabase.objects.Artifact;
import de.intevation.gnv.artifactdatabase.objects.ArtifactDescription;
import de.intevation.gnv.artifactdatabase.objects.ArtifactFactory;
import de.intevation.gnv.artifactdatabase.objects.ArtifactObject;
import de.intevation.gnv.util.XMLUtils;

/**
 * @author Tim Englich <tim.englich@intevation.de>
 *
 */
public class DefaultArtifactDatabaseClient implements ArtifactDatabaseClient {
    /**
     * The URI of the namespace of the artifacts.
     */
    public final static String NAMESPACE_URI = "http://www.intevation.de/2009/artifacts";
    
    /**
     * The XML prefix for the artifacts namespace.
     */
    public final static String NAMESPACE_PREFIX = "art";

    /**
     * the logger, used to log exceptions and additonaly information
     */
    private static Logger log = Logger.getLogger(DefaultArtifactDatabaseClient.class);
    
    // TODO Container for ArtifactDatabases should be used.
    private static Map<String, String> artifactDatabases = null;
    
    private static boolean initialized = false;
    
    /**
     * Constructor
     */
    public DefaultArtifactDatabaseClient() {
        super();
    }

    /**
     * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#getArtifactFactories()
     */
    public Collection<ArtifactObject> getArtifactFactories() throws ArtifactDatabaseClientException {
        Collection<ArtifactObject> resultValues = null;
        if (!initialized){
            this.initialize();
        }
        try {
           XMLUtils xmlUtils = new XMLUtils();
            log.debug("DefaultArtifactDatabaseClient.getArtifactFactories");
            Iterator<String> it = artifactDatabases.values().iterator();
            while (it.hasNext()){
                String server = it.next();
                String url =  server+ "/factories";
                Document document = this.doGetRequest(url);
                if (resultValues == null){
                    resultValues = this.getArtifactFactories(document,server);
                }else{
                    resultValues.addAll(this.getArtifactFactories(document,server));
                }
            }
        } catch (IOException e) {
            log.error(e,e);
        }
        return resultValues;
    }

    private Collection<ArtifactObject>  getArtifactFactories(Document document, String server){
        XMLUtils xmlUtils = new XMLUtils();
        NodeList artifactFactories = xmlUtils.getNodeSetXPath(document, "/result/factories/factory");
        Collection<ArtifactObject> resultValues = new ArrayList<ArtifactObject>(artifactFactories.getLength());
        if (artifactFactories != null){
            for (int i = 0; i < artifactFactories.getLength(); i++){
                Node  artifactFactoryNode = artifactFactories.item(i);
                String name = xmlUtils.getStringXPath(artifactFactoryNode, "@name");
                String description = xmlUtils.getStringXPath(artifactFactoryNode, "@description");
                ArtifactFactory artifactFactory = new ArtifactFactory(name, description, server);
                resultValues.add(artifactFactory);
            }
        }
        return resultValues;
    }
    
    /**
     * @throws IOException
     */
    private Document doGetRequest(String requestUrl) throws IOException {
        XMLUtils xmlUtils = new XMLUtils();
        Client client = new Client(Protocol.HTTP);
        Response response = client.get(requestUrl);
        Representation output = response.getEntity();
        Document document = xmlUtils.readDocument(output.getStream());
        log.debug(xmlUtils.writeDocument2String(document));
        return document;
    }
    
    /**
     * @throws IOException
     */
    private InputStream doPostRequest(String requestUrl, Document requestBody) throws IOException {
        Client client = new Client(Protocol.HTTP);
        Request request = new Request(Method.POST, requestUrl);
        String documentBody = new XMLUtils().writeDocument2String(requestBody);
        Representation representation = new StringRepresentation(documentBody);
        request.setEntity(representation);
        Response response = client.handle(request);
        Representation output = response.getEntity();
        return output.getStream();
    }
    
    private synchronized void initialize(){
        if (!initialized){
            this.artifactDatabases = new HashMap<String, String>();
            this.artifactDatabases.put("test", "http://localhost:8181");            // TODO Read from Config
            initialized = true;
        }
        
    }

    /**
     * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#createNewArtifact(de.intevation.gnv.artifactdatabase.objects.ArtifactObject)
     */
    public ArtifactObject createNewArtifact(ArtifactObject artifactFactory)
            throws ArtifactDatabaseClientException {
        
        try {
            Document request = this.createCreateRequestBody(artifactFactory.getId());
            Document result = doPostRequest(artifactFactory, request, "create");
            return this.getArtifact(result);
        } catch (IOException e) {
            log.error(e,e);
            throw new ArtifactDatabaseClientException(e);
        }
    }
    
    
    private ArtifactObject getArtifact(Document document){
        XMLUtils xmlUtils = new XMLUtils(); 
        String uuid = xmlUtils.getStringXPath(document, "/result/uuid/@value");
        String hash = xmlUtils.getStringXPath(document, "/result/hash/@value");
        log.info("NEW Artifact: "+uuid+" / "+hash);
        return new Artifact(uuid, hash);
    }
    
    
    
    
    private Document createCreateRequestBody(String artifactFactoryName){
        Document document = new XMLUtils().newDocument();
        Node rootNode  = this.createRootNode(document);
        Element typeNode = this.createArtifactElement(document, "type");
        typeNode.setAttribute("name", "create");
        rootNode.appendChild(typeNode);
             
        Element factoyNode = this.createArtifactElement(document, "factory");
        factoyNode.setAttribute("name", artifactFactoryName);
        rootNode.appendChild(factoyNode);
        
        return document;
    }
    
    private Element createRootNode(Document document){
        Element rootNode = this.createArtifactElement(document,"action");
        document.appendChild(rootNode);
        return rootNode;
    }
    
    /**
     * @param document
     * @return
     */
    private Element createArtifactElement(Document document, String name) {
        Element node = document.createElementNS(NAMESPACE_URI, name);
        node.setPrefix(NAMESPACE_PREFIX);
        return node;
    }

/**
 * @param artifactFactory
 * @param xmlUtils
 * @param request
 * @throws IOException
 */
private Document doPostRequest(ArtifactObject artifactFactory,
        Document request, String suburl) throws IOException {
    XMLUtils xmlUtils = new XMLUtils();
    String url = ((ArtifactFactory)artifactFactory).getDataBaseUrl();
    InputStream is = this.doPostRequest(url+"/"+suburl, request);
    Document result = xmlUtils.readDocument(is);
    // TODO: Fehleranalyse des Dokumentes
    log.debug(xmlUtils.writeDocument2String(result));
    return result;
}
    
    private Document createDescribeRequestBody(ArtifactObject currentArtifact){
        Document document = new XMLUtils().newDocument();
        Node rootNode  = this.createRootNode(document);
        Element typeNode = this.createArtifactElement(document, "type");
        typeNode.setAttribute("name", "describe");
        rootNode.appendChild(typeNode);
             
        Element uuidNode = this.createArtifactElement(document, "uuid");
        uuidNode.setAttribute("value", currentArtifact.getId());
        rootNode.appendChild(uuidNode);
        
        Element hashNode = this.createArtifactElement(document, "hash");
        hashNode.setAttribute("value", currentArtifact.getHash());
        rootNode.appendChild(hashNode);
        
        return document;
    }

    /**
     * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#getCurrentStepDescription(de.intevation.gnv.artifactdatabase.objects.ArtifactFactory, de.intevation.gnv.artifactdatabase.objects.ArtifactObject)
     */
    public ArtifactDescription getCurrentStepDescription(ArtifactObject artifactFactory,
            ArtifactObject currentArtifact)
            throws ArtifactDatabaseClientException {
        try {
            
            Document request = this.createDescribeRequestBody(currentArtifact);
            String url = ((ArtifactFactory)artifactFactory).getDataBaseUrl()+"/artifact/"+ currentArtifact.getId();
            Document result = this.doGetRequest(url);
            return this.readDescription(result,currentArtifact);
        } catch (IOException e) {
            log.error(e,e);
            throw new ArtifactDatabaseClientException(e);
        }
    }
    
    private ArtifactDescription readDescription(Document document, ArtifactObject artifact) throws ArtifactDatabaseClientException{
        XMLUtils xmlUtils = new XMLUtils();
        if (artifact instanceof ArtifactDescription){
            ArtifactDescription ad = (ArtifactDescription)artifact;
            Node uiNode =  xmlUtils.getNodeXPath(document, "/result/ui");
            uiNode = uiNode.getFirstChild();
            Node outputNode = xmlUtils.getNodeXPath(document, "/result/outputs");
            String currentState = xmlUtils.getStringXPath(document, "/result/state/@name");
            NodeList statesList = xmlUtils.getNodeSetXPath(document, "/result/reachable-states/state/@name");
            Collection<String> reachableStates = new ArrayList<String>(statesList.getLength());
            for (int i = 0; i < statesList.getLength(); i++){
                reachableStates.add(statesList.item(i).getNodeValue());
            }
            
            ad.setCurrentOut(outputNode);
            ad.setCurrentUI(uiNode);
            ad.setCurrentState(currentState);
            ad.setReachableStates(reachableStates);
            return ad;
        }else{
            log.error("Artifact must be Instance of ArtifactDescription");
            throw new ArtifactDatabaseClientException("Artifact must be Instance of ArtifactDescription");
        }
       
        
    }
    
    
   
}

http://dive4elements.wald.intevation.org