KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > system > server > ServerInfo


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.system.server;
23
24 import java.lang.reflect.Method JavaDoc;
25 import java.text.DecimalFormat JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29 import java.util.Set JavaDoc;
30 import java.util.TreeSet JavaDoc;
31
32 import javax.management.MBeanRegistration JavaDoc;
33 import javax.management.MBeanServer JavaDoc;
34 import javax.management.ObjectName JavaDoc;
35
36 import org.jboss.logging.Logger;
37 import org.jboss.util.platform.Java;
38
39 /**
40  * An MBean that provides a rich view of system information for the JBoss
41  * server in which it is deployed.
42  *
43  * @author <a HREF="mailto:rickard.oberg@telkel.com">Rickard Oberg</a>
44  * @author <a HREF="mailto:Scott.Stark@jboss.org">Scott Stark</a>
45  * @author <a HREF="mailto:hiram.chirino@jboss.org">Hiram Chirino</a>
46  * @author <a HREF="mailto:jason@planet57.com">Jason Dillon</a>
47  * @author <a HREF="mailto:marc.fleury@jboss.org">Marc Fleury</a>
48  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
49  * @version $Revision: 57108 $
50  */

51 public class ServerInfo
52    implements ServerInfoMBean, MBeanRegistration JavaDoc
53 {
54    /** Class logger. */
55    private static final Logger log = Logger.getLogger(ServerInfo.class);
56
57    /** Zero */
58    private static final Integer JavaDoc ZERO = new Integer JavaDoc(0);
59
60    /** The MBeanServer we are registered to */
61    private MBeanServer JavaDoc server;
62    
63    /** The cached host name for the server. */
64    private String JavaDoc hostName;
65    
66    /** The cached host address for the server. */
67    private String JavaDoc hostAddress;
68
69    /** The cached jdk5+ ThreadMXBean instance */
70    private Object JavaDoc threadMXBean;
71    
72    /** The cached jdk5+ ManagementFactory.getMemoryPoolMXBeans() method */
73    private Method JavaDoc getMemoryPoolMXBeans;
74    
75    /** The cached jdk5+ MemoryPoolMXBean methods */
76    private Method JavaDoc getName;
77    private Method JavaDoc getType;
78    private Method JavaDoc getUsage;
79    private Method JavaDoc getPeakUsage;
80    
81    /** The cached jdk5+ MemoryUsage methods */
82    private Method JavaDoc getInit;
83    private Method JavaDoc getUsed;
84    private Method JavaDoc getCommitted;
85    private Method JavaDoc getMax;
86    
87    /** The cached jdk5+ ThreadMXBean.getThreadInfo() method */
88    private Method JavaDoc getThreadInfo;
89    private Method JavaDoc getAllThreadIds;
90    private Method JavaDoc getThreadCpuTime;
91
92    /** The cached jdk5+ ThreadInfo methods */
93    private Method JavaDoc getThreadName;
94    private Method JavaDoc getThreadState;
95    private Method JavaDoc getLockName;
96    private Method JavaDoc getStackTrace;
97    
98    /** The cached jdk5+ Thread.getId() method */
99    private Method JavaDoc getThreadId;
100    
101    ///////////////////////////////////////////////////////////////////////////
102
// JMX Hooks //
103
///////////////////////////////////////////////////////////////////////////
104

105    public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name)
106       throws Exception JavaDoc
107    {
108       this.server = server;
109       // Dump out basic JVM & OS info as INFO priority msgs
110
log.debug("Java version: " +
111       System.getProperty("java.version") + "," +
112       System.getProperty("java.vendor"));
113       
114       log.info("Java VM: " +
115       System.getProperty("java.vm.name") + " " +
116       System.getProperty("java.vm.version") + "," +
117       System.getProperty("java.vm.vendor"));
118       
119       log.info("OS-System: " +
120       System.getProperty("os.name") + " " +
121       System.getProperty("os.version") + "," +
122       System.getProperty("os.arch"));
123       
124       // Dump out the entire system properties
125
log.debug("Full System Properties Dump");
126       Enumeration JavaDoc names = System.getProperties().propertyNames();
127       while (names.hasMoreElements())
128       {
129          String JavaDoc pname = (String JavaDoc)names.nextElement();
130             log.debug(" " + pname + ": " + System.getProperty(pname));
131       }
132       
133       // cache a reference to the platform ThreadMXBean
134
// and related Thread/ThreadInfo methods, if available
135
if (Java.isCompatible(Java.VERSION_1_5))
136       {
137          try
138          {
139             ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
140             Class JavaDoc clazz = cl.loadClass("java.lang.management.ManagementFactory");
141
142             // cache ThreadMXBean instance
143
Method JavaDoc method = clazz.getMethod("getThreadMXBean", null);
144             this.threadMXBean = method.invoke(null, null);
145             
146             // cache ManagementFactory.getMemoryPoolMXBeans() method
147
this.getMemoryPoolMXBeans = clazz.getMethod("getMemoryPoolMXBeans", null);
148             
149             // cache MemoryPoolMXBean methods
150
clazz = cl.loadClass("java.lang.management.MemoryPoolMXBean");
151             this.getName = clazz.getMethod("getName", null);
152             this.getType = clazz.getMethod("getType", null);
153             this.getUsage = clazz.getMethod("getUsage", null);
154             this.getPeakUsage = clazz.getMethod("getPeakUsage", null);
155             
156             // cache MemoryUsage methods
157
clazz = cl.loadClass("java.lang.management.MemoryUsage");
158             this.getInit = clazz.getMethod("getInit", null);
159             this.getUsed = clazz.getMethod("getUsed", null);
160             this.getCommitted = clazz.getMethod("getCommitted", null);
161             this.getMax = clazz.getMethod("getMax", null);
162             
163             // cache ThreadMXBean.getThreadInfo() method
164
clazz = cl.loadClass("java.lang.management.ThreadMXBean");
165             this.getThreadInfo = clazz.getMethod("getThreadInfo", new Class JavaDoc[] { Long.TYPE, Integer.TYPE } );
166             this.getAllThreadIds = clazz.getMethod("getAllThreadIds", null );
167             this.getThreadCpuTime = clazz.getMethod("getThreadCpuTime", new Class JavaDoc[] { Long.TYPE } );
168
169             // cache ThreadInfo methods
170
clazz = cl.loadClass("java.lang.management.ThreadInfo");
171             this.getThreadName = clazz.getMethod("getThreadName", null);
172             this.getThreadState = clazz.getMethod("getThreadState", null);
173             this.getLockName = clazz.getMethod("getLockName", null);
174             this.getStackTrace = clazz.getMethod("getStackTrace", null);
175             
176             // cache Thread.getId() method
177
clazz = Thread JavaDoc.class;
178             this.getThreadId = clazz.getMethod("getId", null);
179          }
180          catch (Exception JavaDoc e)
181          {
182             log.debug("Cannot access platform ThreadMXBean", e);
183          }
184       }
185       
186       return name == null ? new ObjectName JavaDoc(OBJECT_NAME_STR) : name;
187    }
188    
189    public void postRegister(Boolean JavaDoc registrationDone)
190    {
191       // empty
192
}
193    
194    public void preDeregister() throws Exception JavaDoc
195    {
196       // empty
197
}
198    
199    public void postDeregister()
200    {
201       // empty
202
}
203    
204    
205    ///////////////////////////////////////////////////////////////////////////
206
// Server Information //
207
///////////////////////////////////////////////////////////////////////////
208

