Source Code Cross Referenced for HotSwapAspectInterfaceImpl.java in  » Byte-Code » PROSE » ch » ethz » inf » iks » jvmai » jvmdi » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Byte Code » PROSE » ch.ethz.inf.iks.jvmai.jvmdi 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        ///
0002:        //  This file is part of the prose package.
0003:        //
0004:        //  The contents of this file are subject to the Mozilla Public License
0005:        //  Version 1.1 (the "License"); you may not use this file except in
0006:        //  compliance with the License. You may obtain a copy of the License at
0007:        //  http://www.mozilla.org/MPL/
0008:        //
0009:        //  Software distributed under the License is distributed on an "AS IS" basis,
0010:        //  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0011:        //  for the specific language governing rights and limitations under the
0012:        //  License.
0013:        //
0014:        //  The Original Code is prose.
0015:        //
0016:        //  Contributor(s):
0017:        //  $Id$
0018:        //  =====================================================================
0019:        //
0020:        // (history at end)
0021:        //
0022:
0023:        package ch.ethz.inf.iks.jvmai.jvmdi;
0024:
0025:        import java.util.Set;
0026:        import java.util.HashSet;
0027:        import java.util.Iterator;
0028:        import java.lang.reflect.*;
0029:        import java.io.IOException;
0030:        import java.io.ByteArrayInputStream;
0031:        import java.io.InputStream;
0032:
0033:        import org.apache.bcel.classfile.ClassParser;
0034:        import org.apache.bcel.classfile.JavaClass;
0035:        import org.apache.bcel.generic.ClassGen;
0036:
0037:        import ch.ethz.jvmai.*;
0038:
0039:        /**
0040:         * HotSwapAspectInterfaceImpl class.
0041:         * 
0042:         * @author  Angela Nicoara
0043:         * @author  Gerald Linhofer
0044:         * @version $Revision: 1.1.2.5 $
0045:         */
0046:        public class HotSwapAspectInterfaceImpl extends AspectInterfaceImpl {
0047:
0048:            /**
0049:             * Gathers and holds informations about field and method call join points
0050:             */
0051:            protected static HotSwapClassRegister classRegister = null;
0052:            /**
0053:             * Caches class definitions, which where fetched by {@link #getOriginalClassDefinition}
0054:             * @deprecated
0055:             */
0056:            protected static CacheMap classFileMap = null;
0057:
0058:            /**
0059:             * Caches reflected Method objects resolved by
0060:             * the <CODE>getMethodFromString()</CODE> methods.
0061:             */
0062:            protected static CacheMap resolvedMethods = null;
0063:            /**
0064:             * Caches reflected Field objects resolved by
0065:             * the <CODE>getFieldFromString()</CODE> methods.
0066:             */
0067:            protected static CacheMap resolvedFields = null;
0068:            //
0069:            // Arrays holding the tags for active advices, tags will be
0070:            // added by the set..Watch(), removed by
0071:            // clear...Watch() and used in doOn...() methods.
0072:            //
0073:            protected static Object methodEntryTags[] = null;
0074:            protected static Object methodExitTags[] = null;
0075:            protected static Object constructorTags[] = null;
0076:            // protected static Object methodCallTags[]			= null;
0077:            // protected static Object methodReturnTags[]		= null;
0078:            protected static Object fieldAccessTags[] = null;
0079:            protected static Object fieldModificationTags[] = null;
0080:
0081:            /**
0082:             * <CODE>true</CODE> if HotSwapAspectInterfaceImpl was initialized. 
0083:             */
0084:            protected static boolean initialized = false;
0085:
0086:            /**
0087:             * Replacement tag, will be used as tag, if the user supplied tag
0088:             * is <CODE>null</CODE>. (Required to store the tag in data
0089:             * structures that didn't allow <CODE>null</CODE> entries.)
0090:             */
0091:            protected static Object aopNullTag = new Object();
0092:
0093:            // 
0094:            // Join point objects for the various join points, the objects are preallocated
0095:            // and will be reused at each advice call from the same join point type.
0096:            // (Dont forget to SYNCHRONIZE uses of these objects!!!) 
0097:            //
0098:            protected static HotSwapMethodEntryJoinPointImpl methodEntryJoinPoint = new HotSwapMethodEntryJoinPointImpl();
0099:            protected static HotSwapMethodExitJoinPointImpl methodExitJoinPoint = new HotSwapMethodExitJoinPointImpl();
0100:            protected static HotSwapConstructorJoinPointImpl constructorJoinPoint = new HotSwapConstructorJoinPointImpl();
0101:            protected static HotSwapFieldAccessJoinPointImpl fieldAccessJoinPoint = new HotSwapFieldAccessJoinPointImpl();
0102:            protected static HotSwapFieldModificationJoinPointImpl fieldModificationJoinPoint = new HotSwapFieldModificationJoinPointImpl();
0103:
0104:            //
0105:            // Holds threads that will be ignored, if they call a doOn...() callback method.
0106:            // Used during advice weaving to supress notifications.
0107:            //
0108:            protected static Set suspendedThreads = new HashSet(1024);
0109:            //	protected static Set<Thread> suspendedThreads = new HashSet<Thread>(1024);	// only JDK 1.5 or above
0110:
0111:            // Class loader used by 'get*ClassDefinition' and 'getMethodFromString'.
0112:            private static ClassLoader contingencyLoader = null;
0113:
0114:            // holds the instance of HotSwapAspectInteface (Singelton Pattern)	
0115:            private static HotSwapAspectInterfaceImpl instance;
0116:
0117:            /**
0118:             * Constructor. Dont call it, use {@link HotSwapAspectInterfaceImpl#getInstance 
0119:             * getInstance()} to create an instance of this class.
0120:             * <P>
0121:             * This is not private to allow unit testing.
0122:             */
0123:            protected HotSwapAspectInterfaceImpl() {
0124:            }
0125:
0126:            /**
0127:             * Returns the instance of HotSwapAspectInterfaceImpl and creates it
0128:             * if required. There's only one instance of this class (Singelton Pattern).
0129:             * 
0130:             * @return HotSwapAspectInterfaceImpl instance
0131:             */
0132:            public static HotSwapAspectInterfaceImpl getInstance() {
0133:                if (null == instance)
0134:                    instance = new HotSwapAspectInterfaceImpl();
0135:                return instance;
0136:            }
0137:
0138:            //------------------------------------------------------------------------------------------------------------------
0139:            // Interface for the JoinPointManager
0140:            //------------------------------------------------------------------------------------------------------------------
0141:
0142:            /**
0143:             * Initializes the underlying jvmai system.
0144:             * <p>
0145:             * In addition, this method takes a list of java package-names and a
0146:             * boolean indicating how to interpret this prefixes. The prefixes are
0147:             * used by the jvmai system to determine the set of classes beeing
0148:             * relevant to the system at all.
0149:             * Depeding on the value of <code>openWorldAssumption</code>, prefixes
0150:             * are interpreted as followed:
0151:             * <p>
0152:             * <code>openWorldAssumption == true</code><br>
0153:             * The jvmai-system is instructed to treat ALL classes as relevant,
0154:             * EXCEPT the ones contained in a packages starting with one of the
0155:             * supplied prefixes in <code>packagePrefixes</code>
0156:             * <p>
0157:             * <code>openWorldAssumption == false</code><br>
0158:             * The jvmai-system is instructed to treat as relevant ONLY the classes
0159:             * contained in a packages starting with one of the supplied prefixes
0160:             * in <code>packagePrefixes</code>
0161:             *
0162:             * @param packagePrefixes List of prefixes for java package-names.
0163:             * @param openWorldAssumption Specifies how the prefixes are interpreted.
0164:             * @exception StartupException Use <code>StartupException.getMessage()</code> to get a detailed description
0165:             */
0166:            public synchronized void startup(String[] packagePrefixes,
0167:                    boolean openWorldAssumption) {
0168:                if (null == packagePrefixes)
0169:                    packagePrefixes = new String[0];
0170:
0171:                // make sure all classes that are addressed during event notification are loaded already here
0172:                Class toload;
0173:                toload = ch.ethz.inf.iks.jvmai.jvmdi.JumpFinallyVisitor.class;
0174:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapProvider.class;
0175:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapJoinPointImpl.class;
0176:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapMethodEntryJoinPointImpl.class;
0177:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapMethodExitJoinPointImpl.class;
0178:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapFieldJoinPointImpl.class;
0179:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapFieldAccessJoinPointImpl.class;
0180:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapFieldModificationJoinPointImpl.class;
0181:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapSignatureImpl.class;
0182:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapClassRegister.class;
0183:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapClassWeaver.class;
0184:                toload = ch.ethz.inf.iks.jvmai.jvmdi.HotSwapFieldWeaver.class;
0185:                toload = ch.ethz.inf.iks.jvmai.jvmdi.CacheMap.class;
0186:                toload = ch.ethz.jvmai.MethodRedefineJoinPoint.class;
0187:                toload = ch.ethz.jvmai.UnmodifiableClassException.class;
0188:                toload = ch.ethz.jvmai.IlligalClassFormatException.class;
0189:                // BCEL classes must be loaded at startup to prevent
0190:                // dead locks, if BCEL is used to parse classes on class
0191:                // load.
0192:                toload = org.apache.bcel.Constants.class;
0193:                toload = org.apache.bcel.classfile.AccessFlags.class;
0194:                toload = org.apache.bcel.classfile.Attribute.class;
0195:                toload = org.apache.bcel.classfile.ClassParser.class;
0196:                toload = org.apache.bcel.classfile.JavaClass.class;
0197:                toload = org.apache.bcel.classfile.FieldOrMethod.class;
0198:                toload = org.apache.bcel.classfile.Method.class;
0199:                toload = org.apache.bcel.classfile.Field.class;
0200:                toload = org.apache.bcel.classfile.Code.class;
0201:                toload = org.apache.bcel.classfile.Constant.class;
0202:                toload = org.apache.bcel.classfile.ConstantCP.class;
0203:                toload = org.apache.bcel.classfile.ConstantDouble.class;
0204:                toload = org.apache.bcel.classfile.ConstantFieldref.class;
0205:                toload = org.apache.bcel.classfile.ConstantFloat.class;
0206:                toload = org.apache.bcel.classfile.ConstantInteger.class;
0207:                toload = org.apache.bcel.classfile.ConstantInterfaceMethodref.class;
0208:                toload = org.apache.bcel.classfile.ConstantMethodref.class;
0209:                toload = org.apache.bcel.classfile.ConstantNameAndType.class;
0210:                toload = org.apache.bcel.classfile.ConstantString.class;
0211:                toload = org.apache.bcel.classfile.ConstantUtf8.class;
0212:                toload = org.apache.bcel.classfile.ConstantClass.class;
0213:                toload = org.apache.bcel.classfile.ConstantValue.class;
0214:                toload = org.apache.bcel.classfile.ConstantPool.class;
0215:                toload = org.apache.bcel.classfile.InnerClass.class;
0216:                toload = org.apache.bcel.classfile.InnerClasses.class;
0217:                toload = org.apache.bcel.classfile.ExceptionTable.class;
0218:                toload = org.apache.bcel.classfile.LineNumber.class;
0219:                toload = org.apache.bcel.classfile.LineNumberTable.class;
0220:                toload = org.apache.bcel.classfile.LocalVariable.class;
0221:                toload = org.apache.bcel.classfile.LocalVariableTable.class;
0222:                toload = org.apache.bcel.classfile.StackMapEntry.class;
0223:                toload = org.apache.bcel.classfile.StackMapType.class;
0224:                toload = org.apache.bcel.classfile.StackMap.class;
0225:                toload = org.apache.bcel.classfile.Signature.class;
0226:                toload = org.apache.bcel.classfile.SourceFile.class;
0227:                toload = org.apache.bcel.classfile.Synthetic.class;
0228:                toload = org.apache.bcel.classfile.Deprecated.class;
0229:                toload = org.apache.bcel.classfile.Utility.class;
0230:                toload = org.apache.bcel.generic.AALOAD.class;
0231:                toload = org.apache.bcel.generic.AASTORE.class;
0232:                toload = org.apache.bcel.generic.ACONST_NULL.class;
0233:                toload = org.apache.bcel.generic.ALOAD.class;
0234:                toload = org.apache.bcel.generic.ANEWARRAY.class;
0235:                toload = org.apache.bcel.generic.ARETURN.class;
0236:                toload = org.apache.bcel.generic.ArithmeticInstruction.class;
0237:                toload = org.apache.bcel.generic.ArrayInstruction.class;
0238:                toload = org.apache.bcel.generic.ARRAYLENGTH.class;
0239:                toload = org.apache.bcel.generic.ArrayType.class;
0240:                toload = org.apache.bcel.generic.ALOAD.class;
0241:                toload = org.apache.bcel.generic.ASTORE.class;
0242:                toload = org.apache.bcel.generic.BALOAD.class;
0243:                toload = org.apache.bcel.generic.BasicType.class;
0244:                toload = org.apache.bcel.generic.BASTORE.class;
0245:                toload = org.apache.bcel.generic.BIPUSH.class;
0246:                toload = org.apache.bcel.generic.BranchHandle.class;
0247:                toload = org.apache.bcel.generic.BranchInstruction.class;
0248:                toload = org.apache.bcel.generic.BREAKPOINT.class;
0249:                toload = org.apache.bcel.generic.CALOAD.class;
0250:                toload = org.apache.bcel.generic.CASTORE.class;
0251:                toload = org.apache.bcel.generic.CHECKCAST.class;
0252:                toload = org.apache.bcel.generic.ClassGen.class;
0253:                toload = org.apache.bcel.generic.CodeExceptionGen.class;
0254:                toload = org.apache.bcel.generic.ConstantPoolGen.class;
0255:                toload = org.apache.bcel.generic.ConversionInstruction.class;
0256:                toload = org.apache.bcel.generic.CPInstruction.class;
0257:                toload = org.apache.bcel.generic.D2F.class;
0258:                toload = org.apache.bcel.generic.D2I.class;
0259:                toload = org.apache.bcel.generic.D2L.class;
0260:                toload = org.apache.bcel.generic.DADD.class;
0261:                toload = org.apache.bcel.generic.DALOAD.class;
0262:                toload = org.apache.bcel.generic.DASTORE.class;
0263:                toload = org.apache.bcel.generic.DCMPG.class;
0264:                toload = org.apache.bcel.generic.DCMPL.class;
0265:                toload = org.apache.bcel.generic.DCONST.class;
0266:                toload = org.apache.bcel.generic.DDIV.class;
0267:                toload = org.apache.bcel.generic.DLOAD.class;
0268:                toload = org.apache.bcel.generic.DMUL.class;
0269:                toload = org.apache.bcel.generic.DNEG.class;
0270:                toload = org.apache.bcel.generic.DREM.class;
0271:                toload = org.apache.bcel.generic.DRETURN.class;
0272:                toload = org.apache.bcel.generic.DSTORE.class;
0273:                toload = org.apache.bcel.generic.DSUB.class;
0274:                toload = org.apache.bcel.generic.DUP.class;
0275:                toload = org.apache.bcel.generic.DUP_X1.class;
0276:                toload = org.apache.bcel.generic.DUP_X2.class;
0277:                toload = org.apache.bcel.generic.DUP2.class;
0278:                toload = org.apache.bcel.generic.DUP2_X1.class;
0279:                toload = org.apache.bcel.generic.DUP2_X2.class;
0280:                toload = org.apache.bcel.generic.F2D.class;
0281:                toload = org.apache.bcel.generic.F2I.class;
0282:                toload = org.apache.bcel.generic.F2L.class;
0283:                toload = org.apache.bcel.generic.FADD.class;
0284:                toload = org.apache.bcel.generic.FALOAD.class;
0285:                toload = org.apache.bcel.generic.FASTORE.class;
0286:                toload = org.apache.bcel.generic.FCMPG.class;
0287:                toload = org.apache.bcel.generic.FCMPL.class;
0288:                toload = org.apache.bcel.generic.FCONST.class;
0289:                toload = org.apache.bcel.generic.FDIV.class;
0290:                toload = org.apache.bcel.generic.FieldGen.class;
0291:                toload = org.apache.bcel.generic.FieldGenOrMethodGen.class;
0292:                toload = org.apache.bcel.generic.FieldInstruction.class;
0293:                toload = org.apache.bcel.generic.FieldOrMethod.class;
0294:                toload = org.apache.bcel.generic.FLOAD.class;
0295:                toload = org.apache.bcel.generic.FMUL.class;
0296:                toload = org.apache.bcel.generic.FNEG.class;
0297:                toload = org.apache.bcel.generic.FREM.class;
0298:                toload = org.apache.bcel.generic.FRETURN.class;
0299:                toload = org.apache.bcel.generic.FSTORE.class;
0300:                toload = org.apache.bcel.generic.FSUB.class;
0301:                toload = org.apache.bcel.generic.GETFIELD.class;
0302:                toload = org.apache.bcel.generic.GETSTATIC.class;
0303:                toload = org.apache.bcel.generic.GOTO.class;
0304:                toload = org.apache.bcel.generic.GOTO_W.class;
0305:                toload = org.apache.bcel.generic.GotoInstruction.class;
0306:                toload = org.apache.bcel.generic.I2B.class;
0307:                toload = org.apache.bcel.generic.I2C.class;
0308:                toload = org.apache.bcel.generic.I2D.class;
0309:                toload = org.apache.bcel.generic.I2F.class;
0310:                toload = org.apache.bcel.generic.I2L.class;
0311:                toload = org.apache.bcel.generic.I2S.class;
0312:                toload = org.apache.bcel.generic.IADD.class;
0313:                toload = org.apache.bcel.generic.IALOAD.class;
0314:                toload = org.apache.bcel.generic.IAND.class;
0315:                toload = org.apache.bcel.generic.IASTORE.class;
0316:
0317:                super .startup(packagePrefixes, openWorldAssumption);
0318:
0319:                if (initialized)
0320:                    return;
0321:
0322:                // initialize static fields
0323:                methodEntryTags = new Object[1024];
0324:                methodExitTags = new Object[1024];
0325:                constructorTags = new Object[1024];
0326:                fieldAccessTags = new Object[1024];
0327:                fieldModificationTags = new Object[1024];
0328:                //		methodCallTags			= new Object[1024];
0329:                //		methodReturnTags		= new Object[1024];
0330:
0331:                doStartUp(packagePrefixes, openWorldAssumption);
0332:
0333:                if (contingencyLoader == null) {
0334:                    Iterator i = getLoadedClasses().iterator();
0335:                    while (i.hasNext() && contingencyLoader == null) {
0336:                        Class cls = (Class) i.next();
0337:                        contingencyLoader = cls.getClassLoader();
0338:                    }
0339:                    classFileMap = new CacheMap(1024);
0340:                    resolvedMethods = new CacheMap(1024);
0341:                    resolvedFields = new CacheMap(1024);
0342:                    classRegister = HotSwapClassRegister.getInstance();
0343:                }
0344:
0345:                initialized = true;
0346:
0347:                HotSwapClassWeaver.setAspectInterface(this );
0348:                HotSwapClassRegister.setAspectInterface(this , packagePrefixes,
0349:                        openWorldAssumption);
0350:            }
0351:
0352:            /** 
0353:             *  Teardown the AOP support. As a result,
0354:             *  no events will be sent to the JoinPointHook.
0355:             */
0356:            public synchronized void teardown() {
0357:                super .teardown();
0358:
0359:                // static members
0360:                initialized = false;
0361:                hook = null;
0362:                methodEntryTags = null;
0363:                methodExitTags = null;
0364:                constructorTags = null;
0365:                fieldAccessTags = null;
0366:                fieldModificationTags = null;
0367:                //		methodCallTags			= null;
0368:                //		methodReturnTags		= null;
0369:
0370:                suspendedThreads.clear();
0371:                classFileMap.clear();
0372:                resolvedMethods.clear();
0373:                resolvedFields.clear();
0374:
0375:                classRegister.reset();
0376:            }
0377:
0378:            /**
0379:             * Sets a watch on a method entry joinpoint.
0380:             *
0381:             * @param m the method to be watched.
0382:             * @param aopTag A user-defined object saved with this watch.
0383:             *               When the joinpoint is reached, this object is
0384:             *               passed to the JoinPointHook as part of the
0385:             *               JoinPoint-instance. This object may be <code>null</code>.
0386:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0387:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0388:             * @exception InvalidIdException There exists no method with id <code>methodId</code> in class <code>cls</code>.
0389:             * @exception CannotSetWatchException The method must not be abstract or native.
0390:             * @exception WatchAlreadySetException There already exists a entry-watch on the method.
0391:             */
0392:            public void setMethodEntryWatch(Method m, Object aopTag) {
0393:                // check preconditions
0394:                checkWatchPrecondition(m, aopTag);
0395:
0396:                if ((m.getModifiers() & (Modifier.ABSTRACT | Modifier.NATIVE)) != 0)
0397:                    throw new CannotSetWatchException(
0398:                            "HotSwapAspectInterfaceImpl.setMethodEntryWatch: cannot set watches on interfaces");
0399:
0400:                synchronized (methodEntryTags) {
0401:                    MethodWeaver mw = HotSwapClassWeaver.getWeaver(m);
0402:                    methodEntryTags = setWatch(methodEntryTags, aopTag, mw
0403:                            .getTargetId());
0404:                    mw.setMethodEntryEnabled(true);
0405:                }
0406:            }
0407:
0408:            /**
0409:             * Clears a watch on a method entry joinpoint.
0410:             *
0411:             * @param m the method beeing watched.
0412:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0413:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0414:             * @exception InvalidIdException There exists no method with id <code>methodId</code> in class <code>cls</code>.
0415:             * @exception WatchNotSetException There exists no entry-watch on the method.
0416:             */
0417:            public synchronized void clearMethodEntryWatch(Method m) {
0418:                // preconditions
0419:                if (!initialized)
0420:                    throw new NotInitializedException();
0421:                if (m == null)
0422:                    throw new NullPointerException(
0423:                            "Parameter `m' must not be null.");
0424:                if ((m.getModifiers() & (Modifier.ABSTRACT | Modifier.NATIVE)) != 0)
0425:                    throw new CannotSetWatchException(
0426:                            "HotSwapAspectInterfaceImpl.clearMethodEntryWatch: cannot clear watches on interfaces");
0427:
0428:                //System.out.println("HotSwapAspectInterfaceImpl.clearMethodEntryWatch(): " + m);
0429:                synchronized (methodEntryTags) {
0430:                    MethodWeaver mw = HotSwapClassWeaver.getWeaver(m);
0431:                    clearWatch(methodEntryTags, mw.getTargetId());
0432:                    mw.setMethodEntryEnabled(false);
0433:                }
0434:            }
0435:
0436:            /**
0437:             * Sets a watch on a method exit joinpoint.
0438:             *
0439:             * @param m the method to be watched.
0440:             * @param aopTag A user-defined object saved with this watch.
0441:             *               When the joinpoint is reached, this object is
0442:             *               passed to the JoinPointHook as part of the
0443:             *               JoinPoint-instance. This object may be <code>null</code>.
0444:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0445:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0446:             * @exception InvalidIdException There exists no method with id <code>methodId</code> in class <code>cls</code>.
0447:             * @exception CannotSetWatchException The method must not be abstract or native.
0448:             * @exception WatchAlreadySetException There already exists a exit-watch on the method.
0449:             */
0450:            public synchronized void setMethodExitWatch(Method m, Object aopTag) {
0451:                // preconditions
0452:                checkWatchPrecondition(m, aopTag);
0453:                if ((m.getModifiers() & (Modifier.ABSTRACT | Modifier.NATIVE)) != 0)
0454:                    throw new CannotSetWatchException("Method is abstract: "
0455:                            + m);
0456:
0457:                //System.out.println("HotSwapAspectInterfaceImpl.setMethodExitWatch(): " + m);
0458:                synchronized (methodExitTags) {
0459:                    MethodWeaver mw = HotSwapClassWeaver.getWeaver(m);
0460:                    methodExitTags = setWatch(methodExitTags, aopTag, mw
0461:                            .getTargetId());
0462:                    mw.setMethodExitEnabled(true);
0463:                }
0464:            }
0465:
0466:            /**
0467:             * Clears a watch on a method exit joinpoint.
0468:             *
0469:             * @param m the method beeing watched.
0470:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0471:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0472:             * @exception InvalidIdException There exists no method with id <code>methodId</code> in class <code>cls</code>.
0473:             * @exception WatchNotSetException There exists no exit-watch on the method.
0474:             */
0475:            public void clearMethodExitWatch(Method m) {
0476:                // preconditions
0477:                if (!initialized)
0478:                    throw new NotInitializedException();
0479:                if (m == null)
0480:                    throw new NullPointerException(
0481:                            "Parameter `m' must not be null.");
0482:                if ((m.getModifiers() & (Modifier.ABSTRACT | Modifier.NATIVE)) != 0)
0483:                    throw new CannotSetWatchException("Method is abstract: "
0484:                            + m);
0485:
0486:                //System.out.println("HotSwapAspectInterfaceImpl.clearMethodEntryWatch(): " + m);
0487:                synchronized (methodExitTags) {
0488:                    MethodWeaver mw = HotSwapClassWeaver.getWeaver(m);
0489:                    clearWatch(methodExitTags, mw.getTargetId());
0490:                    mw.setMethodExitEnabled(false);
0491:                }
0492:            }
0493:
0494:            /**
0495:             * Sets a watch on a constructor joinpoint.
0496:             *
0497:             * @param m the constructor to be watched.
0498:             * @param aopTag A user-defined object saved with this watch.
0499:             *               When the joinpoint is reached, this object is
0500:             *               passed to the JoinPointHook as part of the
0501:             *               JoinPoint-instance. This object may be <code>null</code>.
0502:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0503:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0504:             * @exception InvalidIdException There exists no method with id <code>methodId</code> in class <code>cls</code>.
0505:             * @exception CannotSetWatchException The method must not be abstract or native.
0506:             * @exception WatchAlreadySetException There already exists a entry-watch on the method.
0507:             */
0508:            public void setConstructorWatch(Constructor m, Object aopTag) {
0509:                // check preconditions
0510:                checkWatchPrecondition(m, aopTag);
0511:
0512:                if ((m.getModifiers() & Modifier.ABSTRACT) != 0)
0513:                    throw new CannotSetWatchException(
0514:                            "HotSwapAspectInterfaceImpl.setConstructorWatch: cannot set watches on interfaces");
0515:
0516:                synchronized (constructorTags) {
0517:                    MethodWeaver mw = HotSwapClassWeaver.getWeaver(m);
0518:                    constructorTags = setWatch(constructorTags, aopTag, mw
0519:                            .getTargetId());
0520:                    // TODO: change to something like constructor enabled    
0521:                    mw.setMethodEntryEnabled(true);
0522:                }
0523:            }
0524:
0525:            /**
0526:             * Clears a watch on a constructor joinpoint.
0527:             *
0528:             * @param m the constructor beeing watched.
0529:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0530:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0531:             * @exception InvalidIdException There exists no method with id <code>methodId</code> in class <code>cls</code>.
0532:             * @exception WatchNotSetException There exists no entry-watch on the method.
0533:             */
0534:            public synchronized void clearConstructorWatch(Constructor m) {
0535:                // preconditions
0536:                if (!initialized)
0537:                    throw new NotInitializedException();
0538:                if (m == null)
0539:                    throw new NullPointerException(
0540:                            "Parameter `m' must not be null.");
0541:                if ((m.getModifiers() & (Modifier.ABSTRACT | Modifier.NATIVE)) != 0)
0542:                    throw new CannotSetWatchException(
0543:                            "HotSwapAspectInterfaceImpl.clearConstructorWatch: cannot clear watches on interfaces");
0544:
0545:                //System.out.println("HotSwapAspectInterfaceImpl.clearConstructorWatch(): " + m);
0546:                synchronized (constructorTags) {
0547:                    MethodWeaver mw = HotSwapClassWeaver.getWeaver(m);
0548:                    clearWatch(constructorTags, mw.getTargetId());
0549:                    // TODO: change to something like constructor enabled
0550:                    mw.setMethodEntryEnabled(false);
0551:                }
0552:            }
0553:
0554:            /**
0555:             * Sets a watch on a field access joinpoint.
0556:             *
0557:             * @param field the field to be watched.
0558:             * @param aopTag A user-defined object saved with this watch.
0559:             *               When the joinpoint is reached, this object is
0560:             *               passed to the JoinPointHook as part of the
0561:             *               JoinPoint-instance. This object may be <code>null</code>.
0562:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0563:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0564:             * @exception InvalidIdException There exists no field with id <code>fieldId</code> in class <code>cls</code>.
0565:             * @exception CannotSetWatchException ?
0566:             * @exception WatchAlreadySetException There already exists a access-watch on the field.
0567:             */
0568:            public void setFieldAccessWatch(Field field, Object aopTag) {
0569:                // check preconditions
0570:                checkWatchPrecondition(field, aopTag);
0571:
0572:                synchronized (fieldAccessTags) {
0573:                    HotSwapFieldWeaver fw = HotSwapFieldWeaver.getWeaver(field);
0574:                    fieldAccessTags = setWatch(fieldAccessTags, aopTag, fw
0575:                            .getTargetId());
0576:                    fw.setFieldAccessEnabled(true);
0577:                }
0578:            }
0579:
0580:            /**
0581:             * Clears a watch on a field access joinpoint.
0582:             *
0583:             * @param field the field beeing watched.
0584:             * @exception NotInitializedException Aspect-interface has not been intialized yet. Call <code>setup</code> first.
0585:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0586:             * @exception InvalidIdException There exists no field with id <code>fieldId</code> in class <code>cls</code>.
0587:             * @exception WatchNotSetException There exists no access-watch on the field.
0588:             */
0589:            public void clearFieldAccessWatch(Field field) {
0590:                if (!isInitialized || !initialized)
0591:                    throw new NotInitializedException(
0592:                            "HotSwapAspectInterfaceImpl.clearFieldAccessWatch: jvmai not initialized");
0593:                if (field == null)
0594:                    throw new NullPointerException(
0595:                            "HotSwapAspectInterfaceImpl.clearFieldAccessWatch: null cls parameter");
0596:
0597:                synchronized (fieldAccessTags) {
0598:                    HotSwapFieldWeaver fw = HotSwapFieldWeaver.getWeaver(field);
0599:                    clearWatch(fieldAccessTags, fw.getTargetId());
0600:                    fw.setFieldAccessEnabled(false);
0601:                }
0602:            }
0603:
0604:            /**
0605:             * Sets a watch on a field modification joinpoint.
0606:             *
0607:             * @param field the field to be watched.
0608:             * @param aopTag A user-defined object saved with this watch.
0609:             *               When the joinpoint is reached, this object is
0610:             *               passed to the JoinPointHook as part of the
0611:             *               JoinPoint-instance. This object may be <code>null</code>.
0612:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0613:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0614:             * @exception InvalidIdException There exist no field with id <code>fieldId</code> in class <code>cls</code>.
0615:             * @exception CannotSetWatchException ?
0616:             * @exception WatchAlreadySetException There already exists a modification-watch on the field.
0617:             */
0618:            public void setFieldModificationWatch(Field field, Object aopTag) {
0619:                //System.out.println("HotSwapAspectInterfaceImpl.setFieldModificationWatch() for " + field );
0620:                // check preconditions
0621:                checkWatchPrecondition(field, aopTag);
0622:
0623:                synchronized (fieldModificationTags) {
0624:                    HotSwapFieldWeaver fw = HotSwapFieldWeaver.getWeaver(field);
0625:                    fieldModificationTags = setWatch(fieldModificationTags,
0626:                            aopTag, fw.getTargetId());
0627:                    fw.setFieldModificationEnabled(true);
0628:                }
0629:            }
0630:
0631:            /**
0632:             * Clears a watch on a field modification joinpoint.
0633:             *
0634:             * @param field the field beeing watched.
0635:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0636:             * @exception NullPointerException <code>cls</code> is <code>null</code>.
0637:             * @exception InvalidIdException There exists no field with id <code>fieldId</code> in class <code>cls</code>.
0638:             * @exception WatchNotSetException There exists no modification-watch on the field.
0639:             */
0640:            public void clearFieldModificationWatch(Field field) {
0641:                if (!isInitialized || !initialized)
0642:                    throw new NotInitializedException(
0643:                            "HotSwapAspectInterfaceImpl.clearFieldAccessWatch: jvmai not initialized");
0644:                if (field == null)
0645:                    throw new NullPointerException(
0646:                            "HotSwapAspectInterfaceImpl.clearFieldAccessWatch: null cls parameter");
0647:
0648:                synchronized (fieldModificationTags) {
0649:                    HotSwapFieldWeaver fw = HotSwapFieldWeaver.getWeaver(field);
0650:                    clearWatch(fieldModificationTags, fw.getTargetId());
0651:                    fw.setFieldModificationEnabled(false);
0652:                }
0653:            }
0654:
0655:            /**
0656:             * Suspend notification regarding the specified thread.
0657:             * Successive calls to <code>suspendNotification</code>
0658:             * have to be balanced by (at least) the same number of calls to
0659:             * <code>resumeNotification</code>, or the jvmai-system
0660:             * will not resume notification.
0661:             *
0662:             * @param thread Thread for which to disable notification.
0663:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0664:             * @exception NullPointerException <code>thread</code> is <code>null</code>.
0665:             */
0666:            public void suspendNotification(Thread thread) {
0667:                if (!initialized)
0668:                    throw new NotInitializedException();
0669:                if (thread == null)
0670:                    throw new NullPointerException(
0671:                            "Parameter `thread' must not be null");
0672:
0673:                suspendedThreads.add(thread);
0674:
0675:                super .suspendNotification(thread);
0676:            }
0677:
0678:            /**
0679:             * Resumes notification regarding the specified thread.
0680:             * Successive calls to <code>resumeNotification</code>
0681:             * without preceding calls to <code>suspendNotification</code>
0682:             * will be ignored by the jvmai-system.
0683:             *
0684:             * @param thread Thread for which to reenable notification.
0685:             * @exception NotInitializedException Aspect-interface has not been initialized yet. Call <code>setup</code> first.
0686:             * @exception NullPointerException <code>thread</code> is <code>null</code>.
0687:             */
0688:            public void resumeNotification(Thread thread) {
0689:                if (!initialized)
0690:                    throw new NotInitializedException();
0691:                if (thread == null)
0692:                    throw new NullPointerException(
0693:                            "Parameter `thread' must not be null");
0694:
0695:                try {
0696:                    HotSwapFieldWeaver.commit();
0697:                    HotSwapClassWeaver.commit();
0698:                } finally {
0699:                    suspendedThreads.remove(thread);
0700:                }
0701:
0702:                super .resumeNotification(thread);
0703:            }
0704:
0705:            /**
0706:             * Check if the parameters are not null and if this object
0707:             * was initialized. If not an exception will be thrown.
0708:             * 
0709:             * @param arg
0710:             * @param aopTag
0711:             * @throws NotInitializedException this object was not initialized.
0712:             * @throws NullPointerException <CODE>arg<CODE> is <CODE>null</CODE>.
0713:             * @throws IlligalArgumentExceptin <CODE>aopTag</CODE> is <CODE>null</CODE>.
0714:             */
0715:            private void checkWatchPrecondition(Object arg, Object aopTag) {
0716:                if (!initialized)
0717:                    throw new NotInitializedException(
0718:                            "HotSwapAspectInterfaceImpl.setWatch: jvmai not initialized");
0719:                if (arg == null)
0720:                    throw new NullPointerException(
0721:                            "HotSwapAspectInterfaceImpl.setWatch: null argument parameter");
0722:                if (aopTag == null)
0723:                    throw new IllegalArgumentException(
0724:                            "HotSwapAspectInterfaceImpl.setWatch: null aopTag value");
0725:            }
0726:
0727:            /**
0728:             * Set `tags[id]' to `tag'. If `tags' is too small then resize it
0729:             * appriopriately.
0730:             * 
0731:             * @param tags array holding tags.
0732:             * @param tag tag that should be inserted in <CODE>tags</CODE>.
0733:             * @param id index at which <CODE>tag</CODE> should be inserted.
0734:             * @return the new array for <CODE>tags</CODE>.
0735:             */
0736:            private Object[] setWatch(Object[] tags, Object tag, int id) {
0737:                synchronized (tags) {
0738:                    if (tags.length < id) {
0739:                        Object tmp[] = new Object[2 * id];
0740:                        System.arraycopy(tags, 0, tmp, 0, tags.length);
0741:                        tags = tmp;
0742:                    }
0743:                    if (tags[id] != null)
0744:                        throw new WatchAlreadySetException("<" + id + ">");
0745:                    tags[id] = (tag == null) ? aopNullTag : tag;
0746:                }
0747:                return tags;
0748:            }
0749:
0750:            /**
0751:             * Set `tags[id] = null'. If `id' is out of bounds or the watch already
0752:             * cleared a WatchNotSetException is thrown.
0753:             * 
0754:             * @param tags AOP tag array
0755:             * @param id Index into `tags'
0756:             */
0757:            private void clearWatch(Object[] tags, int id) {
0758:                synchronized (tags) {
0759:                    try {
0760:                        if (tags[id] == null)
0761:                            throw new WatchNotSetException("<" + id + ">");
0762:                        tags[id] = null;
0763:                    } catch (ArrayIndexOutOfBoundsException e) {
0764:                        throw new WatchNotSetException("<" + id + ">");
0765:                    }
0766:                }
0767:            }
0768:
0769:            //-----------------------------------------------------------------------------------------------------------------------------
0770:            // Callback functions
0771:            //-----------------------------------------------------------------------------------------------------------------------------
0772:
0773:            /**
0774:             * This callback will be invoked at method entry join points. Invocation only
0775:             * takes place if the callback is woven in to the corresponding method.
0776:             * 
0777:             * @param methodId method identifier
0778:             */
0779:            public static final void doOnMethodEntry(int methodId) {
0780:                Object aopTag = methodEntryTags[methodId];
0781:                Thread currentThread = Thread.currentThread();
0782:
0783:                if (hook == null || suspendedThreads.contains(currentThread)
0784:                        || null == aopTag)
0785:                    return;
0786:
0787:                // Suspend this thread to prevent crosscutting of advice execution
0788:                // 1) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects 
0789:                suspendedThreads.add(currentThread);
0790:
0791:                try {
0792:                    // there's only one join point of this type, so it
0793:                    // must be synchronized.
0794:                    synchronized (methodEntryJoinPoint) {
0795:                        methodEntryJoinPoint.init(methodId, aopTag);
0796:                        hook.onMethodEntry(methodEntryJoinPoint);
0797:                    }
0798:                } finally {
0799:                    // 2) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects
0800:                    suspendedThreads.remove(currentThread);
0801:                }
0802:                // TODO: benchmark if it's faster to generate a new join point object
0803:                //hook.onMethodEntry( new HotSwapMethodEntryJoinPointImpl( methodId, aopTag) );
0804:            }
0805:
0806:            /**
0807:             * This callback will be invoked at method exit join points. Invocation only
0808:             * takes place if the callback is woven in to the corresponding method.
0809:             * 
0810:             * @param methodId method identifier
0811:             * @param resultSlot index of the result in the local variable table
0812:             */
0813:            public static final void doOnMethodExit(int methodId, int resultSlot) {
0814:                Object aopTag = methodExitTags[methodId];
0815:                Thread currentThread = Thread.currentThread();
0816:
0817:                if (hook == null || suspendedThreads.contains(currentThread)
0818:                        || null == aopTag)
0819:                    return;
0820:
0821:                // Suspend this thread to prevent crosscutting of advice execution
0822:                // 1) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects 
0823:                suspendedThreads.add(currentThread);
0824:
0825:                try {
0826:                    // there's only one join point of this type, so it
0827:                    // must be synchronized.
0828:                    synchronized (methodExitJoinPoint) {
0829:                        methodExitJoinPoint.init(methodId, aopTag, resultSlot);
0830:                        hook.onMethodExit(methodExitJoinPoint);
0831:                    }
0832:                } finally {
0833:                    // 2) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects
0834:                    suspendedThreads.remove(currentThread);
0835:                }
0836:
0837:                // TODO: benchmark if it's faster to generate a new join point object
0838:                //hook.onMethodExit( new HotSwapMethodEntryJoinPointImpl( methodId, aopTag, resultSlot ) );
0839:            }
0840:
0841:            /**
0842:             * This callback will be invoked at constructor join points. Invocation only
0843:             * takes place if the callback is woven in to the corresponding constructor.
0844:             * 
0845:             * @param methodId method identifier
0846:             */
0847:            public static final void doOnConstructor(
0848:                    /*Object this0,*/int methodId) {
0849:                Object aopTag = constructorTags[methodId];
0850:                Thread currentThread = Thread.currentThread();
0851:
0852:                if (hook == null || suspendedThreads.contains(currentThread)
0853:                        || null == aopTag)
0854:                    return;
0855:
0856:                // Suspend this thread to prevent crosscutting of advice execution
0857:                // 1) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects 
0858:                suspendedThreads.add(currentThread);
0859:
0860:                try {
0861:                    // there's only one join point of this type, so it
0862:                    // must be synchronized.
0863:                    synchronized (constructorJoinPoint) {
0864:                        constructorJoinPoint.init(null /*this0*/, methodId,
0865:                                aopTag);
0866:                        hook.onConstructor(constructorJoinPoint);
0867:                    }
0868:                } finally {
0869:                    // 2) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects
0870:                    suspendedThreads.remove(currentThread);
0871:                }
0872:
0873:                // TODO: benchmark if it's faster to generate a new join point object
0874:                //hook.onConstructor( new HotSwapMethodEntryJoinPointImpl( this0, methodId, aopTag) );
0875:            }
0876:
0877:            /**
0878:             * This callback will be invoked at field access join points. Invocation only
0879:             * takes place if the callback is woven in to the corresponding method.
0880:             * 
0881:             * @param owner object that contains the field
0882:             * @param fieldId field identifier
0883:             */
0884:            public static final void doOnFieldAccess(Object owner, int fieldId) {
0885:                //System.out.println("HotSwapAspectInterfaceImpl.doOnFieldAccess(" + owner + "," + fieldId + ")");
0886:                Object aopTag = fieldAccessTags[fieldId];
0887:                Thread currentThread = Thread.currentThread();
0888:
0889:                if (hook == null || suspendedThreads.contains(currentThread)
0890:                        || null == aopTag)
0891:                    return;
0892:
0893:                // Suspend this thread to prevent crosscutting of advice execution
0894:                // 1) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects 
0895:                suspendedThreads.add(currentThread);
0896:
0897:                try {
0898:                    // there's only one join point of this type, so it
0899:                    // must be synchronized.
0900:                    synchronized (fieldAccessJoinPoint) {
0901:                        fieldAccessJoinPoint.init(aopTag, fieldId, owner);
0902:                        hook.onFieldAccess(fieldAccessJoinPoint);
0903:                    }
0904:                } finally {
0905:                    // 2) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects
0906:                    suspendedThreads.remove(currentThread);
0907:                }
0908:
0909:                // TODO: benchmark if it's faster to generate a new join point object
0910:                //hook.onFieldAccess( new HotSwapMethodEntryJoinPointImpl( aopTag, fieldId, owner ) );
0911:            }
0912:
0913:            /**
0914:             * This callback will be invoked at field modification join points. Invocation only
0915:             * takes place if the callback is woven in to the corresponding method.
0916:             * 
0917:             * @param owner object that contains the field
0918:             * @param fieldId field identifier
0919:             * @param slot index of the local variable that contains the new value for the field
0920:             */
0921:            public static final void doOnFieldModification(Object owner,
0922:                    int fieldId, int slot) {
0923:                //System.out.println("HotSwapAspectInterfaceImpl.doOnFieldModification(" + owner + "," + fieldId + "," + slot + ")");
0924:                Object aopTag = fieldModificationTags[fieldId];
0925:                Thread currentThread = Thread.currentThread();
0926:
0927:                if (hook == null || suspendedThreads.contains(currentThread)
0928:                        || null == aopTag)
0929:                    return;
0930:
0931:                // Suspend this thread to prevent crosscutting of advice execution
0932:                // 1) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects 
0933:                suspendedThreads.add(currentThread);
0934:
0935:                try {
0936:                    // there's only one join point of this type, so it
0937:                    // must be synchronized.
0938:                    synchronized (fieldModificationJoinPoint) {
0939:                        fieldModificationJoinPoint.init(aopTag, slot, fieldId,
0940:                                owner);
0941:                        hook.onFieldModification(fieldModificationJoinPoint);
0942:                    }
0943:                } finally {
0944:                    // 2) Note: Comment 1) 'suspendThread' and 2) 'resumeThread' in order to allow crosscuting of aspects
0945:                    suspendedThreads.remove(currentThread);
0946:                }
0947:
0948:                // TODO: benchmark if it's faster to generate a new join point object
0949:                //hook.onFieldModification( new HotSwapMethodEntryJoinPointImpl( aopTag, slot, fieldId, owner ) );
0950:            }
0951:
0952:            /**
0953:             * Called when ever a new class is loaded by the VM. 
0954:             * @param cls the new class.
0955:             */
0956:            public static void doOnClassLoad(Class cls) {
0957:                if (null != hook) {
0958:                    // 1. Notify JoinPointManager
0959:                    hook.onClassLoad(cls);
0960:                }
0961:                // 2. Notify HotSwapClassRegister (scanns the class if required)
0962:                // may also trigger weaving.
0963:                classRegister.classLoaded(cls);
0964:            }
0965:
0966:            /**
0967:             * Called when ever the VM unloads a class.
0968:             * This works only with JVMDI, JVMTI has no
0969:             * support for unload events.
0970:             * 
0971:             * @param cls
0972:             */
0973:            public static void doOnClassUnload(Class cls) {
0974:                if (null == classRepository)
0975:                    return;
0976:
0977:                // Remove from class file repository.
0978:                JavaClass bcelClass = classRepository.findClass(cls.getName());
0979:                if (null != bcelClass)
0980:                    classRepository.removeClass(bcelClass);
0981:                // Notify HotSwapClassRegister
0982:                //HotSwapClassRegister.getInstance().classUnloaded( cls );	
0983:            }
0984:
0985:            //------------------------------------------------------------------------------
0986:            // Utility functions
0987:            //------------------------------------------------------------------------------
0988:
0989:            /**
0990:             * Returns the reflected Method, for a id string containing the class name,
0991:             * the method name and it's signature, separated by '#'.
0992:             * <P>
0993:             * The id string for this method would be <CODE>
0994:             * ch.ethz.inf.iks.jvmai.jvmdi.HotSwapClassWeaver#getMethodFromString#(Ljava/lang/String)Ljava/lang/reflect/Method"
0995:             * </CODE>.
0996:             * <P>
0997:             * Note: The class must declare the method, if it only inherits it from a super
0998:             * 		class, this method will throw an {@link java.lang.NoSuchMethodError
0999:             * 		NoSuchMethodError}.
1000:             * 
1001:             * @param id unique method identification string
1002:             * @return Member the reflected object for <CODE>id</CODE> (type is either 
1003:             * 	{@link java.lang.reflect.Method} or {@link java.lang.reflect.Constructor}).
1004:             * @throws java.lang.ClassNotFoundException can not find the class, declaring the method.
1005:             * @throws ch.ethz.jvmai.InvalidIdException id has wrong format (doesn't contain two '#').
1006:             * @throws java.lang.NoSuchMethodError can not find the method in the declaring class.
1007:             * @throws ch.ethz.jvmai.JVMAIRuntimeException class was not initialized.
1008:             */
1009:            // id strings are usually generated by HotSwapClassRegister and consumed by the
1010:            // various Weavers.
1011:            public static Member getMethodFromString(String id)
1012:                    throws ClassNotFoundException {
1013:                if (null == contingencyLoader)
1014:                    throw new JVMAIRuntimeException("not initialized");
1015:
1016:                // 1 Try to get it from cache
1017:                Object cachedResult = (Member) resolvedMethods.get(id);
1018:                if (null != cachedResult)
1019:                    return (Member) cachedResult;
1020:
1021:                // 2. find the positions of the separators
1022:                int sep1 = id.indexOf('#'); // between class name & method name
1023:                int sep2 = id.indexOf('#', sep1 + 1); // between method name & signature
1024:                int sep3 = id.indexOf('#', sep2 + 1); // indicates a static method (if present)
1025:                // Check if the seperators are valid
1026:                if (sep1 < 0 || sep2 < 0)
1027:                    throw new InvalidIdException(
1028:                            "Invalid method identifier string: " + id);
1029:                // 3. get the (sub)strings
1030:                Class clazz = Class.forName(id.substring(0, sep1).replace('/',
1031:                        '.'), true, contingencyLoader);
1032:                String methodName = id.substring(sep1 + 1, sep2);
1033:                // 4. get the method object
1034:                Member result;
1035:                if (-1 == sep3) { // non static method
1036:                    String signature = id.substring(sep2 + 1);
1037:                    result = getMethodFromStrings(clazz, methodName, signature,
1038:                            false);
1039:                } else { // static method
1040:                    String signature = id.substring(sep2 + 1, sep3);
1041:                    result = getMethodFromStrings(clazz, methodName, signature,
1042:                            true);
1043:                }
1044:                // 5. cache it.
1045:                resolvedMethods.put(id, result);
1046:                return result;
1047:            }
1048:
1049:            /**
1050:             * Returns the reflected Method, for a id string containing the class name,
1051:             * the method name and it's signature, separated by '#'.
1052:             * <P>
1053:             * The id string for this method would be <CODE>
1054:             * ch.ethz.inf.iks.jvmai.jvmdi.HotSwapClassWeaver#getMethodFromString#(Ljava/lang/String)Ljava/lang/reflect/Method"
1055:             * </CODE>.
1056:             * <P>
1057:             * Note: The class must declare the method, if it only inherits it from a super
1058:             * 		class, this method will throw an {@link java.lang.NoSuchMethodError
1059:             * 		NoSuchMethodError}.
1060:             * 
1061:             * @param className String holding the full qualified name of the class.
1062:             * @param methodName String holding the methods name.
1063:             * @param signature String holding the methods signature.
1064:             * @param isStatic <CODE>true</CODE> if the method is static.
1065:             * @return Member the reflected Method or Constructor object.
1066:             * @throws java.lang.ClassNotFoundException can not find the class, declaring the method.
1067:             * @throws ch.ethz.jvmai.InvalidIdException id has wrong format (doesn't contain two '#').
1068:             * @throws java.lang.NoSuchMethodError can not find the method in the declaring class.
1069:             * @throws ch.ethz.jvmai.JVMAIRuntimeException class was not initialized.
1070:             */
1071:            public static Member getMethodFromString(String className,
1072:                    String methodName, String signature, boolean isStatic)
1073:                    throws ClassNotFoundException {
1074:                if (null == contingencyLoader)
1075:                    throw new JVMAIRuntimeException("not initialized");
1076:                // 1. Try to get it from cache
1077:                String key = className + '#' + methodName + '#' + signature
1078:                        + (isStatic ? "#" : "");
1079:                Object cachedResult = resolvedMethods.get(key);
1080:                if (null != cachedResult)
1081:                    return (Member) cachedResult;
1082:                // 2. Resolve the class
1083:                Class clazz = Class.forName(className.replace('/', '.'), true,
1084:                        contingencyLoader);
1085:                // 3. Get the method object
1086:                Member result = getMethodFromStrings(clazz, methodName,
1087:                        signature, isStatic);
1088:                // 4. Cache it.
1089:                resolvedMethods.put(key, result);
1090:                return result;
1091:            }
1092:
1093:            /**
1094:             * Returns the reflected Field, for a id string containing the class name,
1095:             * the field name and it's signature separated by '#'.
1096:             * <P>
1097:             * Note: The class must declare the field, if it only inherits it from a super
1098:             * 		class, this method will throw an {@link java.lang.NoSuchFieldException
1099:             * 		NoSuchFieldException}.
1100:             * 
1101:             * @param id String holding an unique identiefier for the field.
1102:             * @param isStatic <CODE>true</CODE> if the field is static.
1103:             * @return Field
1104:             * @throws ClassNotFoundException can not find the class, the field belongs to.
1105:             * @throws NoSuchFieldException can not find the field
1106:             * @throws InvalidIdException the id string is not well formated.
1107:             */
1108:            public static Field getFieldFromString(String id, boolean isStatic)
1109:                    throws ClassNotFoundException, NoSuchFieldException {
1110:                if (null == contingencyLoader)
1111:                    throw new JVMAIRuntimeException("not initialized");
1112:                // 1. try to get it from cache
1113:                Object cachedResult = resolvedFields.get(id);
1114:                if (null != cachedResult)
1115:                    return (Field) cachedResult;
1116:
1117:                // 2. Find the position of the separator
1118:                // In most cases the full class name is longer as the simple
1119:                // field name, so it's faster to search from the end to the beginning.
1120:                int sep1 = id.indexOf('#');
1121:                int sep2 = id.lastIndexOf('#');
1122:                if (sep1 >= sep2 || sep1 < 0)
1123:                    throw new InvalidIdException(
1124:                            "Invalid field identifier string: " + id);
1125:
1126:                // 3. Get the substrings
1127:                String className = id.substring(0, sep1);
1128:                String fieldName = id.substring(sep1 + 1, sep2);
1129:                String signature = id.substring(sep2 + 1);
1130:                // 4. Resolve the class
1131:                Class clazz = Class.forName(className.replace('/', '.'), true,
1132:                        contingencyLoader);
1133:                // 5. Get the field object
1134:                Field result = getFieldFromStrings(clazz, fieldName, signature,
1135:                        isStatic);
1136:                // 6. Cache the result
1137:                resolvedFields.put(id, result);
1138:                return result;
1139:            }
1140:
1141:            /**
1142:             * Returns the reflected Field, for a id string containing the class name,
1143:             * the field name and it's signature separated by '#'.
1144:             * <P>
1145:             * Note: The class must declare the field, if it only inherits it from a super
1146:             * 		class, this method will throw an {@link java.lang.NoSuchFieldException
1147:             * 		NoSuchFieldException}.
1148:             * 
1149:             * @param className String holding the full qualified class name.
1150:             * @param fieldName String holding the fields name.
1151:             * @param signature String holding the signature (type) of the field.
1152:             * @param isStatic <CODE>true</CODE> if the field is static.
1153:             * @return Field
1154:             * @throws ClassNotFoundException can not find the class, the field belongs to.
1155:             * @throws NoSuchFieldException can not find the field
1156:             * @throws InvalidIdException the id string is not well formated.
1157:             */
1158:            public static Field getFieldFromString(String className,
1159:                    String fieldName, String signature, boolean isStatic)
1160:                    throws ClassNotFoundException, NoSuchFieldException {
1161:                if (null == contingencyLoader)
1162:                    throw new JVMAIRuntimeException("not initialized");
1163:                // 1. Try to get it from cache
1164:                String key = className + "#" + fieldName + "#" + signature;
1165:                Object cachedResult = resolvedFields.get(key);
1166:                if (null != cachedResult)
1167:                    return (Field) cachedResult;
1168:                // 2. Resolve the class
1169:                Class clazz = Class.forName(className.replace('/', '.'), true,
1170:                        contingencyLoader);
1171:                // 3. Get the field object
1172:                Field result = getFieldFromStrings(clazz, fieldName, signature,
1173:                        isStatic);
1174:                // 4. Cache the field
1175:                resolvedFields.put(key, result);
1176:                return result;
1177:            }
1178:
1179:            /**
1180:             * Returns a BCEL class of a java class.
1181:             * 
1182:             * @param cls
1183:             * @return JavaClass BCEL class for <CODE>cls</CODE>
1184:             * @throws JVMAIRuntimeException the class is not initialized, <CODE>startup()</CODE>
1185:             * 						was never invoked.
1186:             * @throws ClassNotFoundException can not find the class or the class file
1187:             */
1188:            public static JavaClass getBCELClassDefinition(Class cls)
1189:                    throws ClassNotFoundException {
1190:                if (null == classRepository)
1191:                    throw new JVMAIRuntimeException("not initialized");
1192:
1193:                return classRepository.loadClass(cls); // throws an exception, if not found
1194:            }
1195:
1196:            /**
1197:             * Returns the original class implementation from a class file
1198:             * in CLASS_PATH, if available. This is deprecated use 
1199:             * {@link #getBCELClassDefinition(Class)} instead.
1200:             *
1201:             * @param cls Class thats implementation should be returned.
1202:             * @return InputStream with the contents of the class file.
1203:             * @exception RuntimeException if class file was not found.
1204:             * @exception NullPointerException if <CODE>cls</CODE> is <CODE>null</CODE>.
1205:             * 
1206:             * @deprecated
1207:             */
1208:            public java.io.InputStream getOriginalClassDefinition(Class cls)
1209:                    throws IOException {
1210:                if (null == cls)
1211:                    throw new NullPointerException();
1212:
1213:                java.io.InputStream result;
1214:
1215:                // Try to get the definition from the cache
1216:                Object classCache = classFileMap.get(cls);
1217:                if (null == classCache) {
1218:                    // Get definition from class file
1219:                    ClassLoader cl = cls.getClassLoader();
1220:                    if (cl == null)
1221:                        cl = contingencyLoader;
1222:
1223:                    String fileName = cls.getName().replace('.', '/')
1224:                            + ".class";
1225:                    result = cl.getResourceAsStream(fileName);
1226:
1227:                    if (null == result)
1228:                        throw new JVMAIRuntimeException(
1229:                                "JVMAspectInterface.getOriginalClassDefinition: could not find classfile "
1230:                                        + cls.getName());
1231:
1232:                    // Add definition to cache
1233:                    int fileSize = result.available();
1234:                    byte[] classDef = new byte[fileSize];
1235:
1236:                    if (result.markSupported()) {
1237:                        result.mark(fileSize);
1238:                        result.read(classDef);
1239:                        result.reset();
1240:                    } else {
1241:                        result.read(classDef);
1242:                        result = new ByteArrayInputStream(classDef);
1243:                    }
1244:
1245:                    classFileMap.put(cls, classDef);
1246:                } else
1247:                    // Definition was in cache, just have to wrap it in a stream.
1248:                    result = new ByteArrayInputStream((byte[]) classCache);
1249:
1250:                return result;
1251:            }
1252:
1253:            //------------------------------------------------------------------------------
1254:            // Native methods
1255:            //------------------------------------------------------------------------------
1256:
1257:            /**
1258:             * Returns a reflected method object for a method identified by 
1259:             * it's name and signature.
1260:             * <P>
1261:             * This is a native function because some (synthetic) methods may not be 
1262:             * accessed via the Java reflection API (and this should also be faster).
1263:             * 
1264:             * @param className name of a class holding the method (all classes containing 
1265:             * this method are valid, not only the declaring class)
1266:             * @param methodName name of the method
1267:             * @param signature method's signature.
1268:             * @param isStatic <CODE>true</CODE> if the method is a static class member.
1269:             * @return Member reflected object representing the method, may either be
1270:             * of type {@link java.lang.reflected.Method java.lang.reflected.Method}
1271:             * or {@link java.lang.reflected.Constructor java.lang.reflected.Constructor}. 
1272:             */
1273:            private static native Member getMethodFromStrings(Class clazz,
1274:                    String methodName, String signature, boolean isStatic);
1275:
1276:            /**
1277:             * Returns a reflected field object for a field identified by 
1278:             * it's name and signature.
1279:             * <P>
1280:             * This is a native function because some fields may not be 
1281:             * accessed via the Java reflection API (and this should also be faster).
1282:             * 
1283:             * @param className name of a class holding the field (all classes containing 
1284:             * this method are valid, not only the declaring class)
1285:             * @param fieldName name of the field
1286:             * @param signature the signature of the field (type).
1287:             * @param isStatic <CODE>true</CODE> if the field is a static class member.
1288:             * @return Field reflected object representing the field. 
1289:             */
1290:            private static native Field getFieldFromStrings(Class clazz,
1291:                    String fieldName, String signature, boolean isStatic);
1292:
1293:            /// initializes the native part of this class.
1294:            private native void doStartUp(String[] prefixes, boolean openWorld);
1295:        }
1296:
1297:        //======================================================================
1298:        //
1299:        //$Log$
1300:        //
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.