##### Coverage Report - org.apache.commons.scxml.model.Assign

Classes in this File | Line Coverage | Branch Coverage | Complexity
Assign |
84% |
90% |
| 1.9230769230769231;1.923

1 |  |
     /*
2 |  |
      *
3 |  |
      *   Copyright 2005 The Apache Software Foundation.
4 |  |
      *
5 |  |
      *  Licensed under the Apache License, Version 2.0 (the "License");
6 |  |
      *  you may not use this file except in compliance with the License.
7 |  |
      *  You may obtain a copy of the License at
8 |  |
      *
9 |  |
      *      http://www.apache.org/licenses/LICENSE-2.0
10 |  |
      *
11 |  |
      *  Unless required by applicable law or agreed to in writing, software
12 |  |
      *  distributed under the License is distributed on an "AS IS" BASIS,
13 |  |
      *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 |  |
      *  See the License for the specific language governing permissions and
15 |  |
      *  limitations under the License.
16 |  |
      *
17 |  |
      */
18 |  |
     package org.apache.commons.scxml.model;
19 |  |
20 |  |
     import java.util.Collection;
21 |  |
22 |  |
     import javax.xml.parsers.DocumentBuilderFactory;
23 |  |
24 |  |
     import org.apache.commons.logging.Log;
25 |  |
     import org.apache.commons.logging.LogFactory;
26 |  |
     import org.apache.commons.scxml.Context;
27 |  |
     import org.apache.commons.scxml.ErrorReporter;
28 |  |
     import org.apache.commons.scxml.Evaluator;
29 |  |
     import org.apache.commons.scxml.EventDispatcher;
30 |  |
     import org.apache.commons.scxml.PathResolver;
31 |  |
     import org.apache.commons.scxml.SCInstance;
32 |  |
     import org.apache.commons.scxml.SCXMLExpressionException;
33 |  |
     import org.apache.commons.scxml.SCXMLHelper;
34 |  |
     import org.apache.commons.scxml.TriggerEvent;
35 |  |
     import org.w3c.dom.Document;
36 |  |
     import org.w3c.dom.Node;
37 |  |
38 |  |
     /**
39 |  |
      * The class in this SCXML object model that corresponds to the
40 |  |
      * &lt;assign&gt; SCXML element.
41 |  |
      *
42 |  |
      */
