KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > config > TransparencyClassSpec


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.object.config;
6
7 import com.tc.asm.ClassVisitor;
8 import com.tc.aspectwerkz.reflect.ClassInfo;
9 import com.tc.object.bytecode.ByteCodeUtil;
10 import com.tc.object.bytecode.ClassAdapterBase;
11 import com.tc.object.bytecode.ClassAdapterFactory;
12 import com.tc.object.bytecode.DateMethodAdapter;
13 import com.tc.object.bytecode.DistributedMethodCallAdapter;
14 import com.tc.object.bytecode.LogicalMethodAdapter;
15 import com.tc.object.bytecode.ManagerHelper;
16 import com.tc.object.bytecode.MethodAdapter;
17 import com.tc.object.bytecode.MethodCreator;
18 import com.tc.object.config.schema.IncludeOnLoad;
19 import com.tc.object.logging.InstrumentationLogger;
20
21 import java.lang.reflect.Modifier JavaDoc;
22 import java.util.Collections JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.HashSet JavaDoc;
25 import java.util.Iterator JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Map JavaDoc;
29 import java.util.Set JavaDoc;
30
31 /**
32  * Describe the Custom adaption of a class
33  */

34 public class TransparencyClassSpec {
35   private static final Object JavaDoc HONOR_TRANSIENT_KEY = "honor-transient";
36   private static final Object JavaDoc HONOR_VOLATILE_KEY = "honor-volatile";
37
38   public static final byte NOT_SET = 0x00;
39   public static final byte NOT_ADAPTABLE = 0x01;
40   public static final byte ADAPTABLE = 0x02;
41   public static final byte PORTABLE = 0x03;
42
43   private final DSOClientConfigHelper configuration;
44   private final String JavaDoc className;
45   private final List JavaDoc supportMethodCreators = new LinkedList JavaDoc();
46   private final Map JavaDoc methodAdapters = new HashMap JavaDoc();
47   private final Map JavaDoc flags = new HashMap JavaDoc();
48   private final Set JavaDoc transients = new HashSet JavaDoc();
49   private final Map JavaDoc codeSpecs = new HashMap JavaDoc();
50   private final Set JavaDoc nonInstrumentedMethods = Collections.synchronizedSet(new HashSet JavaDoc());
51   private String JavaDoc changeApplicatorClassName;
52   private ChangeApplicatorSpec changeApplicatorSpec;
53   private boolean isLogical;
54   private final IncludeOnLoad onLoad = new IncludeOnLoad();
55   private boolean preInstrumented;
56
57   private boolean useNonDefaultConstructor = false;
58   private boolean generateNonStaticTCFields = true;
59   private boolean honorJDKSubVersionSpecific = false;
60
61   private byte instrumentationAction = NOT_SET;
62
63   private String JavaDoc postCreateMethod = null;
64   private String JavaDoc logicalExtendingClassName = null;
65   private ClassAdapterFactory customClassAdapter = null;
66
67   public TransparencyClassSpec(String JavaDoc className, DSOClientConfigHelper configuration, String JavaDoc changeApplicatorClassName) {
68     this.configuration = configuration;
69     this.className = className;
70     this.changeApplicatorClassName = changeApplicatorClassName;
71     this.changeApplicatorSpec = new DSOChangeApplicatorSpec(changeApplicatorClassName);
72     this.isLogical = true;
73   }
74
75   public TransparencyClassSpec(String JavaDoc className, DSOClientConfigHelper configuration) {
76     this.className = className;
77     this.configuration = configuration;
78     this.isLogical = false;
79     this.changeApplicatorClassName = null;
80     this.changeApplicatorSpec = null;
81     this.changeApplicatorSpec = null;
82   }
83
84   public TransparencyClassSpec getClassSpec(String JavaDoc clazzName) {
85     String JavaDoc name = clazzName.replace('/', '.');
86     return configuration.getSpec(name);
87   }
88
89   public boolean hasPhysicallyPortableSpecs(ClassInfo classInfo) {
90     String JavaDoc name = classInfo.getName();
91     return configuration.shouldBeAdapted(classInfo) && !configuration.isLogical(name)
92            && (configuration.getSpec(name) != null)
93            && (configuration.getSpec(name).getInstrumentationAction() != ADAPTABLE);
94   }
95
96   public TransparencyClassSpec addRoot(String JavaDoc variableName, String JavaDoc rootName) {
97     configuration.addRoot(className, variableName, rootName, false);
98     return this;
99   }
100
101   public TransparencyClassSpec addRoot(String JavaDoc variableName, String JavaDoc rootName, boolean dsoFinal) {
102     configuration.addRoot(className, variableName, rootName, dsoFinal, false);
103     return this;
104   }
105
106   public void addDoNotInstrument(String JavaDoc methodName) {
107     nonInstrumentedMethods.add(methodName);
108   }
109
110   public boolean doNotInstrument(String JavaDoc methodName) {
111     return nonInstrumentedMethods.contains(methodName);
112   }
113
114   public TransparencyClassSpec markPreInstrumented() {
115     preInstrumented = true;
116     return this;
117   }
118
119   public boolean isPreInstrumented() {
120     return preInstrumented;
121   }
122
123   public synchronized LockDefinition[] lockDefinitionsFor(int modifiers, String JavaDoc methodName, String JavaDoc desc,
124                                                           String JavaDoc[] exceptions) {
125     return configuration.lockDefinitionsFor(modifiers, className, methodName, desc, exceptions);
126   }
127
128   public synchronized LockDefinition autolockDefinitionFor(int access, String JavaDoc methodName, String JavaDoc description,
129                                                            String JavaDoc[] exceptions) {
130     LockDefinition[] lds = lockDefinitionsFor(access, methodName, description, exceptions);
131     for (int i = 0; i < lds.length; i++) {
132       if (lds[i].isAutolock()) { return lds[i]; }
133     }
134     throw new AssertionError JavaDoc("Can't be an autolock and not have an autolock def:" + methodName + " className:"
135                              + className);
136   }
137
138   /**
139    * returns null if no LockDefinitions exists that makes the method autolocked.
140    */

141   public LockDefinition getAutolockDefinition(LockDefinition lds[]) {
142     if (lds == null) return null;
143     for (int i = 0; i < lds.length; i++) {
144       if (lds[i].isAutolock()) { return lds[i]; }
145     }
146     return null;
147   }
148
149   public LockDefinition getNonAutoLockDefinition(LockDefinition lds[]) {
150     if (lds == null) return null;
151     for (int i = 0; i < lds.length; i++) {
152       if (!lds[i].isAutolock()) { return lds[i]; }
153     }
154     return null;
155   }
156
157   public TransparencyClassSpec addSupportMethodCreator(MethodCreator creator) {
158     supportMethodCreators.add(creator);
159     return this;
160   }
161
162   public TransparencyClassSpec addDistributedMethodCall(String JavaDoc methodName, String JavaDoc description, boolean runOnAllNodes) {
163     if ("<init>".equals(methodName) || "<clinit>".equals(methodName)) { throw new AssertionError JavaDoc(
164                                                                                                  "Initializers of class "
165                                                                                                      + className
166                                                                                                      + " cannot be participated in distrbuted method call and are ignored."); }
167     StringBuffer JavaDoc sb = new StringBuffer JavaDoc("* ");
168     sb.append(className);
169     sb.append(".");
170     sb.append(methodName);
171     String JavaDoc arguments = ByteCodeUtil.methodDescriptionToMethodArgument(description);
172     sb.append(arguments);
173     final DistributedMethodSpec dms = new DistributedMethodSpec(sb.toString(), runOnAllNodes);
174     configuration.addDistributedMethodCall(dms);
175     return this;
176   }
177
178   public TransparencyClassSpec addTransient(String JavaDoc variableName) {
179     transients.add(variableName);
180     return this;
181   }
182
183   public TransparencyClassSpec addMethodAdapter(String JavaDoc method, MethodAdapter adapter) {
184     methodAdapters.put(method, adapter);
185     return this;
186   }
187
188   public String JavaDoc getClassName() {
189     return className;
190   }
191
192   public void createClassSupportMethods(ClassVisitor classVisitor) {
193     for (Iterator JavaDoc i = supportMethodCreators.iterator(); i.hasNext();) {
194       MethodCreator mc = (MethodCreator) i.next();
195       mc.createMethods(classVisitor);
196     }
197   }
198
199   public boolean isLogical() {
200     return isLogical;
201   }
202
203   public boolean isPhysical() {
204     return !isLogical;
205   }
206
207   public boolean ignoreChecks() {
208     return TransparencyClassSpecUtil.ignoreChecks(className);
209   }
210
211   public boolean isRootInThisClass(String JavaDoc fieldName) {
212     return configuration.isRoot(className, fieldName);
213   }
214
215   public boolean isRoot(String JavaDoc classname, String JavaDoc fieldName) {
216     return configuration.isRoot(classname, fieldName);
217   }
218
219   public boolean isRootDSOFinal(String JavaDoc fieldName, boolean isPrimitive) {
220     return configuration.isRootDSOFinal(className, fieldName, isPrimitive);
221   }
222
223   public boolean isTransient(int access, String JavaDoc fieldName) {
224     if (ClassAdapterBase.isDelegateFieldName(fieldName)) { return false; }
225     if (transients.contains(fieldName)) return true;
226     return configuration.isTransient(access, className, fieldName);
227   }
228
229   public boolean isVolatile(int access, String JavaDoc fieldName) {
230     return configuration.isVolatile(access, className, fieldName);
231   }
232
233   public String JavaDoc rootNameFor(String JavaDoc fieldName) {
234     return configuration.rootNameFor(className, fieldName);
235   }
236
237   public boolean isLockMethod(int access, String JavaDoc methodName, String JavaDoc description, String JavaDoc[] exceptions) {
238     return configuration.isLockMethod(access, className, methodName, description, exceptions);
239   }
240
241   /**
242    * returns null if no LockDefinitions exists that makes the method locked.
243    */

244   public LockDefinition getLockMethodLockDefinition(int access, LockDefinition lds[]) {
245     if (lds == null) return null;
246     for (int i = 0; i < lds.length; i++) {
247       if ((lds[i].isAutolock() && Modifier.isSynchronized(access) && !Modifier.isStatic(access))
248           || !lds[i].isAutolock()) { return lds[i]; }
249     }
250     return null;
251   }
252
253   public boolean hasCustomMethodAdapter(int access, String JavaDoc methodName, String JavaDoc description, String JavaDoc[] exceptions) {
254     return getMethodAdapter(access, methodName, description, exceptions) != null;
255   }
256
257   public MethodAdapter customMethodAdapterFor(ManagerHelper managerHelper, int access, String JavaDoc methodName,
258                                               String JavaDoc origMethodName, String JavaDoc description, String JavaDoc signature,
259                                               String JavaDoc[] exceptions, InstrumentationLogger logger) {
260     MethodAdapter ma = getMethodAdapter(access, origMethodName, description, exceptions);
261     ma.initialize(managerHelper, access, className, methodName, origMethodName, description, signature, exceptions,
262                   logger);
263     return ma;
264   }
265
266   private MethodAdapter getMethodAdapter(int access, String JavaDoc methodName, String JavaDoc description, String JavaDoc[] exceptions) {
267     DistributedMethodSpec dms = configuration.getDmiSpec(access, className, methodName, description, exceptions);
268     if (dms == null) return (MethodAdapter) methodAdapters.get(methodName + description);
269     return new DistributedMethodCallAdapter(dms.runOnAllNodes());
270   }
271
272   public ChangeApplicatorSpec getChangeApplicatorSpec() {
273     return changeApplicatorSpec;
274   }
275
276   public String JavaDoc getLogicalExtendingClassName() {
277     return this.logicalExtendingClassName;
278   }
279
280   public void moveToLogical(TransparencyClassSpec superClassSpec) {
281     this.isLogical = true;
282     String JavaDoc superClassLogicalExtendingClassName = superClassSpec.getLogicalExtendingClassName();
283     if (superClassLogicalExtendingClassName == null) {
284       superClassLogicalExtendingClassName = superClassSpec.getClassName();
285     }
286     this.changeApplicatorClassName = superClassSpec.changeApplicatorClassName;
287     this.changeApplicatorSpec = new DSOChangeApplicatorSpec(superClassSpec.changeApplicatorClassName);
288     this.logicalExtendingClassName = superClassLogicalExtendingClassName;
289   }
290
291   public void addAlwaysLogSpec(String JavaDoc name) {
292     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.ALWAYS_LOG));
293   }
294
295   public void addIfTrueLogSpec(String JavaDoc name) {
296     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.IF_TRUE_LOG));
297   }
298
299   public void addSetIteratorWrapperSpec(String JavaDoc name) {
300     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.SET_ITERATOR_WRAPPER_LOG));
301   }
302
303   public void addViewSetWrapperSpec(String JavaDoc name) {
304     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.SORTED_SET_VIEW_WRAPPER_LOG));
305   }
306
307   public void addEntrySetWrapperSpec(String JavaDoc name) {
308     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.ENTRY_SET_WRAPPER_LOG));
309   }
310
311   public void addKeySetWrapperSpec(String JavaDoc name) {
312     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.KEY_SET_WRAPPER_LOG));
313   }
314
315   public void addValuesWrapperSpec(String JavaDoc name) {
316     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.VALUES_WRAPPER_LOG));
317   }
318
319   public void addHashMapPutLogSpec(String JavaDoc name) {
320     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.HASHMAP_PUT_LOG));
321   }
322
323   public void addHashtablePutLogSpec(String JavaDoc name) {
324     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.HASHTABLE_PUT_LOG));
325   }
326
327   public void addTHashMapPutLogSpec(String JavaDoc name) {
328     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.THASHMAP_PUT_LOG));
329   }
330
331   public void addTHashSetAddLogSpec(String JavaDoc name) {
332     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.THASHSET_ADD_LOG));
333   }
334
335   public void addTHashRemoveAtLogSpec(String JavaDoc name) {
336     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.THASH_REMOVE_AT_LOG));
337   }
338
339   public void addTHashSetRemoveAtLogSpec(String JavaDoc name) {
340     // Do nothing it's taken care of in the add method
341
}
342
343   public void addHashtableClearLogSpec(String JavaDoc name) {
344     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.HASHTABLE_CLEAR_LOG));
345   }
346
347   public void addHashtableRemoveLogSpec(String JavaDoc name) {
348     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.HASHTABLE_REMOVE_LOG));
349   }
350
351   public void addHashMapRemoveLogSpec(String JavaDoc name) {
352     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.HASHMAP_REMOVE_LOG));
353   }
354
355   public void addListRemoveLogSpec(String JavaDoc name) {
356     methodAdapters.put(name, new LogicalMethodAdapter(name, MethodSpec.LIST_REMOVE_LOG));
357   }
358
359   public void addArrayCopyMethodCodeSpec(String JavaDoc name) {
360     TransparencyCodeSpec codeSpec = new TransparencyCodeSpec();
361     codeSpec.setArraycopyInstrumentationReq(true);
362     codeSpec.setArrayOperatorInstrumentationReq(true);
363     codeSpecs.put(name, codeSpec);
364   }
365
366   public void disableWaitNotifyCodeSpec(String JavaDoc name) {
367     TransparencyCodeSpec codeSpec = TransparencyCodeSpec.getDefaultPhysicalCodeSpec();
368     codeSpec.setWaitNotifyInstrumentationReq(false);
369     codeSpecs.put(name, codeSpec);
370   }
371
372   public void addDateMethodLogSpec(String JavaDoc name) {
373     methodAdapters.put(name, new DateMethodAdapter(name, MethodSpec.DATE_ADD_SET_TIME_WRAPPER_LOG));
374   }
375
376   public void addDateMethodLogSpec(String JavaDoc name, int methodSpec) {
377     methodAdapters.put(name, new DateMethodAdapter(name, methodSpec));
378   }
379
380   public void addMethodCodeSpec(String JavaDoc name, TransparencyCodeSpec codeSpec) {
381     codeSpecs.put(name, codeSpec);
382   }
383
384   public TransparencyClassSpec setHonorVolatile(boolean b) {
385     flags.put(HONOR_VOLATILE_KEY, new Boolean JavaDoc(b));
386     return this;
387   }
388
389   public boolean isHonorVolatileSet() {
390     return flags.containsKey(HONOR_VOLATILE_KEY);
391   }
392
393   public boolean isHonorVolatile() {
394     Object JavaDoc flag = flags.get(HONOR_VOLATILE_KEY);
395     if (flag == null) return false;
396     return ((Boolean JavaDoc) flag).booleanValue();
397   }
398
399   public TransparencyClassSpec setHonorTransient(boolean b) {
400     flags.put(HONOR_TRANSIENT_KEY, new Boolean JavaDoc(b));
401     return this;
402   }
403
404   public TransparencyClassSpec setCallConstructorOnLoad(boolean b) {
405     onLoad.setToCallConstructorOnLoad(b);
406     return this;
407   }
408
409   public TransparencyClassSpec setExecuteScriptOnLoad(String JavaDoc script) {
410     onLoad.setExecuteScriptOnLoad(script);
411     return this;
412   }
413
414   public TransparencyClassSpec setCallMethodOnLoad(String JavaDoc method) {
415     onLoad.setMethodCallOnLoad(method);
416     return this;
417   }
418
419   private boolean basicIsHonorJavaTransient() {
420     return ((Boolean JavaDoc) flags.get(HONOR_TRANSIENT_KEY)).booleanValue();
421   }
422
423   public boolean isCallConstructorSet() {
424     return onLoad.isCallConstructorOnLoadType();
425   }
426
427   public boolean isHonorJavaTransient() {
428     return basicIsHonorJavaTransient();
429   }
430
431   public boolean isCallConstructorOnLoad() {
432     return onLoad.isCallConstructorOnLoad();
433   }
434
435   public boolean isHonorTransientSet() {
436     return flags.containsKey(HONOR_TRANSIENT_KEY);
437   }
438
439   public TransparencyCodeSpec getCodeSpec(String JavaDoc methodName, String JavaDoc description, boolean isAutolock) {
440     Object JavaDoc o = codeSpecs.get(methodName + description);
441     if (o == null) { return TransparencyCodeSpec.getDefaultCodeSpec(className, isLogical, isAutolock); }
442     return (TransparencyCodeSpec) o;
443   }
444
445   public boolean isExecuteScriptOnLoadSet() {
446     return onLoad.isExecuteScriptOnLoadType();
447   }
448
449   public boolean isCallMethodOnLoadSet() {
450     return onLoad.isCallMethodOnLoadType();
451   }
452
453   public String JavaDoc getOnLoadMethod() {
454     return onLoad.getMethod();
455   }
456
457   public String JavaDoc getOnLoadExecuteScript() {
458     return onLoad.getExecuteScript();
459   }
460
461   public boolean isUseNonDefaultConstructor() {
462     return this.useNonDefaultConstructor;
463   }
464
465   public void setUseNonDefaultConstructor(boolean useNonDefaultConstructor) {
466     this.useNonDefaultConstructor = useNonDefaultConstructor;
467   }
468
469   public void generateNonStaticTCFields(boolean b) {
470     this.generateNonStaticTCFields = b;
471   }
472
473   public boolean generateNonStaticTCFields() {
474     return this.generateNonStaticTCFields;
475   }
476
477   public void setInstrumentationAction(byte action) {
478     this.instrumentationAction = action;
479   }
480
481   public byte getInstrumentationAction() {
482     return this.instrumentationAction;
483   }
484
485   public boolean isHonorJDKSubVersionSpecific() {
486     return honorJDKSubVersionSpecific;
487   }
488
489   public void setHonorJDKSubVersionSpecific(boolean honorJDKSubVersionSpecific) {
490     this.honorJDKSubVersionSpecific = honorJDKSubVersionSpecific;
491   }
492
493   public boolean isPostCreateMethodSet() {
494     return postCreateMethod != null;
495   }
496
497   public String JavaDoc getPostCreateMethod() {
498     return postCreateMethod;
499   }
500
501   public void setPostCreateMethod(String JavaDoc postCreateMethod) {
502     this.postCreateMethod = postCreateMethod;
503   }
504
505   public void setCustomClassAdapter(ClassAdapterFactory customClassAdapter) {
506     this.customClassAdapter = customClassAdapter;
507   }
508
509   public ClassAdapterFactory getCustomClassAdapter() {
510     return customClassAdapter;
511   }
512 }
513
Popular Tags