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

Classes in this File | Line Coverage | Branch Coverage | Complexity
Path |
98% |
100% |
| 3.2857142857142856;3.286

1 |  |
     /*
2 |  |
      * Licensed to the Apache Software Foundation (ASF) under one or more
3 |  |
      * contributor license agreements.  See the NOTICE file distributed with
4 |  |
      * this work for additional information regarding copyright ownership.
5 |  |
      * The ASF licenses this file to You under the Apache License, Version 2.0
6 |  |
      * (the "License"); you may not use this file except in compliance with
7 |  |
      * the License.  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 |  |
     package org.apache.commons.scxml.model;
18 |  |
19 |  |
     import java.io.Serializable;
20 |  |
     import java.util.ArrayList;
21 |  |
     import java.util.Iterator;
22 |  |
     import java.util.LinkedList;
23 |  |
     import java.util.List;
24 |  |
25 |  |
     import org.apache.commons.scxml.SCXMLHelper;
26 |  |
27 |  |
     /**
28 |  |
      * A helper class for this SCXML implementation that represents the
29 |  |
      * path taken to transition from one TransitionTarget to another in
30 |  |
      * the SCXML document.
31 |  |
      *
32 |  |
      * The Path consists of the &quot;up segment&quot; that traces up to
33 |  |
      * the least common ancestor and a &quot;down segment&quot; that traces
34 |  |
      * down to the target of the Transition.
35 |  |
      *
36 |  |
      */
