comparison 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
comparison
equal deleted inserted replaced
293:6b0ef2324d02 376:d8f3ef441bf2
1 /**
2 *
3 */
4 package de.intevation.gnv.artifacts;
5
6 import java.io.IOException;
7 import java.io.OutputStream;
8 import java.util.ArrayList;
9 import java.util.Collection;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.Map;
13
14 import javax.xml.xpath.XPathConstants;
15
16 import org.apache.log4j.Logger;
17 import org.w3c.dom.Document;
18 import org.w3c.dom.Element;
19 import org.w3c.dom.Node;
20 import org.w3c.dom.NodeList;
21
22 import de.intevation.artifactdatabase.Config;
23 import de.intevation.artifactdatabase.DefaultArtifact;
24 import de.intevation.artifactdatabase.XMLUtils;
25 import de.intevation.artifacts.ArtifactFactory;
26 import de.intevation.artifacts.ArtifactNamespaceContext;
27 import de.intevation.artifacts.CallContext;
28 import de.intevation.artifacts.CallMeta;
29 import de.intevation.gnv.artifacts.context.GNVArtifactContext;
30 import de.intevation.gnv.state.DefaultInputData;
31 import de.intevation.gnv.state.InputData;
32 import de.intevation.gnv.state.InputValue;
33 import de.intevation.gnv.state.OutputMode;
34 import de.intevation.gnv.state.OutputState;
35 import de.intevation.gnv.state.State;
36 import de.intevation.gnv.state.StateFactory;
37 import de.intevation.gnv.state.exception.StateException;
38 import de.intevation.gnv.transition.Transition;
39 import de.intevation.gnv.transition.TransitionFactory;
40 import de.intevation.gnv.utils.ArtifactXMLUtilities;
41
42 /**
43 * @author Tim Englich <tim.englich@intevation.de>
44 *
45 */
46 public abstract class GNVArtifactBase extends DefaultArtifact {
47 /**
48 * the logger, used to log exceptions and additonaly information
49 */
50 private static Logger log = Logger.getLogger(GNVArtifactBase.class);
51 /**
52 * The UID of this Class
53 */
54 private static final long serialVersionUID = -8907096744400741458L;
55
56 /**
57 * The Identifier for the Replacement of the Artifactname
58 */
59 public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER";
60
61 /**
62 * The XPATH to the XML-Fragment that should be used for the Configuration
63 */
64 public static final String XPATH_ARTIFACT_CONFIGURATION = "/artifact-database/artifacts/artifact[@name='"
65 + XPATH_IDENTIFIER_REPLACE
66 + "']";
67
68 /**
69 * The current State
70 */
71 protected State current = null;
72
73 /**
74 * The States that can be used
75 */
76 protected Map<String, State> states = null;
77
78 /**
79 * The Transitions which can switch between the different States.
80 */
81 protected Collection<Transition> transitions = null;
82
83 /**
84 * The Name of the Artifact
85 */
86 protected String name = null;
87
88 private ArtifactXMLUtilities xmlUtilities = new ArtifactXMLUtilities();
89
90 /**
91 * Constructor
92 */
93 public GNVArtifactBase() {
94 super();
95 }
96
97 /**
98 * @see de.intevation.artifactdatabase.DefaultArtifact#advance(org.w3c.dom.Document,
99 * de.intevation.artifacts.CallContext)
100 */
101 @Override
102 public Document advance(Document target, CallContext context) {
103 log.debug("GNVArtifactBase.advance");
104 Document result = XMLUtils.newDocument();
105 try {
106 if (this.current != null) {
107 String stateName = this.readStateName(target);
108 log.debug("Statename: " + stateName);
109 if (this.isStateCurrentlyReachable(stateName)) {
110 try {
111 State nextStep = this.states
112 .get(stateName);
113 // 1.Ergebnisse Berechnen
114 this.current.advance(super.identifier, context.getMeta());
115 // 2. Ergebnisse Übergeben
116 nextStep.putInputData(this.current.getInputData(),
117 super.identifier);
118 // 3. Umschalten auf neue Transistion
119 this.current = nextStep;
120
121 // 4. Initialisieren des nächsten Schrittes == Laden der Daten
122 this.current.initialize(super.identifier, context.getMeta());
123
124 result = new ArtifactXMLUtilities()
125 .createSuccessReport("Advance success",
126 XMLUtils.newDocument());
127 } catch (StateException e) {
128 log.error(e, e);
129 result = new ArtifactXMLUtilities()
130 .createExceptionReport(e
131 .getLocalizedMessage(), XMLUtils
132 .newDocument());
133 }
134 } else {
135 String msg = "Transitionsübergang wird nicht unterstützt.";
136 log.error(msg);
137 result = new ArtifactXMLUtilities().createExceptionReport(
138 msg, XMLUtils.newDocument());
139 }
140 } else {
141 String msg = "Kein State aktiviert.";
142 log.error(msg);
143 result = new ArtifactXMLUtilities().createExceptionReport(msg,
144 XMLUtils.newDocument());
145 }
146 } catch (Exception e) {
147 log.error(e, e);
148 result = new ArtifactXMLUtilities().createExceptionReport(e
149 .getLocalizedMessage(), XMLUtils.newDocument());
150 }
151 return result;
152 }
153
154
155 private boolean isStateCurrentlyReachable(String stateid){
156 log.debug("GNVArtifactBase.isStateCurrentlyReachable "+stateid);
157 Iterator<Transition> it = this.transitions.iterator();
158 String from = this.current.getID();
159 while (it.hasNext()){
160 Transition transition = it.next();
161 if (transition.getFrom().equals(from)){
162 if (transition.getTo().equals(stateid) && transition.isValid(this.current)){
163 return true;
164 }
165 }
166 }
167 return false;
168 }
169
170 public Document initialize (CallContext context) {
171 Document result = XMLUtils.newDocument();
172 try {
173 this.current.initialize(super.identifier, context.getMeta());
174 result = new ArtifactXMLUtilities()
175 .createSuccessReport("Initialize success",
176 XMLUtils.newDocument());
177 } catch (StateException e) {
178 log.error(e,e);
179 result = new ArtifactXMLUtilities().createExceptionReport(e
180 .getLocalizedMessage(), XMLUtils.newDocument());
181 }
182 return result;
183 }
184
185 protected String readStateName(Document document) {
186 String returnValue = Config.getStringXPath(document,
187 "action/target/@name");
188 return returnValue;
189 }
190
191 protected Node getConfigurationFragment(Document document) {
192 log.debug("GNVArtifactBase.getConfigurationFragment");
193 String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll(
194 XPATH_IDENTIFIER_REPLACE, this.name);
195 log.debug(xpathQuery);
196
197 Element configurationNode = (Element)Config.getNodeXPath(document, xpathQuery);
198
199 String link = configurationNode.getAttribute("xlink:href");
200 if (link != null ){
201 String absolutFileName = Config.replaceConfigDir(link);
202 configurationNode = (Element)new ArtifactXMLUtilities().readConfiguration(absolutFileName);
203 }
204
205 return configurationNode;
206 }
207
208 /**
209 * @see de.intevation.artifactdatabase.DefaultArtifact#feed(org.w3c.dom.Document,
210 * de.intevation.artifacts.CallContext)
211 */
212 @Override
213 public Document feed(Document target, CallContext context) {
214 log.debug("GNVArtifactBase.feed");
215 Document result = XMLUtils.newDocument();
216 try {
217 if (this.current != null) {
218 Collection<InputData> inputData = this.parseInputData(target,
219 "/action/data/input");
220 if (!inputData.isEmpty()){
221 this.current.putInputData(inputData, super.identifier);
222 result = new ArtifactXMLUtilities().createSuccessReport(
223 "Feed success", XMLUtils.newDocument());
224 }else{
225 String msg = "No Inputdata given. Please select at least one Entry.";
226 log.warn(msg);
227 result = new ArtifactXMLUtilities().createExceptionReport(msg,
228 XMLUtils.newDocument());
229 }
230 } else {
231 String msg = "No State instantiated";
232 log.warn(msg);
233 result = new ArtifactXMLUtilities().createExceptionReport(msg,
234 XMLUtils.newDocument());
235 }
236 } catch (StateException e) {
237 log.error(e, e);
238 result = new ArtifactXMLUtilities().createExceptionReport(e
239 .getLocalizedMessage(), XMLUtils.newDocument());
240 }
241 return result;
242 }
243
244 /**
245 * @see de.intevation.artifactdatabase.DefaultArtifact#setup(java.lang.String,
246 * java.lang.Object)
247 */
248 @Override
249 public void setup(String identifier, ArtifactFactory factory, Object context) {
250 log.debug("GNVArtifactBase.setup");
251 super.setup(identifier, factory, context);
252
253 Object localContext = context;
254 if (context instanceof CallContext) {
255 localContext = ((CallContext) context).globalContext();
256
257 }
258
259 if (localContext instanceof GNVArtifactContext) {
260 GNVArtifactContext gnvContext = (GNVArtifactContext) localContext;
261 Document doc = gnvContext.getConfig();
262 Node artifactNode = this.getConfigurationFragment(doc);
263
264 NodeList stateList = Config.getNodeSetXPath(artifactNode,
265 "states/state");
266 this.states = new HashMap<String, State>(stateList
267 .getLength());
268 for (int i = 0; i < stateList.getLength(); i++) {
269 State tmpState = StateFactory.getInstance()
270 .createState(stateList.item(i));
271 if (tmpState != null) {
272 this.states.put(tmpState.getID(), tmpState);
273 if (this.current == null) {
274 this.current = tmpState;
275 }
276 }
277 }
278
279 NodeList transitionList = Config.getNodeSetXPath(artifactNode,
280 "states/transition");
281 this.transitions = new ArrayList<Transition>(transitionList.getLength());
282 for (int i = 0; i < transitionList.getLength(); i++) {
283 Transition tmpTransition = TransitionFactory.getInstance()
284 .createTransition(transitionList.item(i));
285 if (tmpTransition != null) {
286 this.transitions.add(tmpTransition);
287 }
288 }
289
290 }
291 }
292
293
294
295 protected Document createDescibeOutput(CallMeta callMeta, String uuid, boolean incudeUI) {
296 log.debug("GNVArtifactBase.createDescibeOutput");
297 Document document = XMLUtils.newDocument();
298 Element rootNode = this.createRootNode(document);
299 this.createHeader(rootNode, document, "describe");
300 this.createOutputs(rootNode, document);
301 this.createCurrentState(rootNode, document);
302 this.createReachableStates(rootNode, document);
303 this.createModel(rootNode, document);
304 if (incudeUI){
305 this.createUserInterface(rootNode, document, callMeta, uuid);
306 }
307 return document;
308 }
309
310 protected boolean getIncludeUIFromDocument(Document document){
311 String value = Config.getStringXPath(document, "action/include-ui");
312 boolean includeUI = false;
313 if (value != null){
314 includeUI = Boolean.parseBoolean(value);
315 }
316 return includeUI;
317 }
318
319 protected Element createRootNode(Document document) {
320 Element rootNode = xmlUtilities.createArtifactElement(document,
321 "result");
322 document.appendChild(rootNode);
323 return rootNode;
324 }
325
326 protected void createHeader(Element parent, Document document,
327 String documentType) {
328 Element typeNode = xmlUtilities.createArtifactElement(document, "type");
329 typeNode.setAttribute("name", documentType);
330 parent.appendChild(typeNode);
331
332 Element uuidNode = xmlUtilities.createArtifactElement(document, "uuid");
333 uuidNode.setAttribute("value", super.identifier);
334 parent.appendChild(uuidNode);
335
336 Element hashNode = xmlUtilities.createArtifactElement(document, "hash");
337 hashNode.setAttribute("value", this.hash());
338 parent.appendChild(hashNode);
339 }
340
341 protected void createReachableStates(Element parent, Document document) {
342 Element stateNode = xmlUtilities.createArtifactElement(document,
343 "reachable-states");
344 if (this.current != null) {
345 Iterator<Transition> transitions = this.transitions.iterator();
346 while (transitions.hasNext()) {
347 Transition tmpTransition = transitions.next();
348 if (tmpTransition.getFrom().equals(current.getID()) &&
349 tmpTransition.isValid(this.current)){
350 Element currentNode = xmlUtilities.createArtifactElement(
351 document, "state");
352 currentNode.setAttribute("name", tmpTransition.getTo());
353 log.debug("Reachable State: " + tmpTransition.getTo());
354 currentNode.setAttribute("description",
355 this.states.get(tmpTransition.getTo())
356 .getDescription());
357 stateNode.appendChild(currentNode);
358 }
359 }
360 }
361 parent.appendChild(stateNode);
362 }
363
364 protected void createCurrentState(Element parent, Document document) {
365 Element stateNode = xmlUtilities.createArtifactElement(document,
366 "state");
367 stateNode.setAttribute("name", this.current.getID());
368 stateNode.setAttribute("description", this.current.getDescription());
369 parent.appendChild(stateNode);
370 }
371
372 protected void createModel(Element parent, Document document) {
373 Element modelNode = xmlUtilities.createArtifactElement(document,
374 "model");
375 if (this.current != null) {
376 Collection<InputValue> inputValues = this.current
377 .getRequiredInputValues();
378 if (inputValues != null) {
379 Iterator<InputValue> it = inputValues.iterator();
380 while (it.hasNext()) {
381 InputValue inputValue = it.next();
382 Element inputNode = xmlUtilities.createArtifactElement(
383 document, "input");
384 inputNode.setAttribute("name", inputValue.getName());
385 inputNode.setAttribute("type", inputValue.getType());
386 modelNode.appendChild(inputNode);
387 }
388 }
389 }
390 parent.appendChild(modelNode);
391 }
392
393 protected void createUserInterface(Element parent, Document document,
394 CallMeta callMeta, String uuid) {
395 Element uiNode = xmlUtilities.createArtifactElement(document, "ui");
396
397 if (this.current != null) {
398 this.current.describe(document, uiNode, callMeta, uuid);
399 }
400
401 parent.appendChild(uiNode);
402 }
403
404 protected void createOutputs(Element parent, Document document) {
405 log.debug("GNVArtifactBase.createOutputs");
406 Element outputsNode = xmlUtilities.createArtifactElement(document,
407 "outputs");
408 if (this.current instanceof OutputState) {
409 Collection<OutputMode> outputModes = ((OutputState) this.current)
410 .getOutputModes();
411 if (outputModes != null) {
412 Iterator<OutputMode> it = outputModes.iterator();
413 while (it.hasNext()) {
414 OutputMode outputMode = it.next();
415 log.debug("Write Outputnode for " + outputMode.toString());
416 Element outputModeNode = xmlUtilities
417 .createArtifactElement(document, "output");
418 outputModeNode.setAttribute("name", outputMode.getName());
419 outputModeNode.setAttribute("description", outputMode
420 .getDescription());
421 outputModeNode.setAttribute("mime-type", outputMode
422 .getMimeType());
423 outputsNode.appendChild(outputModeNode);
424
425 Collection<InputValue> inputParameters = outputMode
426 .getInputParameters();
427 if (inputParameters != null) {
428 Element inputParametersNode = xmlUtilities
429 .createArtifactElement(document, "parameter");
430 outputModeNode.appendChild(inputParametersNode);
431 Iterator<InputValue> it2 = inputParameters.iterator();
432 while (it2.hasNext()) {
433 InputValue inputValue = it2.next();
434 Element inputParameterNode = xmlUtilities
435 .createArtifactElement(document,
436 "parameter");
437 inputParametersNode.appendChild(inputParameterNode);
438 inputParameterNode.setAttribute("name", inputValue
439 .getName());
440 inputParameterNode.setAttribute("type", inputValue
441 .getType());
442 inputParameterNode.setAttribute("value", inputValue
443 .getDefaultValue());
444 }
445 }
446 }
447 } else {
448 log.warn("No Outputmodes given.");
449 }
450 }
451 parent.appendChild(outputsNode);
452 }
453
454 protected Collection<InputData> parseInputData(Document document,
455 String xPath) {
456 log.debug("GNVArtifactBase.parseInputData");
457 HashMap<String, InputData> returnValue = null;
458
459 log.debug(new ArtifactXMLUtilities().writeDocument2String(document));
460
461 NodeList inputElemets = (NodeList) XMLUtils.xpath(document, xPath,
462 XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);// Config.getNodeSetXPath(document,
463 // "");
464 if (inputElemets != null) {
465 returnValue = new HashMap<String, InputData>(inputElemets
466 .getLength());
467 for (int i = 0; i < inputElemets.getLength(); i++) {
468 Element inputDataNode = (Element)inputElemets.item(i);
469 String name = inputDataNode.getAttribute("name");
470 String value = inputDataNode.getAttribute("value");
471
472 if (returnValue.containsKey(name)) {
473 InputData inputData = returnValue.get(name);
474 inputData.concartValue(value);
475 log.debug(inputData.toString());
476 returnValue.put(name, inputData);
477 } else {
478 InputData inputData = new DefaultInputData(name, value);
479
480 returnValue.put(name, inputData);
481 }
482 }
483 }
484 return returnValue.values();
485 }
486
487 /**
488 * @see de.intevation.artifactdatabase.DefaultArtifact#out(org.w3c.dom.Document,
489 * java.io.OutputStream, de.intevation.artifacts.CallContext)
490 */
491 @Override
492 public void out(Document format, OutputStream outputStream,
493 CallContext context) throws IOException {
494 log.debug("TGNVArtifactBase.out");
495 try {
496
497 if (current != null && current instanceof OutputState) {
498 ((OutputState) current)
499 .out(format, this.parseInputData(
500 format, "/action/out/params/input"),
501 outputStream, super.identifier, context);
502 }
503 } catch (StateException e) {
504 log.error(e, e);
505 throw new IOException(e.getMessage());
506 }
507 }
508
509 protected String readOutputType(Document document) {
510 String value = Config.getStringXPath(document, "action/out/@name");
511 return value;
512 }
513 }

http://dive4elements.wald.intevation.org