Author: ate Date: Thu Oct 9 22:52:54 2014 New Revision: 1630612 URL: http://svn.apache.org/r1630612 Log: SCXML-209: improve and fix legal state configuration check in ModelUpdater
Added: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml (with props) commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml (with props) commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml (with props) Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/io/ModelUpdater.java commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/SCXMLReaderTest.java Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/io/ModelUpdater.java URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/io/ModelUpdater.java?rev=1630612&r1=1630611&r2=1630612&view=diff ============================================================================== --- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/io/ModelUpdater.java (original) +++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/io/ModelUpdater.java Thu Oct 9 22:52:54 2014 @@ -17,7 +17,6 @@ package org.apache.commons.scxml2.io; import java.text.MessageFormat; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -472,35 +471,35 @@ final class ModelUpdater { * * @param tts The transition targets * @return Whether this is a legal configuration - * @see <a href=http://www.w3.org/TR/2014/CR-scxml-20140313/#LegalStateConfigurations"> - * http://www.w3.org/TR/2014/CR-scxml-20140313/#LegalStateConfigurations</a> + * @see <a href=http://www.w3.org/TR/scxml/#LegalStateConfigurations"> + * http://www.w3.org/TR/scxml/#LegalStateConfigurations</a> */ private static boolean verifyTransitionTargets(final Set<TransitionTarget> tts) { - if (tts.size() <= 1) { // No contention + if (tts.size() < 2) { // No contention return true; } - - Set<EnterableState> parents = new HashSet<EnterableState>(); + TransitionTarget first = null; + int i = 0; for (TransitionTarget tt : tts) { - boolean hasParallelParent = false; - for (int i = tt.getNumberOfAncestors()-1; i > -1; i--) { - EnterableState parent = tt.getAncestor(i); - if (parent instanceof Parallel) { - hasParallelParent = true; - // keep on 'reading' as a parallel may have a parent parallel (and even intermediate states) - } - else { - if (!parents.add(parent)) { - // this TransitionTarget is an descendant of another, or shares the same Parallel region - return false; - } - } - } - if (!hasParallelParent || !(tt.getAncestor(0) instanceof Parallel)) { - // multiple targets MUST all be children of a shared parallel + if (first == null) { + first = tt; + i = tt.getNumberOfAncestors(); + continue; + } + // find least common ancestor + for (i = Math.min(i, tt.getNumberOfAncestors()); i > 0 && first.getAncestor(i-1) != tt.getAncestor(i-1); i--) ; + if (i == 0) { + // no common ancestor return false; } + // ensure no target is an ancestor of any other target on the list + for (TransitionTarget other : tts) { + if (other != tt && other.isDescendantOf(tt) || tt.isDescendantOf(other)) { + return false; + } + } } - return true; + // least common ancestor must be a parallel + return first != null && i > 0 && first.getAncestor(i-1) instanceof Parallel; } } \ No newline at end of file Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java?rev=1630612&r1=1630611&r2=1630612&view=diff ============================================================================== --- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java (original) +++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCXMLTestHelper.java Thu Oct 9 22:52:54 2014 @@ -66,6 +66,10 @@ public class SCXMLTestHelper { return Integer.toString(++sequence); } + public static URL getResource(String name) { + return SCXMLTestHelper.class.getClassLoader().getResource(name); + } + public static SCXML parse(final URL url) throws Exception { return parse(url, null); } Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/SCXMLReaderTest.java URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/SCXMLReaderTest.java?rev=1630612&r1=1630611&r2=1630612&view=diff ============================================================================== --- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/SCXMLReaderTest.java (original) +++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/SCXMLReaderTest.java Thu Oct 9 22:52:54 2014 @@ -192,7 +192,25 @@ public class SCXMLReaderTest { Final foo = (Final) scxml.getInitialTransition().getTargets().iterator().next(); Assert.assertEquals("foo", foo.getId()); } - + + @Test + public void testSCXMLValidTransitionTargets() throws Exception { + // ModelUpdater will fail on invalid transition targets + SCXMLTestHelper.parse(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml")); + } + + @Test(expected=org.apache.commons.scxml2.model.ModelException.class) + public void testSCXMLInValidTransitionTargets1() throws Exception { + // ModelUpdater will fail on invalid transition targets + SCXMLTestHelper.parse(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml")); + } + + @Test(expected=org.apache.commons.scxml2.model.ModelException.class) + public void testSCXMLInValidTransitionTargets2() throws Exception { + // ModelUpdater will fail on invalid transition targets + SCXMLTestHelper.parse(SCXMLTestHelper.getResource("org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml")); + } + @Test public void testSCXMLReaderCustomActionWithBodyTextSample() throws Exception { List<CustomAction> cas = new ArrayList<CustomAction>(); Added: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml?rev=1630612&view=auto ============================================================================== --- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml (added) +++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml Thu Oct 9 22:52:54 2014 @@ -0,0 +1,36 @@ +<?xml version="1.0"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> +<!-- used in SCXMLReaderTest to ensure that multiple transition targets of which one or more is an ancestor of another + will be marked invalid by ModuleUpdater#verifyTransitionTargets and according to the rules in + http://www.w3.org/TR/scxml/#LegalStateConfigurations +--> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" + initial="s1c1p1s0 s1c1p1s1 s1c1p1s1s1"> + <state id="s1"> + <state id="s1s1"> + <state id="s1s1s1"/> + <parallel id="s1s1p1"> + <state id="s1c1p1s0"/> + <state id="s1c1p1s1"> + <state id="s1c1p1s1s1"/> + </state> + <state id="s1c1p1s2"/> + </parallel> + </state> + </state> +</scxml> Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml ------------------------------------------------------------------------------ svn:keywords = Id Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test1.xml ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml?rev=1630612&view=auto ============================================================================== --- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml (added) +++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml Thu Oct 9 22:52:54 2014 @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> +<!-- used in SCXMLReaderTest to ensure that multiple transition targets without a least common parallel ancestor + will be marked invalid by ModuleUpdater#verifyTransitionTargets and according to the rules in + http://www.w3.org/TR/scxml/#LegalStateConfigurations +--> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" + initial="s1c1p1s0 s1c1p1s1 s1c1p2s0"> + <state id="s1"> + <state id="s1s1"> + <state id="s1s1s1"/> + <parallel id="s1s1p1"> + <state id="s1c1p1s0"/> + <state id="s1c1p1s1"/> + <state id="s1c1p1s2"/> + </parallel> + <parallel id="s1s1p2"> + <state id="s1c1p2s0"/> + </parallel> + </state> + </state> +</scxml> Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml ------------------------------------------------------------------------------ svn:keywords = Id Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-invalid-transition-targets-test2.xml ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml?rev=1630612&view=auto ============================================================================== --- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml (added) +++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml Thu Oct 9 22:52:54 2014 @@ -0,0 +1,34 @@ +<?xml version="1.0"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> +<!-- used in SCXMLReaderTest to validate that multiple transition targets within a deeply nested parallel + can be reached as validated by ModuleUpdater#verifyTransitionTargets and according to the rules in + http://www.w3.org/TR/scxml/#LegalStateConfigurations +--> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" + initial="s1c1p1s1 s1c1p1s2 s1c1p1s3"> + <state id="s1"> + <state id="s1s1"> + <state id="s1s1s1"/> + <parallel id="s1s1p1"> + <state id="s1c1p1s1"/> + <state id="s1c1p1s2"/> + <state id="s1c1p1s3"/> + </parallel> + </state> + </state> +</scxml> Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml ------------------------------------------------------------------------------ svn:eol-style = native Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml ------------------------------------------------------------------------------ svn:keywords = Id Propchange: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/io/scxml-valid-transition-targets-test.xml ------------------------------------------------------------------------------ svn:mime-type = text/plain