1 /*****************************************************************************/
2 /* Software Testing Automation Framework (STAF)                              */
3 /* (C) Copyright IBM Corp. 2002                                              */
4 /*                                                                           */
5 /* This software is licensed under the Eclipse Public License (EPL) V1.0.    */
6 /*****************************************************************************/
7 
8 package com.ibm.staf.service.stax;
9 import org.w3c.dom.Node;
10 import org.w3c.dom.NamedNodeMap;
11 import org.w3c.dom.NodeList;
12 import java.util.List;
13 import java.util.ArrayList;
14 
15 public class STAXTryActionFactory implements STAXActionFactory
16 {
17     private static String fDTDInfo =
18 "\n" +
19 "<!--=============== The Try / Catch / Finally Elements ============= --> \n" +
20 "<!-- \n" +
21 "     The try element allows you to perform a task and to catch \n" +
22 "     exceptions that are thrown.  Also, if a finally element is \n" +
23 "     specified, then the finally task is executed, no matter whether \n" +
24 "     the try task completes normally or abruptly, and no matter whether \n" +
25 "     a catch element is first given control. \n" +
26 "--> \n" +
27 "<!ELEMENT try        ((%task;), ((catch+) | ((catch*), finally)))> \n" +
28 "<!-- \n" +
29 "     The catch element performs a task when the specified exception is \n" +
30 "     caught.  The var attribute specifies the name of the variable to \n" +
31 "     receive the data specified within the throw element.  The typevar \n" +
32 "     attribute specifies the name of the variable to receive the type \n" +
33 "     of the exception.  The sourcevar attribute specifies the name\n" +
34 "     of the variable to receive the source information for the exception.\n" +
35 " \n" +
36 "--> \n" +
37 "<!ELEMENT catch      (%task;)> \n" +
38 "<!ATTLIST catch \n" +
39 "          exception  CDATA        #REQUIRED \n" +
40 "          var        CDATA        #IMPLIED \n" +
41 "          typevar    CDATA        #IMPLIED \n" +
42 "          sourcevar  CDATA        #IMPLIED \n" +
43 "> \n" +
44 "<!ELEMENT finally    (%task;)> \n";
45 
getDTDInfo()46     public String getDTDInfo()
47     {
48         return fDTDInfo;
49     }
50 
getDTDTaskName()51     public String getDTDTaskName()
52     {
53         return "try";
54     }
55 
parseAction(STAX staxService, STAXJob job, org.w3c.dom.Node root)56     public STAXAction parseAction(STAX staxService, STAXJob job,
57                                   org.w3c.dom.Node root) throws STAXException
58     {
59         STAXTryAction action = new STAXTryAction();
60 
61         action.setLineNumber(root);
62         action.setXmlFile(job.getXmlFile());
63         action.setXmlMachine(job.getXmlMachine());
64 
65         STAXAction tryAction = null;
66         List<STAXCatchAction> catchList = new ArrayList<STAXCatchAction>();
67 
68         STAXFinallyAction finallyAction = null;
69 
70         NodeList children = root.getChildNodes();
71 
72         for (int i = 0; i < children.getLength(); ++i)
73         {
74             Node thisChild = children.item(i);
75 
76             if (thisChild.getNodeType() == Node.COMMENT_NODE)
77             {
78                 /* Do nothing */
79             }
80             else if (thisChild.getNodeType() == Node.ELEMENT_NODE)
81             {
82                 action.setLineNumber(thisChild);
83 
84                 if (thisChild.getNodeName().equals("catch"))
85                 {
86                     catchList.add(handleCatch(staxService, job, thisChild));
87                 }
88                 else if (thisChild.getNodeName().equals("finally"))
89                 {
90                     finallyAction = handleFinally(staxService, job, thisChild);
91                 }
92                 else
93                 {
94                     STAXActionFactory factory =
95                         staxService.getActionFactory(thisChild.getNodeName());
96 
97                     if (factory == null)
98                     {
99                         action.setElementInfo(new STAXElementInfo(
100                             root.getNodeName(),
101                             STAXElementInfo.NO_ATTRIBUTE_NAME,
102                             STAXElementInfo.LAST_ELEMENT_INDEX,
103                             "No action factory for element type \"" +
104                             thisChild.getNodeName() + "\""));
105 
106                         throw new STAXInvalidXMLElementException(
107                             STAXUtil.formatErrorMessage(action), action);
108                     }
109 
110                     tryAction = factory.parseAction(staxService, job, thisChild);
111                 }
112             }
113             else
114             {
115                 action.setElementInfo(new STAXElementInfo(
116                     root.getNodeName(),
117                     STAXElementInfo.NO_ATTRIBUTE_NAME,
118                     STAXElementInfo.LAST_ELEMENT_INDEX,
119                     "Contains invalid node type: " +
120                     Integer.toString(thisChild.getNodeType())));
121 
122                 throw new STAXInvalidXMLNodeTypeException(
123                     STAXUtil.formatErrorMessage(action), action);
124             }
125         }
126 
127         action.setTryAction(tryAction);
128         action.setCatchList(catchList);
129 
130         if (finallyAction == null)
131         {
132             return action;
133         }
134         else
135         {
136             finallyAction.setTryAction(action);
137             return finallyAction;
138         }
139     }
140 
handleCatch(STAX staxService, STAXJob job, Node root)141     private STAXCatchAction handleCatch(STAX staxService, STAXJob job,
142                                         Node root) throws STAXException
143     {
144         STAXCatchAction action = new STAXCatchAction();
145         action.setLineNumber(root);
146         action.setXmlFile(job.getXmlFile());
147         action.setXmlMachine(job.getXmlMachine());
148 
149         NamedNodeMap attrs = root.getAttributes();
150 
151         for (int i = 0; i < attrs.getLength(); ++i)
152         {
153             Node thisAttr = attrs.item(i);
154 
155             action.setElementInfo(new STAXElementInfo(
156                 root.getNodeName(), thisAttr.getNodeName()));
157 
158             if (thisAttr.getNodeName().equals("exception"))
159             {
160                 action.setExceptionName(STAXUtil.parseAndCompileForPython(
161                     thisAttr.getNodeValue(), action));
162             }
163             else if (thisAttr.getNodeName().equals("var"))
164             {
165                 action.setVarName(thisAttr.getNodeValue());
166             }
167             else if (thisAttr.getNodeName().equals("typevar"))
168             {
169                 action.setTypeVarName(thisAttr.getNodeValue());
170             }
171             else if (thisAttr.getNodeName().equals("sourcevar"))
172             {
173                 action.setSourceVarName(thisAttr.getNodeValue());
174             }
175         }
176 
177         STAXAction catchAction = null;
178 
179         NodeList children = root.getChildNodes();
180 
181         for (int i = 0; i < children.getLength(); ++i)
182         {
183             Node thisChild = children.item(i);
184 
185             if (thisChild.getNodeType() == Node.COMMENT_NODE)
186             {
187                 /* Do nothing */
188             }
189             else if (thisChild.getNodeType() == Node.ELEMENT_NODE)
190             {
191                 STAXActionFactory factory =
192                     staxService.getActionFactory(thisChild.getNodeName());
193 
194                 if (factory == null)
195                 {
196                     action.setElementInfo(new STAXElementInfo(
197                         root.getNodeName(),
198                         STAXElementInfo.NO_ATTRIBUTE_NAME,
199                         STAXElementInfo.LAST_ELEMENT_INDEX,
200                         "No action factory for element type \"" +
201                         thisChild.getNodeName() + "\""));
202 
203                     throw new STAXInvalidXMLElementException(
204                         STAXUtil.formatErrorMessage(action), action);
205                 }
206 
207                 catchAction = factory.parseAction(staxService, job, thisChild);
208             }
209             else
210             {
211                 action.setElementInfo(new STAXElementInfo(
212                     root.getNodeName(),
213                     STAXElementInfo.NO_ATTRIBUTE_NAME,
214                     STAXElementInfo.LAST_ELEMENT_INDEX,
215                     "Contains invalid node type: " +
216                     Integer.toString(thisChild.getNodeType())));
217 
218                 throw new STAXInvalidXMLNodeTypeException(
219                     STAXUtil.formatErrorMessage(action), action);
220             }
221         }
222 
223         action.setAction(catchAction);
224 
225         return action;
226     }
227 
handleFinally(STAX staxService, STAXJob job, Node root)228     private STAXFinallyAction handleFinally(STAX staxService, STAXJob job,
229                                             Node root) throws STAXException
230     {
231         STAXFinallyAction action = new STAXFinallyAction();
232         action.setLineNumber(root);
233         action.setXmlFile(job.getXmlFile());
234         action.setXmlMachine(job.getXmlMachine());
235 
236         STAXAction finallyAction = null;
237 
238         NodeList children = root.getChildNodes();
239 
240         for (int i = 0; i < children.getLength(); ++i)
241         {
242             Node thisChild = children.item(i);
243 
244             if (thisChild.getNodeType() == Node.COMMENT_NODE)
245             {
246                 /* Do nothing */
247             }
248             else if (thisChild.getNodeType() == Node.ELEMENT_NODE)
249             {
250                 STAXActionFactory factory =
251                     staxService.getActionFactory(thisChild.getNodeName());
252 
253                 if (factory == null)
254                 {
255                     action.setElementInfo(new STAXElementInfo(
256                         root.getNodeName(),
257                         STAXElementInfo.NO_ATTRIBUTE_NAME,
258                         STAXElementInfo.LAST_ELEMENT_INDEX,
259                         "No action factory for element type \"" +
260                         thisChild.getNodeName() + "\""));
261 
262                     throw new STAXInvalidXMLElementException(
263                         STAXUtil.formatErrorMessage(action), action);
264                 }
265 
266                 finallyAction = factory.parseAction(
267                     staxService, job, thisChild);
268             }
269             else
270             {
271                 action.setElementInfo(new STAXElementInfo(
272                     root.getNodeName(),
273                     STAXElementInfo.NO_ATTRIBUTE_NAME,
274                     STAXElementInfo.LAST_ELEMENT_INDEX,
275                     "Contains invalid node type: " +
276                     Integer.toString(thisChild.getNodeType())));
277 
278                 throw new STAXInvalidXMLNodeTypeException(
279                     STAXUtil.formatErrorMessage(action), action);
280             }
281         }
282 
283         action.setFinallyAction(finallyAction);
284 
285         return action;
286     }
287 }
288