KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > generation > StatusGenerator


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.generation;
17
18 import org.apache.avalon.framework.configuration.Configurable;
19 import org.apache.avalon.framework.configuration.Configuration;
20 import org.apache.avalon.framework.configuration.ConfigurationException;
21 import org.apache.avalon.framework.context.Context;
22 import org.apache.avalon.framework.context.ContextException;
23 import org.apache.avalon.framework.context.Contextualizable;
24 import org.apache.avalon.framework.parameters.Parameters;
25 import org.apache.avalon.framework.service.ServiceException;
26 import org.apache.avalon.framework.service.ServiceManager;
27
28 import org.apache.cocoon.Constants;
29 import org.apache.cocoon.ProcessingException;
30 import org.apache.cocoon.ResourceNotFoundException;
31 import org.apache.cocoon.components.source.SourceUtil;
32 import org.apache.cocoon.environment.SourceResolver;
33 import org.apache.cocoon.xml.AttributesImpl;
34 import org.apache.cocoon.xml.XMLUtils;
35
36 import org.apache.commons.lang.SystemUtils;
37 import org.apache.excalibur.source.Source;
38 import org.apache.excalibur.source.SourceException;
39 import org.apache.excalibur.source.TraversableSource;
40 import org.apache.excalibur.store.Store;
41 import org.apache.excalibur.store.StoreJanitor;
42 import org.xml.sax.Attributes JavaDoc;
43 import org.xml.sax.SAXException JavaDoc;
44
45 import java.io.File JavaDoc;
46 import java.io.IOException JavaDoc;
47 import java.net.InetAddress JavaDoc;
48 import java.net.UnknownHostException JavaDoc;
49 import java.text.DateFormat JavaDoc;
50 import java.util.ArrayList JavaDoc;
51 import java.util.Collection JavaDoc;
52 import java.util.Date JavaDoc;
53 import java.util.Enumeration JavaDoc;
54 import java.util.Iterator JavaDoc;
55 import java.util.List JavaDoc;
56 import java.util.Map JavaDoc;
57 import java.util.Properties JavaDoc;
58 import java.util.Set JavaDoc;
59 import java.util.StringTokenizer JavaDoc;
60 import java.util.TreeSet JavaDoc;
61
62 /**
63  * @cocoon.sitemap.component.documentation
64  * Generates an XML representation of the current status of Cocoon.
65  *
66  * @cocoon.sitemap.component.name status
67  * @cocoon.sitemap.component.label content
68  * @cocoon.sitemap.component.logger sitemap.generator.status
69  *
70  * @cocoon.sitemap.component.pooling.max 16
71  *
72  * Potted DTD:
73  *
74  * <code>
75  * &lt;!ELEMENT statusinfo (group|value)*&gt;
76  *
77  * &lt;!ATTLIST statusinfo
78  * date CDATA #IMPLIED
79  * host CDATA #IMPLIED
80  * cocoon-version CDATA #IMPLIED
81  * &gt;
82  *
83  * &lt;!ELEMENT group (group|value)*&gt;
84  * &lt;!ATTLIST group
85  * name CDATA #IMPLIED
86  * &gt;
87  *
88  * &lt;!ELEMENT value (line)+&gt;
89  * &lt;!ATTLIST value
90  * name CDATA #REQUIRED
91  *
92  * &lt;!ELEMENT line (#PCDATA)+&gt;
93  * &gt;
94  * </code>
95  *
96  * @author <a HREF="mailto:paul@luminas.co.uk">Paul Russell</a> (Luminas Limited)
97  * @author <a HREF="mailto:stefano@apache.org">Stefano Mazzocchi</a>
98  * @author <a HREF="mailto:skoechlin@ivision.fr">S&eacute;bastien K&oelig;chlin</a> (iVision)
99  * @author <a HREF="mailto:g-froehlich@gmx.de">Gerhard Froehlich</a>
100  * @version $Id: StatusGenerator.java 307064 2005-10-07 09:55:02Z vgritsenko $
101  */

