I wrote:
> Please, do NOT include it into cocoon_20_branch CVS on apache.org, it's
> working, but eat huge quantity of memory, and displayed data are raw.
> This is not for final administrators yet.
Ok, this time, I have a better quality patch for both branchs.
The status page display every key in each store correponding to a
not-null object and the class of this object.
Still to be done :
- Use better names instead of keys.
- Add a counter of cache-hit for each object.
--
S�bastien Koechlin - IVision - [EMAIL PROTECTED]
diff -u -r -x CVS
xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitor.java
xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitor.java
---
xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitor.java
Thu Dec 6 12:32:45 2001
+++ xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitor.java Wed
+Dec 5 18:40:12 2001
@@ -23,4 +23,7 @@
/** unregister method for the stores */
void unregister(Store store);
+
+ /** get an iterator to list registered stores */
+ java.util.Iterator iterator();
}
diff -u -r -x CVS
xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitorImpl.java
xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java
---
xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/components/store/StoreJanitorImpl.java
Thu Dec 6 12:32:46 2001
+++ xml-cocoon2/src/org/apache/cocoon/components/store/StoreJanitorImpl.java Thu
+Dec 6 17:17:50 2001
@@ -16,6 +16,7 @@
import org.apache.avalon.framework.thread.ThreadSafe;
import java.util.ArrayList;
+import java.util.Iterator;
/**
* This class is a implentation of a StoreJanitor. Store classes
@@ -170,6 +171,22 @@
}
}
+ /**
+ * This method return a java.util.Iterator of every registered stores
+ *
+ * <i>The iterators returned is fail-fast: if list is structurally
+ * modified at any time after the iterator is created, in any way, the
+ * iterator will throw a ConcurrentModificationException. Thus, in the
+ * face of concurrent modification, the iterator fails quickly and
+ * cleanly, rather than risking arbitrary, non-deterministic behavior at
+ * an undetermined time in the future.</i>
+ *
+ * @return a java.util.Iterator
+ */
+ public Iterator iterator() {
+ return this.getStoreList().iterator();
+ }
+
/**
* Round Robin alghorithm for freeing the registerd caches.
*/
diff -u -r -x CVS
xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/generation/StatusGenerator.java
xml-cocoon2/src/org/apache/cocoon/generation/StatusGenerator.java
--- xml-cocoon2.cocoon_20_branch/src/org/apache/cocoon/generation/StatusGenerator.java
Thu Dec 6 12:32:46 2001
+++ xml-cocoon2/src/org/apache/cocoon/generation/StatusGenerator.java Thu Dec 6
+18:39:34 2001
@@ -7,7 +7,15 @@
*****************************************************************************/
package org.apache.cocoon.generation;
+import org.apache.avalon.framework.component.ComponentException;
+import org.apache.avalon.framework.component.ComponentManager;
+import org.apache.avalon.framework.component.Composable;
+
import org.apache.avalon.excalibur.pool.Recyclable;
+
+import org.apache.cocoon.components.store.StoreJanitor;
+import org.apache.cocoon.components.store.Store;
+
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@@ -16,10 +24,8 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.StringTokenizer;
+import java.util.*;
+
/** Generates an XML representation of the current status of Cocoon.
* Potted DTD:
@@ -47,10 +53,15 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Paul Russell</a> (Luminas Limited)
* @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Sébastien Kœchlin</a>
+(iVision)
* @version CVS $Revision: 1.4.2.3 $ $Date: 2001/10/11 08:56:12 $
*/
public class StatusGenerator extends ComposerGenerator implements Recyclable {
+ /** The StoreJanitor used to get cache statistics
+ */
+ protected StoreJanitor storejanitor;
+
/** The XML namespace for the output document.
*/
protected static final String namespace =
@@ -61,6 +72,20 @@
protected static final String xlinkNamespace =
"http://www.w3.org/1999/xlink";
+ /**
+ * Set the current <code>ComponentManager</code> instance used by this
+ * <code>Composable</code>.
+ * Need to get statistics about cache hits
+ */
+ public void compose(ComponentManager manager) throws ComponentException {
+ super.compose(manager);
+ try {
+ this.storejanitor = (StoreJanitor)manager.lookup(StoreJanitor.ROLE);
+ } catch(ComponentException ce) {
+ getLogger().info("StoreJanitor is not available. Sorry, no cache
+statistics");
+ }
+ }
+
/** Generate the status information in XML format.
* @throws SAXException
* when there is a problem creating the output SAX events.
@@ -149,6 +174,57 @@
paths.add(tokenizer.nextToken());
}
addMultilineValue(ch, "classpath", paths);
+ // END ClassPath
+
+ // BEGIN Cache
+ startGroup(ch, "Store-Janitor");
+
+ // For each element in StoreJanitor
+ Iterator i = this.storejanitor.iterator();
+ while( i.hasNext() ) {
+ Store store = (Store) i.next();
+ startGroup(ch, store.getClass().getName()+" (hash =
+0x"+Integer.toHexString(store.hashCode())+")" );
+ int size = 0;
+ int empty = 0;
+ atts.addAttribute(namespace, "name", "name", "CDATA", "cached");
+ ch.startElement(namespace, "value", "value", atts);
+ // For each element in Store
+ Enumeration e = store.keys();
+ atts.clear();
+ while( e.hasMoreElements() ) {
+ size++;
+ Object key = e.nextElement();
+ Object val = store.get( key );
+ String line = null;
+ if( val == null ) {
+ empty++;
+ } else {
+ line = key.toString() + " (class: " +
+ val.getClass().getName() +
+ ")" ;
+ ch.startElement(namespace, "line", "line", atts);
+ ch.characters(line.toCharArray(), 0, line.length());
+ ch.endElement(namespace, "line", "line");
+ };
+
+
+ };
+
+ if (size == 0) {
+ atts.clear();
+ ch.startElement(namespace, "line", "line", atts);
+ String value = "[empty]";
+ ch.characters(value.toCharArray(), 0, value.length());
+ ch.endElement(namespace, "line", "line");
+ }
+
+ ch.endElement(namespace, "value", "value");
+
+ addValue(ch, "size", String.valueOf(size) + " items in cache (" + empty +
+" are empty)");
+ endGroup(ch);
+ };
+ endGroup(ch);
+ // END Cache
// BEGIN OS info
endGroup(ch);
diff -u -r -x CVS
xml-cocoon2.cocoon_20_branch/webapp/stylesheets/system/status2html.xsl
xml-cocoon2/webapp/stylesheets/system/status2html.xsl
--- xml-cocoon2.cocoon_20_branch/webapp/stylesheets/system/status2html.xsl Thu
Dec 6 12:32:51 2001
+++ xml-cocoon2/webapp/stylesheets/system/status2html.xsl Thu Dec 6 11:15:53
+2001
@@ -71,21 +71,45 @@
</xsl:template>
- <xsl:template match="status:value">
- <tr>
- <td bgcolor="#0086b2" valign="top" align="left">
- <FONT face="arial,helvetica,sanserif" color="#ffffff">
- <xsl:value-of select="@status:name"/>
- </FONT>
- </td>
- <td bgcolor="ffffff" width="100%">
- <FONT face="arial,helvetica,sanserif">
- <xsl:value-of select="." />
- </FONT>
- </td>
- </tr>
+ <xsl:template match="status:value[count(status:line) <= 1]">
+ <tr>
+ <td bgcolor="#0086b2" valign="top" align="left">
+ <font face="arial,helvetica,sanserif" color="#ffffff">
+ <xsl:value-of select="@status:name"/>
+ </font>
+ </td>
+ <td bgcolor="ffffff" width="100%">
+ <font face="arial,helvetica,sanserif">
+ <xsl:value-of select="status:line" />
+ </font>
+ </td>
+ </tr>
+ </xsl:template>
- </xsl:template>
+
+ <xsl:template match="status:value[count(status:line) > 1]">
+ <tr>
+ <td bgcolor="#0086b2" valign="top" align="left">
+ <font face="arial,helvetica,sanserif" color="#ffffff">
+ <xsl:value-of select="@status:name"/>
+ </font>
+ </td>
+ <td bgcolor="ffffff" width="100%">
+ <ul>
+ <xsl:apply-templates />
+ </ul>
+ </td>
+ </tr>
+ </xsl:template>
+
+
+ <xsl:template match="status:line">
+ <li>
+ <font face="arial,helvetica,sanserif">
+ <xsl:value-of select="." />
+ </font>
+ </li>
+ </xsl:template>
<xsl:template match="status:value[../@status:name='memory' and (
@status:name='total' or @status:name='free')]">
--- xml-cocoon2.head/src/org/apache/cocoon/generation/StatusGenerator.java Thu
Dec 6 14:13:47 2001
+++ xml-cocoon2/src/org/apache/cocoon/generation/StatusGenerator.java Thu Dec 6
+18:54:12 2001
@@ -52,6 +53,7 @@
*
* @author <a href="mailto:[EMAIL PROTECTED]">Paul Russell</a> (Luminas Limited)
* @author <a href="mailto:[EMAIL PROTECTED]">Stefano Mazzocchi</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Sébastien Kœchlin</a>
+(iVision)
* @version CVS $Revision: 1.8 $ $Date: 2001/12/06 13:13:47 $
*/
public class StatusGenerator extends ComposerGenerator implements Recyclable {
@@ -181,28 +183,30 @@
Iterator i = this.storejanitor.iterator();
while( i.hasNext() ) {
Store store = (Store) i.next();
- startGroup(ch, store.getClass().getName()+" (hash =
"+store.hashCode()+")" );
+ startGroup(ch, store.getClass().getName()+" (hash =
+0x"+Integer.toHexString(store.hashCode())+")" );
int size = 0;
+ int empty = 0;
atts.addAttribute(namespace, "name", "name", "CDATA", "cached");
ch.startElement(namespace, "value", "value", atts);
// For each element in Store
Enumeration e = store.keys();
- List cachelist = new ArrayList();
+ atts.clear();
while( e.hasMoreElements() ) {
size++;
- atts.clear();
-
- ch.startElement(namespace, "line", "line", atts);
-
- Object o = e.nextElement();
- String value =
- o.toString() + " (hash: " +
- o.hashCode() + " | class: " +
- o.getClass().getName() +
+ Object key = e.nextElement();
+ Object val = store.get( key );
+ String line = null;
+ if( val == null ) {
+ empty++;
+ } else {
+ line = key.toString() + " (class: " +
+ val.getClass().getName() +
")" ;
-
- ch.characters(value.toCharArray(), 0, value.length());
+ ch.startElement(namespace, "line", "line", atts);
+ ch.characters(line.toCharArray(), 0, line.length());
ch.endElement(namespace, "line", "line");
+ };
+
};
@@ -216,7 +220,7 @@
ch.endElement(namespace, "value", "value");
- addValue(ch, "size", String.valueOf(size) + " items in cache");
+ addValue(ch, "size", String.valueOf(size) + " items in cache (" + empty +
+" are empty)");
endGroup(ch);
};
endGroup(ch);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]