KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > aspectj > runtime > internal > CFlowStack


1 /* *******************************************************************
2  * Copyright (c) 1999-2001 Xerox Corporation,
3  * 2002 Palo Alto Research Center, Incorporated (PARC).
4  * All rights reserved.
5  * This program and the accompanying materials are made available
6  * under the terms of the Eclipse Public License v1.0
7  * which accompanies this distribution and is available at
8  * http://www.eclipse.org/legal/epl-v10.html
9  *
10  * Contributors:
11  * Xerox/PARC initial implementation
12  * ******************************************************************/

13
14
15 package org.aspectj.runtime.internal;
16
17 import java.util.Stack JavaDoc;
18
19 import org.aspectj.lang.NoAspectBoundException;
20 import org.aspectj.runtime.CFlow;
21 import org.aspectj.runtime.internal.cflowstack.ThreadStack;
22 import org.aspectj.runtime.internal.cflowstack.ThreadStackFactory;
23 import org.aspectj.runtime.internal.cflowstack.ThreadStackFactoryImpl;
24 import org.aspectj.runtime.internal.cflowstack.ThreadStackFactoryImpl11;
25
26 /*
27  * How we benefit from ThreadLocal when it is available at runtime:
28  *
29  * When the CFlowStack class is loaded, we run its static initializer. This checks the JVM
30  * version number and loads an appropriate implementation of the ThreadStackFactory.
31  * There are two possible implementations depending on whether this is a 1.1 or 1.2+ JVM.
32  * Rather than doing a Class.forName for ThreadLocal and catching a ClassNotFoundEx in order
33  * to determine the JVM version, we look at the java class version which I believe can help
34  * us identify the Java level.
35  *
36  * In the 1.1 JVM case we use a factory implementation that does not use ThreadLocal storage.
37  * In the 1.2+ JVM case we use a factory implementation that does use ThreadLocal storage.
38  *
39  * Once we have the factory set, whenever someone builds a CFlowStack object, we ask the
40  * factory for a new stack proxy - this is an object that can return us the right stack
41  * that we should use on a particular thread. The reason we create the proxy in the ctor and
42  * not lazily in the getThreadStack() method is because it means the getThreadStack() method in
43  * this class does not have to be synchronized.
44  *
45  * When any of the methods in CFlowStack need to operate on the stack (peek/pop/etc), they
46  * all delegate to getThreadStack() which asks the proxy for the right stack. Depending on the
47  * factory loaded to build the proxy, the call to proxy.getThreadStack() will return a threadlocal
48  * based stack or it will call the original implementation of getThreadStack() which manages
49  * a Hashtable of threads->stacks.
50  *
51  */

52
53 public class CFlowStack {
54
55     private static ThreadStackFactory tsFactory;
56     private ThreadStack stackProxy;
57
58     static {
59         selectFactoryForVMVersion();
60     }
61     
62     public CFlowStack() {
63         stackProxy = tsFactory.getNewThreadStack();
64     }
65     
66     private Stack JavaDoc getThreadStack() {
67         return stackProxy.getThreadStack();
68     }
69
70     //XXX dangerous, try to remove
71
public void push(Object JavaDoc obj) {
72         getThreadStack().push(obj);
73     }
74
75     public void pushInstance(Object JavaDoc obj) {
76         getThreadStack().push(new CFlow(obj));
77     }
78
79     public void push(Object JavaDoc[] obj) {
80         getThreadStack().push(new CFlowPlusState(obj));
81     }
82
83     public void pop() {
84         getThreadStack().pop();
85     }
86
87     public Object JavaDoc peek() {
88         Stack JavaDoc stack = getThreadStack();
89         if (stack.isEmpty()) throw new org.aspectj.lang.NoAspectBoundException();
90         return (Object JavaDoc)stack.peek();
91     }
92     
93     public Object JavaDoc get(int index) {
94         CFlow cf = peekCFlow();
95         return (null == cf ? null : cf.get(index));
96     }
97
98     public Object JavaDoc peekInstance() {
99         CFlow cf = peekCFlow();
100         if (cf != null ) return cf.getAspect();
101         else throw new NoAspectBoundException();
102     }
103
104     public CFlow peekCFlow() {
105         Stack JavaDoc stack = getThreadStack();
106         if (stack.isEmpty()) return null;
107         return (CFlow)stack.peek();
108     }
109
110     public CFlow peekTopCFlow() {
111         Stack JavaDoc stack = getThreadStack();
112         if (stack.isEmpty()) return null;
113         return (CFlow)stack.elementAt(0);
114     }
115
116     public boolean isValid() {
117         return !getThreadStack().isEmpty();
118     }
119         
120     private static ThreadStackFactory getThreadLocalStackFactory() { return new ThreadStackFactoryImpl(); }
121     private static ThreadStackFactory getThreadLocalStackFactoryFor11() { return new ThreadStackFactoryImpl11(); }
122     
123     private static void selectFactoryForVMVersion() {
124         String JavaDoc override = getSystemPropertyWithoutSecurityException("aspectj.runtime.cflowstack.usethreadlocal","unspecified");
125         boolean useThreadLocalImplementation = false;
126         if (override.equals("unspecified")) {
127             String JavaDoc v = System.getProperty("java.class.version","0.0");
128             // Java 1.2 is version 46.0 and above
129
useThreadLocalImplementation = (v.compareTo("46.0") >= 0);
130         } else {
131             useThreadLocalImplementation = override.equals("yes") || override.equals("true");
132         }
133         // System.err.println("Trying to use thread local implementation? "+useThreadLocalImplementation);
134
if (useThreadLocalImplementation) {
135             tsFactory = getThreadLocalStackFactory();
136         } else {
137             tsFactory = getThreadLocalStackFactoryFor11();
138         }
139     }
140     
141     private static String JavaDoc getSystemPropertyWithoutSecurityException (String JavaDoc aPropertyName, String JavaDoc aDefaultValue) {
142         try {
143             return System.getProperty(aPropertyName, aDefaultValue);
144         }
145         catch (SecurityException JavaDoc ex) {
146             return aDefaultValue;
147         }
148     }
149
150     
151     // For debug ...
152
public static String JavaDoc getThreadStackFactoryClassName() {
153         return tsFactory.getClass().getName();
154     }
155
156 }
157
Popular Tags