1 package org.jbpm.jpdl.xml; 2 3 import java.io.StringReader ; 4 import java.util.List ; 5 6 import org.dom4j.Element; 7 import org.jbpm.graph.def.Action; 8 import org.jbpm.graph.def.Event; 9 import org.jbpm.graph.def.Node; 10 import org.jbpm.graph.def.ProcessDefinition; 11 import org.jbpm.graph.def.Transition; 12 import org.jbpm.graph.node.State; 13 import org.jbpm.instantiation.Delegation; 14 import org.jbpm.jpdl.JpdlException; 15 16 18 public class ActionValidatingXmlTest extends AbstractXmlTestCase { 19 20 private static final String schemaNamespace = "xmlns=\"http://jbpm.org/3/jpdl\""; 21 private static final String JPDL_NAMESPACE = "http://jbpm.org/3/jpdl"; 22 23 public void testInvalidXML() { 24 25 try 26 { 27 ProcessDefinition.parseXmlString( 28 "<process-definition " + 29 schemaNamespace + " >" + 30 " <event type='process-start'>" + 31 " <action xyz='2' class='one'/>" + 32 " <action class='two'/>" + 33 " <action class='three'/>" + 34 " </event>" + 35 "</process-definition>" ); 36 fail("Parser did not catch schema violations as expected."); 37 } 38 catch(JpdlException je) 39 { 40 } 42 43 } 44 45 public void testReadProcessDefinitionAction() { 46 47 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 48 "<process-definition " + 49 schemaNamespace + " >" + 50 " <event type='process-start'>" + 51 " <action class='one'/>" + 52 " <action class='two'/>" + 53 " <action class='three'/>" + 54 " </event>" + 55 "</process-definition>" ); 56 57 58 Event event = processDefinition.getEvent("process-start"); 59 assertEquals(3, event.getActions().size()); 60 assertEquals("one", ((Action)event.getActions().get(0)).getActionDelegation().getClassName()); 61 assertEquals("two", ((Action)event.getActions().get(1)).getActionDelegation().getClassName()); 62 assertEquals("three", ((Action)event.getActions().get(2)).getActionDelegation().getClassName()); 63 64 } 65 66 public void testWriteProcessDefinitionAction() throws Exception { 67 ProcessDefinition processDefinition = new ProcessDefinition(); 68 Event event = new Event("process-start"); 69 processDefinition.addEvent(event); 70 event.addAction(new Action(new Delegation("one"))); 71 event.addAction(new Action(new Delegation("two"))); 72 event.addAction(new Action(new Delegation("three"))); 73 74 Element eventElement = toXmlAndParse( processDefinition, "/process-definition/event", JPDL_NAMESPACE ); 75 76 List actionElements = eventElement.elements("action"); 77 78 assertEquals(3, actionElements.size()); 79 assertEquals("one", ((Element)actionElements.get(0)).attributeValue("class")); 80 assertEquals("two", ((Element)actionElements.get(1)).attributeValue("class")); 81 assertEquals("three", ((Element)actionElements.get(2)).attributeValue("class")); 82 } 83 84 public void testReadActionConfigType() { 85 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 86 "<process-definition " + schemaNamespace + ">" + 87 " <action name='burps' class='org.foo.Burps' config-type='bean' />" + 88 "</process-definition>" 89 ); 90 91 assertEquals("bean", processDefinition.getAction("burps").getActionDelegation().getConfigType() ); 92 } 93 94 public void testWriteActionConfigType() throws Exception { 95 ProcessDefinition processDefinition = new ProcessDefinition(); 96 Delegation actionDelegate = new Delegation("one"); 97 actionDelegate.setConfigType("bean"); 98 Action action = new Action(actionDelegate); 99 action.setName("a"); 100 processDefinition.addAction(action); 101 Element actionElement = toXmlAndParse( processDefinition, "/process-definition/action", JPDL_NAMESPACE ); 102 assertEquals("bean", actionElement.attributeValue("config-type")); 103 } 104 105 public void testReadActionXmlConfiguration() { 106 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 107 "<process-definition " + schemaNamespace + ">\n" + 108 " <action name='burps' class='org.foo.Burps' config-type='bean'>\n" + 109 " <id>63</id>\n" + 110 " <greeting>aloha</greeting>\n" + 111 " </action>\n" + 112 "</process-definition>" 113 ); 114 115 Action action = processDefinition.getAction("burps"); 116 Delegation instantiatableDelegate = action.getActionDelegation(); 117 assertTrue(instantiatableDelegate.getConfiguration().indexOf("<id xmlns=\"http://jbpm.org/3/jpdl\">63</id>")!=-1); 118 assertTrue(instantiatableDelegate.getConfiguration().indexOf("<greeting xmlns=\"http://jbpm.org/3/jpdl\">aloha</greeting>")!=-1 ); 119 } 120 121 public void testWriteActionXmlConfiguration() throws Exception { 122 ProcessDefinition processDefinition = new ProcessDefinition(); 123 Delegation actionDelegate = new Delegation("one"); 124 actionDelegate.setConfiguration("<id>63</id><greeting>aloha</greeting>"); 125 Action action = new Action(actionDelegate); 126 action.setName("a"); 127 processDefinition.addAction(action); 128 Element actionElement = toXmlAndParse( processDefinition, "/process-definition/action", JPDL_NAMESPACE ); 129 assertEquals("63", actionElement.elementTextTrim("id")); 130 assertEquals("aloha", actionElement.elementTextTrim("greeting")); 131 } 132 133 public void testReadActionTextConfiguration() { 134 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 135 "<process-definition " + schemaNamespace + ">\n" + 136 " <action name='burps' class='org.foo.Burps' config-type='constructor'>\n" + 137 " a piece of configuration text\n" + 138 " </action>\n" + 139 "</process-definition>" 140 ); 141 142 Action action = processDefinition.getAction("burps"); 143 Delegation instantiatableDelegate = action.getActionDelegation(); 144 assertTrue(instantiatableDelegate.getConfiguration().indexOf("a piece of configuration text")!=-1); 145 } 146 147 public void testWriteActionTextConfiguration() throws Exception { 148 ProcessDefinition processDefinition = new ProcessDefinition(); 149 Delegation actionDelegate = new Delegation("one"); 150 actionDelegate.setConfiguration("a piece of configuration text"); 151 actionDelegate.setConfigType("constructor"); 152 Action action = new Action(actionDelegate); 153 action.setName("a"); 154 processDefinition.addAction(action); 155 Element actionElement = toXmlAndParse( processDefinition, "/process-definition/action", JPDL_NAMESPACE ); 156 assertEquals("a piece of configuration text", actionElement.getTextTrim()); 157 } 158 159 public void testReadActionAcceptPropagatedEventsDefault() { 160 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 161 "<process-definition " + schemaNamespace + ">" + 162 " <action name='burps' class='org.foo.Burps' />" + 163 "</process-definition>" 164 ); 165 166 Action action = processDefinition.getAction("burps"); 167 assertTrue(action.acceptsPropagatedEvents()); 168 } 169 170 public void testReadActionAcceptPropagatedEventsTrue() { 171 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 172 "<process-definition " + schemaNamespace + ">" + 173 " <action name='burps' class='org.foo.Burps' accept-propagated-events='true' />" + 174 "</process-definition>" 175 ); 176 177 Action action = processDefinition.getAction("burps"); 178 assertTrue(action.acceptsPropagatedEvents()); 179 } 180 181 public void testReadActionAcceptPropagatedEventsFalse() { 182 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 183 "<process-definition " + schemaNamespace + ">" + 184 " <action name='burps' class='org.foo.Burps' accept-propagated-events='false' />" + 185 "</process-definition>" 186 ); 187 188 Action action = processDefinition.getAction("burps"); 189 assertFalse(action.acceptsPropagatedEvents()); 190 } 191 192 public void testWriteActionAcceptPropagatedEventsDefault() throws Exception { 193 ProcessDefinition processDefinition = new ProcessDefinition(); 194 Delegation actionDelegate = new Delegation("one"); 195 Action action = new Action(actionDelegate); 196 action.setName("a"); 197 processDefinition.addAction(action); 198 Element actionElement = toXmlAndParse( processDefinition, "/process-definition/action", JPDL_NAMESPACE ); 199 assertNull(actionElement.attribute("accept-propagated-events")); 200 } 201 202 public void testWriteActionAcceptPropagatedEventsTrue() throws Exception { 203 ProcessDefinition processDefinition = new ProcessDefinition(); 204 Delegation actionDelegate = new Delegation("one"); 205 Action action = new Action(actionDelegate); 206 action.setName("a"); 207 action.setPropagationAllowed(true); 208 processDefinition.addAction(action); 209 Element actionElement = toXmlAndParse( processDefinition, "/process-definition/action", JPDL_NAMESPACE ); 210 assertNull(actionElement.attribute("accept-propagated-events")); 211 } 212 213 public void testWriteActionAcceptPropagatedEventsFalse() throws Exception { 214 ProcessDefinition processDefinition = new ProcessDefinition(); 215 Delegation actionDelegate = new Delegation("one"); 216 Action action = new Action(actionDelegate); 217 action.setName("a"); 218 action.setPropagationAllowed(false); 219 processDefinition.addAction(action); 220 Element actionElement = toXmlAndParse( processDefinition, "/process-definition/action", JPDL_NAMESPACE ); 221 assertEquals("false", actionElement.attributeValue("accept-propagated-events")); 222 } 223 224 public void testReadNodeActionName() { 225 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 226 "<process-definition " + schemaNamespace + ">" + 227 " <node name='a'>" + 228 " <action class='one'/>" + 229 " <event type='node-enter'>" + 230 " <action name='burps' class='org.foo.Burps'/>" + 231 " </event>" + 232 " </node>" + 233 "</process-definition>" 234 ); 235 Action burps = (Action)processDefinition.getNode("a").getEvent("node-enter").getActions().get(0); 236 assertEquals("burps", burps.getName()); 237 } 238 239 public void testWriteNodeActionName() throws Exception { 240 ProcessDefinition processDefinition = new ProcessDefinition(); 241 Node node = processDefinition.addNode( new Node() ); 242 Delegation instantiatableDelegate = new Delegation(); 243 instantiatableDelegate.setClassName("com.foo.Fighting"); 244 node.setAction(new Action(instantiatableDelegate)); 245 246 Element actionElement = AbstractXmlTestCase.toXmlAndParse( processDefinition, "/process-definition/node/action", JPDL_NAMESPACE ); 247 assertNotNull(actionElement); 248 assertEquals("action", actionElement.getName()); 249 assertEquals("com.foo.Fighting", actionElement.attributeValue("class")); 250 } 251 252 public void testReadNodeEnterAction() { 253 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 254 "<process-definition " + schemaNamespace + ">" + 255 " <node name='a'>" + 256 " <action class='one'/>" + 257 " <event type='node-enter'>" + 258 " <action class='org.foo.Burps'/>" + 259 " </event>" + 260 " </node>" + 261 "</process-definition>" 262 ); 263 assertEquals("org.foo.Burps", ((Action)processDefinition.getNode("a").getEvent("node-enter").getActions().get(0)).getActionDelegation().getClassName()); 264 } 265 266 public void testWriteNodeEnterAction() throws Exception { 267 ProcessDefinition processDefinition = new ProcessDefinition(); 268 Node node = processDefinition.addNode( new Node() ); 269 Delegation instantiatableDelegate = new Delegation(); 270 instantiatableDelegate.setClassName("com.foo.Fighting"); 271 node.addEvent(new Event("node-enter")).addAction(new Action(instantiatableDelegate)); 272 Element element = AbstractXmlTestCase.toXmlAndParse( processDefinition, "/process-definition/node[1]/event[1]", JPDL_NAMESPACE ); 273 274 assertNotNull(element); 275 assertEquals("event", element.getName()); 276 assertEquals("node-enter", element.attributeValue("type")); 277 assertEquals(1, element.elements("action").size()); 278 279 element = element.element("action"); 280 assertNotNull(element); 281 assertEquals("action", element.getName()); 282 assertEquals("com.foo.Fighting", element.attributeValue("class")); 283 } 284 285 public void testParseAndWriteOfNamedEventActions() throws Exception { 286 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 287 "<process-definition " + schemaNamespace + ">\n" + 288 " <node name='a'>" + 289 " <action class='one'/>" + 290 " <event type='node-enter'>" + 291 " <action name='burps' class='org.foo.Burps'/>" + 292 " </event>" + 293 " </node>" + 294 "</process-definition>" 295 ); 296 Action burps = (Action)processDefinition.getNode("a").getEvent("node-enter").getActions().get(0); 297 assertSame(burps, processDefinition.getAction("burps")); 298 Element processDefinitionElement = toXmlAndParse( processDefinition, "/process-definition" ); 299 assertEquals(0, processDefinitionElement.elements("action").size()); 300 } 301 302 public void testParseStateAction() { 303 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 304 "<process-definition " + schemaNamespace + ">\n" + 305 " <state name='a'>\n" + 306 " <event type='node-enter'>\n" + 307 " <action class='org.foo.Burps' config-type='constructor'>\n" + 308 " this text should be passed in the constructor\n" + 309 " </action>\n" + 310 " </event>\n" + 311 " </state>\n" + 312 "</process-definition>" 313 ); 314 315 Node node = processDefinition.getNode("a"); 316 Event event = node.getEvent("node-enter"); 317 Action action = (Action) event.getActions().iterator().next(); 318 Delegation instantiatableDelegate = action.getActionDelegation(); 319 assertEquals("org.foo.Burps", instantiatableDelegate.getClassName()); 320 assertEquals("constructor", instantiatableDelegate.getConfigType()); 321 assertTrue(instantiatableDelegate.getConfiguration().indexOf("this text should be passed in the constructor")!=-1 ); 322 } 323 324 public void testParseTransitionAction() { 325 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 326 "<process-definition " + schemaNamespace + ">\n" + 327 " <state name='a'>" + 328 " <transition to='b'>" + 329 " <action class='org.foo.Burps'/>" + 330 " </transition>" + 331 " </state>" + 332 " <state name='b' />" + 333 "</process-definition>" 334 ); 335 336 Node node = processDefinition.getNode("a"); 337 assertEquals( 1, node.getLeavingTransitionsMap().size() ); 338 Transition transition = node.getDefaultLeavingTransition(); 339 Event event = transition.getEvent(Event.EVENTTYPE_TRANSITION); 340 Action action = (Action) event.getActions().iterator().next(); 341 Delegation instantiatableDelegate = action.getActionDelegation(); 342 assertEquals("org.foo.Burps", instantiatableDelegate.getClassName()); 343 } 344 345 public void testParseReferencedAction() { 346 ProcessDefinition processDefinition = null; 347 try 348 { 349 processDefinition = ProcessDefinition.parseXmlString( 350 "<process-definition " + schemaNamespace + ">\n" + 351 " <node name='a'>" + 352 " <action class='one'/>" + 353 " <transition to='b'>" + 354 " <action ref-name='scratch'/>" + 355 " </transition>" + 356 " </node>" + 357 " <node name='b'>" + 358 " <action class='two'/>" + 359 " </node>" + 360 " <action name='scratch' class='com.itch.Scratch' />" + 361 "</process-definition>" 362 ); 363 } 364 catch(JpdlException je) 365 { 366 fail("XML did not pass validation as expected:\n" + je.toString()); 367 } 368 369 Node node = processDefinition.getNode("a"); 370 Transition transition = node.getDefaultLeavingTransition(); 371 Event event = transition.getEvent(Event.EVENTTYPE_TRANSITION); 372 Action transitionAction = (Action) event.getActions().iterator().next(); 373 374 Action processAction = processDefinition.getAction("scratch"); 375 assertEquals("scratch", processAction.getName()); 376 assertSame(processAction, transitionAction.getReferencedAction()); 377 378 Delegation instantiatableDelegate = processAction.getActionDelegation(); 379 assertEquals("com.itch.Scratch", instantiatableDelegate.getClassName()); 380 } 381 382 public void testParseActionWithoutClass() { 383 StringReader stringReader = new StringReader ( 384 "<process-definition " + schemaNamespace + ">\n" + 385 " <node name='a'>\n" + 386 " <action class='one'/>" + 387 " <event type='node-enter'>\n" + 388 " <action />\n" + 389 " </event>\n" + 390 " </node>\n" + 391 "</process-definition>"); 392 JpdlXmlReader jpdlReader = new JpdlXmlReader(stringReader); 393 jpdlReader.readProcessDefinition(); 394 assertTrue(Problem.containsProblemsOfLevel(jpdlReader.problems, Problem.LEVEL_WARNING)); 395 } 396 397 public void testParseActionWithInvalidReference() { 398 StringReader stringReader = new StringReader ( 399 "<process-definition " + schemaNamespace + ">\n" + 400 " <node name='a'>" + 401 " <action class='one'/>" + 402 " <event type='node-enter'>" + 403 " <action ref-name='non-existing-action-name'/>" + 404 " </event>" + 405 " </node>" + 406 "</process-definition>"); 407 JpdlXmlReader jpdlReader = new JpdlXmlReader(stringReader); 408 jpdlReader.readProcessDefinition(); 409 assertTrue(Problem.containsProblemsOfLevel(jpdlReader.problems, Problem.LEVEL_WARNING)); 410 } 411 412 public void testWriteTransitionAction() throws Exception { 413 ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( 414 "<process-definition " + schemaNamespace + ">\n" + 415 " <state name='a'>" + 416 " <transition to='b' />" + 417 " </state>" + 418 " <state name='b' />" + 419 "</process-definition>" 420 ); 421 Transition transition = processDefinition.getNode("a").getDefaultLeavingTransition(); 422 423 Delegation instantiatableDelegate = new Delegation(); 424 instantiatableDelegate.setClassName("com.foo.Fighting"); 425 transition.addEvent(new Event(Event.EVENTTYPE_TRANSITION)).addAction(new Action(instantiatableDelegate)); 426 Element element = AbstractXmlTestCase.toXmlAndParse( processDefinition, "/process-definition/state/transition", JPDL_NAMESPACE ); 427 428 assertNotNull(element); 429 assertEquals("transition", element.getName()); 430 assertEquals(1, element.elements("action").size()); 431 432 element = element.element("action"); 433 assertNotNull(element); 434 assertEquals("action", element.getName()); 435 assertEquals("com.foo.Fighting", element.attributeValue("class")); 436 } 437 438 public void testWriteConfigurableAction() throws Exception { 439 ProcessDefinition processDefinition = new ProcessDefinition(); 440 State state = (State) processDefinition.addNode( new State("a") ); 441 Delegation instantiatableDelegate = new Delegation(); 442 instantiatableDelegate.setClassName("com.foo.Fighting"); 443 instantiatableDelegate.setConfigType("bean"); 444 instantiatableDelegate.setConfiguration("<id>4</id><greeting>aloha</greeting>"); 445 state.addEvent(new Event("node-enter")).addAction(new Action(instantiatableDelegate)); 446 Element element = AbstractXmlTestCase.toXmlAndParse( processDefinition, "/process-definition/state[1]/event[1]/action[1]", JPDL_NAMESPACE ); 447 448 assertNotNull(element); 449 assertEquals("action", element.getName()); 450 assertEquals("bean", element.attributeValue("config-type")); 451 assertEquals("4", element.element("id").getTextTrim() ); 452 assertEquals("aloha", element.element("greeting").getTextTrim() ); 453 } 454 455 public void testWriteReferenceAction() throws Exception { 456 ProcessDefinition processDefinition = new ProcessDefinition(); 457 458 Delegation instantiatableDelegate = new Delegation(); 460 instantiatableDelegate.setClassName("com.foo.Fighting"); 461 instantiatableDelegate.setConfigType("bean"); 462 instantiatableDelegate.setConfiguration("<id>4</id><greeting>aloha</greeting>"); 463 Action action = new Action(); 464 action.setName("pina colada"); 465 action.setActionDelegation(instantiatableDelegate); 466 processDefinition.addAction(action); 467 468 State state = (State) processDefinition.addNode( new State() ); 470 Action refAction = new Action(); 471 refAction.setReferencedAction(action); 472 state.addEvent(new Event(Event.EVENTTYPE_NODE_ENTER)).addAction(refAction); 473 474 AbstractXmlTestCase.toXmlAndParse( processDefinition, "/process-definition/state[1]/event[1]/action[1]" ); 475 } 476 } 477 | Popular Tags |