Coverage Report - th.co.edge.jseq.Activation
 
Classes in this File Line Coverage Branch Coverage Complexity
Activation
62%
33/53
50%
9/18
0
 
 1  
 /*
 2  
  * Copyright (c) 2003-2008, by Henrik Arro and Contributors
 3  
  *
 4  
  * This file is part of JSeq, a tool to automatically create
 5  
  * sequence diagrams by tracing program execution.
 6  
  *
 7  
  * See <http://jseq.sourceforge.net> for more information.
 8  
  *
 9  
  * JSeq is free software: you can redistribute it and/or modify
 10  
  * it under the terms of the GNU Lesser General Public License as
 11  
  * published by the Free Software Foundation, either version 3 of
 12  
  * the License, or (at your option) any later version.
 13  
  *
 14  
  * JSeq is distributed in the hope that it will be useful,
 15  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 17  
  * GNU Lesser General Public License for more details.
 18  
  *
 19  
  * You should have received a copy of the GNU Lesser General Public License
 20  
  * along with JSeq. If not, see <http://www.gnu.org/licenses/>.
 21  
  */
 22  
 
 23  
 package th.co.edge.jseq;
 24  
 
 25  
 import com.sun.jdi.Method;
 26  
 
 27  
 /**
 28  
  * An <code>Activation</code> represents one method call, or in other words,
 29  
  * one stack frame.
 30  
  */
 31  
 public class Activation implements java.io.Serializable {
 32  
     private static final long serialVersionUID = -774147570250028530L;
 33  
     private static final int INDENT_SIZE = 4;
 34  
 
 35  
     private Activation parent;
 36  
     private String className;
 37  
     private Method method;
 38  
     private int frameCount;
 39  123
     private int numRepetitions = 1;
 40  123
     private ActivationList nestedActivations = new ActivationList();
 41  
 
 42  
     /**
 43  
      * Creates a new <code>Activation</code> instance, representing a certain
 44  
      * method call.
 45  
      *
 46  
      * @param parent
 47  
      *            the <code>Activation</code> representing the method that
 48  
      *            called this method, or <code>null</code> if this is a root
 49  
      *            activation. The newly created <code>Activation</code> will
 50  
      *            be added as a nested activation of <code>parent</code>
 51  
      * @param className
 52  
      *            the name of the class that this method call belongs to
 53  
      * @param method
 54  
      *            the <code>Method</code> that is being called
 55  
      * @param frameCount
 56  
      *            the index number of the stack frame associated with this
 57  
      *            <code>Association</code>
 58  
      */
 59  
     public Activation(Activation parent, String className, Method method,
 60  123
             int frameCount) {
 61  123
         this.parent = parent;
 62  123
         this.className = className;
 63  123
         this.method = method;
 64  123
         this.frameCount = frameCount;
 65  123
         if (parent != null) {
 66  85
             parent.add(this);
 67  
         }
 68  123
     }
 69  
 
 70  
     /**
 71  
      * Performs a deep copy of this <code>Activation</code> instance.
 72  
      *
 73  
      * @param parentOfCopy
 74  
      *            the <code>Activation</code> representing the method that
 75  
      *            called this method, potentially different from the original,
 76  
      *            or <code>null</code> if the copy is a root activation. The
 77  
      *            newly created <code>Activation</code> will be added as a
 78  
      *            nested activation of <code>parentOfCopy</code>
 79  
      *
 80  
      * @return a copy of this <code>Activation</code> instance
 81  
      */
 82  
     public Activation copy(Activation parentOfCopy) {
 83  42
         Activation copy =
 84  
                 new Activation(parentOfCopy, getClassName(), getMethod(),
 85  
                         getFrameCount());
 86  42
         for (Activation child : nestedActivations) {
 87  30
             child.copy(copy);
 88  
         }
 89  42
         return copy;
 90  
     }
 91  
 
 92  
     /**
 93  
      * Returns the <code>Activation</code> that called this
 94  
      * <code>Activation</code>, or <code>null</code> if this is a root
 95  
      * activation.
 96  
      *
 97  
      * @return the caller of this <code>Activation</code>
 98  
      */
 99  
     public Activation getParent() {
 100  21
         return parent;
 101  
     }
 102  
 
 103  
     /**
 104  
      * Sets the <code>Activation</code> that called this
 105  
      * <code>Activation</code>.
 106  
      *
 107  
      * @param parent
 108  
      *            the caller of this <code>Activation</code>, or
 109  
      *            <code>null</code> if this is a root activation
 110  
      */
 111  
     public void setParent(Activation parent) {
 112  8
         this.parent = parent;
 113  8
     }
 114  
 
 115  
     /**
 116  
      * Returns the name of the class that this <code>Activation</code> belongs
 117  
      * to.
 118  
      *
 119  
      * @return the class name of this <code>Activation</code>
 120  
      */
 121  
     public String getClassName() {
 122  136
         return className;
 123  
     }
 124  
 
 125  
     /**
 126  
      * Returns the <code>Method</code> that is being called by this
 127  
      * <code>Activation</code>.
 128  
      *
 129  
      * @return the <code>Method</code> represented by this
 130  
      *         <code>Activation</code>
 131  
      */
 132  
     public Method getMethod() {
 133  91
         return method;
 134  
     }
 135  
 
 136  
     /**
 137  
      * Returns the index number of the stack frame associated with this
 138  
      * <code>Association</code>.
 139  
      *
 140  
      * @return the index number of this stack frame
 141  
      */
 142  
     public int getFrameCount() {
 143  42
         return frameCount;
 144  
     }
 145  
 
 146  
     /**
 147  
      * Returns the number of times the method represented by this
 148  
      * <code>Activation</code> is being called consecutively, with no other
 149  
      * calls in between. If this number is greater than one, it may be
 150  
      * represented in a sequence diagram in some special way, e.g., "*[3]" for
 151  
      * three repetitions.
 152  
      *
 153  
      * @return the number of consecutive calls to this method
 154  
      */
 155  
     public int getNumRepetitions() {
 156  0
         return numRepetitions;
 157  
     }
 158  
 
 159  
     /**
 160  
      * Increases the number of consecutive calls of this method by one.
 161  
      */
 162  
     public void increaseNumRepetitions() {
 163  4
         numRepetitions++;
 164  4
     }
 165  
 
 166  
     /**
 167  
      * Adds another nested <code>Activation</code> to this
 168  
      * <code>Activation</code>. This represents a method call made by this
 169  
      * method.
 170  
      *
 171  
      * @param nestedActivation
 172  
      *            the nested <code>Activation</code> to add to this
 173  
      *            <code>Activation</code>
 174  
      */
 175  
     public void add(Activation nestedActivation) {
 176  85
         nestedActivations.add(nestedActivation);
 177  85
     }
 178  
 
 179  
     /**
 180  
      * Returns an <code>ActivationList</code> with all nested
 181  
      * <code>Activation</code>s, that is, all methods called by this method.
 182  
      *
 183  
      * @return an <code>ActivationList</code> with all nested activations.
 184  
      */
 185  
     public ActivationList getNestedActivations() {
 186  58
         return nestedActivations;
 187  
     }
 188  
 
 189  
     /**
 190  
      * Sets the <code>ActivationList</code> with all nested
 191  
      * <code>Activation</code>s called by this method.
 192  
      *
 193  
      * @param nestedActivations
 194  
      *            the new <code>ActivationList</code> with nested activations.
 195  
      */
 196  
     public void setNestedActivations(ActivationList nestedActivations) {
 197  10
         this.nestedActivations = nestedActivations;
 198  10
     }
 199  
 
 200  
     /**
 201  
      * Returns the number of nested activations.
 202  
      *
 203  
      * @return the number of method calls made by this activation.
 204  
      */
 205  
     public int getNumCalls() {
 206  8
         return nestedActivations.size();
 207  
     }
 208  
 
 209  
     /**
 210  
      * Returns a string representation of this <code>Activation</code> and all
 211  
      * its nested <code>Activation</code>s, with each activation on a
 212  
      * separate line, and nested activations indented.
 213  
      *
 214  
      * @return a string representation of this <code>Activation</code>
 215  
      */
 216  
     @Override
 217  
     public String toString() {
 218  0
         return toString(0);
 219  
     }
 220  
 
 221  
     /**
 222  
      * As <code>toString()</code>, but indents the first activation a given
 223  
      * number of spaces.
 224  
      *
 225  
      * @param indent
 226  
      *            the number of spaces to indent the first activation
 227  
      *
 228  
      * @return a string representation of this <code>Activation</code>, with
 229  
      *         the first indented <code>indent</code> number of spaces, and
 230  
      *         nested activations further indented
 231  
      */
 232  
     public String toString(int indent) {
 233  0
         StringBuffer s = new StringBuffer();
 234  0
         indent(s, indent);
 235  0
         s.append(getClassName() + ".");
 236  0
         s.append(getMethod().name());
 237  0
         if (getNumRepetitions() > 1) {
 238  0
             s.append(" (x " + getNumRepetitions() + ")");
 239  
         }
 240  0
         s.append("\n");
 241  0
         for (Activation nestedActivation : nestedActivations) {
 242  0
             s.append(nestedActivation.toString(indent + INDENT_SIZE));
 243  
         }
 244  0
         return s.toString();
 245  
     }
 246  
 
 247  
     private void indent(StringBuffer s, int indent) {
 248  0
         for (int i = 0; i < indent; i++) {
 249  0
             s.append(" ");
 250  
         }
 251  0
     }
 252  
 
 253  
     /**
 254  
      * Compares this <code>Activation</code> to another object, and returns
 255  
      * <code>true</code> if and only if the other object is an
 256  
      * <code>Activation</code> with the same class and method names, and equal
 257  
      * nested activations.
 258  
      *
 259  
      * @param o
 260  
      *            the object to compare this <code>Activation</code> to
 261  
      *
 262  
      * @return <code>true</code> if <code>o</code> is an
 263  
      *         <code>Activation</code> with the same class and method names
 264  
      *         and the equal nested activations, <code>false</code> otherwise
 265  
      */
 266  
     @Override
 267  
     public boolean equals(Object o) {
 268  19
         boolean equal = false;
 269  19
         if (o instanceof Activation) {
 270  19
             Activation otherActivation = (Activation) o;
 271  19
             equal =
 272  
                     className.equals(otherActivation.className) &&
 273  
                             method.name().equals(otherActivation.method.name()) &&
 274  
                             nestedActivations
 275  
                                     .equals(otherActivation.nestedActivations);
 276  
         }
 277  19
         return equal;
 278  
     }
 279  
 
 280  
     /**
 281  
      * Returns a hash code for this <code>Activation</code>.
 282  
      *
 283  
      * @return a hash code for this <code>Activation</code>
 284  
      */
 285  
     @Override
 286  
     public int hashCode() {
 287  0
         int result = 17;
 288  0
         result = 31 * result + className.hashCode();
 289  0
         result = 31 * result + method.name().hashCode();
 290  0
         result = 31 * result + nestedActivations.hashCode();
 291  0
         return result;
 292  
     }
 293  
 
 294  
 }