43 |  |
     public final class Assign extends Action implements PathResolverHolder {
44 |  |
45 |  |
         /**
46 |  |
          * Left hand side expression evaluating to a previously
47 |  |
          * defined variable.
48 |  |
          */
49 |  |
         private String name;
50 |  |
51 |  |
         /**
52 |  |
          * Left hand side expression evaluating to a location within
53 |  |
          * a previously defined XML data tree.
54 |  |
          */
55 |  |
         private String location;
56 |  |
57 |  |
         /**
58 |  |
          * The source where the new XML instance for this location exists.
59 |  |
          */
60 |  |
         private String src;
61 |  |
62 |  |
         /**
63 |  |
          * Expression evaluating to the new value of the variable.
64 |  |
          */
65 |  |
         private String expr;
66 |  |
67 |  |
         /**
68 |  |
          * {@link PathResolver} for resolving the "src" result.
69 |  |
          */
70 |  |
         private PathResolver pathResolver;
71 |  |
72 |  |
         /**
73 |  |
          * Constructor.
74 |  |
          */
75 |  |
         public Assign() {
76 | 48 |
             super();
77 | 48 |
         }
78 |  |
79 |  |
         /**
80 |  |
          * Get the variable to be assigned a new value.
81 |  |
          *
82 |  |
          * @return Returns the name.
83 |  |
          */
84 |  |
         public String getName() {
85 | 5 |
             return name;
86 |  |
         }
87 |  |
88 |  |
         /**
89 |  |
          * Get the variable to be assigned a new value.
90 |  |
          *
91 |  |
          * @param name The name to set.
92 |  |
          */
93 |  |
         public void setName(final String name) {
94 | 33 |
             this.name = name;
95 | 33 |
         }
96 |  |
97 |  |
         /**
98 |  |
          * Get the expr that will evaluate to the new value.
99 |  |
          *
100 |  |
          * @return Returns the expr.
101 |  |
          */
102 |  |
         public String getExpr() {
103 | 5 |
             return expr;
104 |  |
         }
105 |  |
106 |  |
         /**
107 |  |
          * Set the expr that will evaluate to the new value.
108 |  |
          *
109 |  |
          * @param expr The expr to set.
110 |  |
          */
111 |  |
         public void setExpr(final String expr) {
112 | 43 |
             this.expr = expr;
113 | 43 |
         }
114 |  |
115 |  |
         /**
116 |  |
          * Get the location for a previously defined XML data tree.
117 |  |
          *
118 |  |
          * @return Returns the location.
119 |  |
          */
120 |  |
         public String getLocation() {
121 | 5 |
             return location;
122 |  |
         }
123 |  |
124 |  |
         /**
125 |  |
          * Set the location for a previously defined XML data tree.
126 |  |
          *
127 |  |
          * @param location The location.
128 |  |
          */
129 |  |
         public void setLocation(final String location) {
130 | 11 |
             this.location = location;
131 | 11 |
         }
132 |  |
133 |  |
         /**
134 |  |
          * Get the source where the new XML instance for this location exists.
135 |  |
          *
136 |  |
          * @return Returns the source.
137 |  |
          */
138 |  |
         public String getSrc() {
139 | 0 |
             return src;
140 |  |
         }
141 |  |
142 |  |
         /**
143 |  |
          * Set the source where the new XML instance for this location exists.
144 |  |
          *
145 |  |
          * @param src The source.
146 |  |
          */
147 |  |
         public void setSrc(final String src) {
148 | 1 |
             this.src = src;
149 | 1 |
         }
150 |  |
151 |  |
         /**
152 |  |
          * Get the {@link PathResolver}.
153 |  |
          *
154 |  |
          * @return Returns the pathResolver.
155 |  |
          */
156 |  |
         public PathResolver getPathResolver() {
157 | 0 |
             return pathResolver;
158 |  |
         }
159 |  |
160 |  |
         /**
161 |  |
          * Set the {@link PathResolver}.
162 |  |
          *
163 |  |
          * @param pathResolver The pathResolver to set.
164 |  |
          */
165 |  |
         public void setPathResolver(final PathResolver pathResolver) {
166 | 43 |
             this.pathResolver = pathResolver;
167 | 43 |
         }
168 |  |
169 |  |
         /**
170 |  |
          * {@inheritDoc}
171 |  |
          */
172 |  |
         public void execute(final EventDispatcher evtDispatcher,
173 |  |
                 final ErrorReporter errRep, final SCInstance scInstance,
174 |  |
                 final Log appLog, final Collection derivedEvents)
175 |  |
         throws ModelException, SCXMLExpressionException {
176 | 31 |
             State parentState = getParentState();
177 | 31 |
             Context ctx = scInstance.getContext(parentState);
178 | 31 |
             Evaluator eval = scInstance.getEvaluator();
179 |  |
             // "location" gets preference over "name"
180 | 31 |
             if (!SCXMLHelper.isStringEmpty(location)) {
181 | 11 |
                 Node oldNode = eval.evalLocation(ctx, location);
182 | 11 |
                 if (oldNode != null) {
183 |  |
                     //// rvalue may be ...
184 |  |
                     // a Node, if so, import it at location
185 | 11 |
                     Node newNode = null;
186 |  |
                     try {
187 | 11 |
                         if (src != null && src.trim().length() > 0) {
188 | 1 |
                             newNode = getSrcNode();
189 |  |
                         } else {
190 | 10 |
                             newNode = eval.evalLocation(ctx, expr);
191 |  |
                         }
192 | 5 |
                         if (newNode != null) {
193 |  |
                             // adopt children, possible spec clarification needed
194 | 5 |
                             for (Node child = newNode.getFirstChild();
195 | 12 |
                                     child != null;
196 | 7 |
                                     child = child.getNextSibling()) {
197 | 7 |
                                 Node importedNode = oldNode.getOwnerDocument().
198 |  |
                                     importNode(child, true);
199 | 7 |
                                 oldNode.appendChild(importedNode);
200 |  |
                             }
201 |  |
                         }
202 | 6 |
                     } catch (SCXMLExpressionException see) {
203 |  |
                         // or something else, stuff toString() into lvalue
204 | 6 |
                         Object valueObject = eval.eval(ctx, expr);
205 | 6 |
                         SCXMLHelper.setNodeValue(oldNode, valueObject.toString());
206 | 5 |
                     }
207 | 11 |
                     TriggerEvent ev = new TriggerEvent(name + ".change",
208 |  |
                         TriggerEvent.CHANGE_EVENT);
209 | 11 |
                     derivedEvents.add(ev);
210 |  |
                 } else {
211 | 0 |
                     appLog.error("<assign>: location does not point to"
212 |  |
                         + " a <data> node");
213 |  |
                 }
214 |  |
             } else {
215 |  |
                 // lets try "name" (usage as in Sep '05 WD, useful with <var>)
216 | 20 |
                 if (!ctx.has(name)) {
217 | 0 |
                     errRep.onError(ErrorReporter.UNDEFINED_VARIABLE, name
218 |  |
                         + " = null", parentState);
219 |  |
                 } else {
220 | 20 |
                     Object varObj = null;
221 | 20 |
                     if (src != null && src.trim().length() > 0) {
222 | 0 |
                         varObj = getSrcNode();
223 |  |
                     } else {
224 | 20 |
                         varObj = eval.eval(ctx, expr);
225 |  |
                     }
226 | 20 |
                     ctx.set(name, varObj);
227 | 20 |
                     TriggerEvent ev = new TriggerEvent(name + ".change",
228 |  |
                         TriggerEvent.CHANGE_EVENT);
229 | 20 |
                     derivedEvents.add(ev);
230 |  |
                 }
231 |  |
             }
232 | 31 |
         }
233 |  |
234 |  |
         /**
235 |  |
          * Get the {@link Node} the "src" attribute points to.
236 |  |
          *
237 |  |
          * @return The node the "src" attribute points to.
238 |  |
          */
239 |  |
         private Node getSrcNode() {
240 | 1 |
             String resolvedSrc = src;
241 | 1 |
             if (pathResolver != null) {
242 | 1 |
                 resolvedSrc = pathResolver.resolvePath(src);
243 |  |
             }
244 | 1 |
             Document doc = null;
245 |  |
             try {
246 | 1 |
                 doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().
247 |  |
                     parse(resolvedSrc);
248 | 0 |
             } catch (Throwable t) {
249 | 0 |
                 org.apache.commons.logging.Log log = LogFactory.
250 | 0 |
                     getLog(Assign.class);
251 | 0 |
                 log.error(t.getMessage(), t);
252 | 1 |
             }
253 | 1 |
             if (doc == null) {
254 | 0 |
                 return null;
255 |  |
             }
256 | 1 |
             return doc.getDocumentElement();
257 |  |
         }
258 |  |
259 |  |
     }