Mercurial > dive4elements > gnv-client
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 } |