209    /**
210     * @jmx:managed-attribute
211     */

212    public String JavaDoc getJavaVersion()
213    {
214       return System.getProperty("java.version");
215    }
216
217    /**
218     * @jmx:managed-attribute
219     */

220    public String JavaDoc getJavaVendor()
221    {
222       return System.getProperty("java.vendor");
223    }
224
225    /**
226     * @jmx:managed-attribute
227     */

228    public String JavaDoc getJavaVMName()
229    {
230       return System.getProperty("java.vm.name");
231    }
232
233    /**
234     * @jmx:managed-attribute
235     */

236    public String JavaDoc getJavaVMVersion()
237    {
238       return System.getProperty("java.vm.version");
239    }
240
241    /**
242     * @jmx:managed-attribute
243     */

244    public String JavaDoc getJavaVMVendor()
245    {
246       return System.getProperty("java.vm.vendor");
247    }
248
249    /**
250     * @jmx:managed-attribute
251     */

252    public String JavaDoc getOSName()
253    {
254       return System.getProperty("os.name");
255    }
256
257    /**
258     * @jmx:managed-attribute
259     */

260    public String JavaDoc getOSVersion()
261    {
262       return System.getProperty("os.version");
263    }
264
265    /**
266     * @jmx:managed-attribute
267     */

