1    package com.instantbank.servicing.control.web;
2    
3    import java.net.URL;
4    import java.util.ArrayList;
5    import java.util.HashMap;
6    
7    import org.w3c.dom.Element;
8    import org.w3c.dom.Document;
9    import org.w3c.dom.NodeList;
10   import org.w3c.dom.Node;
11   import org.xml.sax.InputSource;
12   import org.xml.sax.SAXException;
13   import org.xml.sax.SAXParseException;
14   import org.xml.sax.SAXException;
15   
16   // jaxp 1.0.1 imports
17   import javax.xml.parsers.DocumentBuilderFactory;
18   import javax.xml.parsers.DocumentBuilder;
19   import com.instantbank.common.utilcomponents.Debug;
20   
21   /**
22    *  This class provides the data bindings for the screendefinitions.xml and the
23    *  requestmappings.xml files. The data obtained is maintained by the
24    *  ScreenFlowManager (clase DAO para procesar archivos xml con la definicion de
25    *  pantallazos y de sus transiciones)
26    *
27    * @author Instant-bank (Consuelo Franky)
28    * @created September 2002
29    */
30   
31   public class ScreenFlowXmlDAO {
32   
33     // event - flow constants (aparecen en requestmappings.xml)
34   
35     public static final String URL_MAPPING = "url-mapping";
36   
37     public static final String SCREEN_DEFINITION = "screen-definition";
38   
39     public static final String URL = "url";
40   
41     public static final String LANGUAGE = "language";
42   
43     public static final String TEMPLATE = "template";
44   
45     public static final String RESULT = "result";
46   
47     public static final String NEXT_SCREEN = "screen";
48   
49     public static final String USE_REQUEST_HANDLER = "useRequestHandler";
50   
51     public static final String USE_FLOW_HANDLER = "useFlowHandler";
52   
53     public static final String FLOW_HANDLER_CLASS = "class";
54   
55     public static final String
56       REQUEST_HANDLER_CLASS = "request-handler-class";
57   
58     public static final String HANDLER_RESULT = "handler-result";
59   
60     public static final String FLOW_HANDLER = "flow-handler";
61   
62     // screendefinitions.xml contansts
63   
64     public static final String KEY = "key";
65   
66     public static final String VALUE = "value";
67   
68     public static final String DIRECT = "direct";
69   
70     public static final String SCREEN = "screen";
71   
72     public static final String SCREEN_NAME = "screen-name";
73   
74     public static final String PARAMETER = "parameter";
75   
76     // for debugging:
77     private static Debug debug = null;
78   
79     static {
80       debug = new Debug();
81       debug.setDebugginOn(true);
82       debug.setPreMessage("** ScreenFlowXmlDAO: ");
83     }
84   
85   
86     /**
87      *  build tree from xml file
88      *
89      * @param location
90      * @return Element
91      */
92     public static Element loadDocument(String location) {
93       Document doc = null;
94       try {
95         URL url = new URL(location);
96         InputSource xmlInp = new InputSource(url.openStream());
97   
98         DocumentBuilderFactory docBuilderFactory
99            = DocumentBuilderFactory.newInstance();
100        DocumentBuilder parser
101           = docBuilderFactory.newDocumentBuilder();
102        doc = parser.parse(xmlInp);
103        Element root = doc.getDocumentElement();
104        root.normalize();
105        return root;
106      }
107      catch(SAXParseException err) {
108        debug.println(" Parsing error"
109          + ", line " + err.getLineNumber() + ", uri "
110          + err.getSystemId());
111        debug.println(" error: " + err.getMessage());
112      }
113      catch(SAXException e) {
114        debug.println(" error: " + e);
115      }
116      catch(java.net.MalformedURLException mfx) {
117        debug.println(" error: " + mfx);
118      }
119      catch(java.io.IOException e) {
120        debug.println(" error: " + e);
121      }
122      catch(Exception pce) {
123        debug.println(" error: " + pce);
124      }
125      return null;
126    }
127  
128  
129    /**
130     *  load initial data of requestmappings.xml file for getting path of
131     *  screensdefinitions.xml of each language
132     *
133     * @param location
134     * @return HashMap corresponding to screensDefinitionsMappings
135     */
136    public static HashMap loadScreenDefinitionMappings(String location) {
137      Element root = loadDocument(location);
138      return getScreenDefinitions(root);
139    }
140  
141  
142    /**
143     *  loads screendefinitions.xml file and returns the equivalent HashMap
144     *
145     * @param location
146     * @return HashMap corresponding to screens
147     */
148    public static HashMap loadScreenDefinitions(String location) {
149      Element root = loadDocument(location);
150      return getScreens(root);
151    }
152  
153  
154    /**
155     *  loads requestmappings.xml file and returns the equivalent HashMap
156     *
157     * @param location
158     * @return HashMap corresponding to urlMappings
159     */
160    public static HashMap loadRequestMappings(String location) {
161      Element root = loadDocument(location);
162      return getRequestMappings(root);
163    }
164  
165  
166    /**
167     * auxliary method for loadScreenDefinitionMappings() that builds
168     *  screensDefinitionsMappings structure
169     *
170     * @param root
171     * @return The screenDefinitions value
172     */
173    public static HashMap getScreenDefinitions(Element root) {
174      HashMap screensDefs = new HashMap();
175      NodeList list = root.getElementsByTagName(SCREEN_DEFINITION);
176      for(int loop = 0; loop < list.getLength(); loop++) {
177        Node node = list.item(loop);
178        if(node != null) {
179          String language = null;
180          String url = null;
181          if(node instanceof Element) {
182            language = ((Element)node).getAttribute(LANGUAGE);
183            url = ((Element)node).getAttribute(URL);
184          }
185          if((language != null) && (url != null)
186            && !screensDefs.containsKey(language)) {
187            screensDefs.put(language, url);
188          }
189          else {
190            debug.println("*** Non Fatal errror: "
191              + "ScreenDefinitions for language " + language
192              + " defined more than once in "
193              + " screen definitions file");
194          }
195        }
196      }
197      return screensDefs;
198    }
199  
200  
201    /**
202     *  auxiliary method for loadScreenDefinitions() that builds screens structure
203     *
204     * @param root
205     * @return The screens value
206     */
207    public static HashMap getScreens(Element root) {
208      HashMap screens = new HashMap();
209      // get the template
210      String templateName = getTagValue(root, TEMPLATE);
211      screens.put(TEMPLATE, templateName);
212      // get screens
213      NodeList list = root.getElementsByTagName(SCREEN);
214      for(int loop = 0; loop < list.getLength(); loop++) {
215        Node node = list.item(loop);
216        if(node != null) {
217          String screenName = getSubTagValue(node, SCREEN_NAME);
218          HashMap parameters = getParameters(node);
219          Screen screen = new Screen(screenName, parameters);
220          if(!screens.containsKey(screenName)) {
221            screens.put(screenName, screen);
222          }
223          else {
224            debug.println("*** Non Fatal errror: Screen "
225              + screenName + " defined more than once in "
226              + "screen definitions file");
227          }
228        }
229      }
230      return screens;
231    }
232  
233  
234    /**
235     *   auxiliary method for  getScreens() that builds parameters sctructure
236     *   corresponding to a screen
237     *
238     * @param node
239     * @return The parameters value
240     */
241  
242    private static HashMap getParameters(Node node) {
243      HashMap params = new HashMap();
244      if(node != null) {
245        NodeList children = node.getChildNodes();
246        for(int innerLoop = 0;
247          innerLoop < children.getLength(); innerLoop++) {
248          Node child = children.item(innerLoop);
249          if((child != null) && (child.getNodeName() != null)
250            && child.getNodeName().equals(PARAMETER)) {
251            if(child instanceof Element) {
252              Element childElement = ((Element)child);
253              String key = childElement.getAttribute(KEY);
254              String value = childElement.getAttribute(VALUE);
255              String directString
256                 = childElement.getAttribute(DIRECT);
257              boolean direct = false;
258              if((directString != null)
259                && directString.equals("true")) {
260                direct = true;
261              }
262              if(!params.containsKey(key)) {
263                params.put
264                  (key, new Parameter(key, value, direct));
265              }
266              else {
267                debug.println("*** Non Fatal errror: "
268                  + "Parameter " + key
269                  + " is defined more than once");
270  
271              }
272            }
273          }
274        }
275        // end inner loop
276      }
277      return params;
278    }
279  
280  
281    /**
282     *  auxiliary method for loadRequestMappings() that builds urlMappings structure
283     *
284     * @param root
285     * @return The requestMappings value
286     */
287    public static HashMap getRequestMappings(Element root) {
288      HashMap urlMappings = new HashMap();
289      NodeList list = root.getElementsByTagName(URL_MAPPING);
290      for(int loop = 0; loop < list.getLength(); loop++) {
291        Node node = list.item(loop);
292        if(node != null) {
293          String url = "";
294          String screen = null;
295          String useRequestHandlerString = null;
296          String useFlowHandlerString = null;
297          String flowHandler = null;
298          String requestHandler = null;
299          HashMap resultMappings = null;
300          boolean useFlowHandler = false;
301          boolean useRequestHandler = false;
302          // get url mapping attributes
303          // need to be a element to get attributes
304          if(node instanceof Element) {
305            Element element = ((Element)node);
306            url = element.getAttribute(URL);
307            screen = element.getAttribute(NEXT_SCREEN);
308            useRequestHandlerString
309              = element.getAttribute(USE_REQUEST_HANDLER);
310  
311            useFlowHandlerString
312              = element.getAttribute(USE_FLOW_HANDLER);
313          }
314          if((useRequestHandlerString != null)
315            && useRequestHandlerString.equals("true")) {
316            useRequestHandler = true;
317          }
318          if(useRequestHandler) {
319            requestHandler
320              = getSubTagValue(node, REQUEST_HANDLER_CLASS);
321          }
322          // get request handler
323          if((useFlowHandlerString != null)
324            && useFlowHandlerString.equals("true")) {
325            useFlowHandler = true;
326          }
327          // get flow handler
328          if((useFlowHandlerString != null)
329            && useFlowHandlerString.equals("true")) {
330            useFlowHandler = true;
331          }
332          if(useFlowHandler) {
333            // need to be a element to find sub nodes by name
334            if(node instanceof Element) {
335              Element element = (Element)node;
336              NodeList children
337                 = element.getElementsByTagName(FLOW_HANDLER);
338              Node flowHandlerNode = null;
339              if(children.getLength() >= 1) {
340                flowHandlerNode = children.item(0);
341              }
342              if(children.getLength() > 1) {
343                debug.println("Non fatal error: "
344                  + " There can be only one <"
345                  + FLOW_HANDLER + "> definition in a <"
346                  + URL_MAPPING + ">");
347              }
348              // get the flow handler details
349              if(flowHandlerNode != null) {
350                if(flowHandlerNode instanceof Element) {
351                  Element flowElement
352                     = (Element)flowHandlerNode;
353                  flowHandler
354                    = flowElement.getAttribute
355                    (FLOW_HANDLER_CLASS);
356                  NodeList results
357                     = flowElement.getElementsByTagName
358                    (HANDLER_RESULT);
359                  if(results.getLength() > 0) {
360                    resultMappings = new HashMap();
361                  }
362                  for(int resultLoop = 0;
363                    resultLoop < results.getLength();
364                    resultLoop++) {
365                    Node resultNode
366                       = results.item(resultLoop);
367  
368                    if(resultNode instanceof Element) {
369                      Element resultElement
370                         = (Element)resultNode;
371                      String key = resultElement.getAttribute(RESULT);
372                      String value
373                         = resultElement.getAttribute(NEXT_SCREEN);
374                      if(!resultMappings.containsKey(key)) {
375                        resultMappings.put(key, value);
376                      }
377                      else {
378                        debug.println("***Non Fatal error: "
379                          + "Screen " + url + " <"
380                          + FLOW_HANDLER + "> key "
381                          + "\"" + key
382                          + "\" defined more than "
383                          + "one time");
384                      }
385                    }
386                  }
387                  // end for
388                }
389              }
390              // end if (flowHandler != null)
391            }
392          }
393          // end if (useFlowHandler)
394          URLMapping mapping = new URLMapping(url, screen,
395            useRequestHandler,
396            useFlowHandler,
397            requestHandler,
398            flowHandler,
399            resultMappings);
400  
401          if(!urlMappings.containsKey(url)) {
402            urlMappings.put(url, mapping);
403          }
404          else {
405            debug.println("*** Non Fatal errror: Screen " + url
406              + " defined more than once in "
407              + " screen definitions file");
408          }
409        }
410      }
411      return urlMappings;
412    }
413  
414  
415    /**
416     *  auxiliary method for working with xml tree;
417     *  invoked by getscreens() and  getrequestMappings()
418     *
419     * @param node
420     * @param subTagName
421     * @return The subTagValue value
422     */
423    public static String getSubTagValue(Node node, String subTagName) {
424      String returnString = "";
425      if(node != null) {
426        NodeList children = node.getChildNodes();
427        for(int innerLoop = 0;
428          innerLoop < children.getLength(); innerLoop++) {
429          Node child = children.item(innerLoop);
430          if((child != null) && (child.getNodeName() != null)
431            && child.getNodeName().equals(subTagName)) {
432            Node grandChild = child.getFirstChild();
433            if(grandChild.getNodeValue() != null) {
434              return grandChild.getNodeValue();
435            }
436          }
437        }
438        // end inner loop
439      }
440      return returnString;
441    }
442  
443  
444    /**
445     *  auxiliary method for working with xml tree;
446     *  invoked by getscreens() and  getrequestMappings()
447     *
448     * @param root
449     * @param tagName
450     * @param subTagName
451     * @return The subTagValue value
452     */
453    public static String getSubTagValue
454      (Element root, String tagName, String subTagName) {
455      String returnString = "";
456      NodeList list = root.getElementsByTagName(tagName);
457  
458      for(int loop = 0; loop < list.getLength(); loop++) {
459        Node node = list.item(loop);
460        if(node != null) {
461          NodeList children = node.getChildNodes();
462          for(int innerLoop = 0;
463            innerLoop < children.getLength(); innerLoop++) {
464            Node child = children.item(innerLoop);
465            if((child != null) && (child.getNodeName() != null)
466              && child.getNodeName().equals(subTagName)) {
467              Node grandChild = child.getFirstChild();
468              if(grandChild.getNodeValue() != null) {
469                return grandChild.getNodeValue();
470              }
471            }
472          }
473          // end inner loop
474        }
475      }
476      return returnString;
477    }
478  
479  
480    /**
481     *  auxiliary method for working with xml tree;
482     *  invoked by getscreens()
483     *
484     * @param root
485     * @param tagName
486     * @return The tagValue value
487     */
488    public static String getTagValue(Element root, String tagName) {
489      String returnString = "";
490      NodeList list = root.getElementsByTagName(tagName);
491      for(int loop = 0; loop < list.getLength(); loop++) {
492        Node node = list.item(loop);
493        if(node != null) {
494          Node child = node.getFirstChild();
495          if((child != null) && child.getNodeValue() != null) {
496            return child.getNodeValue();
497          }
498        }
499      }
500      return returnString;
501    }
502  
503  
504    /**
505     *  auxiliary method for working with xml tree;
506     *
507     * @param root
508     * @param tagName
509     * @param subTagName
510     * @param attribute
511     * @return The subTagAttribute value
512     */
513    private static String getSubTagAttribute(Element root, String tagName,
514                                             String subTagName, String attribute) {
515      String returnString = "";
516      NodeList list = root.getElementsByTagName(tagName);
517      for(int loop = 0; loop < list.getLength(); loop++) {
518        Node node = list.item(loop);
519        if(node != null) {
520          NodeList children = node.getChildNodes();
521          for(int innerLoop = 0;
522            innerLoop < children.getLength(); innerLoop++) {
523            Node child = children.item(innerLoop);
524            if((child != null) && (child.getNodeName() != null)
525              && child.getNodeName().equals(subTagName)) {
526              if(child instanceof Element) {
527                return ((Element)child).getAttribute(attribute);
528              }
529            }
530          }
531          // end inner loop
532        }
533      }
534      return returnString;
535    }
536  }
537  
538