102 public class StatusGenerator extends ServiceableGenerator
103                              implements Contextualizable, Configurable {
104
105     /**
106      * The XML namespace for the output document.
107      */

108     public static final String JavaDoc NAMESPACE = "http://apache.org/cocoon/status/2.0";
109
110     /**
111      * The XML namespace for xlink
112      */

113     protected static final String JavaDoc XLINK_NS = "http://www.w3.org/1999/xlink";
114
115     /**
116      * The namespace prefix for xlink namespace
117      */

118     protected static final String JavaDoc XLINK_PREFIX = "xlink";
119
120     /**
121      * The component context.
122      */

123     protected Context context;
124
125     /**
126      * The StoreJanitor used to get cache statistics
127      */

128     protected StoreJanitor storeJanitor;
129
130     /**
131      * The persistent store
132      */

133     protected Store storePersistent;
134
135     /**
136      * List & show the contents of WEB/lib
137      */

138     private boolean showLibrary;
139
140     /**
141      * WEB-INF/lib directory
142      */

143     private Source libDirectory;
144
145
146     public void contextualize(Context context) throws ContextException {
147         this.context = context;
148     }
149
150     public void configure(Configuration configuration) throws ConfigurationException {
151         this.showLibrary = configuration.getChild("show-libraries").getValueAsBoolean(true);
152     }
153
154     /**
155      * Set the current <code>ServiceManager</code> instance used by this
156      * <code>Serviceable</code>.
157      * Need to get statistics about cache hits
158      */

159     public void service(ServiceManager manager) throws ServiceException {
160         super.service(manager);
161
162         if (this.manager.hasService(StoreJanitor.ROLE)) {
163             this.storeJanitor = (StoreJanitor) manager.lookup(StoreJanitor.ROLE);
164         } else {
165             getLogger().info("StoreJanitor is not available. Sorry, no cache statistics");
166         }
167
168         if (this.manager.hasService(Store.PERSISTENT_STORE)) {
169             this.storePersistent = (Store) this.manager.lookup(Store.PERSISTENT_STORE);
170         } else {
171             getLogger().info("Persistent Store is not available. Sorry no cache statistics about it.");
172         }
173     }
174
175     public void setup(SourceResolver resolver, Map JavaDoc objectModel, String JavaDoc src, Parameters par)
176     throws ProcessingException, SAXException JavaDoc, IOException JavaDoc {
177         super.setup(resolver, objectModel, src, par);
178
179         if (this.showLibrary) {
180             try {
181                 this.libDirectory = super.resolver.resolveURI("context://WEB-INF/lib");
182             } catch (SourceException e) {
183                 throw SourceUtil.handle(e);
184             }
185         }
186     }
187
188     /**
189      * @see org.apache.avalon.framework.activity.Disposable#dispose()
190      */

191     public void dispose() {
192         if (this.manager != null) {
193             this.manager.release(this.storePersistent);
194             this.manager.release(this.storeJanitor);
195             this.storePersistent = null;
196             this.storeJanitor = null;
197         }
198
199         if (this.libDirectory != null) {
200             super.resolver.release(this.libDirectory);
201             this.libDirectory = null;
202         }
203
204         super.dispose();
205     }
206
207     /**
208      * Generate the status information in XML format.
209      * @throws SAXException
210      * when there is a problem creating the output SAX events.
211      */

212     public void generate() throws SAXException JavaDoc, ProcessingException {
213
214         // Start the document and set the namespace.
215
super.contentHandler.startDocument();
216         super.contentHandler.startPrefixMapping("", NAMESPACE);
217         super.contentHandler.startPrefixMapping(XLINK_PREFIX, XLINK_NS);
218
219         genStatus();
220
221         // End the document.
222
super.contentHandler.endPrefixMapping(XLINK_PREFIX);
223         super.contentHandler.endPrefixMapping("");
224         super.contentHandler.endDocument();
225     }
226
227     /**
228      * Generate the main status document.
229      */

230     private void genStatus() throws SAXException JavaDoc, ProcessingException {
231         // Root element.
232

233         // The current date and time.
234
String JavaDoc dateTime = DateFormat.getDateTimeInstance().format(new Date JavaDoc());
235         String JavaDoc localHost;
236
237         // The local host.
238
try {
239             localHost = InetAddress.getLocalHost().getHostName();
240         } catch (UnknownHostException JavaDoc e) {
241             getLogger().debug("StatusGenerator:UnknownHost", e);
242             localHost = "";
243         } catch (SecurityException JavaDoc e) {
244             getLogger().debug("StatusGenerator:Security", e);
245             localHost = "";
246         }
247
248         AttributesImpl atts = new AttributesImpl();
249         atts.addCDATAAttribute(NAMESPACE, "date", dateTime);
250         atts.addCDATAAttribute(NAMESPACE, "host", localHost);
251         atts.addCDATAAttribute(NAMESPACE, "cocoon-version", Constants.VERSION);
252         super.contentHandler.startElement(NAMESPACE, "statusinfo", "statusinfo", atts);
253
254         genVMStatus();
255         genProperties();
256         if (this.showLibrary) {
257             genLibrarylist();
258         }
259
260         // End root element.
261
super.contentHandler.endElement(NAMESPACE, "statusinfo", "statusinfo");
262     }
263
264     private void genVMStatus() throws SAXException JavaDoc {
265         AttributesImpl atts = new AttributesImpl();
266         startGroup("VM");
267
268         // BEGIN ClassPath
269
String JavaDoc classpath = SystemUtils.JAVA_CLASS_PATH;
270         if (classpath != null) {
271             List JavaDoc paths = new ArrayList JavaDoc();
272             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(classpath, SystemUtils.PATH_SEPARATOR);
273             while (tokenizer.hasMoreTokens()) {
274                 paths.add(tokenizer.nextToken());
275             }
276             addMultilineValue("classpath", paths);
277         }
278         // END ClassPath
279

280         // BEGIN CONTEXT CLASSPATH
281
String JavaDoc contextClassPath = null;
282         try {
283             contextClassPath = (String JavaDoc) this.context.get(Constants.CONTEXT_CLASSPATH);
284         } catch (ContextException e) {
285             // we ignore this
286
}
287         if (contextClassPath != null) {
288             List JavaDoc paths = new ArrayList JavaDoc();
289             StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc(contextClassPath, File.pathSeparator);
290             while (tokenizer.hasMoreTokens()) {
291                 paths.add(tokenizer.nextToken());
292             }
293             addMultilineValue("context-classpath", paths);
294         }
295         // END CONTEXT CLASSPATH
296

297         // BEGIN Memory status
298
startGroup("Memory");
299         final long totalMemory = Runtime.getRuntime().totalMemory();
300         final long freeMemory = Runtime.getRuntime().freeMemory();
301         addValue("total", String.valueOf(totalMemory));
302         addValue("used", String.valueOf(totalMemory - freeMemory));
303         addValue("free", String.valueOf(freeMemory));
304         endGroup();
305         // END Memory status
306

307         // BEGIN JRE
308
startGroup("JRE");
309         addValue("version", SystemUtils.JAVA_VERSION);
310         atts.clear();
311         // qName = prefix + ':' + localName
312
atts.addAttribute(XLINK_NS, "type", XLINK_PREFIX + ":type", "CDATA", "simple");
313         atts.addAttribute(XLINK_NS, "href", XLINK_PREFIX + ":href", "CDATA", SystemUtils.JAVA_VENDOR_URL);
314         addValue("java-vendor", SystemUtils.JAVA_VENDOR, atts);
315         endGroup();
316         // END JRE
317

318         // BEGIN Operating system
319
startGroup("Operating System");
320         addValue("name", SystemUtils.OS_NAME);
321         addValue("architecture", SystemUtils.OS_ARCH);
322         addValue("version", SystemUtils.OS_VERSION);
323         endGroup();
324         // END operating system
325

326         // BEGIN Cache
327
if (this.storeJanitor != null) {
328             startGroup("Store Janitor");
329
330             // For each element in StoreJanitor
331
Iterator JavaDoc i = this.storeJanitor.iterator();
332             while (i.hasNext()) {
333                 Store store = (Store) i.next();
334                 startGroup(store.getClass().getName() + " (hash = 0x" + Integer.toHexString(store.hashCode()) + ")");
335                 int size = 0;
336                 int empty = 0;
337                 atts.clear();
338                 atts.addAttribute(NAMESPACE, "name", "name", "CDATA", "cached");
339                 super.contentHandler.startElement(NAMESPACE, "value", "value", atts);
340
341                 atts.clear();
342                 Enumeration JavaDoc e = store.keys();
343                 while (e.hasMoreElements()) {
344                     size++;
345                     Object JavaDoc key = e.nextElement();
346                     Object JavaDoc val = store.get(key);
347                     String JavaDoc line;
348                     if (val == null) {
349                         empty++;
350                     } else {
351                         line = key + " (class: " + val.getClass().getName() + ")";
352                         super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
353                         super.contentHandler.characters(line.toCharArray(), 0, line.length());
354                         super.contentHandler.endElement(NAMESPACE, "line", "line");
355                     }
356                 }
357                 if (size == 0) {
358                     super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
359                     String JavaDoc value = "[empty]";
360                     super.contentHandler.characters(value.toCharArray(), 0, value.length());
361                     super.contentHandler.endElement(NAMESPACE, "line", "line");
362                 }
363                 super.contentHandler.endElement(NAMESPACE, "value", "value");
364
365                 addValue("size", String.valueOf(size) + " items in cache (" + empty + " are empty)");
366                 endGroup();
367             }
368             endGroup();
369         }
370
371         if (this.storePersistent != null) {
372             startGroup(storePersistent.getClass().getName() + " (hash = 0x" + Integer.toHexString(storePersistent.hashCode()) + ")");
373             int size = 0;
374             int empty = 0;
375             atts.clear();
376             atts.addAttribute(NAMESPACE, "name", "name", "CDATA", "cached");
377             super.contentHandler.startElement(NAMESPACE, "value", "value", atts);
378
379             atts.clear();
380             Enumeration JavaDoc e = this.storePersistent.keys();
381             while (e.hasMoreElements()) {
382                 size++;
383                 Object JavaDoc key = e.nextElement();
384                 Object JavaDoc val = storePersistent.get(key);
385                 String JavaDoc line;
386                 if (val == null) {
387                     empty++;
388                 } else {
389                     line = key + " (class: " + val.getClass().getName() + ")";
390                     super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
391                     super.contentHandler.characters(line.toCharArray(), 0, line.length());
392                     super.contentHandler.endElement(NAMESPACE, "line", "line");
393                 }
394             }
395             if (size == 0) {
396                 super.contentHandler.startElement(NAMESPACE, "line", "line", atts);
397                 String JavaDoc value = "[empty]";
398                 super.contentHandler.characters(value.toCharArray(), 0, value.length());
399                 super.contentHandler.endElement(NAMESPACE, "line", "line");
400             }
401             super.contentHandler.endElement(NAMESPACE, "value", "value");
402
403             addValue("size", size + " items in cache (" + empty + " are empty)");
404             endGroup();
405         }
406         // END Cache
407

408         endGroup();
409     }
410
411     private void genProperties() throws SAXException JavaDoc {
412         this.startGroup("System-Properties");
413         final Properties JavaDoc p = System.getProperties();
414         final Enumeration JavaDoc e = p.keys();
415         while ( e.hasMoreElements() ) {
416             final String JavaDoc key = (String JavaDoc)e.nextElement();
417             final String JavaDoc value = p.getProperty(key);
418             this.addValue(key, value);
419         }
420         this.endGroup();
421     }
422
423     private void genLibrarylist() throws SAXException JavaDoc,ProcessingException {
424         try {
425             if (this.libDirectory instanceof TraversableSource) {
426                 startGroup("WEB-INF/lib");
427
428                 Set JavaDoc files = new TreeSet JavaDoc();
429                 Collection JavaDoc kids = ((TraversableSource) this.libDirectory).getChildren();
430                 try {
431                     for (Iterator JavaDoc i = kids.iterator(); i.hasNext(); ) {
432                         final Source lib = (Source) i.next();
433                         final String JavaDoc name = lib.getURI().substring(lib.getURI().lastIndexOf('/'));
434                         files.add(name);
435                     }
436                 } finally {
437                     for (Iterator JavaDoc i = kids.iterator(); i.hasNext(); ) {
438                         final Source lib = (Source) i.next();
439                         super.resolver.release(lib);
440                     }
441                 }
442
443                 for (Iterator JavaDoc i = files.iterator(); i.hasNext(); ) {
444                     addValue("file", (String JavaDoc) i.next());
445                 }
446
447                 endGroup();
448             }
449         } catch (SourceException e) {
450             throw new ResourceNotFoundException("Could not read directory", e);
451         }
452     }
453
454     /** Utility function to begin a <code>group</code> tag pair. */
455     private void startGroup(String JavaDoc name) throws SAXException JavaDoc {
456         startGroup(name, null);
457     }
458
459     /** Utility function to begin a <code>group</code> tag pair with added attributes. */
460     private void startGroup(String JavaDoc name, Attributes JavaDoc atts)
461     throws SAXException JavaDoc {
462         AttributesImpl ai = (atts == null) ? new AttributesImpl() : new AttributesImpl(atts);
463         ai.addAttribute(NAMESPACE, "name", "name", "CDATA", name);
464         super.contentHandler.startElement(NAMESPACE, "group", "group", ai);
465     }
466
467     /** Utility function to end a <code>group</code> tag pair. */
468     private void endGroup() throws SAXException JavaDoc {
469         super.contentHandler.endElement(NAMESPACE, "group", "group");
470     }
471
472     /** Utility function to begin and end a <code>value</code> tag pair. */
473     private void addValue(String JavaDoc name, String JavaDoc value)
474     throws SAXException JavaDoc {
475         addValue(name, value, null);
476     }
477
478     /** Utility function to begin and end a <code>value</code> tag pair with added attributes. */
479     private void addValue(String JavaDoc name, String JavaDoc value, Attributes JavaDoc atts)
480     throws SAXException JavaDoc {
481         AttributesImpl ai = (atts == null) ? new AttributesImpl() : new AttributesImpl(atts);
482         ai.addAttribute(NAMESPACE, "name", "name", "CDATA", name);
483         super.contentHandler.startElement(NAMESPACE, "value", "value", ai);
484         super.contentHandler.startElement(NAMESPACE, "line", "line", XMLUtils.EMPTY_ATTRIBUTES);
485
486         if (value != null) {
487             super.contentHandler.characters(value.toCharArray(), 0, value.length());
488         }
489
490         super.contentHandler.endElement(NAMESPACE, "line", "line");
491         super.contentHandler.endElement(NAMESPACE, "value", "value");
492     }
493
494     /** Utility function to begin and end a <code>value</code> tag pair. */
495     private void addMultilineValue(String JavaDoc name, List JavaDoc values)
496     throws SAXException JavaDoc {
497         addMultilineValue(name, values, null);
498     }
499
500     /** Utility function to begin and end a <code>value</code> tag pair with added attributes. */
501     private void addMultilineValue(String JavaDoc name, List JavaDoc values, Attributes JavaDoc atts)
502     throws SAXException JavaDoc {
503         AttributesImpl ai = (atts == null) ? new AttributesImpl() : new AttributesImpl(atts);
504         ai.addAttribute(NAMESPACE, "name", "name", "CDATA", name);
505         super.contentHandler.startElement(NAMESPACE, "value", "value", ai);
506
507         for (int i = 0; i < values.size(); i++) {
508             String JavaDoc value = (String JavaDoc) values.get(i);
509             if (value != null) {
510                 super.contentHandler.startElement(NAMESPACE, "line", "line", XMLUtils.EMPTY_ATTRIBUTES);
511                 super.contentHandler.characters(value.toCharArray(), 0, value.length());
512                 super.contentHandler.endElement(NAMESPACE, "line", "line");
513             }
514         }
515         super.contentHandler.endElement(NAMESPACE, "value", "value");
516     }
517 }
518
Popular Tags