tim@52: /** tim@52: * tim@52: */ tim@52: package de.intevation.gnv.artifacts; tim@52: tim@73: import java.io.IOException; tim@73: import java.io.OutputStream; tim@56: import java.util.Collection; tim@52: import java.util.HashMap; tim@54: import java.util.Iterator; tim@52: import java.util.Map; tim@52: tim@71: import javax.xml.xpath.XPathConstants; tim@71: tim@52: import org.apache.log4j.Logger; tim@52: import org.w3c.dom.Document; tim@54: import org.w3c.dom.Element; tim@52: import org.w3c.dom.Node; tim@52: import org.w3c.dom.NodeList; tim@52: tim@52: import de.intevation.artifactdatabase.Config; tim@52: import de.intevation.artifactdatabase.DefaultArtifact; tim@71: import de.intevation.artifactdatabase.XMLUtils; tim@70: import de.intevation.artifacts.ArtifactFactory; tim@70: import de.intevation.artifacts.ArtifactNamespaceContext; tim@73: import de.intevation.artifacts.CallContext; tim@117: import de.intevation.artifacts.CallMeta; tim@52: import de.intevation.gnv.artifacts.context.GNVArtifactContext; tim@57: import de.intevation.gnv.transition.DefaultInputData; tim@57: import de.intevation.gnv.transition.InputData; tim@56: import de.intevation.gnv.transition.InputValue; tim@64: import de.intevation.gnv.transition.OutputMode; tim@64: import de.intevation.gnv.transition.OutputTransition; tim@52: import de.intevation.gnv.transition.Transition; tim@52: import de.intevation.gnv.transition.TransitionFactory; tim@57: import de.intevation.gnv.transition.exception.TransitionException; tim@71: import de.intevation.gnv.utils.ArtifactXMLUtilities; tim@52: tim@52: /** tim@52: * @author Tim Englich tim@52: * tim@52: */ tim@52: public abstract class GNVArtifactBase extends DefaultArtifact { tim@52: /** tim@52: * the logger, used to log exceptions and additonaly information tim@52: */ tim@52: private static Logger log = Logger.getLogger(GNVArtifactBase.class); tim@52: /** tim@52: * The UID of this Class tim@52: */ tim@52: private static final long serialVersionUID = -8907096744400741458L; tim@52: tim@54: /** tim@54: * The Identifier for the Replacement of the Artifactname tim@54: */ tim@52: public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER"; tim@54: tim@52: /** tim@52: * The XPATH to the XML-Fragment that should be used for the Configuration tim@52: */ tim@52: public static final String XPATH_ARTIFACT_CONFIGURATION= "/artifact-database/artifacts/artifact[@name='"+XPATH_IDENTIFIER_REPLACE+"']"; tim@52: tim@54: tim@54: /** tim@54: * The current Transition tim@54: */ tim@52: protected Transition current = null; tim@52: tim@54: /** tim@54: * The Transitions that can be used tim@54: */ tim@52: protected Map transitions = null; tim@52: tim@54: /** tim@54: * The Name of the Artifact tim@54: */ tim@52: protected String name = null; tim@54: tim@71: private ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities(); tim@71: tim@52: /** tim@52: * Constructor tim@52: */ tim@52: public GNVArtifactBase() { tim@52: super(); tim@52: } tim@52: tim@58: /** tim@73: * @see de.intevation.artifactdatabase.DefaultArtifact#advance(org.w3c.dom.Document, de.intevation.artifacts.CallContext) tim@58: */ tim@58: @Override tim@73: public Document advance(Document target, CallContext context) { tim@89: log.debug("GNVArtifactBase.advance"); tim@99: String uuid = Config.getStringXPath(target, "action/uuid/@value"); tim@71: Document result = XMLUtils.newDocument(); tim@88: try { tim@88: if (this.current != null){ tim@88: String transitionName = this.readTransitionName(target); tim@116: log.debug("Transitionsname: "+transitionName); tim@88: if (this.current.isTransitionReachable(transitionName)){ tim@88: // 1. Prüfung ob Transition valide ist tim@88: if (this.current.validate()){ tim@88: tim@88: try { tim@88: Transition nextStep = this.transitions.get(transitionName); tim@88: // 2.Ergebnisse Berechnen tim@117: this.current.advance(uuid,context.getMeta()); tim@88: // 3. Ergebnisse übergeben tim@88: nextStep.setDescibeData(this.current.getDescibeData()); tim@99: nextStep.putInputData(this.current.getInputData(),uuid); tim@88: // 4. Umschalten auf neue Transistion tim@88: this.current = nextStep; tim@89: result = new ArtifactXMLUtilities().createSuccessReport("Advance success", XMLUtils.newDocument()); tim@88: } catch (TransitionException e) { tim@88: log.error(e,e); tim@88: result = new ArtifactXMLUtilities().createExceptionReport(e.getLocalizedMessage(), XMLUtils.newDocument()); tim@88: } tim@88: tim@88: }else{ tim@88: String msg = "Advance nicht möglich, da die Bedingungen für den Übergang " + tim@88: "in den neuen Zustand noch nicht gegeben ist."; tim@88: log.error(msg); tim@88: result = new ArtifactXMLUtilities().createExceptionReport(msg, XMLUtils.newDocument()); tim@58: } tim@58: tim@58: }else{ tim@88: String msg = "Transitionsübergang wird nicht unterstützt."; tim@88: log.error(msg); tim@88: result = new ArtifactXMLUtilities().createExceptionReport(msg, XMLUtils.newDocument()); tim@58: } tim@58: }else{ tim@88: String msg = "Kein Transitionsschritt aktiviert."; tim@88: log.error(msg); tim@88: result = new ArtifactXMLUtilities().createExceptionReport(msg, XMLUtils.newDocument()); tim@58: } tim@88: } catch (Exception e) { tim@88: log.error(e,e); tim@88: result = new ArtifactXMLUtilities().createExceptionReport(e.getLocalizedMessage(), XMLUtils.newDocument()); tim@58: } tim@58: return result; tim@58: } tim@58: tim@58: protected String readTransitionName(Document document) { tim@58: String returnValue = Config.getStringXPath(document, "action/target/@name"); tim@58: return returnValue; tim@58: } tim@58: tim@52: protected Node getConfigurationFragment(Document document){ tim@52: log.debug("GNVArtifactBase.getConfigurationFragment"); tim@52: String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll(XPATH_IDENTIFIER_REPLACE, this.name); tim@52: log.debug(xpathQuery); tim@52: return Config.getNodeXPath(document,xpathQuery); tim@52: } tim@52: tim@52: /** tim@73: * @see de.intevation.artifactdatabase.DefaultArtifact#feed(org.w3c.dom.Document, de.intevation.artifacts.CallContext) tim@57: */ tim@57: @Override tim@73: public Document feed(Document target, CallContext context) { tim@89: log.debug("GNVArtifactBase.feed"); tim@71: Document result = XMLUtils.newDocument(); tim@57: try { tim@57: if (this.current != null){ tim@99: String uuid = Config.getStringXPath(target, "action/uuid/@value"); tim@99: this.current.putInputData(this.parseInputData(target, "/action/data/input"),uuid); tim@89: result = new ArtifactXMLUtilities().createSuccessReport("Feed success", XMLUtils.newDocument()); tim@89: }else{ tim@89: String msg = "No Transition instantiated"; tim@89: log.warn(msg); tim@89: result = new ArtifactXMLUtilities().createExceptionReport(msg, XMLUtils.newDocument()); tim@57: } tim@57: } catch (TransitionException e) { tim@57: log.error(e,e); tim@89: result = new ArtifactXMLUtilities().createExceptionReport(e.getLocalizedMessage(), XMLUtils.newDocument()); tim@57: } tim@57: return result; tim@57: } tim@57: tim@57: /** tim@52: * @see de.intevation.artifactdatabase.DefaultArtifact#setup(java.lang.String, java.lang.Object) tim@52: */ tim@52: @Override tim@70: public void setup(String identifier, ArtifactFactory factory, Object context) { tim@52: log.debug("GNVArtifactBase.setup"); tim@70: super.setup(identifier, factory, context); tim@77: tim@77: Object localContext = context; tim@77: if (context instanceof CallContext){ tim@77: localContext = ((CallContext)context).globalContext(); tim@77: tim@77: } tim@77: tim@77: if (localContext instanceof GNVArtifactContext){ tim@77: GNVArtifactContext gnvContext = (GNVArtifactContext)localContext; tim@52: Document doc = gnvContext.getConfig(); tim@52: Node artifactNode = this.getConfigurationFragment(doc); tim@52: NodeList transitionList = Config.getNodeSetXPath(artifactNode, "transitions/transition"); tim@52: this.transitions = new HashMap(transitionList.getLength()); tim@52: for (int i = 0 ; i < transitionList.getLength(); i++){ tim@52: Transition tmpTransition = TransitionFactory.getInstance().createTransition(transitionList.item(i)); tim@52: if (tmpTransition != null){ tim@52: this.transitions.put(tmpTransition.getID(), tmpTransition); tim@52: if (this.current == null){ tim@52: this.current = tmpTransition; tim@52: } tim@52: } tim@52: } tim@52: tim@52: } tim@52: } tim@52: tim@54: tim@117: protected Document createDescibeOutput(CallMeta callMeta){ tim@54: log.debug("GNVArtifactBase.createDescibeOutput"); tim@71: Document document = XMLUtils.newDocument(); tim@88: Element rootNode = this.createRootNode(document); tim@54: this.createHeader(rootNode, document, "describe"); tim@59: this.createOutputs(rootNode, document); tim@54: this.createCurrentState(rootNode, document); tim@54: this.createReachableStates(rootNode, document); tim@54: this.createModel(rootNode, document); tim@117: this.createUserInterface(rootNode, document,callMeta); tim@54: return document; tim@54: } tim@54: tim@54: protected Element createRootNode(Document document){ tim@71: Element rootNode = xmlUtilities.createArtifactElement(document,"result"); tim@54: document.appendChild(rootNode); tim@54: return rootNode; tim@54: } tim@54: tim@54: protected void createHeader(Element parent, Document document, String documentType){ tim@71: Element typeNode = xmlUtilities.createArtifactElement(document,"type"); tim@54: typeNode.setAttribute("name", documentType); tim@54: parent.appendChild(typeNode); tim@54: tim@71: Element uuidNode = xmlUtilities.createArtifactElement(document,"uuid"); tim@54: uuidNode.setAttribute("value", super.identifier); tim@54: parent.appendChild(uuidNode); tim@54: tim@71: Element hashNode = xmlUtilities.createArtifactElement(document,"hash"); tim@54: hashNode.setAttribute("value", this.hash()); tim@54: parent.appendChild(hashNode); tim@89: } tim@54: tim@54: protected void createReachableStates(Element parent,Document document){ tim@71: Element stateNode = xmlUtilities.createArtifactElement(document,"reachable-states"); tim@54: if (this.current != null){ tim@54: Iterator states = this.current.reachableTransitions().iterator(); tim@54: while(states.hasNext()){ tim@54: String value = states.next(); tim@71: Element currentNode = xmlUtilities.createArtifactElement(document,"state"); tim@54: currentNode.setAttribute("name", value); tim@88: log.debug("Reachable State: "+value); tim@54: currentNode.setAttribute("description", transitions.get(value).getDescription()); tim@54: stateNode.appendChild(currentNode); tim@54: } tim@54: } tim@54: parent.appendChild(stateNode); tim@54: } tim@54: tim@54: protected void createCurrentState(Element parent, Document document){ tim@71: Element stateNode = xmlUtilities.createArtifactElement(document,"state"); tim@54: stateNode.setAttribute("name", this.current.getID()); tim@54: stateNode.setAttribute("description", this.current.getDescription()); tim@54: parent.appendChild(stateNode); tim@54: } tim@54: tim@54: tim@54: protected void createModel(Element parent, Document document){ tim@71: Element modelNode = xmlUtilities.createArtifactElement(document,"model"); tim@56: if (this.current != null){ tim@56: Collection inputValues = this.current.getRequiredInputValues(); tim@56: if (inputValues != null){ tim@56: Iterator it = inputValues.iterator(); tim@56: while(it.hasNext()){ tim@56: InputValue inputValue = it.next(); tim@71: Element inputNode = xmlUtilities.createArtifactElement(document,"input"); tim@56: inputNode.setAttribute("name", inputValue.getName()); tim@56: inputNode.setAttribute("type", inputValue.getType()); tim@56: modelNode.appendChild(inputNode); tim@56: } tim@56: } tim@56: } tim@54: parent.appendChild(modelNode); tim@54: } tim@54: tim@117: protected void createUserInterface(Element parent, Document document, CallMeta callMeta){ tim@71: Element uiNode = xmlUtilities.createArtifactElement(document,"ui"); tim@54: tim@61: if (this.current != null){ tim@117: this.current.describe(document, uiNode,callMeta); tim@61: } tim@54: tim@54: parent.appendChild(uiNode); tim@54: } tim@54: tim@54: protected void createOutputs(Element parent, Document document){ tim@64: log.debug("GNVArtifactBase.createOutputs"); tim@71: Element outputsNode = xmlUtilities.createArtifactElement(document,"outputs"); tim@64: if (this.current instanceof OutputTransition){ tim@64: Collection outputModes = ((OutputTransition)this.current).getOutputModes(); tim@64: if (outputModes != null){ tim@64: Iterator it = outputModes.iterator(); tim@64: while(it.hasNext()){ tim@64: OutputMode outputMode = it.next(); tim@64: log.debug("Write Outputnode for "+ outputMode.toString()); tim@71: Element outputModeNode = xmlUtilities.createArtifactElement(document,"output"); tim@64: outputModeNode.setAttribute("name", outputMode.getName()); tim@64: outputModeNode.setAttribute("description", outputMode.getDescription()); tim@64: outputModeNode.setAttribute("mime-type", outputMode.getMimeType()); tim@64: outputsNode.appendChild(outputModeNode); tim@91: tim@91: Collection inputParameters = outputMode.getInputParameters(); tim@91: if (inputParameters != null){ tim@91: Element inputParametersNode = xmlUtilities.createArtifactElement(document,"parameter"); tim@91: outputModeNode.appendChild(inputParametersNode); tim@91: Iterator it2 = inputParameters.iterator(); tim@91: while (it2.hasNext()){ tim@91: InputValue inputValue = it2.next(); tim@91: Element inputParameterNode = xmlUtilities.createArtifactElement(document,"parameter"); tim@91: inputParametersNode.appendChild(inputParameterNode); tim@91: inputParameterNode.setAttribute("name", inputValue.getName()); tim@91: inputParameterNode.setAttribute("type", inputValue.getType()); tim@91: inputParameterNode.setAttribute("value", inputValue.getDefaultValue()); tim@91: } tim@91: } tim@64: } tim@64: }else{ tim@64: log.warn("No Outputmodes given."); tim@64: } tim@64: } tim@54: parent.appendChild(outputsNode); tim@54: } tim@54: tim@54: tim@91: protected Collection parseInputData(Document document, String xPath){ tim@57: log.debug("GNVArtifactBase.parseInputData"); tim@78: HashMap returnValue = null; tim@57: tim@71: log.debug(new ArtifactXMLUtilities().writeDocument2String(document)); tim@71: tim@91: NodeList inputElemets = (NodeList)XMLUtils.xpath(document, xPath,XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);//Config.getNodeSetXPath(document, ""); tim@57: if(inputElemets != null){ tim@78: returnValue = new HashMap(inputElemets.getLength()); tim@57: for (int i = 0; i < inputElemets.getLength(); i++){ tim@57: Node inputDataNode = inputElemets.item(i); tim@78: String name = Config.getStringXPath(inputDataNode,"@name"); tim@78: String value = Config.getStringXPath(inputDataNode,"@value"); tim@78: tim@78: if (returnValue.containsKey(name)){ tim@78: InputData inputData = returnValue.get(name); tim@78: inputData.concartValue(value); tim@78: log.debug(inputData.toString()); tim@78: returnValue.put(name, inputData); tim@78: }else{ tim@78: InputData inputData = new DefaultInputData(name,value); tim@78: tim@78: returnValue.put(name,inputData); tim@78: } tim@57: } tim@57: } tim@78: return returnValue.values(); tim@57: } tim@99: tim@73: tim@73: /** tim@117: * @see de.intevation.artifactdatabase.DefaultArtifact#out(org.w3c.dom.Document, tim@117: * java.io.OutputStream, de.intevation.artifacts.CallContext) tim@73: */ tim@73: @Override tim@117: public void out(Document format, OutputStream outputStream, tim@117: CallContext context) throws IOException { tim@68: log.debug("TGNVArtifactBase.out"); tim@68: try { tim@117: tim@117: if (current != null && current instanceof OutputTransition) { tim@117: String uuid = Config.getStringXPath(format, tim@117: "action/uuid/@value"); tim@117: ((OutputTransition) current) tim@117: .out(this.readOutputType(format), this.parseInputData( tim@117: format, "/action/out/params/input"), tim@117: outputStream, uuid, context.getMeta()); tim@68: } tim@68: } catch (TransitionException e) { tim@117: log.error(e, e); tim@89: throw new IOException(e.getMessage()); tim@68: } tim@68: } tim@73: tim@91: tim@68: protected String readOutputType(Document document){ tim@68: String value = Config.getStringXPath(document,"action/out/@name"); tim@68: return value; tim@68: } tim@52: }