Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java @ 376:d8f3ef441bf2
merged gnv-artifacts/0.3
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:47 +0200 |
parents | 2f7a28f211c7 |
children | 3ddc22aab764 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java Fri Sep 28 12:13:47 2012 +0200 @@ -0,0 +1,513 @@ +/** + * + */ +package de.intevation.gnv.artifacts; + +import java.io.IOException; +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 javax.xml.xpath.XPathConstants; + +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import de.intevation.artifactdatabase.Config; +import de.intevation.artifactdatabase.DefaultArtifact; +import de.intevation.artifactdatabase.XMLUtils; +import de.intevation.artifacts.ArtifactFactory; +import de.intevation.artifacts.ArtifactNamespaceContext; +import de.intevation.artifacts.CallContext; +import de.intevation.artifacts.CallMeta; +import de.intevation.gnv.artifacts.context.GNVArtifactContext; +import de.intevation.gnv.state.DefaultInputData; +import de.intevation.gnv.state.InputData; +import de.intevation.gnv.state.InputValue; +import de.intevation.gnv.state.OutputMode; +import de.intevation.gnv.state.OutputState; +import de.intevation.gnv.state.State; +import de.intevation.gnv.state.StateFactory; +import de.intevation.gnv.state.exception.StateException; +import de.intevation.gnv.transition.Transition; +import de.intevation.gnv.transition.TransitionFactory; +import de.intevation.gnv.utils.ArtifactXMLUtilities; + +/** + * @author Tim Englich <tim.englich@intevation.de> + * + */ +public abstract class GNVArtifactBase extends DefaultArtifact { + /** + * the logger, used to log exceptions and additonaly information + */ + private static Logger log = Logger.getLogger(GNVArtifactBase.class); + /** + * The UID of this Class + */ + private static final long serialVersionUID = -8907096744400741458L; + + /** + * The Identifier for the Replacement of the Artifactname + */ + public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER"; + + /** + * The XPATH to the XML-Fragment that should be used for the Configuration + */ + public static final String XPATH_ARTIFACT_CONFIGURATION = "/artifact-database/artifacts/artifact[@name='" + + XPATH_IDENTIFIER_REPLACE + + "']"; + + /** + * The current State + */ + protected State current = null; + + /** + * The States that can be used + */ + protected Map<String, State> states = null; + + /** + * The Transitions which can switch between the different States. + */ + protected Collection<Transition> transitions = null; + + /** + * The Name of the Artifact + */ + protected String name = null; + + private ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); + + /** + * Constructor + */ + public GNVArtifactBase() { + super(); + } + + /** + * @see de.intevation.artifactdatabase.DefaultArtifact#advance(org.w3c.dom.Document, + * de.intevation.artifacts.CallContext) + */ + @Override + public Document advance(Document target, CallContext context) { + log.debug("GNVArtifactBase.advance"); + Document result = XMLUtils.newDocument(); + try { + if (this.current != null) { + String stateName = this.readStateName(target); + log.debug("Statename: " + stateName); + if (this.isStateCurrentlyReachable(stateName)) { + try { + State nextStep = this.states + .get(stateName); + // 1.Ergebnisse Berechnen + this.current.advance(super.identifier, context.getMeta()); + // 2. Ergebnisse Übergeben + nextStep.putInputData(this.current.getInputData(), + super.identifier); + // 3. Umschalten auf neue Transistion + this.current = nextStep; + + // 4. Initialisieren des nächsten Schrittes == Laden der Daten + this.current.initialize(super.identifier, context.getMeta()); + + result = new ArtifactXMLUtilities() + .createSuccessReport("Advance success", + XMLUtils.newDocument()); + } catch (StateException e) { + log.error(e, e); + result = new ArtifactXMLUtilities() + .createExceptionReport(e + .getLocalizedMessage(), XMLUtils + .newDocument()); + } + } else { + String msg = "Transitionsübergang wird nicht unterstützt."; + log.error(msg); + result = new ArtifactXMLUtilities().createExceptionReport( + msg, XMLUtils.newDocument()); + } + } else { + String msg = "Kein State aktiviert."; + log.error(msg); + result = new ArtifactXMLUtilities().createExceptionReport(msg, + XMLUtils.newDocument()); + } + } catch (Exception e) { + log.error(e, e); + result = new ArtifactXMLUtilities().createExceptionReport(e + .getLocalizedMessage(), XMLUtils.newDocument()); + } + return result; + } + + + private boolean isStateCurrentlyReachable(String stateid){ + log.debug("GNVArtifactBase.isStateCurrentlyReachable "+stateid); + Iterator<Transition> it = this.transitions.iterator(); + String from = this.current.getID(); + while (it.hasNext()){ + Transition transition = it.next(); + if (transition.getFrom().equals(from)){ + if (transition.getTo().equals(stateid) && transition.isValid(this.current)){ + return true; + } + } + } + return false; + } + + public Document initialize (CallContext context) { + Document result = XMLUtils.newDocument(); + try { + this.current.initialize(super.identifier, context.getMeta()); + result = new ArtifactXMLUtilities() + .createSuccessReport("Initialize success", + XMLUtils.newDocument()); + } catch (StateException e) { + log.error(e,e); + result = new ArtifactXMLUtilities().createExceptionReport(e + .getLocalizedMessage(), XMLUtils.newDocument()); + } + return result; + } + + protected String readStateName(Document document) { + String returnValue = Config.getStringXPath(document, + "action/target/@name"); + return returnValue; + } + + protected Node getConfigurationFragment(Document document) { + log.debug("GNVArtifactBase.getConfigurationFragment"); + String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll( + XPATH_IDENTIFIER_REPLACE, this.name); + log.debug(xpathQuery); + + Element configurationNode = (Element)Config.getNodeXPath(document, xpathQuery); + + String link = configurationNode.getAttribute("xlink:href"); + if (link != null ){ + String absolutFileName = Config.replaceConfigDir(link); + configurationNode = (Element)new ArtifactXMLUtilities().readConfiguration(absolutFileName); + } + + return configurationNode; + } + + /** + * @see de.intevation.artifactdatabase.DefaultArtifact#feed(org.w3c.dom.Document, + * de.intevation.artifacts.CallContext) + */ + @Override + public Document feed(Document target, CallContext context) { + log.debug("GNVArtifactBase.feed"); + Document result = XMLUtils.newDocument(); + try { + if (this.current != null) { + Collection<InputData> inputData = this.parseInputData(target, + "/action/data/input"); + if (!inputData.isEmpty()){ + this.current.putInputData(inputData, super.identifier); + result = new ArtifactXMLUtilities().createSuccessReport( + "Feed success", XMLUtils.newDocument()); + }else{ + String msg = "No Inputdata given. Please select at least one Entry."; + log.warn(msg); + result = new ArtifactXMLUtilities().createExceptionReport(msg, + XMLUtils.newDocument()); + } + } else { + String msg = "No State instantiated"; + log.warn(msg); + result = new ArtifactXMLUtilities().createExceptionReport(msg, + XMLUtils.newDocument()); + } + } catch (StateException e) { + log.error(e, e); + result = new ArtifactXMLUtilities().createExceptionReport(e + .getLocalizedMessage(), XMLUtils.newDocument()); + } + return result; + } + + /** + * @see de.intevation.artifactdatabase.DefaultArtifact#setup(java.lang.String, + * java.lang.Object) + */ + @Override + public void setup(String identifier, ArtifactFactory factory, Object context) { + log.debug("GNVArtifactBase.setup"); + super.setup(identifier, factory, context); + + Object localContext = context; + if (context instanceof CallContext) { + localContext = ((CallContext) context).globalContext(); + + } + + if (localContext instanceof GNVArtifactContext) { + GNVArtifactContext gnvContext = (GNVArtifactContext) localContext; + Document doc = gnvContext.getConfig(); + Node artifactNode = this.getConfigurationFragment(doc); + + NodeList stateList = Config.getNodeSetXPath(artifactNode, + "states/state"); + this.states = new HashMap<String, State>(stateList + .getLength()); + for (int i = 0; i < stateList.getLength(); i++) { + State tmpState = StateFactory.getInstance() + .createState(stateList.item(i)); + if (tmpState != null) { + this.states.put(tmpState.getID(), tmpState); + if (this.current == null) { + this.current = tmpState; + } + } + } + + NodeList transitionList = Config.getNodeSetXPath(artifactNode, + "states/transition"); + this.transitions = new ArrayList<Transition>(transitionList.getLength()); + for (int i = 0; i < transitionList.getLength(); i++) { + Transition tmpTransition = TransitionFactory.getInstance() + .createTransition(transitionList.item(i)); + if (tmpTransition != null) { + this.transitions.add(tmpTransition); + } + } + + } + } + + + + protected Document createDescibeOutput(CallMeta callMeta, String uuid, boolean incudeUI) { + log.debug("GNVArtifactBase.createDescibeOutput"); + Document document = XMLUtils.newDocument(); + Element rootNode = this.createRootNode(document); + this.createHeader(rootNode, document, "describe"); + this.createOutputs(rootNode, document); + this.createCurrentState(rootNode, document); + this.createReachableStates(rootNode, document); + this.createModel(rootNode, document); + if (incudeUI){ + this.createUserInterface(rootNode, document, callMeta, uuid); + } + return document; + } + + protected boolean getIncludeUIFromDocument(Document document){ + String value = Config.getStringXPath(document, "action/include-ui"); + boolean includeUI = false; + if (value != null){ + includeUI = Boolean.parseBoolean(value); + } + return includeUI; + } + + protected Element createRootNode(Document document) { + Element rootNode = xmlUtilities.createArtifactElement(document, + "result"); + document.appendChild(rootNode); + return rootNode; + } + + protected void createHeader(Element parent, Document document, + String documentType) { + Element typeNode = xmlUtilities.createArtifactElement(document, "type"); + typeNode.setAttribute("name", documentType); + parent.appendChild(typeNode); + + Element uuidNode = xmlUtilities.createArtifactElement(document, "uuid"); + uuidNode.setAttribute("value", super.identifier); + parent.appendChild(uuidNode); + + Element hashNode = xmlUtilities.createArtifactElement(document, "hash"); + hashNode.setAttribute("value", this.hash()); + parent.appendChild(hashNode); + } + + protected void createReachableStates(Element parent, Document document) { + Element stateNode = xmlUtilities.createArtifactElement(document, + "reachable-states"); + if (this.current != null) { + Iterator<Transition> transitions = this.transitions.iterator(); + while (transitions.hasNext()) { + Transition tmpTransition = transitions.next(); + if (tmpTransition.getFrom().equals(current.getID()) && + tmpTransition.isValid(this.current)){ + Element currentNode = xmlUtilities.createArtifactElement( + document, "state"); + currentNode.setAttribute("name", tmpTransition.getTo()); + log.debug("Reachable State: " + tmpTransition.getTo()); + currentNode.setAttribute("description", + this.states.get(tmpTransition.getTo()) + .getDescription()); + stateNode.appendChild(currentNode); + } + } + } + parent.appendChild(stateNode); + } + + protected void createCurrentState(Element parent, Document document) { + Element stateNode = xmlUtilities.createArtifactElement(document, + "state"); + stateNode.setAttribute("name", this.current.getID()); + stateNode.setAttribute("description", this.current.getDescription()); + parent.appendChild(stateNode); + } + + protected void createModel(Element parent, Document document) { + Element modelNode = xmlUtilities.createArtifactElement(document, + "model"); + if (this.current != null) { + Collection<InputValue> inputValues = this.current + .getRequiredInputValues(); + if (inputValues != null) { + Iterator<InputValue> it = inputValues.iterator(); + while (it.hasNext()) { + InputValue inputValue = it.next(); + Element inputNode = xmlUtilities.createArtifactElement( + document, "input"); + inputNode.setAttribute("name", inputValue.getName()); + inputNode.setAttribute("type", inputValue.getType()); + modelNode.appendChild(inputNode); + } + } + } + parent.appendChild(modelNode); + } + + protected void createUserInterface(Element parent, Document document, + CallMeta callMeta, String uuid) { + Element uiNode = xmlUtilities.createArtifactElement(document, "ui"); + + if (this.current != null) { + this.current.describe(document, uiNode, callMeta, uuid); + } + + parent.appendChild(uiNode); + } + + protected void createOutputs(Element parent, Document document) { + log.debug("GNVArtifactBase.createOutputs"); + Element outputsNode = xmlUtilities.createArtifactElement(document, + "outputs"); + if (this.current instanceof OutputState) { + Collection<OutputMode> outputModes = ((OutputState) this.current) + .getOutputModes(); + if (outputModes != null) { + Iterator<OutputMode> it = outputModes.iterator(); + while (it.hasNext()) { + OutputMode outputMode = it.next(); + log.debug("Write Outputnode for " + outputMode.toString()); + Element outputModeNode = xmlUtilities + .createArtifactElement(document, "output"); + outputModeNode.setAttribute("name", outputMode.getName()); + outputModeNode.setAttribute("description", outputMode + .getDescription()); + outputModeNode.setAttribute("mime-type", outputMode + .getMimeType()); + outputsNode.appendChild(outputModeNode); + + Collection<InputValue> inputParameters = outputMode + .getInputParameters(); + if (inputParameters != null) { + Element inputParametersNode = xmlUtilities + .createArtifactElement(document, "parameter"); + outputModeNode.appendChild(inputParametersNode); + Iterator<InputValue> it2 = inputParameters.iterator(); + while (it2.hasNext()) { + InputValue inputValue = it2.next(); + Element inputParameterNode = xmlUtilities + .createArtifactElement(document, + "parameter"); + inputParametersNode.appendChild(inputParameterNode); + inputParameterNode.setAttribute("name", inputValue + .getName()); + inputParameterNode.setAttribute("type", inputValue + .getType()); + inputParameterNode.setAttribute("value", inputValue + .getDefaultValue()); + } + } + } + } else { + log.warn("No Outputmodes given."); + } + } + parent.appendChild(outputsNode); + } + + protected Collection<InputData> parseInputData(Document document, + String xPath) { + log.debug("GNVArtifactBase.parseInputData"); + HashMap<String, InputData> returnValue = null; + + log.debug(new ArtifactXMLUtilities().writeDocument2String(document)); + + NodeList inputElemets = (NodeList) XMLUtils.xpath(document, xPath, + XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);// Config.getNodeSetXPath(document, + // ""); + if (inputElemets != null) { + returnValue = new HashMap<String, InputData>(inputElemets + .getLength()); + for (int i = 0; i < inputElemets.getLength(); i++) { + Element inputDataNode = (Element)inputElemets.item(i); + String name = inputDataNode.getAttribute("name"); + String value = inputDataNode.getAttribute("value"); + + if (returnValue.containsKey(name)) { + InputData inputData = returnValue.get(name); + inputData.concartValue(value); + log.debug(inputData.toString()); + returnValue.put(name, inputData); + } else { + InputData inputData = new DefaultInputData(name, value); + + returnValue.put(name, inputData); + } + } + } + return returnValue.values(); + } + + /** + * @see de.intevation.artifactdatabase.DefaultArtifact#out(org.w3c.dom.Document, + * java.io.OutputStream, de.intevation.artifacts.CallContext) + */ + @Override + public void out(Document format, OutputStream outputStream, + CallContext context) throws IOException { + log.debug("TGNVArtifactBase.out"); + try { + + if (current != null && current instanceof OutputState) { + ((OutputState) current) + .out(format, this.parseInputData( + format, "/action/out/params/input"), + outputStream, super.identifier, context); + } + } catch (StateException e) { + log.error(e, e); + throw new IOException(e.getMessage()); + } + } + + protected String readOutputType(Document document) { + String value = Config.getStringXPath(document, "action/out/@name"); + return value; + } +}