268    public String JavaDoc getOSArch()
269    {
270       return System.getProperty("os.arch");
271    }
272    
273    /**
274     * @jmx:managed-attribute
275     */

276    public Long JavaDoc getTotalMemory()
277    {
278       return new Long JavaDoc(Runtime.getRuntime().totalMemory());
279    }
280    
281    /**
282     * @jmx:managed-attribute
283     */

284    public Long JavaDoc getFreeMemory()
285    {
286       return new Long JavaDoc(Runtime.getRuntime().freeMemory());
287    }
288    
289    /**
290     * Returns <tt>Runtime.getRuntime().maxMemory()<tt> on
291     * JDK 1.4 vms or -1 on previous versions.
292     *
293     * @jmx:managed-attribute
294     */

295    public Long JavaDoc getMaxMemory()
296    {
297       if (Java.isCompatible(Java.VERSION_1_4)) {
298          // Uncomment when JDK 1.4 is the base JVM
299
// return new Long(Runtime.getRuntime().maxMemory());
300

301          // until then use reflection to do the job
302
try {
303             Runtime JavaDoc rt = Runtime.getRuntime();
304             Method JavaDoc m = rt.getClass().getMethod("maxMemory", new Class JavaDoc[0]);
305             return (Long JavaDoc)m.invoke(rt, new Object JavaDoc[0]);
306          }
307          catch (Exception JavaDoc e) {
308             log.error("Operation failed", e);
309          }
310       }
311
312       return new Long JavaDoc(-1);
313    }
314
315    /**
316     * Returns <tt>Runtime.getRuntime().availableProcessors()</tt> on
317     * JDK 1.4 vms or -1 on previous versions.
318     *
319     * @jmx:managed-attribute
320     */

321    public Integer JavaDoc getAvailableProcessors()
322    {
323       if (Java.isCompatible(Java.VERSION_1_4)) {
324          // Uncomment when JDK 1.4 is the base JVM
325
// return new Integer(Runtime.getRuntime().availableProcessors());
326

327          // until then use reflection to do the job
328
try {
329             Runtime JavaDoc rt = Runtime.getRuntime();
330             Method JavaDoc m = rt.getClass().getMethod("availableProcessors", new Class JavaDoc[0]);
331             return (Integer JavaDoc)m.invoke(rt, new Object JavaDoc[0]);
332          }
333          catch (Exception JavaDoc e) {
334             log.error("Operation failed", e);
335          }
336       }
337
338       return new Integer JavaDoc(-1);
339    }
340
341    /**
342     * Returns InetAddress.getLocalHost().getHostName();
343     *
344     * @jmx:managed-attribute
345     */

346    public String JavaDoc getHostName()
347    {
348       if (hostName == null)
349       {
350          try
351          {
352             hostName = java.net.InetAddress.getLocalHost().getHostName();
353          }
354          catch (java.net.UnknownHostException JavaDoc e)
355          {
356             log.error("Error looking up local hostname", e);
357             hostName = "<unknown>";
358          }
359       }
360       
361       return hostName;
362    }
363    
364    /**
365     * Returns InetAddress.getLocalHost().getHostAddress();
366     *
367     * @jmx:managed-attribute
368     */

369    public String JavaDoc getHostAddress()
370    {
371       if (hostAddress == null)
372       {
373          try
374          {
375             hostAddress = java.net.InetAddress.getLocalHost().getHostAddress();
376          }
377          catch (java.net.UnknownHostException JavaDoc e)
378          {
379             log.error("Error looking up local address", e);
380             hostAddress = "<unknown>";
381          }
382       }
383       
384       return hostAddress;
385    }
386
387    /**
388     * Return a listing of the thread pools on jdk5+.
389     *
390     * @jmx:managed-operation
391     *
392     * @param fancy produce a text-based graph when true
393     */