37 |  |
     public class Path implements Serializable {
38 |  |
39 |  |
         /**
40 |  |
          * Serial version UID.
41 |  |
          */
42 |  |
         private static final long serialVersionUID = 1L;
43 |  |
44 |  |
         /**
45 |  |
          * The list of TransitionTargets in the &quot;up segment&quot;.
46 |  |
          */
47 | 110 |
         private List upSeg = new ArrayList();
48 |  |
49 |  |
         /**
50 |  |
          * The list of TransitionTargets in the &quot;down segment&quot;.
51 |  |
          */
52 | 110 |
         private List downSeg = new ArrayList();
53 |  |
54 |  |
         /**
55 |  |
          * &quot;Lowest&quot; state which is not being exited nor entered by
56 |  |
          * the transition.
57 |  |
          */
58 | 110 |
         private State scope = null;
59 |  |
60 |  |
         /**
61 |  |
          * Whether the path crosses region border(s).
62 |  |
          */
63 | 110 |
         private boolean crossRegion = false;
64 |  |
65 |  |
         /**
66 |  |
          * Constructor.
67 |  |
          *
68 |  |
          * @param source The source TransitionTarget
69 |  |
          * @param target The target TransitionTarget
70 |  |
          */
71 | 110 |
         Path(final TransitionTarget source, final TransitionTarget target) {
72 | 110 |
             if (target == null) {
73 |  |
                 //a local "stay" transition
74 | 6 |
                 scope = (State) source;
75 |  |
                 //all segments remain empty
76 |  |
             } else {
77 | 104 |
                 TransitionTarget tt = SCXMLHelper.getLCA(source, target);
78 | 104 |
                 if (tt != null) {
79 | 38 |
                     if (tt instanceof State) {
80 | 38 |
                         scope = (State) tt;
81 |  |
                     } else {
82 | 0 |
                         scope = tt.getParentState();
83 |  |
                     }
84 | 38 |
                     if (scope == source || scope == target) {
85 | 4 |
                         scope = scope.getParentState();
86 |  |
                     }
87 |  |
                 }
88 | 104 |
                 tt = source;
89 | 217 |
                 while (tt != scope) {
90 | 113 |
                     upSeg.add(tt);
91 | 113 |
                     if (tt instanceof State) {
92 | 107 |
                         State st = (State) tt;
93 | 107 |
                         if (st.isRegion()) {
94 | 4 |
                             crossRegion = true;
95 |  |
                         }
96 |  |
                     }
97 | 113 |
                     tt = tt.getParent();
98 |  |
                 }
99 | 104 |
                 tt = target;
100 | 218 |
                 while (tt != scope) {
101 | 114 |
                     downSeg.add(0, tt);
102 | 114 |
                     if (tt instanceof State) {
103 | 105 |
                         State st = (State) tt;
104 | 105 |
                         if (st.isRegion()) {
105 | 4 |
                             crossRegion = true;
106 |  |
                         }
107 |  |
                     }
108 | 114 |
                     tt = tt.getParent();
109 |  |
                 }
110 |  |
             }
111 | 110 |
         }
112 |  |
113 |  |
         /**
114 |  |
          * Does this &quot;path&quot; cross regions.
115 |  |
          *
116 |  |
          * @return true when the path crosses a region border(s)
117 |  |
          * @see State#isRegion()
118 |  |
          */
119 |  |
         public final boolean isCrossRegion() {
120 | 233 |
             return crossRegion;
121 |  |
         }
122 |  |
123 |  |
         /**
124 |  |
          * Get the list of regions exited.
125 |  |
          *
126 |  |
          * @return List a list of exited regions sorted bottom-up;
127 |  |
          *         no order defined for siblings
128 |  |
          * @see State#isRegion()
129 |  |
          */
130 |  |
         public final List getRegionsExited() {
131 | 5 |
             LinkedList ll = new LinkedList();
132 | 5 |
             for (Iterator i = upSeg.iterator(); i.hasNext();) {
133 | 6 |
                 Object o = i.next();
134 | 6 |
                 if (o instanceof State) {
135 | 3 |
                     State st = (State) o;
136 | 3 |
                     if (st.isRegion()) {
137 | 2 |
                         ll.add(st);
138 |  |
                     }
139 |  |
                 }
140 |  |
             }
141 | 5 |
             return ll;
142 |  |
         }
143 |  |
144 |  |
         /**
145 |  |
          * Get the list of regions entered.
146 |  |
          *
147 |  |
          * @return List a list of entered regions sorted top-down; no order
148 |  |
          *         defined for siblings
149 |  |
          * @see State#isRegion()
150 |  |
          */
151 |  |
         public final List getRegionsEntered() {
152 | 5 |
             LinkedList ll = new LinkedList();
153 | 5 |
             for (Iterator i = downSeg.iterator(); i.hasNext();) {
154 | 6 |
                 Object o = i.next();
155 | 6 |
                 if (o instanceof State) {
156 | 3 |
                     State st = (State) o;
157 | 3 |
                     if (st.isRegion()) {
158 | 2 |
                         ll.add(st);
159 |  |
                     }
160 |  |
                 }
161 |  |
             }
162 | 5 |
             return ll;
163 |  |
         }
164 |  |
165 |  |
         /**
166 |  |
          * Get the farthest state from root which is not being exited
167 |  |
          * nor entered by the transition (null if scope is document root).
168 |  |
          *
169 |  |
          * @return State scope of the transition path, null means global transition
170 |  |
          *         (SCXML document level) Scope is the least state which is not
171 |  |
          *         being exited nor entered by the transition.
172 |  |
          */
173 |  |
         public final State getScope() {
174 | 8 |
             return scope;
175 |  |
         }
176 |  |
177 |  |
         /**
178 |  |
          * Get the upward segment.
179 |  |
          *
180 |  |
          * @return List upward segment of the path up to the scope
181 |  |
          */
182 |  |
         public final List getUpwardSegment() {
183 | 117 |
             return upSeg;
184 |  |
         }
185 |  |
186 |  |
         /**
187 |  |
          * Get the downward segment.
188 |  |
          *
189 |  |
          * @return List downward segment from the scope to the target
190 |  |
          */
191 |  |
         public final List getDownwardSegment() {
192 | 117 |
             return downSeg;
193 |  |
         }
194 |  |
     }
195 |  |