Source Code Cross Referenced for MonProxyFactory.java in  » Profiler » JAMon » com » jamonapi » proxy » 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 » Profiler » JAMon » com.jamonapi.proxy 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package com.jamonapi.proxy;
002:
003:        import com.jamonapi.*;
004:        import java.lang.reflect.Proxy;
005:        import java.sql.*;
006:        import java.util.*;
007:
008:        /**
009:         * MonProxyFactory allows developers to monitor ANY interface by simply passing the Object implementing 
010:         * the interface to the monitor method.  (note the object passed MUST implement an interface or it will 
011:         * be a runtime error).  A great use of this is to monitor jdbc interfaces and to aid in this there are 
012:         * overloaded methods that take Connections, Statements, PreparedStatements, CallableStatements, and 
013:         * ResultSets.  These overloaded methods take advantage of knowledege of SQL and track additional statistics.   
014:         * The following capabilities can be acquired by using MonProxyFactory.  All can individually be enabled/disabled.
015:         * 
016:         *  0) Overall monitoring can be enabled/disabled by calling MonProxyFactory.enable(...).  This will enable/disable monitors.
017:         *  You can start out by enabling all monitors and disabling the ones you wish or vice versa.
018:         *  
019:         *  1) All methods of a given interface will have a jamon rows.  Any jamon row will have the label (in this 
020:         *  case the method signature), hits, avg/min/max execution time, active/avg active/max active, last value and 
021:         *  more. By default interface monitoring is on.  It can be enabled/disabled by calling MonProxyFactory.enableInterfaceM(...). 
022:         *  JDBC classes such as Connections, Statements, PreparedStatemetns, CallableStatements, and ResultsSets
023:         *  will also automatically be monitored if the class returning them was monitored.  If you don't wish this 
024:         *  to occur then you can use the monitor method that takes an Object.  
025:         *  
026:         *  2) ResultSet interfaces can be monitored however methods like getObject and next are called so much and 
027:         *  typically don't cause performance problems, so there is a seperate enable/disable capability for them.  Note for 
028:         *  ResultSet monitoring to occur interface monitoring must also be enabled.  
029:         *  However it can be enabled if interface monitoring is enabled and MonProxyFactory.enabledResultSets(true) is called.
030:         *  ResultSet's are by default not monitored.  
031:         *  
032:         *  3) SQLSummary will add a jamon row for all sql text issued against a PreparedStatement, CallableStatement,
033:         *  or Statement.  Argument values are replaced with ? for Statements to ensure the logical queries are matched.
034:         *  PreparedStatements need not be changed to do this, but Statements may look a little different
035:         *  For example:  select * from table where name='jeff beck' would become select * from table where name=?
036:         *  This is a powerful monitor as it allows you to see hits, avg/min/max query times for all queries in your 
037:         *  application.  This is enabled/disabled by calling MonProxyFactory.enableSQLSummary(...).
038:         *  
039:         *  4) SQLDetail puts the last N (configurable) queries that have been run into a rolling buffer.   The SQL buffer
040:         *  will have the actual query in the case of a Statement and the version with ? for PreparedStatements.  In addition
041:         *  other stats will be in this buffer such as how long the query took to execute, how many times has the PreparedStatement
042:         *  been reused, the jdbc method that executed the sql, and the exception stack trace if it occured.  This can be enabled/disabled
043:         *  by calling MonProxyFactory.enableSQLDetail(...)
044:         *  
045:         *  5) Exception Summary will add several jamon rows when an exception occurs.  Note the Exception buffer is used for any kind of Exception
046:         *  including SQLExceptions.  The exceptions added are 1. One containing the method that through the exception as well as the exception.
047:         *  2. One indicating how many exceptions total have been thrown through proxies, 3) One containing the exception type that was thrown.  
048:         *  This can be enabled/disabled by calling MonProxyFactory.enableExceptionSummary(...)
049:         *  
050:         *  6) ExceptionDetail puts the last N (configurable) exceptions that have occured to any interface that is being monitored into a buffer.
051:         *  The stack trace is in the row as well as when it was thrown and what method threw it.  This can be enabled/disabled by calling 
052:         *  MonProxyFactory.enableExceptionDetail(...).
053:         *  
054:         * Sample code:
055:         *   ResultSet rs= MonProxyFactory.monitor(resultSet);
056:         *   Connection conn=MonProxyFactory.monitor(connection);
057:         *   MyInterface my=(MyInterface) MonProxyFactory.monitor(myObject);//myObject implements MyInterface
058:         *   YourInterface your=(YourInterface) MonProxyFactory.monitor(yourObject);//myObject implements MyInterface
059:         *
060:         *  
061:         * @author steve souza
062:         *
063:         */
064:
065:        public class MonProxyFactory {
066:            private static final Class[] CLASS_ARRAY = new Class[0];
067:            private static Params params = new Params();
068:
069:            /** By passing any interface to the monitor method, all public method calls and exceptions
070:             *  will be monitored. It will be a runtime error if the Object passed does not implement an interface. Note that
071:             *  only interfaces implemented directly by the passed in Object are monitored.  Should you want to cast to an interface
072:             *  implemented by a base class to the passed in Object you should call one of the more explicit monitor(..) methods
073:             *  
074:             *    Sample call:
075:             *     MyInterface myProxyObject=(MyInterface) MonProxyFactory.monitor(myObject);
076:             */
077:
078:            public static Object monitor(Object object) {
079:                if (!isEnabled() || object == null) // if not enabled return the original object unchanged, not the proxy
080:                    return object;
081:                else
082:                    return monitorNoCheck(object, getInterfaces(object
083:                            .getClass()));// proxy will implement ALL interfaces of this class
084:            }
085:
086:            /** By passing any interface to the monitor method, and an array of interfaces to implement then all public method calls and exceptions
087:             *  will be monitored. It will be a runtime error if the Object passed does not implement an interface.
088:             *  
089:             *    Sample call:
090:             *     MyInterface myProxyObject=(MyInterface) MonProxyFactory.monitor(myObject, ineterfaces);
091:             */
092:            public static Object monitor(Object object, Class[] interfaces) {
093:                if (!isEnabled() || object == null) // if not enabled return the original object unchanged, not the proxy
094:                    return object;
095:                else
096:                    return monitorNoCheck(object, interfaces);
097:            }
098:
099:            private static Object monitorNoCheck(Object object,
100:                    Class[] interfaces) {
101:                return Proxy.newProxyInstance(object.getClass()
102:                        .getClassLoader(), interfaces,// proxy will implement ALL interfaces in array
103:                        new MonProxy(object, params));
104:
105:            }
106:
107:            /** By passing any interface to the monitor method, and an interface to implement then all public method calls and exceptions
108:             *  will be monitored. It will be a runtime error if the Object passed does not implement an interface.
109:             *  
110:             *    Sample call:
111:             *     MyInterface myProxyObject=(MyInterface) MonProxyFactory.monitor(myObject, com.mypackage.MyInterface.class);
112:             */
113:
114:            public static Object monitor(Object object, Class iface) {
115:                return monitor(object, new Class[] { iface });
116:            }
117:
118:            /** Note if a connection object is monitored any Statements, PreparedStatements, CallableStatements, and
119:             * optionally ResultSets that it creates will automatically be monitored.  So for jdbc interfaces usually it will be sufficient 
120:             * to simply monitor the connection.   You could also call MonProxyFactory.monitor((Object)conn);
121:             * and the connection would be monitored however other child objects wouldn't be and recently executed sql would not be put 
122:             * in a buffer.  The same applies to the other overloaded sql monitor(...) method calls below.  For sql monitored objects
123:             * to be monitored both the overall monitoring must be enabled.  Monitoring rules apply as discussed in the top of this document.
124:
125:             * 
126:             */
127:            public static Connection monitor(Connection conn) {
128:                return (Connection) monitorJDBC(conn);
129:            }
130:
131:            /** Monitor a resultSets methods.  Note the version that takes an explicit class is used for when the class is a proxy*/
132:            public static ResultSet monitor(ResultSet rs) {
133:                return (ResultSet) monitorJDBC(rs);
134:            }
135:
136:            /** Monitor a Statements methods, as well as any ResultSets it returns (assuming the proper monitoring options are enabled) */
137:            public static Statement monitor(Statement statement) {
138:                return (Statement) monitorJDBC(statement);
139:            }
140:
141:            /** Monitor a PreparedStatements methods, as well as any ResultSets it returns (assuming the proper monitoring options are enabled) */
142:            public static PreparedStatement monitor(PreparedStatement statement) {
143:                return (PreparedStatement) monitorJDBC(statement);
144:            }
145:
146:            /** Monitor a CallableStatements methods, as well as any ResultSets it returns (assuming the proper monitoring options are enabled) */
147:            public static CallableStatement monitor(CallableStatement statement) {
148:                return (CallableStatement) monitorJDBC(statement);
149:            }
150:
151:            static Object monitorJDBC(Object object) {
152:
153:                // if monitoring is not enabled, sql monitoring is not enabled, the object is a null or already an instance of a proxy then return
154:                // the original object unchanged.  (it would have to be a proxy object with a JDBCMonProxy invocation handler
155:                if (!params.isEnabled
156:                        || (!params.isSQLSummaryEnabled && !params.isSQLDetailEnabled)
157:                        || object == null
158:                        || (object instanceof  Proxy && Proxy
159:                                .getInvocationHandler(object) instanceof  JDBCMonProxy)) // if not enabled return the original object unchanged, not the proxy
160:                    return object;
161:                else
162:                    return Proxy.newProxyInstance(object.getClass()
163:                            .getClassLoader(),
164:                            getInterfaces(object.getClass()),// proxy will implement passed in interfaces
165:                            new JDBCMonProxy(object, params));
166:            }
167:
168:            /** For every class in the Object/Interface heirarchy find its implemented interfaces.  All interfaces this class 
169:             * implements are returned.  Either the Class of an Object or interfaces Class may be passed to 
170:             *  this method.  The difference between this method and the method 'Class.getInterfaces()' is 
171:             *  that this one returns ALL implemented interfaces whereas that one only returns interfaces that 
172:             *  are directly implemented by the Class.  
173:             */
174:            public static Class[] getInterfaces(Class cls) {
175:                if (cls == null)
176:                    return null;
177:
178:                Set interfaceHeirarchy = new HashSet();
179:                // Get class heirarchy and loop through it and its interfaces adding each interface to the passed
180:                // in Set.
181:                Class[] objTree = getClassHeirarchy(cls);
182:                for (int i = 0; i < objTree.length; i++)
183:                    getInterfaces(objTree[i], interfaceHeirarchy);
184:
185:                return toClassArray(interfaceHeirarchy);
186:
187:            }
188:
189:            /** Convert a Collection to a Class[] array */
190:            private static Class[] toClassArray(Collection coll) {
191:                if (coll == null || coll.size() == 0)
192:                    return null;
193:                else
194:                    return (Class[]) coll.toArray(CLASS_ARRAY);// convert the Set to Class[]
195:
196:            }
197:
198:            /*
199:             *  Returns the inheritance heirarchy of the specified Class that was passed in.  For example if there
200:             *  are three levels such as Base1, Base2, Base3 then it would return an array of these 3 Class elements.
201:             */
202:
203:            private static Class[] getClassHeirarchy(Class cls) {
204:                if (cls == null)
205:                    return null;
206:
207:                // classes will contain the inheritance chain of Objects.
208:                List classes = new ArrayList();
209:                // Loop through super classes until null is found which indicates there are no more Objects
210:                // in the inheritance chain.
211:                while (cls != null) {
212:                    classes.add(cls);
213:                    cls = cls.getSuperclass();
214:                }
215:
216:                return toClassArray(classes);
217:            }
218:
219:            /** A recursive method called for each Object or interface in the heirarchy.  All interfaces are added into the 
220:             * passed in Set.  When either a Class is null, or it implements no other interfaces the recursive method bubbles
221:             * up the chain.
222:             * 
223:             */
224:            private static void getInterfaces(Class cls, Set heirarchy) {
225:                if (cls != null) {
226:                    Class[] heir = cls.getInterfaces();// gets immediate implemented interfaces of passed in Class or interface
227:                    int len = (heir == null) ? 0 : heir.length;
228:                    for (int i = 0; i < len; i++) {
229:                        heirarchy.add(heir[i]);
230:                        getInterfaces(heir[i], heirarchy);// recursive
231:                    }
232:                }
233:
234:            }
235:
236:            // Standard and Exception monitoring methods
237:
238:            /** 
239:             * Get the number of Exceptions that can be stored in the buffer before the oldest entries must
240:             * be removed.
241:             * 
242:             */
243:            public static int getExceptionBufferSize() {
244:                return params.exceptionBuffer.getBufferSize();
245:            }
246:
247:            /** 
248:             * Set the number of Exceptions that can be stored in the buffer before the oldest entries must
249:             * be removed.  A value of 0 will disable collecting of Exceptions in the buffer. 
250:             * 
251:             */
252:
253:            public static void setExceptionBufferSize(int exceptionBufferSize) {
254:                params.exceptionBuffer.setBufferSize(exceptionBufferSize);
255:            }
256:
257:            /** 
258:             * Remove all Exceptions from the buffer.
259:             *
260:             */
261:            public static void resetExceptionDetail() {
262:                params.exceptionBuffer.reset();
263:            }
264:
265:            /** Inidicates whether methods of the interface are monitored or not */
266:            public static boolean isInterfaceEnabled() {
267:                return params.isInterfaceEnabled;
268:            }
269:
270:            /** Enables/disables whether methods of the interface are monitored or not */
271:            public static void enableInterface(boolean enable) {
272:                params.isInterfaceEnabled = enable;
273:                if (enable)
274:                    enable(true);
275:            }
276:
277:            /** Indicates whether jamon summary stats are kept for exceptions */
278:            public static boolean isExceptionSummaryEnabled() {
279:                return params.isExceptionSummaryEnabled;
280:            }
281:
282:            /** Enables/disables jamon summary stats for exceptions */
283:            public static void enableExceptionSummary(boolean enable) {
284:                params.isExceptionSummaryEnabled = enable;
285:                if (enable)
286:                    enable(true);
287:            }
288:
289:            /** Indicates whether exceptions are tracked in a rolling buffer */
290:            public static boolean isExceptionDetailEnabled() {
291:                return params.isExceptionDetailEnabled;
292:            }
293:
294:            /** Enables/Disables whether exceptions are tracked in a rolling buffer */
295:            public static void enableExceptionDetail(boolean enable) {
296:                params.isExceptionDetailEnabled = enable;
297:                if (enable)
298:                    params.exceptionBuffer.enable();
299:                else
300:                    params.exceptionBuffer.disable();
301:
302:                if (enable)
303:                    enable(true);
304:
305:            }
306:
307:            /** Indicates whether jamon summary stats are kept for SQL */
308:            public static boolean isSQLSummaryEnabled() {
309:                return params.isSQLSummaryEnabled;
310:            }
311:
312:            /** Enables/Disables jamon summary stats for SQL */
313:            public static void enableSQLSummary(boolean enable) {
314:                params.isSQLSummaryEnabled = enable;
315:                if (enable)
316:                    enable(true);
317:            }
318:
319:            /** Indicates whether sql command details (time, sql, stack trace, ...) are kept in a rolling buffer */
320:            public static boolean isSQLDetailEnabled() {
321:                return params.isSQLDetailEnabled;
322:            }
323:
324:            /** Enables/disables whether sql command details (time, sql, stack trace, ...) are kept in a rolling buffer */
325:            public static void enableSQLDetail(boolean enable) {
326:                params.isSQLDetailEnabled = enable;
327:                if (enable)
328:                    params.sqlBuffer.enable();
329:                else
330:                    params.sqlBuffer.disable();
331:
332:                if (enable)
333:                    enable(true);
334:            }
335:
336:            /** Indicates whether ResultSet methods are monitored.  Note interface monitoring must also be enabled for ResultSet monitoring to occur */
337:            public static boolean isResultSetEnabled() {
338:                return params.isResultSetEnabled;
339:            }
340:
341:            /** Enables/disables whether ResultSet methods are monitored.  Note interface monitoring must also be enabled for ResultSet monitoring to occur */
342:            public static void enableResultSet(boolean enable) {
343:                params.isResultSetEnabled = enable;
344:                if (enable) {
345:                    enableInterface(true);
346:                    enable(true);
347:                }
348:            }
349:
350:            /** Returns true if MonProxyFactory is enabled.  */
351:            public static boolean isEnabled() {
352:                return params.isEnabled;
353:            }
354:
355:            /** Enables all monitors.  This overrides all other monitor booleans.  It never enables ResultSet monitoring
356:             * That must be done as a separates step as that is not the enabled monitoring by default.  All other monitors will be disabled/enabled when
357:             * calling this method. 
358:             * */
359:            public static void enableAll(boolean enable) {
360:                enable(enable);
361:                enableInterface(enable);
362:                enableExceptionSummary(enable);
363:                enableExceptionDetail(enable);
364:                enableSQLSummary(enable);
365:                enableSQLDetail(enable);
366:                enableResultSet(enable);
367:            }
368:
369:            public static boolean isAllEnabled() {
370:                return (params.isEnabled && params.isExceptionDetailEnabled
371:                        && params.isExceptionSummaryEnabled
372:                        && params.isSQLSummaryEnabled
373:                        && params.isSQLDetailEnabled
374:                        && params.isInterfaceEnabled && params.isResultSetEnabled);
375:            }
376:
377:            /** Enables all monitors except ResultSet monitoring.  This overrides all other monitor booleans.  It never enables ResultSet monitoring
378:             * That must be done as a separates step as that is not the enabled monitoring by default.  All other monitors will be disabled/enabled when
379:             * calling this method. 
380:             * */
381:            public static void enable(boolean enable) {
382:                params.isEnabled = enable;
383:            }
384:
385:            static Params getParams() {
386:                return params;
387:            }
388:
389:            /** Get the header that can be used to display the Exceptions buffer */
390:            public static String[] getExceptionDetailHeader() {
391:                return params.exceptionBuffer.getHeader();
392:            }
393:
394:            /** Get the exception buffer as an array, so it can be displayed */
395:            public static Object[][] getExceptionDetail() {
396:                return params.exceptionBuffer.getData();
397:            }
398:
399:            // JDBC Monitoroing methods
400:
401:            /**
402:             * Get the number of SQL statements that can be stored in the buffer before the
403:             * oldest entries must be removed.
404:             * 
405:             */
406:            public static int getSQLBufferSize() {
407:                return params.sqlBuffer.getBufferSize();
408:            }
409:
410:            /** 
411:             * Set the number of SQL Statements that can be stored in the buffer before the oldest entries must
412:             * be removed.  A value of 0 will disable the collection of Exceptions in the buffer.  Note if 
413:             * monitoring is disabled exceptions will also not be put in the buffer.
414:             * 
415:             */
416:
417:            public static void setSQLBufferSize(int sqlBufferSize) {
418:                params.sqlBuffer.setBufferSize(sqlBufferSize);
419:            }
420:
421:            /** 
422:             * Remove all SQL from the buffer.
423:             *
424:             */
425:            public static void resetSQLDetail() {
426:                params.sqlBuffer.reset();
427:            }
428:
429:            /** Get the header that can be used to display the SQL buffer */
430:            public static String[] getSQLDetailHeader() {
431:                return params.sqlBuffer.getHeader();
432:            }
433:
434:            /** Get the sql buffer as an array, so it can be displayed */
435:            public static Object[][] getSQLDetail() {
436:                return params.sqlBuffer.getData();
437:            }
438:
439:            /** Get a list of the strings to match in the parsed query.  This can be used to count tables hits and times of queries that hit them for example
440:             * 
441:             * 
442:             */
443:
444:            public static List getMatchStrings() {
445:                return params.matchStrings;
446:            }
447:
448:            /** Set the strings to match */
449:            public static void setMatchStrings(List ms) {
450:                params.matchStrings = ms;
451:            }
452:
453:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.