394    public String JavaDoc listMemoryPools(boolean fancy)
395    {
396       if (getMemoryPoolMXBeans != null)
397       {
398          // running under jdk5+
399
StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc(4196);
400          try
401          {
402             // get the pools
403
List JavaDoc poolList = (List JavaDoc)getMemoryPoolMXBeans.invoke(null, null);
404             sbuf.append("<b>Total Memory Pools:</b> ").append(poolList.size());
405             sbuf.append("<blockquote>");
406             for (Iterator JavaDoc i = poolList.iterator(); i.hasNext(); )
407             {
408                // MemoryPoolMXBean instance
409
Object JavaDoc pool = i.next();
410                String JavaDoc name = (String JavaDoc)getName.invoke(pool, null);
411                // enum MemoryType
412
Object JavaDoc type = getType.invoke(pool, null);
413                sbuf.append("<b>Pool: ").append(name);
414                sbuf.append("</b> (").append(type).append(")");
415                
416                // PeakUsage/CurrentUsage
417
Object JavaDoc peakUsage = getPeakUsage.invoke(pool, null);
418                Object JavaDoc usage = getUsage.invoke(pool, null);
419                
420                sbuf.append("<blockquote>");
421                if (usage != null && peakUsage != null)
422                {
423                   Long JavaDoc init = (Long JavaDoc)getInit.invoke(peakUsage, null);
424                   Long JavaDoc used = (Long JavaDoc)getUsed.invoke(peakUsage, null);
425                   Long JavaDoc committed = (Long JavaDoc)getCommitted.invoke(peakUsage, null);
426                   Long JavaDoc max = (Long JavaDoc)getMax.invoke(peakUsage, null);
427
428                   sbuf.append("Peak Usage : ");
429                   sbuf.append("init:").append(init);
430                   sbuf.append(", used:").append(used);
431                   sbuf.append(", committed:").append(committed);
432                   sbuf.append(", max:").append(max);
433                   sbuf.append("<br>");
434                   
435                   init = (Long JavaDoc)getInit.invoke(usage, null);
436                   used = (Long JavaDoc)getUsed.invoke(usage, null);
437                   committed = (Long JavaDoc)getCommitted.invoke(usage, null);
438                   max = (Long JavaDoc)getMax.invoke(usage, null);
439
440                   sbuf.append("Current Usage : ");
441                   sbuf.append("init:").append(init);
442                   sbuf.append(", used:").append(used);
443                   sbuf.append(", committed:").append(committed);
444                   sbuf.append(", max:").append(max);
445                   
446                   if (fancy)
447                   {
448                      TextGraphHelper.poolUsage(sbuf, used.longValue(), committed.longValue(), max.longValue());
449                   }
450                }
451                else
452                {
453                   sbuf.append("Memory pool NOT valid!");
454                }
455                sbuf.append("</blockquote><br>");
456             }
457             sbuf.append("</blockquote>");
458          }
459          catch (Exception JavaDoc e)
460          {
461             // ignore
462
}
463          return sbuf.toString();
464       }
465       else
466       {
467          return "<b>Memory pool information available only under a JDK5+ compatible JVM!</b>";
468       }
469    }
470    
471    /**
472     * @jmx:managed-operation
473     */

474    public Integer JavaDoc getActiveThreadCount()
475    {
476       return new Integer JavaDoc(getRootThreadGroup().activeCount());
477    }
478
479    /**
480     * @jmx:managed-operation
481     */

482    public Integer JavaDoc getActiveThreadGroupCount()
483    {
484       return new Integer JavaDoc(getRootThreadGroup().activeGroupCount());
485    }
486    
487    /**
488     * Return a listing of the active threads and thread groups.
489     *
490     * @jmx:managed-operation
491     */

492    public String JavaDoc listThreadDump()
493    {
494       ThreadGroup JavaDoc root = getRootThreadGroup();
495       
496       // Count the threads/groups during our traversal
497
// rather than use the often inaccurate ThreadGroup
498
// activeCount() and activeGroupCount()
499
ThreadGroupCount count = new ThreadGroupCount();
500
501       // traverse
502
String JavaDoc threadGroupInfo = getThreadGroupInfo(root, count);
503       // attach counters
504
String JavaDoc threadDump =
505          "<b>Total Threads:</b> " + count.threads + "<br>" +
506          "<b>Total Thread Groups:</b> " + count.groups + "<br>" +
507          threadGroupInfo;
508       
509       return threadDump;
510    }
511    
512    /**
513     * Return a listing of the active threads and thread groups.
514     *
515     * @jmx:managed-operation
516     */

