comparison gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java @ 1119:7c4f81f74c47

merged gnv-artifacts
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:00 +0200
parents c01c220312d0
children
comparison
equal deleted inserted replaced
1027:fca4b5eb8d2f 1119:7c4f81f74c47
1 /*
2 * Copyright (c) 2010 by Intevation GmbH
3 *
4 * This program is free software under the LGPL (>=v2.1)
5 * Read the file LGPL.txt coming with the software for details
6 * or visit http://www.gnu.org/licenses/ if it does not exist.
7 */
8
9 package de.intevation.gnv.artifacts;
10
11 import de.intevation.artifacts.common.utils.Config;
12 import de.intevation.artifactdatabase.ProxyArtifact;
13 import de.intevation.artifacts.common.utils.XMLUtils;
14
15 import de.intevation.artifacts.Artifact;
16 import de.intevation.artifacts.ArtifactDatabase;
17 import de.intevation.artifacts.ArtifactFactory;
18 import de.intevation.artifacts.ArtifactNamespaceContext;
19 import de.intevation.artifacts.CallContext;
20 import de.intevation.artifacts.CallMeta;
21 import de.intevation.artifacts.GlobalContext;
22
23 import de.intevation.gnv.artifacts.context.GNVArtifactContext;
24
25 import de.intevation.gnv.artifacts.fis.product.Product;
26
27 import de.intevation.gnv.artifacts.ressource.RessourceFactory;
28
29 import de.intevation.gnv.state.AutoResumeState;
30 import de.intevation.gnv.state.DefaultInputData;
31 import de.intevation.gnv.state.ExportMode;
32 import de.intevation.gnv.state.InputData;
33 import de.intevation.gnv.state.InputValue;
34 import de.intevation.gnv.state.OutputMode;
35 import de.intevation.gnv.state.OutputState;
36 import de.intevation.gnv.state.State;
37 import de.intevation.gnv.state.StateFactory;
38
39 import de.intevation.gnv.state.exception.StateException;
40
41 import de.intevation.gnv.transition.Transition;
42 import de.intevation.gnv.transition.TransitionFactory;
43
44 import de.intevation.gnv.utils.ArtifactXMLUtilities;
45
46 import java.io.IOException;
47 import java.io.OutputStream;
48
49 import java.util.ArrayList;
50 import java.util.Collection;
51 import java.util.HashMap;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Locale;
55 import java.util.Map;
56
57 import javax.xml.xpath.XPathConstants;
58
59 import org.apache.log4j.Logger;
60
61 import org.w3c.dom.Document;
62 import org.w3c.dom.Element;
63 import org.w3c.dom.Node;
64 import org.w3c.dom.NodeList;
65
66 /**
67 * This is the major gnv artifact and handles the requests specified in
68 * <code>de.intevation.artifactdatabase.Artifact</code>.
69 *
70 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
71 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
72 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
73 */
74 public abstract class GNVArtifactBase extends GNVDefaultArtifact
75 implements PreSettingArtifact {
76
77 /**
78 * the logger, used to log exceptions and additonaly information
79 */
80 private static Logger log = Logger.getLogger(GNVArtifactBase.class);
81 /**
82 * The UID of this Class
83 */
84 private static final long serialVersionUID = -8907096744400741458L;
85
86 /**
87 * The Identifier for the Replacement of the Artifactname
88 */
89 public static final String XPATH_IDENTIFIER_REPLACE = "IDENTIFIER";
90
91 /**
92 * The XPATH to the XML-Fragment that should be used for the Configuration
93 */
94 public static final String XPATH_ARTIFACT_CONFIGURATION = "/artifact-database/artifacts/artifact[@name='"
95 + XPATH_IDENTIFIER_REPLACE
96 + "']";
97
98 public static final String XPATH_STATIC_NODE = "/art:result/art:ui/art:static";
99
100 public static final String XPATH_INPUT_DATA = "/art:action/art:data/art:input";
101
102 public static final String XPATH_INCLUDE_UI = "/art:action/art:include-ui";
103
104 public static final String XPATH_TARGET_NAME = "/art:action/art:target/@name";
105
106 public static final String XPATH_OUTPUT_NAME = "/art:action/art:out/@name";
107
108 public static final String XPATH_OUTPUT_PARAMS = "/art:action/art:out/art:params/art:input";
109
110 public static final String INITIAL_STATE = "product";
111
112 /**
113 * The current State
114 */
115 protected State current = null;
116
117 /**
118 * The States that can be used
119 */
120 protected Map<String, State> states = null;
121
122 /**
123 * The Transitions which can switch between the different States.
124 */
125 protected Collection<Transition> transitions = null;
126
127 /**
128 * The current product
129 */
130 protected Product product;
131
132 /**
133 * The Name of the Artifact
134 */
135 protected String name = null;
136
137 /**
138 * The Presettings of InputData which can be used to
139 * travel through the States in different Ways or
140 * manipulate the InputData
141 */
142 private Map<String, InputData> preSettings = null;
143
144 /**
145 * Constructor
146 */
147 public GNVArtifactBase() {
148 super();
149 }
150
151
152 /**
153 * This method handles request for changing the current state of an
154 * artifact. It is possible to step forward, backward, or to the initial
155 * state for choosing a fis.
156 */
157 @Override
158 public Document advance(Document target, CallContext context) {
159 log.debug("GNVArtifactBase.advance()");
160
161 Document result = XMLUtils.newDocument();
162 String targetState = XMLUtils.xpathString(
163 target, XPATH_TARGET_NAME, ArtifactNamespaceContext.INSTANCE
164 );
165
166 // no current state...
167 if (current == null) {
168 log.warn("No current state. Advance not possible.");
169
170 result = createReport(
171 result,
172 "exceptionreport",
173 "exception",
174 "No State activated."
175 );
176
177 return result;
178 }
179
180 State next = null;
181
182 try {
183
184 // step forward
185 if (isStateCurrentlyReachable(targetState)) {
186
187 next = states.get(targetState);
188
189 boolean success = go2NextState(context, result, next);
190
191 if (success){
192 result = createReport(
193 result, "result", "success", "Advance success"
194 );
195 }else{
196 result = ArtifactXMLUtilities.
197 createExceptionReport("Error while going to next State.",
198 XMLUtils.newDocument());
199 }
200 }
201
202 // step backward
203 else if((next = getPreviousState(current, targetState, context))
204 != null)
205 {
206
207 if (current != null) {
208 current.endOfLife(context.globalContext());
209 }
210
211 current = next;
212
213 // 2. Transfer Results
214 current.reset(identifier);
215
216 result = createReport(
217 result, "result", "success", "Advance success"
218 );
219 }
220
221 // goto initial step
222 else if(targetState.equals(INITIAL_STATE)) {
223
224 String fis = product.getArtifactFactory();
225 ArtifactDatabase db = context.getDatabase();
226 GNVProductArtifactFactory fac = (GNVProductArtifactFactory)
227 db.getInternalArtifactFactory(fis);
228
229 Artifact select = fac.createArtifact(
230 identifier,
231 (GlobalContext) context.globalContext(),
232 context.getMeta(),
233 null);
234
235 context.putContextValue(ProxyArtifact.REPLACE_PROXY, select);
236
237 result = createReport(
238 result, "result", "success", "Advance success"
239 );
240 }
241
242 // advance not possible
243 else {
244 log.warn("advance not possible for target: " + targetState);
245 result = createReport(
246 result,
247 "exceptionreport",
248 "exception",
249 "Statetransition not supported"
250 );
251 }
252 }
253 catch (StateException se) {
254 log.error(se, se);
255 result = createReport(
256 result,
257 "exceptionreport",
258 "exception",
259 se.getLocalizedMessage()
260 );
261 }
262
263 return result;
264 }
265
266
267 private boolean go2NextState(CallContext context, Document result,
268 State next) throws StateException {
269 // 2. Transfer Results
270 next.putInputData(current.getInputData(), identifier);
271 next.setParent(current);
272 next.setPreSettings(this.preSettings);
273
274 // 3. Switch to next State
275 current = next;
276
277 // 4. Initialize next Step
278 current.initialize(identifier, context);
279
280 return true;
281 }
282
283
284 protected Document createReport(
285 Document document,
286 String nodeName,
287 String state,
288 String msg
289 ) {
290 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
291 document,
292 ArtifactNamespaceContext.NAMESPACE_URI,
293 ArtifactNamespaceContext.NAMESPACE_PREFIX
294 );
295
296 Element reportNode = creator.create(nodeName);
297 Element stateNode = creator.create(state);
298
299 stateNode.setTextContent(msg);
300 reportNode.appendChild(stateNode);
301 document.appendChild(reportNode);
302
303 return document;
304
305 }
306
307
308 /**
309 * Step back to the previous state specified by <code>name</code>.
310 */
311 protected State getPreviousState(
312 State current, String name, CallContext context)
313 {
314 if (current == null) {
315 return null;
316 }
317
318 if (current.getID().equals(name)) {
319 return current;
320 }
321 else {
322 current.endOfLife(context);
323 return getPreviousState(current.getParent(), name, context);
324 }
325 }
326
327
328 private boolean isStateCurrentlyReachable(String stateid){
329 Iterator<Transition> it = this.transitions.iterator();
330 String from = this.current.getID();
331 while (it.hasNext()){
332 Transition transition = it.next();
333 if (transition.getFrom().equals(from)){
334 if (transition.getTo().equals(stateid) && transition.isValid(this.current)){
335 return true;
336 }
337 }
338 }
339 return false;
340 }
341
342
343 public Document initialize(CallContext context) {
344 Document result = XMLUtils.newDocument();
345 try {
346 this.current.initialize(super.identifier, context);
347
348 if (this.current instanceof AutoResumeState){
349 // Jump to next State using the Transitions.
350 State next = this.getNextReachableState(this.current);
351 if (next != null){
352 boolean success = go2NextState(context, result, next);
353 if (success){
354 result = ArtifactXMLUtilities
355 .createSuccessReport("Initialize success",
356 XMLUtils.newDocument());
357 }else{
358 result = ArtifactXMLUtilities.
359 createExceptionReport(
360 "Error while going to next State.",
361 XMLUtils.newDocument());
362 }
363 }else{
364 result = ArtifactXMLUtilities.
365 createExceptionReport("No propper State found.",
366 XMLUtils.newDocument());
367 }
368 }else{
369 result = ArtifactXMLUtilities
370 .createSuccessReport("Initialize success",
371 XMLUtils.newDocument());
372 }
373 } catch (StateException e) {
374 log.error(e,e);
375 result = ArtifactXMLUtilities.createExceptionReport(e
376 .getLocalizedMessage(), XMLUtils.newDocument());
377 }
378 return result;
379 }
380
381 /**
382 * Step forward to the next reachable state.
383 * @param current Current state.
384 * @return Reachable state.
385 */
386 protected State getNextReachableState(State current){
387 Iterator<Transition> it = this.transitions.iterator();
388 String from = current.getID();
389 while (it.hasNext()){
390 Transition transition = it.next();
391 if (transition.getFrom().equals(from)){
392 if (transition.isValid(current)){
393 return this.states.get(transition.getTo());
394 }
395 }
396 }
397 return null;
398 }
399
400
401 protected String readStateName(Document document) {
402 String returnValue = XMLUtils.xpathString(
403 document, XPATH_TARGET_NAME, ArtifactNamespaceContext.INSTANCE);
404 return returnValue;
405 }
406
407
408 protected Node getConfigurationFragment(Document document) {
409 log.debug("GNVArtifactBase.getConfigurationFragment");
410 String xpathQuery = XPATH_ARTIFACT_CONFIGURATION.replaceAll(
411 XPATH_IDENTIFIER_REPLACE, this.name);
412
413 Element configurationNode = (Element)Config.getNodeXPath(document, xpathQuery);
414
415 String link = configurationNode.getAttribute("xlink:href");
416 if (link != null ){
417 String absolutFileName = Config.replaceConfigDir(link);
418 configurationNode = (Element)new ArtifactXMLUtilities().readConfiguration(absolutFileName);
419 }
420
421 return configurationNode;
422 }
423
424 /**
425 * Insert new data included in <code>target</code> into the current state.
426 * @param target XML document which contains data.
427 * @param context CallContext
428 * @return XML document with success or error message.
429 */
430 @Override
431 public Document feed(Document target, CallContext context) {
432 log.debug("GNVArtifactBase.feed");
433 RessourceFactory fac = RessourceFactory.getInstance();
434 Locale[] locales = fac.getLocales();
435 Locale locale = context.getMeta().getPreferredLocale(locales);
436 Document result = XMLUtils.newDocument();
437
438 try {
439 if (this.current != null) {
440 Collection<InputData> inputData = this.parseInputData(
441 target,
442 XPATH_INPUT_DATA);
443
444 if (!inputData.isEmpty()){
445 result = current.feed(context, inputData, super.identifier);
446 }else{
447 //String msg = "No Inputdata given. Please select at least one Entry.";
448 String msg = fac.getRessource(
449 locale,
450 EXCEPTION_NO_INPUT,
451 EXCEPTION_NO_INPUT);
452
453 log.warn(msg);
454 result = ArtifactXMLUtilities.createInputExceptionReport(
455 msg,
456 XMLUtils.newDocument());
457 }
458 } else {
459 String msg = "No State instantiated";
460 log.warn(msg);
461 result = ArtifactXMLUtilities.createExceptionReport(msg,
462 XMLUtils.newDocument());
463 }
464 } catch (StateException e) {
465 log.error(e, e);
466 result = ArtifactXMLUtilities.createExceptionReport(e
467 .getLocalizedMessage(), XMLUtils.newDocument());
468 }
469 return result;
470 }
471
472
473 /**
474 * Describe the current artifact.
475 * @return The description of the current artifact.
476 */
477 @Override
478 public Document describe(Document data, CallContext context) {
479 log.debug("GNVArtifactBase.describe");
480
481 Document document = createDescibeOutput(
482 context,
483 identifier,
484 getIncludeUIFromDocument(data)
485 );
486
487 return document;
488 }
489
490 /**
491 * Initialse this artifact and insert some data if <code>data</code>
492 * contains necessary information for this artifact.
493 */
494 @Override
495 public void setup(
496 String identifier,
497 ArtifactFactory factory,
498 Object context,
499 CallMeta meta,
500 Document data
501 ) {
502 log.debug("GNVArtifactBase.setup");
503 super.setup(identifier, factory, context, meta, data);
504
505 Object localContext = context;
506 if (context instanceof CallContext) {
507 localContext = ((CallContext) context).globalContext();
508
509 }
510
511 if (localContext instanceof GNVArtifactContext) {
512 GNVArtifactContext gnvContext = (GNVArtifactContext) localContext;
513 Document doc = gnvContext.getConfig();
514 Node artifactNode = this.getConfigurationFragment(doc);
515
516 NodeList stateList = Config.getNodeSetXPath(artifactNode,
517 "states/state");
518 this.states = new HashMap<String, State>(stateList
519 .getLength());
520 for (int i = 0; i < stateList.getLength(); i++) {
521 State tmpState = StateFactory.getInstance()
522 .createState(stateList.item(i));
523 if (tmpState != null) {
524 log.debug("Initiate new state: " + tmpState.getID());
525 this.states.put(tmpState.getID(), tmpState);
526 if (this.current == null) {
527 this.current = tmpState;
528 }
529 }
530 }
531
532 NodeList transitionList = Config.getNodeSetXPath(artifactNode,
533 "states/transition");
534 this.transitions = new ArrayList<Transition>(transitionList.getLength());
535 for (int i = 0; i < transitionList.getLength(); i++) {
536 Transition tmpTransition = TransitionFactory.getInstance()
537 .createTransition(transitionList.item(i));
538 if (tmpTransition != null) {
539 this.transitions.add(tmpTransition);
540 }
541 }
542
543 }
544 }
545
546
547 /**
548 * Create the xml document returned in {@link #describe(org.w3c.dom.Document,
549 * de.intevation.artifacts.CallContext)}
550 */
551 protected Document createDescibeOutput(
552 CallContext context,
553 String uuid,
554 boolean incudeUI
555 ) {
556 log.debug("GNVArtifactBase.createDescibeOutput");
557 Document document = XMLUtils.newDocument();
558
559 XMLUtils.ElementCreator creator = new XMLUtils.ElementCreator(
560 document,
561 ArtifactNamespaceContext.NAMESPACE_URI,
562 ArtifactNamespaceContext.NAMESPACE_PREFIX
563 );
564 Element rootNode = this.createRootNode(creator, document);
565 this.createHeader(creator, rootNode, document, "describe");
566 this.createOutputs(creator, rootNode, document);
567 this.createCurrentState(creator, rootNode, document);
568 this.createReachableStates(creator, rootNode, document);
569 this.createModel(creator, rootNode, document);
570 if (incudeUI){
571 this.createUserInterface(creator, rootNode, document, context, uuid);
572 }
573
574 return document;
575 }
576
577 /**
578 * Determine the wish to append the user interface description to the
579 * describe document.
580 *
581 * @return True, if the user interface description should be appended,
582 * otherwise false.
583 */
584 protected boolean getIncludeUIFromDocument(Document document){
585 String value = XMLUtils.xpathString(
586 document, XPATH_INCLUDE_UI, ArtifactNamespaceContext.INSTANCE);
587
588 boolean includeUI = false;
589 if (value != null){
590 includeUI = Boolean.parseBoolean(value);
591 }
592 return includeUI;
593 }
594
595
596 protected Element createRootNode(
597 XMLUtils.ElementCreator creator,
598 Document document
599 ) {
600 Element rootNode = creator.create("result");
601 document.appendChild(rootNode);
602 return rootNode;
603 }
604
605 /**
606 * Append information about the current artifact (uuid, hash).
607 */
608 protected void createHeader(
609 XMLUtils.ElementCreator creator,
610 Element parent,
611 Document document,
612 String documentType
613 ) {
614 Element typeNode = creator.create("type");
615 creator.addAttr(typeNode, "name", documentType);
616 parent.appendChild(typeNode);
617
618 Element uuidNode = creator.create("uuid");
619 creator.addAttr(uuidNode, "value", super.identifier);
620 parent.appendChild(uuidNode);
621
622 Element hashNode = creator.create("hash");
623 creator.addAttr(hashNode, "value", this.hash());
624 parent.appendChild(hashNode);
625 }
626
627 /**
628 * Create the fis select box.
629 */
630 protected Element createSelectBox(
631 XMLUtils.ElementCreator artCreator,
632 XMLUtils.ElementCreator creator,
633 Document document,
634 CallContext context
635 ) {
636 RessourceFactory resource = RessourceFactory.getInstance();
637 CallMeta callMeta = (CallMeta) context.getMeta();
638 String productName = product.getName();
639
640 Element selectNode = creator.create("select1");
641 creator.addAttr(selectNode, "ref", "product");
642 artCreator.addAttr(selectNode, "state", INITIAL_STATE, true);
643
644
645 Element labelNode = creator.create("label");
646 labelNode.setTextContent(
647 resource.getRessource(callMeta.getLanguages(), "product", "product")
648 );
649
650 Element choicesNode = creator.create("choices");
651
652 Element itemNode = creator.create("item");
653 creator.addAttr(itemNode, "selected", "true");
654
655 Element choiceLabel = creator.create("label");
656 choiceLabel.setTextContent(resource.getRessource(
657 callMeta.getLanguages(),
658 productName,
659 productName
660 ));
661
662 Element choiceValue = creator.create("value");
663 choiceValue.setTextContent(productName);
664
665 itemNode.appendChild(choiceLabel);
666 itemNode.appendChild(choiceValue);
667 choicesNode.appendChild(itemNode);
668
669 selectNode.appendChild(labelNode);
670 selectNode.appendChild(choicesNode);
671
672 return selectNode;
673 }
674
675
676 /**
677 * Insert all reachable states into the describe document returned by
678 * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)}
679 */
680 protected void createReachableStates(
681 XMLUtils.ElementCreator creator,
682 Element parent,
683 Document document
684 ) {
685 Element stateNode = creator.create("reachable-states");
686 if (this.current != null) {
687
688 // add future states
689 Iterator<Transition> transitions = this.transitions.iterator();
690 while (transitions.hasNext()) {
691 Transition tmpTransition = transitions.next();
692 if (tmpTransition.getFrom().equals(current.getID()) &&
693 tmpTransition.isValid(this.current)){
694 Element currentNode = creator.create("state");
695 creator.addAttr(currentNode, "name", tmpTransition.getTo());
696 creator.addAttr(
697 currentNode,
698 "description",
699 this.states.get(tmpTransition.getTo()).getDescription());
700 stateNode.appendChild(currentNode);
701 }
702 }
703
704
705 // add old states
706 appendOldReachableStates(creator, stateNode, current);
707 }
708 parent.appendChild(stateNode);
709 }
710
711
712 /**
713 * Insert states which have been visited by this artifact into the xml
714 * document returned by {@link #describe(org.w3c.dom.Document,
715 * de.intevation.artifacts.CallContext)}
716 */
717 protected void appendOldReachableStates(
718 XMLUtils.ElementCreator creator,
719 Element parent,
720 State state
721 ) {
722 if (state == null)
723 return;
724
725 while (state != null) {
726 Element currentNode = creator.create("state");
727 creator.addAttr(currentNode, "name", state.getID());
728 creator.addAttr(currentNode, "description", state.getDescription());
729 parent.appendChild(currentNode);
730
731 state = state.getParent();
732 }
733 }
734
735
736 /**
737 * Insert the current state into the xml document returned by
738 * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)}
739 */
740 protected void createCurrentState(
741 XMLUtils.ElementCreator creator,
742 Element parent,
743 Document document
744 ) {
745 Element stateNode = creator.create("state");
746 creator.addAttr(stateNode, "name", this.current.getID());
747 creator.addAttr(stateNode, "description", this.current.getDescription());
748 parent.appendChild(stateNode);
749 }
750
751
752 protected void createModel(
753 XMLUtils.ElementCreator creator,
754 Element parent,
755 Document document
756 ) {
757 Element modelNode = creator.create("model");
758 if (this.current != null) {
759 Collection<InputValue> inputValues = this.current
760 .getRequiredInputValues();
761 if (inputValues != null) {
762 Iterator<InputValue> it = inputValues.iterator();
763 while (it.hasNext()) {
764 InputValue inputValue = it.next();
765 Element inputNode = creator.create("input");
766 creator.addAttr(inputNode, "name", inputValue.getName());
767 creator.addAttr(inputNode, "type", inputValue.getType());
768 modelNode.appendChild(inputNode);
769 }
770 }
771 }
772 parent.appendChild(modelNode);
773 }
774
775 /**
776 * Append the user interface description to the document returned by
777 * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)}
778 * @param creator XML element creator.
779 * @param parent New elements are appended to this node.
780 * @param document Current document.
781 * @param context CallContext
782 * @param uuid The uuid of the artifact.
783 */
784 protected void createUserInterface(
785 XMLUtils.ElementCreator creator,
786 Element parent,
787 Document document,
788 CallContext context,
789 String uuid
790 ) {
791 XMLUtils.ElementCreator xCreator = new XMLUtils.ElementCreator(
792 document,
793 XMLUtils.XFORM_URL,
794 XMLUtils.XFORM_PREFIX
795 );
796
797 Element uiNode = creator.create("ui");
798 Element staticNode = creator.create("static");
799 Element dynamic = creator.create("dynamic");
800
801 uiNode.appendChild(staticNode);
802 uiNode.appendChild(dynamic);
803
804 parent.appendChild(uiNode);
805
806 // append fis to dynamic part
807 appendFis(document, staticNode, context, product.getArtifactFactory());
808
809 if (this.current != null) {
810 Element staticUI = createSelectBox(
811 creator, xCreator, document, context
812 );
813 staticNode.appendChild(staticUI);
814
815 this.current.describe(
816 document, uiNode, context, uuid
817 );
818 }
819 }
820
821
822 /**
823 * Append possible output targets to the document returned by
824 * {@link #describe(org.w3c.dom.Document, de.intevation.artifacts.CallContext)}
825 * @param creator Used to create xml elements.
826 * @param parent New elements are appended to this node.
827 * @param document The current document.
828 */
829 protected void createOutputs(
830 XMLUtils.ElementCreator creator,
831 Element parent,
832 Document document
833 ) {
834 log.debug("GNVArtifactBase.createOutputs");
835 Element outputsNode = creator.create("outputs");
836 if (this.current instanceof OutputState) {
837 Collection<OutputMode> outputModes = ((OutputState) this.current)
838 .getOutputModes();
839 if (outputModes != null) {
840 Iterator<OutputMode> it = outputModes.iterator();
841 while (it.hasNext()) {
842 OutputMode outputMode = it.next();
843 log.debug("Write Outputnode for " + outputMode.toString());
844 Element outputModeNode = creator.create("output");
845 creator.addAttr(
846 outputModeNode, "name", outputMode.getName());
847 creator.addAttr(
848 outputModeNode, "description", outputMode.getDescription());
849 creator.addAttr(
850 outputModeNode, "mime-type", outputMode.getMimeType());
851 outputsNode.appendChild(outputModeNode);
852
853 Collection<InputValue> inputParameters = outputMode
854 .getInputParameters();
855 if (inputParameters != null) {
856 Element inputParametersNode = creator.create("parameter");
857 outputModeNode.appendChild(inputParametersNode);
858 Iterator<InputValue> it2 = inputParameters.iterator();
859 while (it2.hasNext()) {
860 InputValue inputValue = it2.next();
861 Element inputParameterNode =
862 creator.create("parameter");
863 creator.addAttr(
864 inputParameterNode, "name", inputValue.getName());
865 creator.addAttr(
866 inputParameterNode, "type", inputValue.getType());
867 creator.addAttr(
868 inputParameterNode, "value", inputValue.getDefaultValue());
869 inputParametersNode.appendChild(inputParameterNode);
870 }
871 }
872
873 // append export modes
874 List<ExportMode> exportModes = outputMode.getExportModes();
875 if (exportModes != null) {
876 Element exports = creator.create("exports");
877 outputModeNode.appendChild(exports);
878
879 for (ExportMode exp: exportModes) {
880 Element export = creator.create("export");
881 creator.addAttr(
882 export, "name", exp.getName());
883 creator.addAttr(
884 export, "description", exp.getDescription());
885 creator.addAttr(
886 export, "mime-type", exp.getMimeType());
887
888 exports.appendChild(export);
889 }
890 }
891 }
892 } else {
893 log.warn("No Outputmodes given.");
894 }
895 }
896 parent.appendChild(outputsNode);
897 }
898
899 /**
900 * Parse input data from feed-document.
901 * @param document Feed-document
902 * @param xPath Path to input data.
903 * @return A collection with InputData objects.
904 */
905 protected Collection<InputData> parseInputData(Document document,
906 String xPath) {
907 HashMap<String, InputData> returnValue = null;
908
909 NodeList inputElemets = (NodeList) XMLUtils.xpath(document, xPath,
910 XPathConstants.NODESET, ArtifactNamespaceContext.INSTANCE);
911 if (inputElemets != null) {
912 returnValue = new HashMap<String, InputData>();
913
914 for (int i = 0; i < inputElemets.getLength(); i++) {
915 Element inputDataNode = (Element)inputElemets.item(i);
916 String name = inputDataNode.getAttribute("name");
917 String value = inputDataNode.getAttribute("value");
918
919 if (returnValue.containsKey(name)) {
920 InputData inputData = returnValue.get(name);
921 inputData.concartValue(value);
922 log.debug(inputData.toString());
923 returnValue.put(name, inputData);
924 } else {
925 InputData inputData = new DefaultInputData(name, value);
926
927 returnValue.put(name, inputData);
928 }
929 }
930 }
931 return returnValue.values();
932 }
933
934 /**
935 * Call an output target (e.g. chart, wms, etc.)
936 * @param format XML document which contains some further information about
937 * the desired output.
938 * @param outputStream Stream used for writing the output.
939 * @param context CallContext
940 * @throws IOException If an error occured while writing the result to the
941 * output stream.
942 */
943 @Override
944 public void out(Document format, OutputStream outputStream,
945 CallContext context) throws IOException {
946 log.debug("TGNVArtifactBase.out");
947 try {
948
949 if (current != null && current instanceof OutputState) {
950 ((OutputState) current)
951 .out(format, this.parseInputData(
952 format, XPATH_OUTPUT_PARAMS),
953 outputStream, super.identifier, context);
954 }
955 } catch (StateException e) {
956 log.error(e, e);
957 throw new IOException(e.getMessage());
958 }
959 }
960
961
962 protected static String readOutputType(Document document) {
963 String value = XMLUtils.xpathString(
964 document, XPATH_OUTPUT_NAME, ArtifactNamespaceContext.INSTANCE);
965 return value;
966 }
967
968
969 /**
970 * The the current product.
971 * @param product New product.
972 */
973 public void setProduct(Product product) {
974 this.product = product;
975 }
976
977 /**
978 * Call endOfLife of parent class and the current state.
979 */
980 @Override
981 public void endOfLife(Object globalContext) {
982 super.endOfLife(globalContext);
983
984 if (current != null) {
985 current.endOfLife(globalContext);
986 }
987 }
988
989 /**
990 * Retrieves a map with given InputData which have been inserted into the
991 * current artifact before the parameterization began.
992 */
993 public Map<String, InputData> getPreSettings() {
994 return this.preSettings;
995 }
996
997 /**
998 * Set InputData which are used in later states.
999 */
1000 public void setPreSettings(Map<String, InputData> preSettings) {
1001 this.preSettings = preSettings;
1002 if (this.current != null){
1003 this.current.setPreSettings(preSettings);
1004 }
1005 }
1006 }
1007 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org