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

Classes in this File Line Coverage Branch Coverage Complexity
Path
98% 
100% 
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 "up segment" that traces up to
 33  
  * the least common ancestor and a "down segment" 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 "up segment".
 46  
      */
 47  110
     private List upSeg = new ArrayList();
 48  
 
 49  
     /**
 50  
      * The list of TransitionTargets in the "down segment".
 51  
      */
 52  110
     private List downSeg = new ArrayList();
 53  
 
 54  
     /**
 55  
      * "Lowest" 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 "path" 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