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      */
CallVerificationStack()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      */
getInstance()71     public static CallVerificationStack getInstance() {
72         return _instance;
73     }
74 
75     /**
76      * Pushes the call stack.
77      */
pushCallStack()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      */
getCurrentSourceClass()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      */
getCurrentSourceMethod()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
clear()111     public void clear() {
112         this.callStack.clear();
113         super.clear();
114     }
115 
116     @Override
push(Object o)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      */
push(boolean val)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      */
push(char val)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      */
push(double val)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      */
push(float val)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      */
push(int val)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      */
push(long val)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      */
push(short val)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
pop()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      */
popBoolean()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      */
popChar()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      */
popDouble()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      */
popFloat()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      */
popInt()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      */
popLong()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      */
popShort()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            */
BaseTypeWrapper(boolean val)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            */
BaseTypeWrapper(byte val)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            */
BaseTypeWrapper(char val)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            */
BaseTypeWrapper(double val)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            */
BaseTypeWrapper(float val)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            */
BaseTypeWrapper(int val)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            */
BaseTypeWrapper(long val)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            */
BaseTypeWrapper(short val)333         public BaseTypeWrapper(short val) {
334             this.value = new Short(val);
335         }
336 
337         /*
338            * Gets the internal value.
339            */
getValue()340         public Object getValue() {
341             return this.value;
342         }
343     }
344 }
345