517    public String JavaDoc listThreadCpuUtilization()
518    {
519       Set JavaDoc threads = getThreadCpuUtilization();
520
521       if (threads == null)
522       {
523          return("Thread cpu utilization requires J2SE5+");
524       }
525       else
526       {
527          long totalCPU = 0;
528          StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
529          buffer.append("<table><tr><th>Thread Name</th><th>CPU (milliseconds)</th></tr>");
530          for (Iterator JavaDoc i = threads.iterator(); i.hasNext();)
531          {
532             ThreadCPU thread = (ThreadCPU) i.next();
533             buffer.append("<tr><td>").append(thread.name).append("</td><td>");
534             buffer.append(thread.cpuTime).append("</td></tr>");
535             totalCPU += thread.cpuTime;
536          }
537          buffer.append("<tr><td>&nbsp;</td><td>&nbsp;</td></tr><tr><td>Total</td><td>");
538          buffer.append(totalCPU).append("</td></tr></table>");
539          return buffer.toString();
540       }
541    }
542    
543    ///////////////////////////////////////////////////////////////////////////
544
// Private //
545
///////////////////////////////////////////////////////////////////////////
546

547    /**
548     * Get the Thread cpu utilization
549     *
550     * @return an ordered
551     */

552    private Set JavaDoc getThreadCpuUtilization()
553    {
554       if (threadMXBean == null)
555          return null;
556       
557       try
558       {
559          TreeSet JavaDoc result = new TreeSet JavaDoc();
560          long[] threads = (long[]) getAllThreadIds.invoke(threadMXBean, null);
561          for (int i = 0; i < threads.length; ++i)
562          {
563             Long JavaDoc id = new Long JavaDoc(threads[i]);
564             Long JavaDoc cpuTime = (Long JavaDoc) getThreadCpuTime.invoke(threadMXBean, new Object JavaDoc[] { id });
565             Object JavaDoc threadInfo = getThreadInfo.invoke(threadMXBean, new Object JavaDoc[] { id, ZERO });
566             String JavaDoc name = (String JavaDoc) getThreadName.invoke(threadInfo, null);
567             result.add(new ThreadCPU(name, cpuTime.longValue()));
568          }
569          return result;
570       }
571       catch (Exception JavaDoc e)
572       {
573          log.warn("Error retrieving thread cpu utiliation", e);
574          return null;
575       }
576    }
577    
578    /*
579     * Traverse to the root thread group
580     */

581    private ThreadGroup JavaDoc getRootThreadGroup()
582    {
583       ThreadGroup JavaDoc group = Thread.currentThread().getThreadGroup();
584       while (group.getParent() != null)
585       {
586          group = group.getParent();
587       }
588
589       return group;
590    }
591    
592    /*
593     * Recurse inside ThreadGroups to create the thread dump
594     */

595    private String JavaDoc getThreadGroupInfo(ThreadGroup JavaDoc group, ThreadGroupCount count)
596    {
597       StringBuffer JavaDoc rc = new StringBuffer JavaDoc();
598       
599       // Visit one more group
600
count.groups++;
601       
602       rc.append("<br><b>");
603       rc.append("Thread Group: " + group.getName());
604       rc.append("</b> : ");
605       rc.append("max priority:" + group.getMaxPriority() +
606                 ", demon:" + group.isDaemon());
607       
608       rc.append("<blockquote>");
609       Thread JavaDoc threads[]= new Thread JavaDoc[group.activeCount()];
610       group.enumerate(threads, false);
611       for (int i= 0; i < threads.length && threads[i] != null; i++)
612       {
613          // Visit one more thread
614
count.threads++;
615          
616          rc.append("<b>");
617          rc.append("Thread: " + threads[i].getName());
618          rc.append("</b> : ");
619          rc.append("priority:" + threads[i].getPriority() +
620          ", demon:" + threads[i].isDaemon());
621          // Output extra info with jdk5+, or just <br>
622
outputJdk5ThreadMXBeanInfo(rc, threads[i]);
623       }
624       
625       ThreadGroup JavaDoc groups[]= new ThreadGroup JavaDoc[group.activeGroupCount()];
626       group.enumerate(groups, false);
627       for (int i= 0; i < groups.length && groups[i] != null; i++)
628       {
629          rc.append(getThreadGroupInfo(groups[i], count));
630       }
631       rc.append("</blockquote>");
632       
633       return rc.toString();
634    }
635
636    /*
637     * Complete the output of thread info, with optional stuff
638     * when running under jdk5+, or just change line.
639     */

