Source Code Cross Referenced for LazyNode.java in  » Profiler » ejp » ejp » presenter » api » model » tree » 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 » ejp » ejp.presenter.api.model.tree 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         $Id: LazyNode.java,v 1.11 2005/03/11 13:14:49 vauclair Exp $
003:
004:         Copyright (C) 2002-2005 Sebastien Vauclair
005:
006:         This file is part of Extensible Java Profiler.
007:
008:         Extensible Java Profiler is free software; you can redistribute it and/or
009:         modify it under the terms of the GNU General Public License as published by
010:         the Free Software Foundation; either version 2 of the License, or
011:         (at your option) any later version.
012:
013:         Extensible Java Profiler is distributed in the hope that it will be useful,
014:         but WITHOUT ANY WARRANTY; without even the implied warranty of
015:         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016:         GNU General Public License for more details.
017:
018:         You should have received a copy of the GNU General Public License
019:         along with Extensible Java Profiler; if not, write to the Free Software
020:         Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
021:         */
022:
023:        package ejp.presenter.api.model.tree;
024:
025:        import java.awt.Color;
026:        import java.util.Enumeration;
027:        import java.util.Vector;
028:        import java.util.logging.Level;
029:
030:        import javax.swing.tree.TreeNode;
031:
032:        import ejp.presenter.api.filters.AbstractFilterImpl;
033:        import ejp.presenter.api.model.LoadedMethod;
034:        import ejp.presenter.api.util.CustomLogger;
035:        import ejp.presenter.api.util.ValuesRenderer;
036:        import ejp.presenter.parser.IMethodTimeNode;
037:
038:        /**
039:         * Super class of all presented call tree nodes.
040:         * 
041:         * Implements lazy application of filters.
042:         * 
043:         * @author Sebastien Vauclair
044:         * @version <code>$Revision: 1.11 $<br>$Date: 2005/03/11 13:14:49 $</code>
045:         */
046:        public class LazyNode implements  TreeNode {
047:            // ///////////////////////////////////////////////////////////////////////////
048:            // PROTECTED FIELDS
049:            // ///////////////////////////////////////////////////////////////////////////
050:
051:            /**
052:             * Parent node.
053:             * 
054:             * Might be <code>null</code> for a root node.
055:             */
056:            protected LazyNode parent;
057:
058:            /**
059:             * Array of filters to apply.
060:             * 
061:             * Is not <code>null</code> iff the node is a root node.
062:             */
063:            protected AbstractFilterImpl[] filterImpls;
064:
065:            /**
066:             * Method time node associated with this node.
067:             * 
068:             * Might not be <code>null</code> in <code>LazyNode</code> class.
069:             */
070:            protected final IMethodTimeNode methodTimeNode;
071:
072:            /**
073:             * Current list of children nodes.
074:             * 
075:             * This is a list of <code>LazyNode</code> instances.
076:             */
077:            protected Vector children;
078:
079:            /**
080:             * Number of last filter fully applied.
081:             * 
082:             * If equal to <code>-1</code>, no filter was applied.
083:             */
084:            protected int lastAppliedFilter;
085:
086:            /**
087:             * Node's text color.
088:             * 
089:             * Default color is black.
090:             */
091:            protected Color color = Color.black;
092:
093:            /**
094:             * Node's text.
095:             * 
096:             * If <code>null</code>, the associated method (if any) will be used to get
097:             * the node's caption.
098:             */
099:            protected String text = null;
100:
101:            /**
102:             * Prefix text.
103:             */
104:            protected String prefix = "";
105:
106:            /**
107:             * Suffix text.
108:             */
109:            protected String suffix = "";
110:
111:            /**
112:             * Own time + children time.
113:             */
114:            protected long totalTime = 0;
115:
116:            /**
117:             * Time spent in own body.
118:             */
119:            protected long ownTime = 0;
120:
121:            /**
122:             * Ratio of time spent in sub-tree rooted at this node.
123:             * 
124:             * Default value is <code>-1</code> (N/A).
125:             */
126:            protected double ratio = -1;
127:
128:            /**
129:             * Total execution time of profiled program.
130:             * 
131:             * <code>-1</code> means not yet initialized.
132:             */
133:            protected long profileTime = -1;
134:
135:            protected long entryTime = -1;
136:
137:            protected long exitTime = -1;
138:
139:            // ///////////////////////////////////////////////////////////////////////////
140:            // CONSTRUCTORS
141:            // ///////////////////////////////////////////////////////////////////////////
142:
143:            /**
144:             * Creates a new lazy node instance that mirrors one single method time node
145:             * instance.
146:             * 
147:             * @param aMethodTimeNode
148:             *          associated <code>MethodTimeNode</code> value.
149:             */
150:            protected LazyNode(IMethodTimeNode aMethodTimeNode) {
151:                invalidateChildren();
152:                methodTimeNode = aMethodTimeNode;
153:
154:                if (methodTimeNode != null) {
155:                    totalTime = aMethodTimeNode.getTotalTime();
156:                    ownTime = aMethodTimeNode.getTime();
157:                    entryTime = aMethodTimeNode.getEntryTime();
158:                    exitTime = aMethodTimeNode.getExitTime();
159:                }
160:            }
161:
162:            /**
163:             * Creates a root lazy node mirroring a root method time node.
164:             * 
165:             * @param aMethodTimeNode
166:             *          associated <code>MethodTimeNode</code> value.
167:             * @param aFilterImpls
168:             *          array of filters to apply on tree.
169:             */
170:            public LazyNode(IMethodTimeNode aMethodTimeNode,
171:                    AbstractFilterImpl[] aFilterImpls) {
172:                this (aMethodTimeNode);
173:                parent = null;
174:                filterImpls = aFilterImpls;
175:
176:                // apply all filters to this root node (for node renderers)
177:                for (int i = 0; i < aFilterImpls.length; i++)
178:                    aFilterImpls[i].applyToRoot(this );
179:            }
180:
181:            /**
182:             * Creates a new child lazy node instance that mirrors one single method time
183:             * node instance.
184:             * 
185:             * @param aMethodTimeNode
186:             *          associated <code>MethodTimeNode</code> value.
187:             * @param aParent
188:             *          the new node's parent.
189:             */
190:            public LazyNode(IMethodTimeNode aMethodTimeNode, LazyNode aParent) {
191:                this (aMethodTimeNode);
192:                parent = aParent;
193:                filterImpls = null;
194:            }
195:
196:            // ///////////////////////////////////////////////////////////////////////////
197:            // CHILDREN BUILDING AND PROCESSING (FILTERS APPLICATION)
198:            // ///////////////////////////////////////////////////////////////////////////
199:
200:            /**
201:             * Builds the list of children lazy nodes without any processing.
202:             * 
203:             * The method implemented in this class builds the list of lazy nodes from
204:             * associated method time node's children.
205:             * 
206:             * @return a list of <code>LazyNode</code> values.
207:             */
208:            protected Vector buildChildren() {
209:                IMethodTimeNode[] childrenMTN = methodTimeNode.getChildren();
210:
211:                // ask it again after MTN children computation
212:                ownTime = methodTimeNode.getTime();
213:
214:                int nb = childrenMTN.length;
215:                Vector result = new Vector(nb);
216:                for (int i = 0; i < nb; i++)
217:                    result
218:                            .add(new LazyNode(
219:                                    childrenMTN[i] /* method time node */,
220:                                    this  /* parent */));
221:                return result;
222:            }
223:
224:            /**
225:             * Computes the fully-processed list of children of this node.
226:             * 
227:             * Calls <code>buildChildren()</code> to generate the list of children lazy
228:             * nodes before processing it.
229:             */
230:            protected final void computeChildren() {
231:                // get array of filters impl
232:                AbstractFilterImpl[] filters = getFilterImpls();
233:
234:                // build list of children
235:                children = buildChildren();
236:
237:                // apply all filters
238:                for (int i = 0; i < filters.length; i++) {
239:                    lastAppliedFilter = i;
240:
241:                    try {
242:                        filters[i].applyTo(this , children);
243:                    } catch (Exception e) {
244:                        CustomLogger.INSTANCE.log(Level.WARNING,
245:                                "An exception occured while applying filter "
246:                                        + filters[i], e);
247:                        throw new RuntimeException(e);
248:                    }
249:                }
250:            }
251:
252:            /**
253:             * Invalidates current list of children nodes.
254:             * 
255:             * This forces it to be computed again next time it is needed.
256:             */
257:            protected void invalidateChildren() {
258:                children = null;
259:                lastAppliedFilter = -1;
260:            }
261:
262:            // ///////////////////////////////////////////////////////////////////////////
263:            // HANDLING OF APPLIED FILTERS
264:            // ///////////////////////////////////////////////////////////////////////////
265:
266:            /**
267:             * Gets array of filters to be applied to this node.
268:             * 
269:             * This array depends on the filters already applied on the node's parent.
270:             * 
271:             * @return an <code>AbstractFilterImpl[]</code> value.
272:             */
273:            protected AbstractFilterImpl[] getFilterImpls() {
274:                if (parent == null)
275:                    return filterImpls; // root node
276:                return parent.getAppliedFilters(); // child node
277:            }
278:
279:            /**
280:             * Gets array of filters applied on parent node.
281:             * 
282:             * @return an <code>AbstractFilterImpl[]</code> value.
283:             */
284:            protected AbstractFilterImpl[] getAppliedFilters() {
285:                AbstractFilterImpl[] result = new AbstractFilterImpl[lastAppliedFilter + 1];
286:
287:                AbstractFilterImpl[] filters = getFilterImpls();
288:                for (int i = 0; i <= lastAppliedFilter; i++)
289:                    result[i] = filters[i];
290:                return result;
291:
292:                // no longer returns all filters
293:                // return getFilterImpls();
294:            }
295:
296:            // ///////////////////////////////////////////////////////////////////////////
297:            // TreeNode INTERFACE
298:            // ///////////////////////////////////////////////////////////////////////////
299:
300:            public TreeNode getParent() {
301:                return parent;
302:            }
303:
304:            public TreeNode getChildAt(int aIndex) {
305:                if (children == null)
306:                    computeChildren();
307:                return (LazyNode) children.get(aIndex);
308:            }
309:
310:            public int getChildCount() {
311:                if (children == null)
312:                    computeChildren();
313:                return children.size();
314:            }
315:
316:            public int getIndex(TreeNode aTreeNode) {
317:                if (children == null)
318:                    computeChildren();
319:                return children.indexOf(aTreeNode);
320:            }
321:
322:            public boolean getAllowsChildren() {
323:                return !isLeaf();
324:            }
325:
326:            public boolean isLeaf() {
327:                if (children == null)
328:                    return false; // before computation, all nodes are openable
329:                return children.isEmpty();
330:            }
331:
332:            public Enumeration children() {
333:                if (children == null)
334:                    computeChildren();
335:                return children.elements(); // this respects laziness
336:            }
337:
338:            // ///////////////////////////////////////////////////////////////////////////
339:            // CONVENIENCE METHODS
340:            // ///////////////////////////////////////////////////////////////////////////
341:
342:            /**
343:             * Convenience method to compute children only on first access.
344:             * 
345:             * @return the list of children of this node.
346:             */
347:            public Vector getChildren() {
348:                if (children == null)
349:                    computeChildren();
350:                return children;
351:            }
352:
353:            // ///////////////////////////////////////////////////////////////////////////
354:            // WRAPPERS TO MethodTimeNode METHODS
355:            // ///////////////////////////////////////////////////////////////////////////
356:
357:            /**
358:             * Gets the description of the method associated with this node.
359:             * 
360:             * @return a <code>LoadedMethod</code> value.
361:             */
362:            public LoadedMethod getMethod() {
363:                return methodTimeNode.getMethod();
364:            }
365:
366:            // ///////////////////////////////////////////////////////////////////////////
367:            // TREE NAVIGATION
368:            // ///////////////////////////////////////////////////////////////////////////
369:
370:            /**
371:             * Gets the parent lazy node of this node, if any.
372:             * 
373:             * @return <code>null</code> iff this node is a root.
374:             */
375:            public LazyNode getParentLazyNode() {
376:                return parent;
377:            }
378:
379:            /**
380:             * Inserts a lazy child node at a given index.
381:             * 
382:             * This requires application of filters.
383:             * 
384:             * @param aChild
385:             *          a <code>LazyNode</code> value.
386:             * @param aIndex
387:             *          index of insertion (if <code>-1</code>, insert at the end).
388:             */
389:            protected void insert(LazyNode aChild, int aIndex) {
390:                if (children == null)
391:                    computeChildren();
392:                if (aIndex == -1)
393:                    children.add(aChild);
394:                else
395:                    children.insertElementAt(aChild, aIndex);
396:            }
397:
398:            /**
399:             * Removes a child lazy node.
400:             * 
401:             * @param aChild
402:             *          a <code>LazyNode</code> value.
403:             * @return <code>true</code> iff the node was present.
404:             */
405:            public boolean remove(LazyNode aChild) {
406:                if (children == null)
407:                    computeChildren();
408:                return children.remove(aChild);
409:            }
410:
411:            /**
412:             * Removes this node from its parent, thus removing it from the tree.
413:             * 
414:             * @return <code>false</code> iff the node was not present in its parent.
415:             */
416:            public boolean removeFromParent() {
417:                return (parent == null ? true : parent.remove(this ));
418:            }
419:
420:            /**
421:             * Changes the parent of this node, by inserting this node at a given index.
422:             * 
423:             * Automatically calls <code>removeFromParent()</code> and inserts into new
424:             * parent's children.
425:             * 
426:             * @param aParent
427:             *          a <code>LazyNode</code> value.
428:             * @param aInsertionIndex
429:             *          index of insertion (if <code>-1</code>, insert at the end).
430:             */
431:            public void setParent(LazyNode aParent, int aInsertionIndex) {
432:                setParent(aParent);
433:                aParent.insert(this , aInsertionIndex);
434:                filterImpls = null;
435:            }
436:
437:            /**
438:             * Changes the parent of this node.
439:             * 
440:             * Automatically calls <code>removeFromParent()</code>.
441:             * 
442:             * @param aParent
443:             *          a <code>LazyNode</code> value.
444:             */
445:            public void setParent(LazyNode aParent) {
446:                removeFromParent();
447:                parent = aParent;
448:            }
449:
450:            // ///////////////////////////////////////////////////////////////////////////
451:            // TIME
452:            // ///////////////////////////////////////////////////////////////////////////
453:
454:            /**
455:             * Adds <i>own </i> time.
456:             * 
457:             * @param aTime
458:             *          a <code>long</code> value.
459:             */
460:            public void addOwnTime(long aTime) {
461:                ownTime += aTime;
462:            }
463:
464:            /**
465:             * Adds <i>own </i> time and updates <i>total </i> time.
466:             * 
467:             * @param aTime
468:             *          a <code>long</code> value.
469:             */
470:            public void addOwnAndTotalTime(long aTime) {
471:                ownTime += aTime;
472:                totalTime += aTime;
473:            }
474:
475:            /**
476:             * Gets <i>own </i> time.
477:             * 
478:             * @return a <code>long</code> value.
479:             */
480:            public long getOwnTime() {
481:                return ownTime;
482:            }
483:
484:            /**
485:             * Gets <i>total </i> time.
486:             * 
487:             * @return a <code>long</code> value.
488:             */
489:            public long getTotalTime() {
490:                return totalTime;
491:            }
492:
493:            /**
494:             * Gets <i>profile </i> time, i.e. total execution time of the program.
495:             * 
496:             * @return a <code>long</code> value.
497:             */
498:            public long getProfileTime() {
499:                if (profileTime == -1) {
500:                    if (parent == null) {
501:                        profileTime = totalTime;
502:                    } else {
503:                        profileTime = parent.getProfileTime();
504:                        if (profileTime == -1) {
505:                            profileTime = totalTime;
506:                        }
507:                    }
508:                }
509:
510:                return profileTime;
511:            }
512:
513:            /**
514:             * Returns the ratio of time spent in this node with respect to profile time.
515:             * 
516:             * @return a <code>double</code> value.
517:             */
518:            public double getRatioOfProfileTime() {
519:                long profTime = getProfileTime();
520:                if (profTime == 0) {
521:                    return 0; // N/A
522:                }
523:                if (profTime == -1) {
524:                    return 0; // N/A
525:                }
526:                return ((double) getTotalTime()) / ((double) profTime);
527:            }
528:
529:            /**
530:             * Returns the ratio of time spent in this node with respect to parent's time.
531:             * 
532:             * @return a <code>double</code> value.
533:             */
534:            public double getRatioOfParentTime() {
535:                if (parent == null)
536:                    return 1;
537:
538:                long parentTime = parent.getTotalTime();
539:                if (parentTime == 0)
540:                    return 0; // N/A
541:                if (parentTime == -1)
542:                    return -1; // N/A
543:
544:                return ((double) getTotalTime()) / ((double) parentTime);
545:            }
546:
547:            // ///////////////////////////////////////////////////////////////////////////
548:            // COLOR / RATIO
549:            // ///////////////////////////////////////////////////////////////////////////
550:
551:            /**
552:             * Sets this node's color.
553:             * 
554:             * @param aColor
555:             *          a <code>Color</code> value.
556:             */
557:            public void setColor(Color aColor) {
558:                color = aColor;
559:            }
560:
561:            /**
562:             * Gets current color of the node.
563:             * 
564:             * Called by GUI to know how to display the node.
565:             * 
566:             * @return a <code>Color</code> value.
567:             */
568:            public Color getColor() {
569:                return color;
570:            }
571:
572:            /**
573:             * Sets the value of the ratio associated with this node.
574:             * 
575:             * @param aRatio
576:             *          a <code>double</code> value.
577:             */
578:            public void setRatio(double aRatio) {
579:                ratio = aRatio;
580:            }
581:
582:            /**
583:             * Gets the value of the ratio associated with this node.
584:             * 
585:             * @return a <code>double</code> value.
586:             */
587:            public double getRatio() {
588:                return ratio;
589:            }
590:
591:            // ///////////////////////////////////////////////////////////////////////////
592:            // DISPLAY METHODS
593:            // ///////////////////////////////////////////////////////////////////////////
594:
595:            /**
596:             * Adds a prefix text.
597:             * 
598:             * @param aText
599:             *          a <code>String</code> value.
600:             */
601:            public void addPrefix(String aText) {
602:                prefix += aText + " ";
603:            }
604:
605:            /**
606:             * Adds a suffix text.
607:             * 
608:             * @param aText
609:             *          a <code>String</code> value.
610:             */
611:            public void addSuffix(String aText) {
612:                suffix += " " + aText;
613:            }
614:
615:            /**
616:             * Gets the node's text.
617:             * 
618:             * @return a <code>String</code> value.
619:             */
620:            public String getText() {
621:                if (text != null)
622:                    return text;
623:
624:                LoadedMethod meth = getMethod();
625:                if (meth != null)
626:                    return getMethod().toNodeLabel();
627:                return "<root>";
628:            }
629:
630:            /**
631:             * Sets the node's text, thus overriding the associated method's name, if any.
632:             * 
633:             * @param aText
634:             *          a <code>String</code> value.
635:             */
636:            public void setText(String aText) {
637:                text = aText;
638:            }
639:
640:            /**
641:             * Returns the node's caption (prefix + text + suffix).
642:             * 
643:             * @return a <code>String</code> value.
644:             */
645:            public String toString() {
646:                return prefix + getText() + suffix;
647:            }
648:
649:            /**
650:             * Returns the node's tooltip text.
651:             * 
652:             * @return a <code>String</code> value.
653:             */
654:            public String getToolTipText() {
655:                StringBuffer buffer = new StringBuffer();
656:
657:                // body time
658:                buffer.append("<font color=blue>Time spent in body</font>: ");
659:                buffer
660:                        .append((children == null ? "? (<i>expand to compute</i>)"
661:                                : ValuesRenderer.renderTime(getOwnTime(), true)));
662:
663:                // source
664:                buffer.append("<br><font color=blue>Source</font>: ");
665:                LoadedMethod meth = getMethod();
666:                buffer.append((meth == null ? "N/A"
667:                        : meth.ownerClass.sourceFile + ":" + meth.sourceLine));
668:
669:                // entry time
670:                if (entryTime != -1) {
671:                    buffer.append("<br><font color=blue>Entry time</font>: ");
672:                    buffer.append(ValuesRenderer.renderTime(entryTime, true));
673:                }
674:
675:                // exit time
676:                if (exitTime != -1) {
677:                    buffer.append("<br><font color=blue>Exit time</font>: ");
678:                    buffer.append(ValuesRenderer.renderTime(exitTime, true));
679:                }
680:
681:                return buffer.toString();
682:            }
683:
684:            // ///////////////////////////////////////////////////////////////////////////
685:            // MISC
686:            // ///////////////////////////////////////////////////////////////////////////
687:
688:            /**
689:             * Recursively gets the node's depth in the tree.
690:             * 
691:             * @return an <code>int</code> value.
692:             */
693:            public int getDepth() {
694:                return (parent == null ? 0 : parent.getDepth() + 1);
695:            }
696:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.