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 18 package tests.util; 19 20 import java.util.Stack; 21 22 /** 23 * A stack to store the parameters of a call, as well as the call stack. 24 */ 25 public class CallVerificationStack extends Stack<Object> { 26 27 /* 28 * -------------------------------------------------------------------- 29 * Class variables 30 * -------------------------------------------------------------------- 31 */ 32 33 private static final long serialVersionUID = 1L; 34 35 // the singleton 36 private static final CallVerificationStack _instance = new CallVerificationStack(); 37 38 /* 39 * -------------------------------------------------------------------- 40 * Instance variables 41 * -------------------------------------------------------------------- 42 */ 43 44 // the call stack, store StackTraceElement 45 private final Stack<StackTraceElement> callStack = new Stack<StackTraceElement>(); 46 47 /* 48 * ------------------------------------------------------------------- 49 * Constructors 50 * ------------------------------------------------------------------- 51 */ 52 53 /** 54 * Can't be instantiated. 55 */ 56 private CallVerificationStack() { 57 // empty 58 } 59 60 /* 61 * ------------------------------------------------------------------- 62 * Methods 63 * ------------------------------------------------------------------- 64 */ 65 66 /** 67 * Gets the singleton instance. 68 * 69 * @return the singleton instance 70 */ 71 public static CallVerificationStack getInstance() { 72 return _instance; 73 } 74 75 /** 76 * Pushes the call stack. 77 */ 78 private void pushCallStack() { 79 StackTraceElement[] eles = (new Throwable()).getStackTrace(); 80 int i; 81 for (i = 1; i < eles.length; i++) { 82 if (!eles[i].getClassName().equals(this.getClass().getName())) { 83 break; 84 } 85 } 86 this.callStack.push(eles[i]); 87 } 88 89 /** 90 * Gets the "current" calling class name. 91 * 92 * @return the "current" calling class name 93 */ 94 public String getCurrentSourceClass() { 95 return this.callStack.peek().getClassName(); 96 } 97 98 /** 99 * Gets the "current" calling method name. 100 * 101 * @return the "current" calling method name 102 */ 103 public String getCurrentSourceMethod() { 104 return this.callStack.peek().getMethodName(); 105 } 106 107 /** 108 * Clear the parameter stack and the call stack. 109 */ 110 @Override 111 public void clear() { 112 this.callStack.clear(); 113 super.clear(); 114 } 115 116 @Override 117 public Object push(Object o) { 118 pushCallStack(); 119 return super.push(o); 120 } 121 122 /** 123 * Pushes a boolean onto the top of this stack. 124 * 125 * @param val the value to push 126 */ 127 public void push(boolean val) { 128 this.push(new BaseTypeWrapper(val)); 129 } 130 131 /** 132 * Pushes a char onto the top of this stack. 133 * 134 * @param val the value to push 135 */ 136 public void push(char val) { 137 this.push(new BaseTypeWrapper(val)); 138 } 139 140 /** 141 * Pushes a double onto the top of this stack. 142 * 143 * @param val the value to push 144 */ 145 public void push(double val) { 146 this.push(new BaseTypeWrapper(val)); 147 } 148 149 /** 150 * Pushes a float onto the top of this stack. 151 * 152 * @param val the value to push 153 */ 154 public void push(float val) { 155 this.push(new BaseTypeWrapper(val)); 156 } 157 158 /** 159 * Pushes an int onto the top of this stack. 160 * 161 * @param val the value to push 162 */ 163 public void push(int val) { 164 this.push(new BaseTypeWrapper(val)); 165 } 166 167 /** 168 * Pushes a long onto the top of this stack. 169 * 170 * @param val the value to push 171 */ 172 public void push(long val) { 173 this.push(new BaseTypeWrapper(val)); 174 } 175 176 /** 177 * Pushes a short onto the top of this stack. 178 * 179 * @param val the value to push 180 */ 181 public void push(short val) { 182 this.push(new BaseTypeWrapper(val)); 183 } 184 185 /** 186 * Pop an object. 187 * 188 * @return the object 189 */ 190 @Override 191 public Object pop() { 192 this.callStack.pop(); 193 return super.pop(); 194 } 195 196 /** 197 * Pop a boolean. 198 * 199 * @return the value 200 */ 201 public boolean popBoolean() { 202 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 203 Boolean value = (Boolean) wrapper.getValue(); 204 return value.booleanValue(); 205 } 206 207 /** 208 * Pop a char. 209 * 210 * @return the value 211 */ 212 public char popChar() { 213 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 214 Character value = (Character) wrapper.getValue(); 215 return value.charValue(); 216 } 217 218 /** 219 * Pop a double. 220 * 221 * @return the value 222 */ 223 public double popDouble() { 224 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 225 Double value = (Double) wrapper.getValue(); 226 return value.doubleValue(); 227 } 228 229 /** 230 * Pop a float. 231 * 232 * @return the value 233 */ 234 public float popFloat() { 235 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 236 Float value = (Float) wrapper.getValue(); 237 return value.floatValue(); 238 } 239 240 /** 241 * Pop a int. 242 * 243 * @return the value 244 */ 245 public int popInt() { 246 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 247 Integer value = (Integer) wrapper.getValue(); 248 return value.intValue(); 249 } 250 251 /** 252 * Pop a long. 253 * 254 * @return the value 255 */ 256 public long popLong() { 257 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 258 Long value = (Long) wrapper.getValue(); 259 return value.longValue(); 260 } 261 262 /** 263 * Pop a short. 264 * 265 * @return the value 266 */ 267 public short popShort() { 268 BaseTypeWrapper wrapper = (BaseTypeWrapper) this.pop(); 269 Short value = (Short) wrapper.getValue(); 270 return value.shortValue(); 271 } 272 273 /* 274 * Wrapper of base types. 275 */ 276 class BaseTypeWrapper { 277 278 // the internal value 279 private Object value; 280 281 /* 282 * Constructs a wrapper object for the base type <code> boolean </code> . 283 */ 284 public BaseTypeWrapper(boolean val) { 285 this.value = new Boolean(val); 286 } 287 288 /* 289 * Constructs a wrapper object for the base type <code> c </code> . 290 */ 291 public BaseTypeWrapper(byte val) { 292 this.value = new Byte(val); 293 } 294 295 /* 296 * Constructs a wrapper object for the base type <code> char </code> . 297 */ 298 public BaseTypeWrapper(char val) { 299 this.value = new Character(val); 300 } 301 302 /* 303 * Constructs a wrapper object for the base type <code> double </code> . 304 */ 305 public BaseTypeWrapper(double val) { 306 this.value = new Double(val); 307 } 308 309 /* 310 * Constructs a wrapper object for the base type <code> float </code> . 311 */ 312 public BaseTypeWrapper(float val) { 313 this.value = new Float(val); 314 } 315 316 /* 317 * Constructs a wrapper object for the base type <code> int </code> . 318 */ 319 public BaseTypeWrapper(int val) { 320 this.value = new Integer(val); 321 } 322 323 /* 324 * Constructs a wrapper object for the base type <code> long </code> . 325 */ 326 public BaseTypeWrapper(long val) { 327 this.value = new Long(val); 328 } 329 330 /* 331 * Constructs a wrapper object for the base type <code> short </code> . 332 */ 333 public BaseTypeWrapper(short val) { 334 this.value = new Short(val); 335 } 336 337 /* 338 * Gets the internal value. 339 */ 340 public Object getValue() { 341 return this.value; 342 } 343 } 344 } 345