640    private void outputJdk5ThreadMXBeanInfo(StringBuffer JavaDoc sbuf, Thread JavaDoc thread)
641    {
642       // if ThreadMXBean has been found, we run under jdk5+
643
if (threadMXBean != null)
644       {
645          // use reflection all the way, until we base on jdk5
646
try
647          {
648             // get the threadId
649
Long JavaDoc threadId = (Long JavaDoc)getThreadId.invoke(thread, null);
650             // get the ThreadInfo object for that threadId, max StackTraceElement depth
651
Object JavaDoc threadInfo = getThreadInfo.invoke(threadMXBean,
652                   new Object JavaDoc[] { threadId, new Integer JavaDoc(Integer.MAX_VALUE) });
653             // get misc info from ThreadInfo
654
Object JavaDoc threadState = getThreadState.invoke(threadInfo, null); // enum
655
String JavaDoc threadLockName = (String JavaDoc)getLockName.invoke(threadInfo, null);
656             Object JavaDoc[] stackTrace = (Object JavaDoc[])getStackTrace.invoke(threadInfo, null);
657             
658             sbuf.append(", threadId:").append(threadId);
659             sbuf.append(", threadState:").append(threadState);
660             sbuf.append(", threadLockName:").append(threadLockName);
661             sbuf.append("<br>");
662             if (stackTrace.length > 0)
663             {
664                sbuf.append("<blockquote>");
665                for (int i = 0; i < stackTrace.length; i++)
666                {
667                   sbuf.append(stackTrace[i]).append("<br>");
668                }
669                sbuf.append("</blockquote>");
670             }
671          }
672          catch (Exception JavaDoc ignore)
673          {
674             // empty
675
}
676       }
677       else
678       {
679          // no jdk5+ info to add, just change line
680
sbuf.append("<br>");
681       }
682    }
683    
684    /**
685     * Display the java.lang.Package info for the pkgName
686     *
687     * @jmx:managed-operation
688     */

689    public String JavaDoc displayPackageInfo(String JavaDoc pkgName)
690    {
691       Package JavaDoc pkg = Package.getPackage(pkgName);
692       if( pkg == null )
693          return "<h2>Package:"+pkgName+" Not Found!</h2>";
694
695       StringBuffer JavaDoc info = new StringBuffer JavaDoc("<h2>Package: "+pkgName+"</h2>");
696       displayPackageInfo(pkg, info);
697       return info.toString();
698    }
699
700    private void displayPackageInfo(Package JavaDoc pkg, StringBuffer JavaDoc info)
701    {
702       info.append("<pre>\n");
703       info.append("SpecificationTitle: "+pkg.getSpecificationTitle());
704       info.append("\nSpecificationVersion: "+pkg.getSpecificationVersion());
705       info.append("\nSpecificationVendor: "+pkg.getSpecificationVendor());
706       info.append("\nImplementationTitle: "+pkg.getImplementationTitle());
707       info.append("\nImplementationVersion: "+pkg.getImplementationVersion());
708       info.append("\nImplementationVendor: "+pkg.getImplementationVendor());
709       info.append("\nisSealed: "+pkg.isSealed());
710       info.append("</pre>\n");
711    }
712    
713    ///////////////////////////////////////////////////////////////////////////
714
// Inner //
715
///////////////////////////////////////////////////////////////////////////
716

717    /*
718     * Inner Helper class for fancy text graphs
719     *
720     * @author dimitris@jboss.org
721     */

