Coverage Report - com.sdmetrics.model.XMIContextStack - www.sdmetrics.com
 
Classes in this File Line Coverage Branch Coverage Complexity
XMIContextStack
100%
33/33
100%
10/10
1,455
XMIContextStack$Context
100%
1/1
N/A
1,455
 
 1  
 /*
 2  
  * SDMetrics Open Core for UML design measurement
 3  
  * Copyright (c) Juergen Wuest
 4  
  * To contact the author, see <http://www.sdmetrics.com/Contact.html>.
 5  
  * 
 6  
  * This file is part of the SDMetrics Open Core.
 7  
  * 
 8  
  * SDMetrics Open Core is free software: you can redistribute it and/or modify
 9  
  * it under the terms of the GNU Affero General Public License as
 10  
  * published by the Free Software Foundation, either version 3 of the
 11  
  * License, or (at your option) any later version.
 12  
     
 13  
  * SDMetrics Open Core is distributed in the hope that it will be useful,
 14  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16  
  * GNU Affero General Public License for more details.
 17  
  *
 18  
  * You should have received a copy of the GNU Affero General Public License
 19  
  * along with SDMetrics Open Core.  If not, see <http://www.gnu.org/licenses/>.
 20  
  *
 21  
  */
 22  
 package com.sdmetrics.model;
 23  
 
 24  
 import java.util.ArrayList;
 25  
 
 26  
 /**
 27  
  * Manages the stack of model elements being processed during parsing of the XMI
 28  
  * file.
 29  
  */
 30  
 class XMIContextStack {
 31  
 
 32  
         /**
 33  
          * Class to store parser context information for a model element on the
 34  
          * stack. The context stack holds instances of this class.
 35  
          */
 36  1826
         private static class Context {
 37  
                 /** The model element of the parse context. */
 38  
                 ModelElement modelElement;
 39  
                 /** Nesting level of the XML element of that model element. */
 40  
                 int nestingLevel;
 41  
                 /** The XMI transformation to use for the model element. */
 42  
                 XMITransformation transformation;
 43  
                 /** The currently active XMI trigger. */
 44  
                 XMITrigger activeTrigger;
 45  
         }
 46  
 
 47  
         /** Model element stack to keep track of the parser state. */
 48  
         private final ArrayList<Context> stack;
 49  
         /** Index of the top element. */
 50  
         private int topIndex;
 51  
         /** Top element on the stack. */
 52  
         private Context top;
 53  
 
 54  
         /** Create a new, empty stack. */
 55  140
         XMIContextStack() {
 56  140
                 stack = new ArrayList<Context>();
 57  
                 // keep a default element at the bottom of the stack with reasonable
 58  
                 // values to return when the stack is otherwise empty.
 59  140
                 top = new Context();
 60  140
                 stack.add(top);
 61  140
                 topIndex = 0;
 62  140
         }
 63  
 
 64  
         /**
 65  
          * Pushes a new model element on top of the stack.
 66  
          * 
 67  
          * @param element the model element
 68  
          * @param trans the XMI transformation applicable to this model element.
 69  
          * @param nesting Nesting level of the XML element that represents the model
 70  
          *        element.
 71  
          */
 72  
         void push(ModelElement element, XMITransformation trans, int nesting) {
 73  13590
                 topIndex++;
 74  13590
                 if (topIndex >= stack.size()) {
 75  773
                         top = new Context();
 76  773
                         stack.add(top);
 77  773
                 } else {
 78  12817
                         top = stack.get(topIndex);
 79  
                 }
 80  
 
 81  13590
                 top.modelElement = element;
 82  13590
                 top.transformation = trans;
 83  13590
                 top.nestingLevel = nesting;
 84  13590
         }
 85  
 
 86  
         /**
 87  
          * Removes the model element on top of the stack and returns it.
 88  
          * 
 89  
          * @return The model element removed from the top of the stack.
 90  
          */
 91  
         ModelElement pop() {
 92  13590
                 ModelElement result = top.modelElement;
 93  13590
                 topIndex--;
 94  13590
                 top = stack.get(topIndex);
 95  13590
                 return result;
 96  
         }
 97  
 
 98  
         /**
 99  
          * Checks if the stack is empty.
 100  
          * 
 101  
          * @return <code>true</code> if the stack is empty.
 102  
          */
 103  
         boolean isEmpty() {
 104  24480
                 return topIndex == 0; // the bottom element does not count
 105  
         }
 106  
 
 107  
         /**
 108  
          * Gets the model element on top of the context stack.
 109  
          * 
 110  
          * @return Model element on top of the stack
 111  
          */
 112  
         ModelElement getModelElement() {
 113  22566
                 return top.modelElement;
 114  
         }
 115  
 
 116  
         /**
 117  
          * Gets the XML nesting level for the model element on top of the stack.
 118  
          * 
 119  
          * @return Nesting level for the top element.
 120  
          */
 121  
         int getNestingLevel() {
 122  139179
                 return top.nestingLevel;
 123  
         }
 124  
 
 125  
         /**
 126  
          * Retrieves the XMI transformations applicable to the model element on top
 127  
          * of the stack.
 128  
          * 
 129  
          * @return XMI transformation for the top element.
 130  
          */
 131  
         XMITransformation getXMITransformation() {
 132  23331
                 return top.transformation;
 133  
         }
 134  
 
 135  
         /**
 136  
          * Tests if the current parse context accepts new model elements. This is
 137  
          * the case if the stack is empty, or the model element on top of the stack
 138  
          * can have sub-elements.
 139  
          * 
 140  
          * @return <code>true</code> if new elements are accepted.
 141  
          */
 142  
         boolean isAcceptingNewElements() {
 143  38048
                 if (top.transformation == null)
 144  1265
                         return true;
 145  36783
                 return top.transformation.getXMIRecurse();
 146  
         }
 147  
 
 148  
         /**
 149  
          * Sets the active trigger for the XMI transformation on top of the stack.
 150  
          * 
 151  
          * @param trigger active trigger for the top XMI transformation
 152  
          */
 153  
         void setActiveTrigger(XMITrigger trigger) {
 154  19704
                 top.activeTrigger = trigger;
 155  19704
         }
 156  
 
 157  
         /**
 158  
          * Gets the active trigger.
 159  
          * 
 160  
          * @return The active trigger for the top XMI transformation
 161  
          */
 162  
         XMITrigger getActiveTrigger() {
 163  8965
                 return top.activeTrigger;
 164  
         }
 165  
 
 166  
         /**
 167  
          * Checks if the active trigger is of the specified type.
 168  
          * 
 169  
          * @param type trigger type to compare the active trigger to
 170  
          * @return <code>true</code> if the active trigger is of the specified type,
 171  
          *         <code>false</code> if it is of a different type or there is no
 172  
          *         current active trigger.
 173  
          */
 174  
         boolean activeTriggerTypeEquals(XMITrigger.TriggerType type) {
 175  96028
                 if (top.activeTrigger == null)
 176  86218
                         return false;
 177  9810
                 return top.activeTrigger.type == type;
 178  
         }
 179  
 }