Mercurial > dive4elements > gnv-client
view gnv/src/main/java/de/intevation/gnv/artifactdatabase/client/DefaultArtifactDatabaseClient.java @ 36:ad381cc47217
Format Code to max 80 Chars per Row
gnv/trunk@172 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Fri, 02 Oct 2009 08:54:13 +0000 |
parents | 4405f31bbc30 |
children | fccf90761825 |
line wrap: on
line source
/** * */ package de.intevation.gnv.artifactdatabase.client; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; 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.artifactdatabase.objects.ArtifactStatisticValue; import de.intevation.gnv.artifactdatabase.objects.DefaultArtifactStatisticValue; import de.intevation.gnv.artifactdatabase.objects.DefaultOutputMode; import de.intevation.gnv.artifactdatabase.objects.DefaultOutputParameter; import de.intevation.gnv.artifactdatabase.objects.InputParameter; import de.intevation.gnv.artifactdatabase.objects.OutputMode; import de.intevation.gnv.artifactdatabase.objects.OutputParameter; import de.intevation.gnv.propertiesreader.PropertiesReader; import de.intevation.gnv.propertiesreader.PropertiesReaderFactory; 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); /** * The Databases which could be used */ private static Collection<String> artifactDatabases = null; /** * Is the Class initialized? */ 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 { log.debug("DefaultArtifactDatabaseClient.getArtifactFactories"); Iterator<String> it = artifactDatabases.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, ArtifactDatabaseClientException { return this.doGetRequest(requestUrl, null); } /** * @throws IOException */ private Document doGetRequest(String requestUrl, Document requestBody) throws IOException, ArtifactDatabaseClientException { XMLUtils xmlUtils = new XMLUtils(); Representation output = doGetRequestInternal(requestUrl, requestBody); Document document = xmlUtils.readDocument(output.getStream()); this.check4ExceptionReport(document); return document; } /** * @param requestUrl * @param requestBody * @return */ private Representation doGetRequestInternal(String requestUrl, Document requestBody) { Client client = new Client(Protocol.HTTP); Request request = new Request(Method.GET, requestUrl); if (requestBody != null) { String documentBody = new XMLUtils() .writeDocument2String(requestBody); Representation representation = new StringRepresentation( documentBody); request.setEntity(representation); } Response response = client.handle(request); // TODO RESPONSESTATUS AUSWERTEN. Representation output = response.getEntity(); return output; } /** * @throws IOException */ private InputStream doPostRequest(String requestUrl, Document requestBody) throws IOException { log.debug("##################################################"); log.debug(new XMLUtils().writeDocument2String(requestBody)); log.debug("##################################################"); 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); // TODO RESPONSESTATUS AUSWERTEN. Representation output = response.getEntity(); return output.getStream(); } private synchronized void initialize() { if (!initialized) { PropertiesReader pr = PropertiesReaderFactory.getInstance() .getPropertiesReader(); int count = Integer.parseInt(pr.getPropertieValue( ARTIFACTDATABASE_COUNT_ID, "0")); artifactDatabases = new ArrayList<String>(count); for (int i = 0; i < count; i++) { artifactDatabases.add(pr.getPropertieValue( ARTIFACTDATABASE_URL_ID + "." + (i + 1), "N/N")); } 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, ArtifactDatabaseClientException { XMLUtils xmlUtils = new XMLUtils(); String url = ((ArtifactFactory) artifactFactory).getDataBaseUrl(); InputStream is = this.doPostRequest(url + "/" + suburl, request); Document result = xmlUtils.readDocument(is); this.check4ExceptionReport(result); return result; } /** * @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 { String url = this.getArtifactUrl(artifactFactory, currentArtifact); Document result = this.doGetRequest(url); return this.readDescription(result, currentArtifact); } catch (IOException e) { log.error(e, e); throw new ArtifactDatabaseClientException(e); } } /** * @param artifactFactory * @param currentArtifact * @return */ private String getArtifactUrl(ArtifactObject artifactFactory, ArtifactObject currentArtifact) { String url = ((ArtifactFactory) artifactFactory).getDataBaseUrl() + "/artifact/" + currentArtifact.getId(); return url; } private ArtifactDescription readDescription(Document document, ArtifactObject artifact) throws ArtifactDatabaseClientException { // Check if there was an Error or Exception reported from the // ArtifactDatabase this.check4ExceptionReport(document); XMLUtils xmlUtils = new XMLUtils(); if (artifact instanceof ArtifactDescription) { ArtifactDescription ad = (ArtifactDescription) artifact; Node uiNode = xmlUtils.getNodeXPath(document, "/result/ui"); Node outputNode = xmlUtils .getNodeXPath(document, "/result/outputs"); Map<String, OutputMode> outputModes = null; if (outputNode != null) { NodeList outputModesNodes = xmlUtils.getNodeSetXPath( outputNode, "output"); if (outputModesNodes != null) { outputModes = new HashMap<String, OutputMode>( outputModesNodes.getLength()); for (int i = 0; i < outputModesNodes.getLength(); i++) { Node outputModeNode = outputModesNodes.item(i); String name = xmlUtils.getStringXPath(outputModeNode, "@name"); String mimeType = xmlUtils.getStringXPath( outputModeNode, "@mime-type"); NodeList parameterNodes = xmlUtils.getNodeSetXPath( outputModeNode, "parameter/parameter"); Collection<OutputParameter> parameter = null; if (parameterNodes != null) { parameter = new ArrayList<OutputParameter>( parameterNodes.getLength()); for (int j = 0; j < parameterNodes.getLength(); j++) { Node outputParameterNode = parameterNodes .item(j); parameter.add(new DefaultOutputParameter( xmlUtils.getStringXPath( outputParameterNode, "@name"), xmlUtils.getStringXPath( outputParameterNode, "@value"), xmlUtils.getStringXPath( outputParameterNode, "@name"), xmlUtils.getStringXPath( outputParameterNode, "@type"))); } } outputModes.put(name, new DefaultOutputMode(name, mimeType, parameter)); } } } 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()); } NodeList inputNodes = xmlUtils.getNodeSetXPath(document, "/result/model/input"); if (inputNodes != null) { Collection<String> inputParameter = new ArrayList<String>( inputNodes.getLength()); for (int i = 0; i < inputNodes.getLength(); i++) { Node inputNode = inputNodes.item(i); String name = xmlUtils.getStringXPath(inputNode, "@name"); inputParameter.add(name); } ad.setInputParameter(inputParameter); } ad.setOutputModes(outputModes); 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"); } } /** * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#doNextStep(de.intevation.gnv.artifactdatabase.objects.ArtifactObject, * de.intevation.gnv.artifactdatabase.objects.ArtifactObject, * java.lang.String, java.util.Collection) */ public ArtifactDescription doNextStep(ArtifactObject artifactFactory, ArtifactObject currentArtifact, String target, Collection<InputParameter> inputParameter) throws ArtifactDatabaseClientException { try { // 1 Feed this.doFeed(artifactFactory, currentArtifact, inputParameter); // 2 Advance String url = this.getArtifactUrl(artifactFactory, currentArtifact); Document advanceDocument = this.createAdvanceRequestBody( currentArtifact, target); InputStream advanceResult = this .doPostRequest(url, advanceDocument); this.check4ExceptionReport(new XMLUtils() .readDocument(advanceResult)); // 3 Describe return this.getCurrentStepDescription(artifactFactory, currentArtifact); } catch (IOException e) { log.error(e, e); throw new ArtifactDatabaseClientException(e); } } private Document createFeedRequestBody(ArtifactObject currentArtifact, Collection<InputParameter> inputParameter) { Document document = new XMLUtils().newDocument(); Node rootNode = this.createRootNode(document); Element typeNode = this.createArtifactElement(document, "type"); typeNode.setAttribute("name", "feed"); 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); Node dataNode = this.createParameterNodes(inputParameter, document, "data"); rootNode.appendChild(dataNode); return document; } /** * @param inputParameter * @param document * @param rootNode */ private Node createParameterNodes( Collection<InputParameter> inputParameter, Document document, String nodeName) { Element dataNode = this.createArtifactElement(document, nodeName); if (inputParameter != null) { Iterator<InputParameter> it = inputParameter.iterator(); while (it.hasNext()) { InputParameter ip = it.next(); String name = ip.getName(); String[] values = ip.getValues(); if (values != null) { for (int i = 0; i < values.length; i++) { String value = values[i]; Element inputNode = this.createArtifactElement( document, "input"); inputNode.setAttribute("name", name); inputNode.setAttribute("value", value); dataNode.appendChild(inputNode); } } } } return dataNode; } private Document createAdvanceRequestBody(ArtifactObject currentArtifact, String target) { Document document = new XMLUtils().newDocument(); Node rootNode = this.createRootNode(document); Element typeNode = this.createArtifactElement(document, "type"); typeNode.setAttribute("name", "advance"); 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); Element targetNode = this.createArtifactElement(document, "target"); targetNode.setAttribute("name", target); rootNode.appendChild(targetNode); return document; } /** * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#doOutput(de.intevation.gnv.artifactdatabase.objects.ArtifactObject, * de.intevation.gnv.artifactdatabase.objects.ArtifactObject, * java.io.OutputStream, java.lang.String, java.lang.String, * java.util.Collection) */ public void doOutput(ArtifactObject artifactFactory, ArtifactObject currentArtifact, OutputStream stream, String targetName, String mimeType, Collection<InputParameter> inputParameter) throws ArtifactDatabaseClientException { try { XMLUtils xmlUtils = new XMLUtils(); Document requestBody = this.createOutRequestBody(currentArtifact, targetName, mimeType, inputParameter); String requestUrl = this.getArtifactUrl(artifactFactory, currentArtifact) + "/" + targetName; InputStream is = this.doPostRequest(requestUrl, requestBody); byte[] b = new byte[4096]; int i = -1; while ((i = is.read(b)) > 0) { stream.write(b, 0, i); } } catch (IOException e) { log.error(e, e); throw new ArtifactDatabaseClientException(e); } } private Document createOutRequestBody(ArtifactObject currentArtifact, String target, String mimeType, Collection<InputParameter> inputParameter) { Document document = new XMLUtils().newDocument(); Node rootNode = this.createRootNode(document); Element typeNode = this.createArtifactElement(document, "type"); typeNode.setAttribute("name", "out"); 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); Element outNode = this.createArtifactElement(document, "out"); outNode.setAttribute("name", target); rootNode.appendChild(outNode); Element mimeTypeNode = this.createArtifactElement(document, "out"); mimeTypeNode.setAttribute("value", mimeType); outNode.appendChild(mimeTypeNode); Node parameterNode = this.createParameterNodes(inputParameter, document, "params"); outNode.appendChild(parameterNode); return document; } /** * @see de.intevation.gnv.artifactdatabase.client.ArtifactDatabaseClient#doFeed(de.intevation.gnv.artifactdatabase.objects.ArtifactObject, * de.intevation.gnv.artifactdatabase.objects.ArtifactObject, * java.util.Collection) */ public void doFeed(ArtifactObject artifactFactory, ArtifactObject currentArtifact, Collection<InputParameter> inputParameter) throws ArtifactDatabaseClientException { try { Document feedDocument = this.createFeedRequestBody(currentArtifact, inputParameter); String url = this.getArtifactUrl(artifactFactory, currentArtifact); InputStream feedResult = this.doPostRequest(url, feedDocument); Document feedResultDocument = new XMLUtils() .readDocument(feedResult); this.check4ExceptionReport(feedResultDocument); } catch (IOException e) { log.error(e, e); throw new ArtifactDatabaseClientException(e); } } private void check4ExceptionReport(Document document) throws ArtifactDatabaseClientException { String message = new XMLUtils().getStringXPath(document, "/exceptionreport/exception"); if (message != null) { throw new ArtifactDatabaseClientException(message); } } public Collection<ArtifactStatisticValue> calculateStatistics( ArtifactObject artifactFactory, ArtifactObject currentArtifact) throws ArtifactDatabaseClientException { log.debug("DefaultArtifactDatabaseClient.calculateStatistics"); Collection<ArtifactStatisticValue> result; try { result = null; String targetName = "statistics"; String requestUrl = this.getArtifactUrl(artifactFactory, currentArtifact) + "/" + targetName; Document requestBody = this.createOutRequestBody(currentArtifact, targetName, "text/xml", null); XMLUtils xmlUtils = new XMLUtils(); InputStream is = this.doPostRequest(requestUrl, requestBody); Document resultDocument = xmlUtils.readDocument(is); if (resultDocument != null) { NodeList resultNodes = xmlUtils.getNodeSetXPath(resultDocument, "/statistic-values/statistic"); if (resultNodes != null) { result = new ArrayList<ArtifactStatisticValue>(resultNodes .getLength()); for (int i = 0; i < resultNodes.getLength(); i++) { Node statisticNode = resultNodes.item(i); String name = xmlUtils.getStringXPath(statisticNode, "@name"); String value = xmlUtils.getStringXPath(statisticNode, "@value"); result.add(new DefaultArtifactStatisticValue(name, value)); } } } } catch (IOException e) { log.error(e, e); throw new ArtifactDatabaseClientException(e); } return result; } }