1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml2.io;
18
19 import java.io.IOException;
20 import java.io.StringReader;
21 import java.util.ArrayList;
22 import java.util.LinkedList;
23 import java.util.List;
24
25 import javax.xml.stream.XMLStreamException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogConfigurationException;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.commons.logging.impl.LogFactoryImpl;
31 import org.apache.commons.logging.impl.SimpleLog;
32 import org.apache.commons.scxml2.ActionExecutionContext;
33 import org.apache.commons.scxml2.SCXMLExpressionException;
34 import org.apache.commons.scxml2.SCXMLTestHelper;
35 import org.apache.commons.scxml2.io.SCXMLReader.Configuration;
36 import org.apache.commons.scxml2.model.Action;
37 import org.apache.commons.scxml2.model.CustomAction;
38 import org.apache.commons.scxml2.model.Data;
39 import org.apache.commons.scxml2.model.Datamodel;
40 import org.apache.commons.scxml2.model.EnterableState;
41 import org.apache.commons.scxml2.model.ExternalContent;
42 import org.apache.commons.scxml2.model.Final;
43 import org.apache.commons.scxml2.model.ModelException;
44 import org.apache.commons.scxml2.model.SCXML;
45 import org.apache.commons.scxml2.model.Send;
46 import org.apache.commons.scxml2.model.State;
47 import org.apache.commons.scxml2.model.Transition;
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Assert;
51 import org.junit.Before;
52 import org.junit.BeforeClass;
53 import org.junit.Test;
54 import org.w3c.dom.Node;
55
56
57
58
59 public class SCXMLReaderTest {
60
61 private static String oldLogFactoryProperty;
62
63 private Log scxmlReaderLog;
64
65 @BeforeClass
66 public static void beforeClass() {
67 oldLogFactoryProperty = System.getProperty(LogFactory.FACTORY_PROPERTY);
68 System.setProperty(LogFactory.FACTORY_PROPERTY, RecordingLogFactory.class.getName());
69 }
70
71 @AfterClass
72 public static void afterClass() {
73 if (oldLogFactoryProperty == null) {
74 System.clearProperty(LogFactory.FACTORY_PROPERTY);
75 } else {
76 System.setProperty(LogFactory.FACTORY_PROPERTY, oldLogFactoryProperty);
77 }
78 }
79
80
81
82
83 @Before
84 public void before() {
85 scxmlReaderLog = LogFactory.getLog(SCXMLReader.class);
86 clearRecordedLogMessages();
87 }
88
89
90
91
92 @Test
93 public void testSCXMLReaderMicrowave03Sample() throws Exception {
94 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/env/jexl/microwave-03.xml");
95 Assert.assertNotNull(scxml);
96 Assert.assertNotNull(serialize(scxml));
97 }
98
99 @Test
100 public void testSCXMLReaderMicrowave04Sample() throws Exception {
101 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/env/jexl/microwave-04.xml");
102 Assert.assertNotNull(scxml);
103 Assert.assertNotNull(serialize(scxml));
104 }
105
106 @Test
107 public void testSCXMLReaderTransitions01Sample() throws Exception {
108 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/transitions-01.xml");
109 Assert.assertNotNull(scxml);
110 Assert.assertNotNull(serialize(scxml));
111 }
112
113 @Test
114 public void testSCXMLReaderPrefix01Sample() throws Exception {
115 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/prefix-01.xml");
116 Assert.assertNotNull(scxml);
117 Assert.assertNotNull(serialize(scxml));
118 }
119
120 @Test
121 public void testSCXMLReaderSend01Sample() throws Exception {
122 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/send-01.xml");
123 State ten = (State) scxml.getInitialTransition().getTargets().iterator().next();
124 Assert.assertEquals("ten", ten.getId());
125 List<Transition> ten_done = ten.getTransitionsList("done.state.ten");
126 Assert.assertEquals(1, ten_done.size());
127 Transition ten2twenty = ten_done.get(0);
128 List<Action> actions = ten2twenty.getActions();
129 Assert.assertEquals(1, actions.size());
130 Send send = (Send) actions.get(0);
131 Assert.assertEquals("send1", send.getId());
132
133
134
135
136
137
138
139
140
141 }
142
143 @Test
144 public void testSCXMLReaderInitialAttr() throws Exception {
145 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/io/scxml-initial-attr.xml");
146 Assert.assertNotNull(scxml);
147 Assert.assertNotNull(serialize(scxml));
148 Final foo = (Final) scxml.getInitialTransition().getTargets().iterator().next();
149 Assert.assertEquals("foo", foo.getId());
150 }
151
152 @Test
153 public void testSCXMLValidTransitionTargets() throws Exception {
154
155 SCXMLTestHelper.parse(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml"));
156 }
157
158 @Test(expected=org.apache.commons.scxml2.model.ModelException.class)
159 public void testSCXMLInValidTransitionTargets1() throws Exception {
160
161 SCXMLTestHelper.parse(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml"));
162 }
163
164 @Test(expected=org.apache.commons.scxml2.model.ModelException.class)
165 public void testSCXMLInValidTransitionTargets2() throws Exception {
166
167 SCXMLTestHelper.parse(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml"));
168 }
169
170 @Test
171 public void testSCXMLReaderCustomActionWithBodyTextSample() throws Exception {
172 List<CustomAction> cas = new ArrayList<CustomAction>();
173 CustomAction ca = new CustomAction("http://my.custom-actions.domain",
174 "action", MyAction.class);
175 cas.add(ca);
176 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/io/custom-action-body-test-1.xml", cas);
177 EnterableState state = (EnterableState) scxml.getInitialTransition().getTargets().iterator().next();
178 Assert.assertEquals("actions", state.getId());
179 List<Action> actions = state.getOnEntries().get(0).getActions();
180 Assert.assertEquals(1, actions.size());
181 MyAction my = (MyAction) actions.get(0);
182 Assert.assertNotNull(my);
183 Assert.assertTrue(my.getExternalNodes().size() > 0);
184 }
185
186 @Test
187 public void testSCXMLReaderWithInvalidElements() throws Exception {
188
189
190 Configuration configuration = new Configuration();
191 SCXML scxml = SCXMLReader.read(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-with-invalid-elems.xml"),
192 configuration);
193 Assert.assertNotNull(scxml);
194 Assert.assertNotNull(serialize(scxml));
195 Final foo = (Final) scxml.getInitialTransition().getTargets().iterator().next();
196 Assert.assertEquals("foo", foo.getId());
197 Datamodel dataModel = scxml.getDatamodel();
198 Assert.assertNotNull(dataModel);
199 List<Data> dataList = dataModel.getData();
200 Assert.assertEquals(1, dataList.size());
201 Assert.assertEquals("time", dataList.get(0).getId());
202 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <datamodel>");
203 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.example.com/scxml\" as child of <datamodel>");
204 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <trace> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <onentry>");
205 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <onbeforeexit> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <final>");
206
207
208
209 clearRecordedLogMessages();
210 scxml = null;
211 configuration = new Configuration();
212 configuration.setStrict(false);
213 configuration.setSilent(true);
214 scxml = SCXMLReader.read(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-with-invalid-elems.xml"),
215 configuration);
216 Assert.assertNotNull(scxml);
217 Assert.assertNotNull(serialize(scxml));
218 foo = (Final) scxml.getInitialTransition().getTargets().iterator().next();
219 Assert.assertEquals("foo", foo.getId());
220 dataModel = scxml.getDatamodel();
221 Assert.assertNotNull(dataModel);
222 dataList = dataModel.getData();
223 Assert.assertEquals(1, dataList.size());
224 Assert.assertEquals("time", dataList.get(0).getId());
225 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <datamodel>");
226 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.example.com/scxml\" as child of <datamodel>");
227 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <trace> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <onentry>");
228 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <onbeforeexit> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <final>");
229
230
231
232 clearRecordedLogMessages();
233 scxml = null;
234 configuration = new Configuration();
235 configuration.setStrict(true);
236 configuration.setSilent(false);
237 try {
238 scxml = SCXMLReader.read(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-with-invalid-elems.xml"),
239 configuration);
240 Assert.fail("In strict mode, it should have thrown a model exception.");
241 } catch (ModelException e) {
242 Assert.assertTrue(e.getMessage().contains("Ignoring unknown or invalid element <baddata>"));
243 }
244 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <datamodel>");
245 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.example.com/scxml\" as child of <datamodel>");
246 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <trace> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <onentry>");
247 assertContainsRecordedLogMessage("Ignoring unknown or invalid element <onbeforeexit> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <final>");
248
249
250
251 clearRecordedLogMessages();
252 scxml = null;
253 configuration = new Configuration();
254 configuration.setStrict(true);
255 configuration.setSilent(true);
256 try {
257 scxml = SCXMLReader.read(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-with-invalid-elems.xml"),
258 configuration);
259 Assert.fail("In strict mode, it should have thrown a model exception.");
260 } catch (ModelException e) {
261 Assert.assertTrue(e.getMessage().contains("Ignoring unknown or invalid element <baddata>"));
262 }
263 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <datamodel>");
264 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <baddata> in namespace \"http://www.example.com/scxml\" as child of <datamodel>");
265 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <trace> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <onentry>");
266 assertNotContainsRecordedLogMessage("Ignoring unknown or invalid element <onbeforeexit> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <final>");
267 }
268
269 @Test
270 public void testSCXMLReaderGroovyClosure() throws Exception {
271 SCXML scxml = SCXMLTestHelper.parse("org/apache/commons/scxml2/env/groovy/groovy-closure.xml");
272 Assert.assertNotNull(scxml);
273 Assert.assertNotNull(scxml.getGlobalScript());
274 String scxmlAsString = serialize(scxml);
275 Assert.assertNotNull(scxmlAsString);
276 scxml = SCXMLTestHelper.parse(new StringReader(scxmlAsString), null);
277 Assert.assertNotNull(scxml);
278 Assert.assertNotNull(scxml.getGlobalScript());
279 }
280
281 private String serialize(final SCXML scxml) throws IOException, XMLStreamException {
282 String scxmlAsString = SCXMLWriter.write(scxml);
283 Assert.assertNotNull(scxmlAsString);
284 return scxmlAsString;
285 }
286
287 private void assertContainsRecordedLogMessage(final String message) {
288 if (scxmlReaderLog instanceof RecordingSimpleLog) {
289 Assert.assertTrue(((RecordingSimpleLog) scxmlReaderLog).containsMessage(
290 "Ignoring unknown or invalid element <baddata> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <datamodel>"));
291 }
292 }
293
294 private void assertNotContainsRecordedLogMessage(final String message) {
295 if (scxmlReaderLog instanceof RecordingSimpleLog) {
296 Assert.assertFalse(((RecordingSimpleLog) scxmlReaderLog).containsMessage(
297 "Ignoring unknown or invalid element <baddata> in namespace \"http://www.w3.org/2005/07/scxml\" as child of <datamodel>"));
298 }
299 }
300
301 private void clearRecordedLogMessages() {
302 if (scxmlReaderLog instanceof RecordingSimpleLog) {
303 ((RecordingSimpleLog) scxmlReaderLog).clearMessages();
304 }
305 }
306
307 public static class MyAction extends Action implements ExternalContent {
308 private static final long serialVersionUID = 1L;
309
310 private List<Node> nodes = new ArrayList<Node>();
311
312 @Override
313 public void execute(ActionExecutionContext exctx) throws ModelException, SCXMLExpressionException {
314
315 }
316
317 @Override
318 public List<Node> getExternalNodes() {
319 return nodes;
320 }
321
322 }
323
324
325
326
327 public static class RecordingLogFactory extends LogFactoryImpl {
328 @Override
329 protected Log newInstance(String name) throws LogConfigurationException {
330 return new RecordingSimpleLog(name);
331 }
332 }
333
334
335
336
337 public static class RecordingSimpleLog extends SimpleLog {
338
339 private static final long serialVersionUID = 1L;
340
341 private List<String> messages = new LinkedList<String>();
342
343 public RecordingSimpleLog(String name) {
344 super(name);
345 }
346
347
348
349
350 public void clearMessages() {
351 messages.clear();
352 }
353
354
355
356
357
358
359 public boolean containsMessage(final String msg) {
360 for (String message : messages) {
361 if (message.contains(msg)) {
362 return true;
363 }
364 }
365 return false;
366 }
367
368 @Override
369 protected boolean isLevelEnabled(int logLevel) {
370 return (logLevel >= LOG_LEVEL_INFO);
371 }
372
373 @Override
374 protected void log(int type, Object message, Throwable t) {
375 super.log(type, message, t);
376 messages.add(message.toString());
377 }
378 }
379 }
380