comparison gnv-artifacts/src/main/java/de/intevation/gnv/artifacts/GNVArtifactBase.java @ 875:5e9efdda6894

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

http://dive4elements.wald.intevation.org