722    private static class TextGraphHelper
723    {
724       // number conversions
725
static final DecimalFormat JavaDoc formatter = new DecimalFormat JavaDoc("#.##");
726       static final long KILO = 1024;
727       static final long MEGA = 1024 * 1024;
728       static final long GIGA = 1024 * 1024 * 1024;
729       
730       // how many dashes+pipe is 100%
731
static final int factor = 70;
732       static char[] fixedline;
733       static char[] baseline;
734       static char[] barline;
735       static char[] spaces;
736       static
737       {
738          // cache a couple of Strings
739
StringBuffer JavaDoc sbuf0 = new StringBuffer JavaDoc();
740          StringBuffer JavaDoc sbuf1 = new StringBuffer JavaDoc();
741          StringBuffer JavaDoc sbuf2 = new StringBuffer JavaDoc();
742          StringBuffer JavaDoc sbuf3 = new StringBuffer JavaDoc();
743          sbuf0.append('+');
744          sbuf1.append('|');
745          sbuf2.append('|');
746          for (int i = 1; i < factor; i++)
747          {
748             sbuf0.append('-');
749             sbuf1.append('-');
750             sbuf2.append('/');
751             sbuf3.append(' ');
752          }
753          sbuf0.append('+');
754          fixedline = sbuf0.toString().toCharArray();
755          baseline = sbuf1.toString().toCharArray();
756          barline = sbuf2.toString().toCharArray();
757          spaces = sbuf3.toString().toCharArray();
758       }
759       
760       private TextGraphHelper()
761       {
762          // do not instantiate
763
}
764       
765       /*
766        * Make a text graph of a memory pool usage:
767        *
768        * +---------------------------| committed:10Mb
769        * +-------------------------------------------------+
770        * |//////////////// | | max:20Mb
771        * +-------------------------------------------------+
772        * +---------------| used:3Mb
773        *
774        * When max is unknown assume max == committed
775        *
776        * |-------------------------------------------------| committed:10Mb
777        * +-------------------------------------------------+
778        * |//////////////// | max:-1
779        * +-------------------------------------------------+
780        * |---------------| used:3Mb
781        */

782       public static void poolUsage(StringBuffer JavaDoc sbuf, long used, long committed, long max)
783       {
784          // there is a chance that max is not provided (-1)
785
long assumedMax = (max == -1) ? committed : max;
786          // find out bar lengths
787
int localUsed = (int)(factor * used / assumedMax);
788          int localCommitted = (int)(factor * committed / assumedMax);
789          int localMax = factor;
790
791          sbuf.append("<blockquote><br>");
792          sbuf.append(baseline, 0, localCommitted).append("| committed:").append(outputNumber(committed)).append("<br>");
793          sbuf.append(fixedline).append("<br>");
794          
795          // the difficult part
796
sbuf.append(barline, 0, localUsed);
797          if (localUsed < localCommitted)
798          {
799             sbuf.append(localUsed > 0 ? '/' : '|');
800             sbuf.append(spaces, 0, localCommitted - localUsed - 1);
801          }
802          sbuf.append('|');
803          if (localCommitted < localMax)
804          {
805             sbuf.append(spaces, 0, localMax - localCommitted - 1);
806             sbuf.append('|');
807          }
808          sbuf.append(" max:").append(outputNumber(max)).append("<br>");
809          
810          sbuf.append(fixedline).append("<br>");
811          sbuf.append(baseline, 0, localUsed).append("| used:").append(outputNumber(used));
812          sbuf.append("</blockquote>");
813       }
814       
815       private static String JavaDoc outputNumber(long value)
816       {
817          if (value >= GIGA)
818          {
819             return formatter.format((double)value / GIGA) + "Gb";
820          }
821          else if (value >= MEGA)
822          {
823             return formatter.format((double)value / MEGA) + "Mb";
824          }
825          else if (value >= KILO)
826          {
827             return formatter.format((double)value / KILO) + "Kb";
828          }
829          else if (value >= 0)
830          {
831             return value + "b";
832          }
833          else
834          {
835             return Long.toString(value);
836          }
837       }
838    }
839    
840    private static class ThreadCPU implements Comparable JavaDoc
841    {
842       public String JavaDoc name;
843       public long cpuTime;
844
845       public ThreadCPU(String JavaDoc name, long cpuTime)
846       {
847          this.name = name;
848          this.cpuTime = cpuTime / 1000000; // convert to millis
849
}
850       
851       public int compareTo(Object JavaDoc o)
852       {
853          ThreadCPU other = (ThreadCPU) o;
854          long value = cpuTime - other.cpuTime;
855          if (value > 0)
856             return -1;
857          else if (value < 0)
858             return +1;
859          else
860             return name.compareTo(other.name);
861       }
862    }
863    
864    /*
865     * Simple data holder
866     */

867    private static class ThreadGroupCount
868    {
869       public int threads;
870       public int groups;
871    }
872 }
Popular Tags