[jbosscache-commits] JBoss Cache SVN: r5023 - in demos/core-demo-gui/trunk: src and 8 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Sun Jan 6 21:11:53 EST 2008


Author: manik.surtani at jboss.com
Date: 2008-01-06 21:11:53 -0500 (Sun, 06 Jan 2008)
New Revision: 5023

Added:
   demos/core-demo-gui/trunk/README.txt
   demos/core-demo-gui/trunk/assembly.xml
   demos/core-demo-gui/trunk/pom.xml
   demos/core-demo-gui/trunk/src/
   demos/core-demo-gui/trunk/src/main/
   demos/core-demo-gui/trunk/src/main/java/
   demos/core-demo-gui/trunk/src/main/java/org/
   demos/core-demo-gui/trunk/src/main/java/org/jboss/
   demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/
   demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/
   demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/DataTreeRefresher.java
   demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.form
   demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.java
   demos/core-demo-gui/trunk/src/main/resources/
   demos/core-demo-gui/trunk/src/main/resources/bin/
   demos/core-demo-gui/trunk/src/main/resources/bin/run.sh
   demos/core-demo-gui/trunk/src/main/resources/demo-cache-config.xml
   demos/core-demo-gui/trunk/src/main/resources/log4j.xml
Log:
Initial checkin

Added: demos/core-demo-gui/trunk/README.txt
===================================================================
--- demos/core-demo-gui/trunk/README.txt	                        (rev 0)
+++ demos/core-demo-gui/trunk/README.txt	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,21 @@
+This is a demo GUI for JBoss Cache.
+
+* Running the demo
+------------------
+
+To run the demo, all you need is a Java 5 compliant JVM.  All dependencies are packaged in the demo ZIP file, which
+can be downloaded from http://www.jbosscache.org
+
+Simply unzip the demo distribution and use the "run.sh" shell script to launch the demo GUI.
+
+* Building the demo
+-------------------
+
+You need to use Maven 2 to build the demo from sources.  Simply check out the sources for the demo from http://anonsvn.jboss.org/repos/jbosscache/demo/trunk
+and build using "mvn clean install", which will generate the ZIP distribution in "target/distribution"
+
+* Developing the demo
+---------------------
+
+You need to use IntelliJ IDEA's UIDesigner to edit the Swing forms in this project.  To generate IDEA project files,
+run "mvn idea:idea" and then open the resulting project file in IntelliJ.

Added: demos/core-demo-gui/trunk/assembly.xml
===================================================================
--- demos/core-demo-gui/trunk/assembly.xml	                        (rev 0)
+++ demos/core-demo-gui/trunk/assembly.xml	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,64 @@
+<assembly>
+   <id>bin</id>
+
+   <formats>
+      <format>zip</format>
+   </formats>
+
+   <includeBaseDirectory>true</includeBaseDirectory>
+
+   <fileSets>
+      <!-- code -->
+      <fileSet>
+         <directory>target</directory>
+         <outputDirectory/>
+         <includes>
+            <include>*.jar</include>
+         </includes>
+         <excludes>
+            <exclude>*test*.jar</exclude>
+         </excludes>
+      </fileSet>
+
+      <!-- resources -->
+      <fileSet>
+         <directory>src/main/resources</directory>
+         <outputDirectory>etc</outputDirectory>
+      </fileSet>
+
+      <!-- EULAs and license files -->
+      <fileSet>
+         <directory>src/main/resources/bin</directory>
+         <outputDirectory/>
+         <includes>
+            <include>**/*</include>
+         </includes>
+         <fileMode>0755</fileMode>
+      </fileSet>
+
+      <fileSet>
+         <directory />
+         <outputDirectory/>
+         <includes>
+            <include>README.txt</include>
+         </includes>
+      </fileSet>
+
+   </fileSets>
+
+   <!-- Make sure we filter out the junk that jboss-common-core pulls in -->
+   <dependencySets>
+      <dependencySet>
+         <outputDirectory>lib</outputDirectory>
+         <outputFileNameMapping>${artifactId}.${extension}</outputFileNameMapping>
+         <unpack>false</unpack>
+         <scope>runtime</scope>
+         <excludes>
+            <exclude>apache-xerces:xml-apis</exclude>
+            <exclude>apache-httpclient:commons-httpclient</exclude>
+            <exclude>apache-slide:webdavlib</exclude>
+         </excludes>
+      </dependencySet>
+   </dependencySets>
+
+</assembly>

Added: demos/core-demo-gui/trunk/pom.xml
===================================================================
--- demos/core-demo-gui/trunk/pom.xml	                        (rev 0)
+++ demos/core-demo-gui/trunk/pom.xml	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+   <properties>
+      <jbosscache-core-version>2.1.0-SNAPSHOT</jbosscache-core-version>
+   </properties>
+   <parent>
+      <groupId>org.jboss.cache</groupId>
+      <artifactId>jbosscache-common-parent</artifactId>
+      <version>1.1-SNAPSHOT</version>
+   </parent>
+   <groupId>org.jboss.cache</groupId>
+   <artifactId>jbosscache-demo</artifactId>
+   <version>${jbosscache-core-version}</version>
+   <name>JBoss Cache - Core Edition GUI Demo</name>
+   <description>JBoss Cache - Core Edition GUI Demo</description>
+   <packaging>jar</packaging>
+   <dependencies>
+      <dependency>
+         <groupId>org.jboss.cache</groupId>
+         <artifactId>jbosscache-core</artifactId>
+         <version>2.1.0-SNAPSHOT</version>
+      </dependency>
+      <dependency>
+         <groupId>jgoodies</groupId>
+         <artifactId>forms</artifactId>
+         <version>1.0.5</version>
+      </dependency>
+      <dependency>
+         <groupId>com.intellij</groupId>
+         <artifactId>forms_rt</artifactId>
+         <version>6.0.5</version>
+      </dependency>
+   </dependencies>
+
+   <build>
+      <plugins>
+         <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <version>2.2-beta-1</version>
+            <executions>
+               <execution>
+                  <id>assemble</id>
+                  <phase>install</phase>
+                  <goals>
+                     <goal>attached</goal>
+                  </goals>
+                  <configuration>
+                     <descriptors>
+                        <descriptor>assembly.xml</descriptor>
+                     </descriptors>
+                     <finalName>${artifactId}</finalName>
+                     <outputDirectory>target/distribution</outputDirectory>
+                     <workDirectory>target/assembly/work</workDirectory>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+
+         <plugin>
+            <groupId>org.codehaus.mojo</groupId>
+            <artifactId>ideauidesigner-maven-plugin</artifactId>
+            <executions>
+               <execution>
+                  <goals>
+                     <goal>javac2</goal>
+                  </goals>
+               </execution>
+            </executions>
+            <configuration>
+               <fork>true</fork>
+               <debug>true</debug>
+               <failOnError>true</failOnError>
+            </configuration>
+         </plugin>
+
+
+      </plugins>
+   </build>
+
+   <!-- basic JBoss repository so that the common parent POM in jbosscache-support can be found -->
+   <repositories>
+      <repository>
+         <id>repository.jboss.org</id>
+         <url>http://repository.jboss.org/maven2</url>
+      </repository>
+      <repository>
+         <id>snapshots.jboss.org</id>
+         <url>http://snapshots.jboss.org/maven2</url>
+      </repository>
+   </repositories>
+</project>

Added: demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/DataTreeRefresher.java
===================================================================
--- demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/DataTreeRefresher.java	                        (rev 0)
+++ demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/DataTreeRefresher.java	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,196 @@
+package org.jboss.cache.demo;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Cache;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.FqnComparator;
+import org.jboss.cache.Node;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreeNode;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * // TODO Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.1.0
+ */
+public class DataTreeRefresher
+{
+   private JTree tree;
+   private Map<Fqn<String>, FqnTreeNode> treeNodes = new ConcurrentHashMap<Fqn<String>, FqnTreeNode>();
+   private Cache<String, String> cache;
+   private Log log = LogFactory.getLog(DataTreeRefresher.class);
+   private JBossCacheDemo.NodeDataTableModel tableModel;
+
+   public DataTreeRefresher(JTree tree, Cache<String, String> cache, JBossCacheDemo.NodeDataTableModel tableModel)
+   {
+      this.tree = tree;
+      this.cache = cache;
+      this.tableModel = tableModel;
+      populateDataTree();
+   }
+
+   private void populateDataTree()
+   {
+      // initialise the root.
+      FqnTreeNode node = new FqnTreeNode(Fqn.ROOT);
+      // put this in the treeNodes map
+      treeNodes.put(Fqn.ROOT, node);
+
+      TreeModel model = new OrderedTreeModel(node);
+      tree.setModel(model);
+
+      // now traverse the cache nodes and populate the tree.
+      populateChildren(cache.getRoot());
+
+      repaint();
+   }
+
+   private void populateChildren(Node<String, String> cacheNode)
+   {
+      for (Node<String, String> cacheChild : cacheNode.getChildren())
+      {
+         getOrCreateTreeNode(cacheChild.getFqn());
+         // now go deep
+         populateChildren(cacheChild);
+      }
+   }
+
+   private FqnTreeNode getOrCreateTreeNode(Fqn<String> f)
+   {
+      FqnTreeNode treeNode = treeNodes.get(f);
+      if (treeNode == null)
+      {
+         treeNode = new FqnTreeNode(f);
+         FqnTreeNode parent = getOrCreateTreeNode(f.getParent());
+         parent.add(treeNode);
+         treeNode.setParent(parent);
+         treeNodes.put(f, treeNode);
+      }
+      return treeNode;
+   }
+
+   public void addNode(Fqn<String> f)
+   {
+      getOrCreateTreeNode(f);
+   }
+
+   public void removeNode(Fqn<String> f)
+   {
+      if (treeNodes.containsKey(f))
+      {
+         removeTreeNode(treeNodes.get(f));
+      }
+   }
+
+   private void removeTreeNode(FqnTreeNode treeNode)
+   {
+      // clear children
+      for (Enumeration en = treeNode.children(); en.hasMoreElements();)
+      {
+         FqnTreeNode child = (FqnTreeNode) en.nextElement();
+         removeTreeNode(child);
+      }
+
+      if (!treeNode.getFqn().isRoot())
+      {
+         // then remove node
+         treeNodes.remove(treeNode.getFqn());
+         treeNode.removeFromParent();
+      }
+   }
+
+   public void repaint()
+   {
+      tableModel.setCurrentFqn(null);
+      Map<String, String> m = Collections.emptyMap();
+      tableModel.setData(m);
+      tree.repaint();
+      ((DefaultTreeModel) tree.getModel()).reload();
+   }
+
+   class FqnTreeNode extends DefaultMutableTreeNode implements Comparable
+   {
+      private Fqn fqn;
+
+      FqnTreeNode(Fqn fqn)
+      {
+         super(fqn.isRoot() ? "/" : fqn.getLastElement());
+         this.fqn = fqn;
+      }
+
+      public Fqn getFqn()
+      {
+         return fqn;
+      }
+
+      public void setFqn(Fqn fqn)
+      {
+         this.fqn = fqn;
+      }
+
+      public int compareTo(Object o)
+      {
+         FqnTreeNode other = (FqnTreeNode) o;
+         return FqnComparator.INSTANCE.compare(fqn, other.getFqn());
+      }
+   }
+
+   class OrderedTreeModel extends DefaultTreeModel
+   {
+      public OrderedTreeModel(TreeNode root)
+      {
+         super(root);
+      }
+
+      public OrderedTreeModel(TreeNode root, boolean asksAllowsChildren)
+      {
+         super(root, asksAllowsChildren);
+      }
+
+      @Override
+      public int getIndexOfChild(Object parent, Object child)
+      {
+         this.orderChildren(parent);
+         return super.getIndexOfChild(parent, child);
+      }
+
+      @Override
+      public Object getChild(Object parent, int index)
+      {
+         this.orderChildren(parent);
+         return super.getChild(parent, index);
+      }
+
+      /**
+       * Orders the children of a DefaultMutableTreeNode
+       *
+       * @param parent
+       */
+      private void orderChildren(Object parent)
+      {
+         if (parent == null) return;
+
+         if (parent instanceof FqnTreeNode)
+         {
+            FqnTreeNode node = (FqnTreeNode) parent;
+            ArrayList children = Collections.list(node.children());
+            Collections.sort(children);
+            node.removeAllChildren();
+            Iterator childrenIterator = children.iterator();
+            while (childrenIterator.hasNext()) node.add((FqnTreeNode) childrenIterator.next());
+         }
+      }
+   }
+}

Added: demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.form
===================================================================
--- demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.form	                        (rev 0)
+++ demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.form	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,627 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jboss.cache.demo.JBossCacheDemo">
+  <grid id="27dc6" binding="panel1" default-binding="true" layout-manager="FormLayout">
+    <rowspec value="center:max(d;4px):noGrow"/>
+    <rowspec value="top:3dlu:noGrow"/>
+    <rowspec value="center:600px:grow"/>
+    <rowspec value="top:3dlu:noGrow"/>
+    <rowspec value="center:max(d;4px):noGrow"/>
+    <colspec value="fill:800px:grow"/>
+    <colspec value="left:4dlu:noGrow"/>
+    <colspec value="fill:100px:grow"/>
+    <constraints>
+      <xy x="20" y="20" width="918" height="661"/>
+    </constraints>
+    <properties/>
+    <border type="line" title="JBoss Cache Demo Application">
+      <font size="14" style="3"/>
+      <title-color color="-16750951"/>
+      <color color="-16750951"/>
+    </border>
+    <children>
+      <tabbedpane id="d853c" binding="mainPane">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false">
+            <preferred-size width="200" height="200"/>
+          </grid>
+          <forms defaultalign-vert="false"/>
+        </constraints>
+        <properties>
+          <background color="-3355648"/>
+        </properties>
+        <border type="none"/>
+        <children>
+          <grid id="7aed3" binding="controlPanelTab" layout-manager="FormLayout">
+            <rowspec value="center:m:noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:d:grow"/>
+            <colspec value="fill:d:noGrow"/>
+            <colspec value="left:4dlu:noGrow"/>
+            <colspec value="fill:max(d;4px):noGrow"/>
+            <colspec value="left:4dlu:noGrow"/>
+            <colspec value="fill:d:grow"/>
+            <constraints>
+              <tabbedpane title="Control panel">
+                <tooltip value="This tab contains cache controls and general information about the cache configuration."/>
+              </tabbedpane>
+            </constraints>
+            <properties>
+              <toolTipText value=""/>
+            </properties>
+            <border type="none"/>
+            <children>
+              <component id="953e7" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-vert="false"/>
+                </constraints>
+                <properties>
+                  <text value="Command"/>
+                </properties>
+              </component>
+              <component id="82b76" class="javax.swing.JButton" binding="actionButton">
+                <constraints>
+                  <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-vert="false"/>
+                </constraints>
+                <properties>
+                  <text value="Button"/>
+                </properties>
+              </component>
+              <vspacer id="8cdf4">
+                <constraints>
+                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-vert="false"/>
+                </constraints>
+              </vspacer>
+              <hspacer id="bfe90">
+                <constraints>
+                  <grid row="0" column="4" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+              </hspacer>
+              <component id="458fc" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-vert="false"/>
+                </constraints>
+                <properties>
+                  <text value="Cache configuration file"/>
+                </properties>
+              </component>
+              <component id="1eef8" class="javax.swing.JLabel" binding="configFileName">
+                <constraints>
+                  <grid row="2" column="2" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-vert="false"/>
+                </constraints>
+                <properties>
+                  <font style="3"/>
+                  <text value=" "/>
+                </properties>
+              </component>
+              <scrollpane id="4638">
+                <constraints>
+                  <grid row="4" column="2" row-span="1" col-span="3" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false" defaultalign-vert="false"/>
+                </constraints>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="ded97" class="javax.swing.JTextArea" binding="configFileContents">
+                    <constraints/>
+                    <properties>
+                      <background color="-103"/>
+                      <font name="Courier New" size="10"/>
+                    </properties>
+                  </component>
+                </children>
+              </scrollpane>
+            </children>
+          </grid>
+          <grid id="73867" binding="dataViewTab" layout-manager="FormLayout">
+            <rowspec value="center:d:grow"/>
+            <colspec value="fill:d:grow"/>
+            <colspec value="left:4dlu:noGrow"/>
+            <colspec value="fill:m:grow"/>
+            <constraints>
+              <tabbedpane title="Data view" enabled="false">
+                <tooltip value="This tab contains a view of all the data in the cache."/>
+              </tabbedpane>
+            </constraints>
+            <properties>
+              <enabled value="true"/>
+              <toolTipText value=""/>
+            </properties>
+            <border type="none"/>
+            <children>
+              <scrollpane id="ea4d">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false" defaultalign-vert="false"/>
+                </constraints>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="a805d" class="javax.swing.JTree" binding="dataTree">
+                    <constraints/>
+                    <properties>
+                      <background color="-1"/>
+                      <showsRootHandles value="true"/>
+                      <toolTipText value="Tree view of the cache"/>
+                    </properties>
+                  </component>
+                </children>
+              </scrollpane>
+              <scrollpane id="f78a6" binding="nodeData">
+                <constraints>
+                  <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false" defaultalign-vert="false"/>
+                </constraints>
+                <properties/>
+                <border type="none"/>
+                <children>
+                  <component id="41fa4" class="javax.swing.JTable" binding="nodeDataTable">
+                    <constraints/>
+                    <properties>
+                      <background color="-103"/>
+                      <gridColor color="-16777216"/>
+                      <intercellSpacing width="3" height="3"/>
+                      <toolTipText value="Data in currently selected node"/>
+                    </properties>
+                  </component>
+                </children>
+              </scrollpane>
+            </children>
+          </grid>
+          <grid id="b4b20" binding="clusterViewTab" layout-manager="FormLayout">
+            <rowspec value="center:d:grow"/>
+            <colspec value="fill:d:grow"/>
+            <constraints>
+              <tabbedpane title="Cluster view" enabled="false">
+                <tooltip value="This tab contains a view of the cluster topology"/>
+              </tabbedpane>
+            </constraints>
+            <properties>
+              <toolTipText value=""/>
+            </properties>
+            <border type="none"/>
+            <children>
+              <scrollpane id="b9d5f">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false" defaultalign-vert="false"/>
+                </constraints>
+                <properties>
+                  <background color="-16737895"/>
+                  <horizontalScrollBarPolicy value="30"/>
+                </properties>
+                <border type="none"/>
+                <children>
+                  <component id="d96d2" class="javax.swing.JTable" binding="clusterTable">
+                    <constraints/>
+                    <properties>
+                      <background color="-103"/>
+                      <gridColor color="-16777216"/>
+                      <intercellSpacing width="3" height="3"/>
+                      <showHorizontalLines value="true"/>
+                      <showVerticalLines value="false"/>
+                    </properties>
+                  </component>
+                </children>
+              </scrollpane>
+            </children>
+          </grid>
+          <grid id="43cd8" binding="statisticsTab" layout-manager="FormLayout">
+            <rowspec value="center:d:noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <colspec value="fill:d:noGrow"/>
+            <colspec value="left:4dlu:noGrow"/>
+            <colspec value="fill:max(d;4px):noGrow"/>
+            <constraints>
+              <tabbedpane title="Statistics" enabled="false">
+                <tooltip value="This tab contains various statistics on the running cache."/>
+              </tabbedpane>
+            </constraints>
+            <properties>
+              <toolTipText value=""/>
+            </properties>
+            <border type="none"/>
+            <children>
+              <component id="cc9c" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="Number of nodes"/>
+                </properties>
+              </component>
+              <component id="5d05" class="javax.swing.JLabel" binding="statsNumberOfNodes">
+                <constraints>
+                  <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value=""/>
+                </properties>
+              </component>
+              <component id="9ba3c" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="Number of keys"/>
+                </properties>
+              </component>
+              <component id="4e154" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="Size of data cached"/>
+                </properties>
+              </component>
+              <component id="ff6b" class="javax.swing.JLabel" binding="statsNumberOfKeys">
+                <constraints>
+                  <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value=""/>
+                </properties>
+              </component>
+              <component id="333b4" class="javax.swing.JLabel" binding="statsSizeOfCachedData">
+                <constraints>
+                  <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value=""/>
+                </properties>
+              </component>
+              <component id="69403" class="javax.swing.JButton" binding="updateStatsButton" default-binding="true">
+                <constraints>
+                  <grid row="8" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties>
+                  <text value="&amp;Update stats"/>
+                </properties>
+              </component>
+              <component id="5ebe9" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="Time last updated"/>
+                </properties>
+              </component>
+              <component id="8eaca" class="javax.swing.JLabel" binding="statsLastUpdated">
+                <constraints>
+                  <grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value=""/>
+                </properties>
+              </component>
+            </children>
+          </grid>
+          <grid id="54b2f" binding="dataGeneratorTab" layout-manager="FormLayout">
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:d:noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:d:grow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:d:grow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <rowspec value="top:3dlu:noGrow"/>
+            <rowspec value="center:max(d;4px):noGrow"/>
+            <colspec value="fill:d:noGrow"/>
+            <colspec value="left:4dlu:noGrow"/>
+            <colspec value="fill:200px:noGrow"/>
+            <colspec value="left:4dlu:noGrow"/>
+            <colspec value="fill:200px:grow"/>
+            <constraints>
+              <tabbedpane title="Data generator" enabled="false">
+                <tooltip value="This tab provides you with the ability to add or remove data from the cache."/>
+              </tabbedpane>
+            </constraints>
+            <properties>
+              <toolTipText value=""/>
+            </properties>
+            <border type="none"/>
+            <children>
+              <component id="236d9" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <labelFor value="fc98"/>
+                  <text value="Fqn"/>
+                </properties>
+              </component>
+              <component id="7917a" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <labelFor value="4e02"/>
+                  <text value="Key"/>
+                </properties>
+              </component>
+              <component id="b834" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <labelFor value="5eb9b"/>
+                  <text value="Value"/>
+                </properties>
+              </component>
+              <component id="fc98" class="javax.swing.JTextField" binding="fqnTextField" default-binding="true">
+                <constraints>
+                  <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="4e02" class="javax.swing.JTextField" binding="keyTextField" default-binding="true">
+                <constraints>
+                  <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="ca2af" class="javax.swing.JRadioButton" binding="createNodeRadioButton" default-binding="true">
+                <constraints>
+                  <grid row="8" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <selected value="true"/>
+                  <text value="&amp;Create Node"/>
+                </properties>
+              </component>
+              <component id="e9453" class="javax.swing.JRadioButton" binding="removeNodeRadioButton" default-binding="true">
+                <constraints>
+                  <grid row="10" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="&amp;Remove Node"/>
+                </properties>
+              </component>
+              <component id="11f60" class="javax.swing.JButton" binding="goButton" default-binding="true">
+                <constraints>
+                  <grid row="12" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties>
+                  <text value="&amp;Go"/>
+                </properties>
+              </component>
+              <component id="f9bf" class="javax.swing.JRadioButton" binding="addKeyRadioButton" default-binding="true">
+                <constraints>
+                  <grid row="8" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="Add &amp;Key"/>
+                </properties>
+              </component>
+              <component id="f2b07" class="javax.swing.JRadioButton" binding="removeKeyRadioButton" default-binding="true">
+                <constraints>
+                  <grid row="10" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <text value="R&amp;emove Key"/>
+                </properties>
+              </component>
+              <component id="5eb9b" class="javax.swing.JTextField" binding="valueTextField" default-binding="true">
+                <constraints>
+                  <grid row="6" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="24ed" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <font style="3"/>
+                  <text value="Single node manipulator"/>
+                </properties>
+              </component>
+              <component id="aacea" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="16" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <font style="3"/>
+                  <text value="Multiple node generator"/>
+                </properties>
+              </component>
+              <component id="bf689" class="javax.swing.JSeparator">
+                <constraints>
+                  <grid row="14" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false" defaultalign-vert="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="dbe5d" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="20" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <labelFor value="b6c72"/>
+                  <text value="Max depth"/>
+                </properties>
+              </component>
+              <component id="c9835" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="18" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <labelFor value="513f3"/>
+                  <text value="Max nodes"/>
+                </properties>
+              </component>
+              <component id="922d3" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="22" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <labelFor value="3108a"/>
+                  <text value="Number of keys per node"/>
+                </properties>
+              </component>
+              <component id="32377" class="javax.swing.JButton" binding="randomGeneratorButton">
+                <constraints>
+                  <grid row="24" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties>
+                  <text value="Ge&amp;nerate"/>
+                </properties>
+              </component>
+              <component id="513f3" class="javax.swing.JTextField" binding="maxNodesTextField" default-binding="true">
+                <constraints>
+                  <grid row="18" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="b6c72" class="javax.swing.JTextField" binding="maxDepthTextField" default-binding="true">
+                <constraints>
+                  <grid row="20" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="3108a" class="javax.swing.JTextField" binding="numberOfKeysPerTextField" default-binding="true">
+                <constraints>
+                  <grid row="22" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="f036" class="javax.swing.JSeparator">
+                <constraints>
+                  <grid row="26" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="6" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false" defaultalign-vert="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="43cf0" class="javax.swing.JButton" binding="cacheClearButton">
+                <constraints>
+                  <grid row="30" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms defaultalign-horz="false"/>
+                </constraints>
+                <properties>
+                  <text value="C&amp;lear cache"/>
+                </properties>
+              </component>
+              <component id="dae1c" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="28" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                  <forms/>
+                </constraints>
+                <properties>
+                  <font style="3"/>
+                  <text value="Clear cache"/>
+                </properties>
+              </component>
+            </children>
+          </grid>
+        </children>
+      </tabbedpane>
+      <component id="97005" class="javax.swing.JLabel" binding="cacheStatus">
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <forms/>
+        </constraints>
+        <properties>
+          <font style="3"/>
+          <text value="Initialising"/>
+          <toolTipText value="Cache status"/>
+          <verticalAlignment value="3"/>
+        </properties>
+      </component>
+      <component id="4afab" class="javax.swing.JProgressBar" binding="cacheStatusProgressBar">
+        <constraints>
+          <grid row="4" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+          <forms defaultalign-horz="false"/>
+        </constraints>
+        <properties>
+          <indeterminate value="true"/>
+          <orientation value="0"/>
+        </properties>
+      </component>
+    </children>
+  </grid>
+  <buttonGroups>
+    <group name="cacheFunction">
+      <member id="ca2af"/>
+      <member id="e9453"/>
+      <member id="f9bf"/>
+      <member id="f2b07"/>
+    </group>
+  </buttonGroups>
+</form>

Added: demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.java
===================================================================
--- demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.java	                        (rev 0)
+++ demos/core-demo-gui/trunk/src/main/java/org/jboss/cache/demo/JBossCacheDemo.java	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,728 @@
+package org.jboss.cache.demo;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jboss.cache.Cache;
+import org.jboss.cache.CacheStatus;
+import static org.jboss.cache.CacheStatus.*;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.Node;
+import org.jboss.cache.notifications.annotation.NodeCreated;
+import org.jboss.cache.notifications.annotation.NodeRemoved;
+import org.jboss.cache.notifications.annotation.ViewChanged;
+import org.jboss.cache.notifications.annotation.BuddyGroupChanged;
+import org.jboss.cache.notifications.event.NodeCreatedEvent;
+import org.jboss.cache.notifications.event.NodeRemovedEvent;
+import org.jboss.cache.notifications.event.ViewChangedEvent;
+import org.jboss.cache.notifications.event.BuddyGroupChangedEvent;
+import org.jgroups.Address;
+
+import javax.swing.*;
+import javax.swing.border.TitledBorder;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.tree.TreePath;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.*;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.Date;
+import java.util.Collections;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.BlockingQueue;
+import java.text.NumberFormat;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+
+import com.jgoodies.forms.layout.FormLayout;
+import com.jgoodies.forms.layout.CellConstraints;
+
+/**
+ * // TODO Document this
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.1.0
+ */
+public class JBossCacheDemo
+{
+   private static Log log = LogFactory.getLog(JBossCacheDemo.class);
+   private static JFrame frame;
+   private JTabbedPane mainPane;
+   private JPanel panel1;
+   private JLabel cacheStatus;
+   private JPanel dataGeneratorTab;
+   private JPanel statisticsTab;
+   private JPanel clusterViewTab;
+   private JPanel dataViewTab;
+   private JPanel controlPanelTab;
+   private JTree dataTree;
+   private JTable clusterTable;
+   private JButton actionButton;
+   private JLabel configFileName;
+   private JProgressBar cacheStatusProgressBar;
+   private JTextField fqnTextField;
+   private JTextField keyTextField;
+   private JTextField valueTextField;
+   private JRadioButton createNodeRadioButton;
+   private JRadioButton removeNodeRadioButton;
+   private JRadioButton addKeyRadioButton;
+   private JRadioButton removeKeyRadioButton;
+   private JButton goButton;
+   private JTable nodeDataTable;
+   private JScrollPane nodeData;
+   private JButton randomGeneratorButton;
+   private JTextField maxNodesTextField;
+   private JTextField maxDepthTextField;
+   private JTextField numberOfKeysPerTextField;
+   private JButton cacheClearButton;
+   private JButton updateStatsButton;
+   private JLabel statsNumberOfNodes;
+   private JLabel statsNumberOfKeys;
+   private JLabel statsSizeOfCachedData;
+   private JLabel statsLastUpdated;
+   private JTextArea configFileContents;
+   private String cacheConfigFile;
+   private Cache<String, String> cache;
+   private String startCacheButtonLabel = "Start Cache", stopCacheButtonLabel = "Stop Cache";
+   private String statusStarting = "Starting Cache ... ", statusStarted = "Cache Running.", statusStopping = "Stopping Cache ...", statusStopped = "Cache Stopped.";
+   private ExecutorService asyncExecutor;
+   private BlockingQueue<Runnable> asyncTaskQueue;
+   private ClusterTableModel clusterDataModel;
+   private NodeDataTableModel nodeDataTableModel;
+   private DataTreeRefresher treeRefresher;
+   private Random r = new Random();
+
+   public static void main(String[] args)
+   {
+      String cfgFileName = "demo-cache-config.xml";
+      if (args.length == 1 && args[0] != null && args[0].toLowerCase().endsWith(".xml"))
+      {
+         // the first arg is the name of the config file.
+         cfgFileName = args[0];
+      }
+
+      frame = new JFrame("JBossCacheDemo (STOPPED)");
+      frame.setContentPane(new JBossCacheDemo(cfgFileName).panel1);
+      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+      frame.pack();
+      frame.setVisible(true);
+      frame.setResizable(false);
+   }
+
+   public JBossCacheDemo(String cfgFileName)
+   {
+      asyncExecutor = Executors.newFixedThreadPool(1);
+      asyncTaskQueue = ((ThreadPoolExecutor) asyncExecutor).getQueue();
+
+      cacheConfigFile = cfgFileName;
+      cacheStatusProgressBar.setVisible(false);
+      cacheStatusProgressBar.setEnabled(false);
+      configFileName.setText(cacheConfigFile);
+      // default state of the action button should be unstarted.
+      actionButton.setText(startCacheButtonLabel);
+      cacheStatus.setText(statusStopped);
+
+      clusterDataModel = new ClusterTableModel();
+      clusterTable.setModel(clusterDataModel);
+
+      nodeDataTableModel = new NodeDataTableModel();
+      nodeDataTable.setModel(nodeDataTableModel);
+
+      // when we start up scan the classpath for a file named
+      actionButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            if (actionButton.getText().equals(startCacheButtonLabel))
+            {
+               // start cache
+               startCache();
+            }
+            else if (actionButton.getText().equals(stopCacheButtonLabel))
+            {
+               // stop cache
+               stopCache();
+            }
+         }
+      });
+      goButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            processAction(goButton, true);
+
+            // do this in a separate thread
+            asyncExecutor.execute(new Runnable()
+            {
+               public void run()
+               {
+                  // based on the value of the radio button:
+                  if (createNodeRadioButton.isSelected())
+                  {
+                     cache.put(fqnTextField.getText(), keyTextField.getText(), valueTextField.getText());
+//               treeRefresher.addNode(Fqn.fromString(fqnTextField.getText()));
+                  }
+                  else if (removeNodeRadioButton.isSelected())
+                  {
+                     cache.removeNode(fqnTextField.getText());
+//               treeRefresher.removeNode(Fqn.fromString(fqnTextField.getText()));
+                  }
+                  else if (addKeyRadioButton.isSelected())
+                  {
+                     cache.put(fqnTextField.getText(), keyTextField.getText(), valueTextField.getText());
+//               treeRefresher.updateNode(Fqn.fromString(fqnTextField.getText()));
+                  }
+                  else if (removeKeyRadioButton.isSelected())
+                  {
+                     cache.remove(fqnTextField.getText(), keyTextField.getText());
+//               treeRefresher.updateNode(Fqn.fromString(fqnTextField.getText()));
+                  }
+                  treeRefresher.repaint();
+                  dataViewTab.repaint();
+                  processAction(goButton, false);
+               }
+            });
+         }
+      });
+      removeNodeRadioButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            fqnTextField.setEnabled(true);
+            keyTextField.setEnabled(false);
+            valueTextField.setEnabled(false);
+         }
+      });
+      removeKeyRadioButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            fqnTextField.setEnabled(true);
+            keyTextField.setEnabled(true);
+            valueTextField.setEnabled(false);
+         }
+      });
+      createNodeRadioButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            fqnTextField.setEnabled(true);
+            keyTextField.setEnabled(true);
+            valueTextField.setEnabled(true);
+         }
+      });
+      addKeyRadioButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            fqnTextField.setEnabled(true);
+            keyTextField.setEnabled(true);
+            valueTextField.setEnabled(true);
+         }
+      });
+      dataTree.addTreeSelectionListener(new TreeSelectionListener()
+      {
+         public void valueChanged(TreeSelectionEvent e)
+         {
+            TreePath path = e.getPath();
+            DataTreeRefresher.FqnTreeNode node = (DataTreeRefresher.FqnTreeNode) path.getLastPathComponent();
+            Fqn f = node.getFqn();
+            if (!f.equals(nodeDataTableModel.getCurrentFqn()))
+            {
+               nodeDataTableModel.setCurrentFqn(f);
+               nodeDataTableModel.setData(cache.getNode(f).getData());
+            }
+         }
+      });
+      randomGeneratorButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            processAction(randomGeneratorButton, true);
+
+            // process this asynchronously
+            asyncExecutor.execute(new Runnable()
+            {
+               public void run()
+               {
+                  int depth = 1;
+                  try
+                  {
+                     depth = Integer.parseInt(maxDepthTextField.getText());
+                  }
+                  catch (NumberFormatException nfe)
+                  {
+                     log.warn("Entered a non-integer for depth.  Using 1.", nfe);
+                  }
+
+                  int maxNodes = 1;
+                  try
+                  {
+                     maxNodes = Integer.parseInt(maxNodesTextField.getText());
+                  }
+                  catch (NumberFormatException nfe)
+                  {
+                     log.warn("Entered a non-integer for max nodes.  Using 1.", nfe);
+                  }
+
+                  int attribsPerNode = 1;
+                  try
+                  {
+                     attribsPerNode = Integer.parseInt(numberOfKeysPerTextField.getText());
+                  }
+                  catch (NumberFormatException nfe)
+                  {
+                     log.warn("Entered a non-integer for keys per node.  Using 1.", nfe);
+                  }
+
+                  Set<Fqn> fqns = new HashSet<Fqn>();
+                  for (int i = 0; i < maxNodes; i++)
+                  {
+                     Fqn fqn = createRandomFqn(depth);
+                     while (fqns.contains(fqn)) fqn = createRandomFqn(depth);
+                     fqns.add(fqn);
+                  }
+
+                  for (Fqn f : fqns)
+                  {
+                     Map m = new HashMap();
+                     for (int i = 0; i < attribsPerNode; i++) m.put(randomString(), randomString());
+                     cache.put(f, m);
+                  }
+
+                  processAction(randomGeneratorButton, false);
+               }
+            });
+         }
+
+         private Fqn createRandomFqn(int depth)
+         {
+            String s = "/";
+            for (int i = 0; i < r.nextInt(depth); i++)
+            {
+               s += randomString() + "/";
+            }
+            return Fqn.fromString(s);
+         }
+
+         private String randomString()
+         {
+            return Integer.toHexString(r.nextInt(Integer.MAX_VALUE)).toUpperCase();
+         }
+      });
+      cacheClearButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            processAction(cacheClearButton, true);
+            asyncExecutor.execute(new Runnable()
+            {
+               public void run()
+               {
+                  cache.removeNode(Fqn.ROOT);
+                  cache.getRoot().clearData();
+                  processAction(cacheClearButton, false);
+               }
+            });
+         }
+      });
+      updateStatsButton.addActionListener(new ActionListener()
+      {
+         public void actionPerformed(ActionEvent e)
+         {
+            processAction(updateStatsButton, true);
+            asyncExecutor.execute(new Runnable()
+            {
+               public void run()
+               {
+                  updateStats();
+                  processAction(updateStatsButton, false);
+               }
+            });
+         }
+      });
+   }
+
+   private void updateStats()
+   {
+      int numNodes = ((CacheSPI) cache).getNumberOfNodes();
+      statsNumberOfNodes.setText(numNodes + " nodes");
+      Map<String, Long> values = new HashMap<String, Long>();
+      values.put("NumKeys", 0l);
+      values.put("Size", 0l);
+      processRecursively(cache.getRoot(), values);
+      statsNumberOfKeys.setText(values.get("NumKeys") + " keys");
+      NumberFormat format = NumberFormat.getIntegerInstance();
+      statsSizeOfCachedData.setText(format.format(values.get("Size")) + " bytes");
+      statsLastUpdated.setText(new Date().toString());
+   }
+
+   private void processRecursively(Node<String, String> node, Map<String, Long> values)
+   {
+      // process children first
+      for (Node child : node.getChildren())
+      {
+         processRecursively(child, values);
+      }
+      // now process current node
+      Map data = node.getData();
+      values.put("NumKeys", values.get("NumKeys") + data.size());
+      values.put("Size", values.get("Size") + calculateSize(data));
+   }
+
+   private int calculateSize(Map<String, String> data)
+   {
+      // since all we have are strings:
+      int size = 0;
+      for (String key : data.keySet())
+      {
+         size += key.length();
+         size += data.get(key).length();
+      }
+      return size;
+   }
+
+   private void moveCacheToState(CacheStatus state)
+   {
+      switch (state)
+      {
+         case STARTING:
+            cacheStatus.setText(statusStarting);
+            processAction(actionButton, true);
+            break;
+         case STARTED:
+            setCacheTabsStatus(true);
+            actionButton.setText(stopCacheButtonLabel);
+            processAction(actionButton, false);
+            cacheStatus.setText(statusStarted);
+            updateTitleBar();
+            break;
+         case STOPPING:
+            cacheStatus.setText(statusStopping);
+            processAction(actionButton, true);
+            break;
+         case STOPPED:
+            setCacheTabsStatus(false);
+            actionButton.setText(startCacheButtonLabel);
+            processAction(actionButton, false);
+            cacheStatus.setText(statusStopped);
+            updateTitleBar();
+      }
+      controlPanelTab.repaint();
+   }
+
+   private void processAction(JButton button, boolean start)
+   {
+      button.setEnabled(!start);
+      cacheStatusProgressBar.setVisible(start);
+      cacheStatusProgressBar.setEnabled(start);
+   }
+
+   private String readContents(InputStream is) throws IOException
+   {
+      BufferedReader r = new BufferedReader(new InputStreamReader(is));
+      String s;
+      StringBuilder sb = new StringBuilder();
+      while ((s = r.readLine()) != null)
+      {
+         sb.append(s);
+         sb.append("\n");
+      }
+      return sb.toString();
+   }
+
+   private void startCache()
+   {
+      moveCacheToState(STARTING);
+
+      // actually start the cache asynchronously.
+      asyncExecutor.execute(new Runnable()
+      {
+         public void run()
+         {
+            if (cache == null)
+            {
+               URL resource = getClass().getClassLoader().getResource(cacheConfigFile);
+               String contents;
+               // update config file display
+               if (resource != null)
+               {
+                  configFileName.setText(resource.toString());
+               }
+               else
+               {
+                  configFileName.setText(cacheConfigFile);
+               }
+               configFileName.repaint();
+
+               try
+               {
+                  configFileContents.setText(readContents(resource == null ? new FileInputStream(cacheConfigFile) : resource.openStream()));
+               }
+               catch (Exception e)
+               {
+                  log.warn("Unable to open config file for display", e);
+               }
+               configFileContents.repaint();
+
+               cache = new DefaultCacheFactory().createCache(cacheConfigFile);
+            }
+            else
+            {
+               cache.start();
+            }
+
+            updateClusterTable(cache.getMembers());
+            treeRefresher = new DataTreeRefresher(dataTree, cache, nodeDataTableModel);
+            cache.addCacheListener(new CacheListener());
+            moveCacheToState(STARTED);
+         }
+      });
+   }
+
+   private void stopCache()
+   {
+      moveCacheToState(CacheStatus.STOPPING);
+      // actually stop the cache asynchronously
+      asyncExecutor.execute(new Runnable()
+      {
+         public void run()
+         {
+            if (cache != null) cache.stop();
+            moveCacheToState(STOPPED);
+         }
+      });
+   }
+
+   private void setCacheTabsStatus(boolean enabled)
+   {
+      int numTabs = mainPane.getTabCount();
+      for (int i = 1; i < numTabs; i++) mainPane.setEnabledAt(i, enabled);
+      panel1.repaint();
+   }
+
+   private void updateClusterTable(List<Address> members)
+   {
+      log.debug("Updating cluster table with new member list " + members);
+      clusterDataModel.setMembers(members);
+      updateTitleBar();
+   }
+
+   private void updateTitleBar()
+   {
+      String title = "JBossCacheDemo";
+      if (cache != null && cache.getCacheStatus() == STARTED)
+      {
+         title += " (STARTED) " + cache.getLocalAddress() + " Cluster size: " + cache.getMembers().size();
+      }
+      else
+      {
+         title += " (STOPPED)";
+      }
+      frame.setTitle(title);
+   }
+
+   @org.jboss.cache.notifications.annotation.CacheListener
+   public class CacheListener
+   {
+      @ViewChanged
+      public void viewChangeEvent(ViewChangedEvent e)
+      {
+         updateClusterTable(e.getNewView().getMembers());
+      }
+
+      @BuddyGroupChanged
+      public void buddyGroupChanged(BuddyGroupChangedEvent e)
+      {
+         clusterDataModel.setBuddies();
+      }
+
+      @NodeCreated
+      public void nodeCreated(NodeCreatedEvent e)
+      {
+         if (!e.isPre())
+         {
+            final Fqn fqn = e.getFqn();
+            asyncExecutor.execute(new Runnable()
+            {
+               public void run()
+               {
+                  treeRefresher.addNode(fqn);
+                  // only refresh if there are no more tasks queued up
+                  if (asyncTaskQueue.isEmpty()) treeRefresher.repaint();
+               }
+            });
+         }
+      }
+
+      @NodeRemoved
+      public void nodeRemoved(NodeRemovedEvent e)
+      {
+         if (!e.isPre())
+         {
+            final Fqn fqn = e.getFqn();
+            asyncExecutor.execute(new Runnable()
+            {
+               public void run()
+               {
+                  treeRefresher.removeNode(fqn);
+                  // only refresh if there are no more tasks queued up
+                  if (asyncTaskQueue.isEmpty()) treeRefresher.repaint();
+               }
+            });
+         }
+      }
+
+      // dont bother with node modified events since the tree GUI widget will refresh each node when it is selected.
+   }
+
+   public class ClusterTableModel extends AbstractTableModel
+   {
+      List<Address> members = new ArrayList<Address>();
+      List<String> memberStates = new ArrayList<String>();
+
+      public void setMembers(List<Address> members)
+      {
+         if (this.members != members)
+         {
+            this.members.clear();
+            this.members.addAll(members);
+         }
+
+         CacheSPI spi = (CacheSPI) cache;
+
+         List<Address> buddies = Collections.emptyList();
+         if (spi.getBuddyManager() != null)
+         {
+            buddies = spi.getBuddyManager().getBuddyAddresses();
+            log.debug("Buddy addresses: " + buddies);
+         }
+
+         memberStates = new ArrayList<String>(members.size());
+         for (Address a : members)
+         {
+            String extraInfo = "Member";
+            // if this is the first member then this is the coordinator
+            if (memberStates.isEmpty()) extraInfo += " (coord)";
+            if (a.equals(cache.getLocalAddress()))
+               extraInfo += " (me)";
+            else if (buddies.contains(a))
+               extraInfo += " (buddy)";
+            memberStates.add(extraInfo);
+         }
+
+         fireTableDataChanged();
+      }
+
+      public void setBuddies()
+      {
+         setMembers(members);
+      }
+
+      public int getRowCount()
+      {
+         return members.size();
+      }
+
+      public int getColumnCount()
+      {
+         return 2;
+      }
+
+      public Object getValueAt(int rowIndex, int columnIndex)
+      {
+         switch (columnIndex)
+         {
+            case 0:
+               return members.get(rowIndex);
+            case 1:
+               return memberStates.get(rowIndex);
+         }
+         return "NULL!";
+      }
+
+      public String getColumnName(int c)
+      {
+         if (c == 0) return "Member Address";
+         if (c == 1) return "Member Info";
+         return "NULL!";
+      }
+   }
+
+   public class NodeDataTableModel extends AbstractTableModel
+   {
+      String[] keys = {};
+      String[] values = {};
+      private Fqn currentFqn;
+
+      public void setData(Map<String, String> data)
+      {
+         keys = new String[data.size()];
+         values = new String[data.size()];
+         int i = 0;
+         for (String key : data.keySet())
+         {
+            keys[i] = key;
+            values[i] = data.get(key);
+            i++;
+         }
+
+         fireTableDataChanged();
+      }
+
+      public int getRowCount()
+      {
+         return keys.length;
+      }
+
+      public int getColumnCount()
+      {
+         return 2;
+      }
+
+      public Object getValueAt(int rowIndex, int columnIndex)
+      {
+         switch (columnIndex)
+         {
+            case 0:
+               return keys[rowIndex];
+            case 1:
+               return values[rowIndex];
+         }
+         return "NULL!";
+      }
+
+      public String getColumnName(int c)
+      {
+         if (c == 0) return "Key";
+         if (c == 1) return "Value";
+         return "NULL!";
+      }
+
+      public Fqn getCurrentFqn()
+      {
+         return currentFqn;
+      }
+
+      public void setCurrentFqn(Fqn currentFqn)
+      {
+         this.currentFqn = currentFqn;
+      }
+   }
+}

Added: demos/core-demo-gui/trunk/src/main/resources/bin/run.sh
===================================================================
--- demos/core-demo-gui/trunk/src/main/resources/bin/run.sh	                        (rev 0)
+++ demos/core-demo-gui/trunk/src/main/resources/bin/run.sh	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+CP=./etc/
+
+for i in lib/*.jar ; do
+   CP=${i}:${CP}
+done
+
+CP=jbosscache-demo.jar:${CP}
+
+java -cp ${CP} org.jboss.cache.demo.JBossCacheDemo ${*}


Property changes on: demos/core-demo-gui/trunk/src/main/resources/bin/run.sh
___________________________________________________________________
Name: svn:executable
   + *

Added: demos/core-demo-gui/trunk/src/main/resources/demo-cache-config.xml
===================================================================
--- demos/core-demo-gui/trunk/src/main/resources/demo-cache-config.xml	                        (rev 0)
+++ demos/core-demo-gui/trunk/src/main/resources/demo-cache-config.xml	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- ===================================================================== -->
+<!--                                                                       -->
+<!--  Sample TreeCache Service Configuration                               -->
+<!--                                                                       -->
+<!-- ===================================================================== -->
+
+<server>
+
+   <!-- ==================================================================== -->
+   <!-- Defines TreeCache configuration                                      -->
+   <!-- ==================================================================== -->
+
+   <mbean code="org.jboss.cache.jmx.CacheJmxWrapper"
+          name="jboss.cache:service=TreeCache">
+
+      <depends>jboss:service=Naming</depends>
+      <depends>jboss:service=TransactionManager</depends>
+
+      <!--
+          Configure the TransactionManager
+      -->
+      <attribute name="TransactionManagerLookupClass">org.jboss.cache.transaction.GenericTransactionManagerLookup
+      </attribute>
+
+      <!--
+          Isolation level : SERIALIZABLE
+                            REPEATABLE_READ (default)
+                            READ_COMMITTED
+                            READ_UNCOMMITTED
+                            NONE
+      -->
+      <attribute name="IsolationLevel">REPEATABLE_READ</attribute>
+
+      <!--
+           Valid modes are LOCAL
+                           REPL_ASYNC
+                           REPL_SYNC
+                           INVALIDATION_ASYNC
+                           INVALIDATION_SYNC
+      -->
+      <attribute name="CacheMode">REPL_SYNC</attribute>
+
+      <!--
+      Just used for async repl: use a replication queue
+      -->
+      <attribute name="UseReplQueue">false</attribute>
+
+      <!--
+          Replication interval for replication queue (in ms)
+      -->
+      <attribute name="ReplQueueInterval">0</attribute>
+
+      <!--
+          Max number of elements which trigger replication
+      -->
+      <attribute name="ReplQueueMaxElements">0</attribute>
+
+      <!-- Name of cluster. Needs to be the same for all TreeCache nodes in a
+           cluster in order to find each other.
+      -->
+      <attribute name="ClusterName">JBossCache-Cluster</attribute>
+
+      <!--Uncomment next three statements to enable JGroups multiplexer.
+This configuration is dependent on the JGroups multiplexer being
+registered in an MBean server such as JBossAS.  -->
+      <!--
+      <depends>jgroups.mux:name=Multiplexer</depends>
+      <attribute name="MultiplexerService">jgroups.mux:name=Multiplexer</attribute>
+      <attribute name="MultiplexerStack">fc-fast-minimalthreads</attribute>
+      -->
+
+      <!-- JGroups protocol stack properties.
+         ClusterConfig isn't used if the multiplexer is enabled and successfully initialized.
+      -->
+      <attribute name="ClusterConfig">
+         <config>
+            <UDP mcast_addr="228.10.10.10"
+                 mcast_port="45588"
+                 tos="8"
+                 ucast_recv_buf_size="20000000"
+                 ucast_send_buf_size="640000"
+                 mcast_recv_buf_size="25000000"
+                 mcast_send_buf_size="640000"
+                 loopback="false"
+                 discard_incompatible_packets="true"
+                 max_bundle_size="64000"
+                 max_bundle_timeout="30"
+                 use_incoming_packet_handler="true"
+                 ip_ttl="2"
+                 enable_bundling="false"
+                 enable_diagnostics="true"
+
+                 use_concurrent_stack="true"
+
+                 thread_naming_pattern="pl"
+
+                 thread_pool.enabled="true"
+                 thread_pool.min_threads="1"
+                 thread_pool.max_threads="25"
+                 thread_pool.keep_alive_time="30000"
+                 thread_pool.queue_enabled="true"
+                 thread_pool.queue_max_size="10"
+                 thread_pool.rejection_policy="Run"
+
+                 oob_thread_pool.enabled="true"
+                 oob_thread_pool.min_threads="1"
+                 oob_thread_pool.max_threads="4"
+                 oob_thread_pool.keep_alive_time="10000"
+                 oob_thread_pool.queue_enabled="true"
+                 oob_thread_pool.queue_max_size="10"
+                 oob_thread_pool.rejection_policy="Run"/>
+
+            <PING timeout="2000" num_initial_members="3"/>
+            <MERGE2 max_interval="30000" min_interval="10000"/>
+            <FD_SOCK/>
+            <FD timeout="10000" max_tries="5" shun="true"/>
+            <VERIFY_SUSPECT timeout="1500"/>
+            <pbcast.NAKACK use_mcast_xmit="false" gc_lag="0"
+                           retransmit_timeout="300,600,1200,2400,4800"
+                           discard_delivered_msgs="true"/>
+            <UNICAST timeout="300,600,1200,2400,3600"/>
+            <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
+                           max_bytes="400000"/>
+            <pbcast.GMS print_local_addr="true" join_timeout="5000" shun="false"
+                        view_bundling="true" view_ack_collection_timeout="5000"/>
+            <FRAG2 frag_size="60000"/>
+            <pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/>
+            <!-- <pbcast.STATE_TRANSFER/> -->
+            <pbcast.FLUSH timeout="0"/>
+         </config>
+      </attribute>
+
+
+      <!--
+       Whether or not to fetch state on joining a cluster
+       NOTE this used to be called FetchStateOnStartup and has been renamed to be more descriptive.
+      -->
+      <attribute name="FetchInMemoryState">true</attribute>
+
+      <!--
+          The max amount of time (in milliseconds) we wait until the
+          state (ie. the contents of the cache) are retrieved from
+          existing members in a clustered environment
+      -->
+      <attribute name="StateRetrievalTimeout">15000</attribute>
+
+      <!--
+          Number of milliseconds to wait until all responses for a
+          synchronous call have been received.
+      -->
+      <attribute name="SyncReplTimeout">15000</attribute>
+
+      <!-- Max number of milliseconds to wait for a lock acquisition -->
+      <attribute name="LockAcquisitionTimeout">10000</attribute>
+
+         <!-- Buddy Replication config -->
+      <attribute name="BuddyReplicationConfig">
+         <config>
+            <buddyReplicationEnabled>true</buddyReplicationEnabled>
+            <!-- these are the default values anyway -->
+            <buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>
+            <!-- numBuddies is the number of backup nodes each node maintains.  ignoreColocatedBuddies means that
+                 each node will *try* to select a buddy on a different physical host.  If not able to do so though,
+                 it will fall back to colocated nodes. -->
+            <buddyLocatorProperties>
+               numBuddies = 1
+               ignoreColocatedBuddies = true
+            </buddyLocatorProperties>
+
+            <!-- A way to specify a preferred replication group.  If specified, we try and pick a buddy why shares
+                 the same pool name (falling back to other buddies if not available).  This allows the sysdmin to hint at
+                 backup buddies are picked, so for example, nodes may be hinted topick buddies on a different physical rack
+                 or power supply for added fault tolerance.  -->
+            <buddyPoolName>myBuddyPoolReplicationGroup</buddyPoolName>
+
+            <!-- communication timeout for inter-buddy group organisation messages (such as assigning to and removing
+                 from groups -->
+            <buddyCommunicationTimeout>2000</buddyCommunicationTimeout>
+
+            <!-- the following three elements, all relating to data gravitation, default to false -->
+            <!-- Should data gravitation be attempted whenever there is a cache miss on finding a node?
+                  If false, data will only be gravitated if an Option is set enabling it -->
+            <autoDataGravitation>false</autoDataGravitation>
+
+            <!-- removes data on remote caches' trees and backup subtrees when gravitated to a new data owner -->
+            <dataGravitationRemoveOnFind>true</dataGravitationRemoveOnFind>
+
+            <!-- search backup subtrees as well for data when gravitating.  Results in backup nodes being able to
+                 answer data gravitation requests. -->
+            <dataGravitationSearchBackupTrees>true</dataGravitationSearchBackupTrees>
+         </config>
+      </attribute>
+
+      <!--
+         Indicate whether to use region based marshalling or not. Set this to true if you are running under a scoped
+         class loader, e.g., inside an application server. Default is "false".
+      -->
+      <attribute name="UseRegionBasedMarshalling">false</attribute>
+   </mbean>
+
+
+   <!--  Uncomment to get a graphical view of the TreeCache MBean above -->
+   <!--   <mbean code="org.jboss.cache.TreeCacheView" name="jboss.cache:service=TreeCacheView">-->
+   <!--      <depends>jboss.cache:service=TreeCache</depends>-->
+   <!--      <attribute name="CacheService">jboss.cache:service=TreeCache</attribute>-->
+   <!--   </mbean>-->
+
+
+</server>

Added: demos/core-demo-gui/trunk/src/main/resources/log4j.xml
===================================================================
--- demos/core-demo-gui/trunk/src/main/resources/log4j.xml	                        (rev 0)
+++ demos/core-demo-gui/trunk/src/main/resources/log4j.xml	2008-01-07 02:11:53 UTC (rev 5023)
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<!-- ===================================================================== -->
+<!--                                                                       -->
+<!--  Log4j Configuration                                                  -->
+<!--                                                                       -->
+<!-- ===================================================================== -->
+
+<!-- $Id: log4j.xml 4661 2007-10-22 12:00:07Z manik.surtani at jboss.com $ -->
+
+<!--
+   | For more configuration infromation and examples see the Jakarta Log4j
+   | owebsite: http://jakarta.apache.org/log4j
+ -->
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
+
+   <!-- ================================= -->
+   <!-- Preserve messages in a local file -->
+   <!-- ================================= -->
+
+   <!-- A time/date based rolling appender -->
+   <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
+      <param name="File" value="output/jbosscache.log"/>
+      <param name="Append" value="true"/>
+
+      <!-- Rollover at midnight each day -->
+      <param name="DatePattern" value="'.'yyyy-MM-dd"/>
+
+      <!-- Rollover at the top of each hour
+      <param name="DatePattern" value="'.'yyyy-MM-dd-HH"/>
+      -->
+      <param name="Threshold" value="DEBUG"/>
+
+      <layout class="org.apache.log4j.PatternLayout">
+         <!-- The default pattern: Date Priority [Category] Message\n -->
+         <param name="ConversionPattern" value="%d %-5p [%c] (%t) %m%n"/>
+
+         <!-- The full pattern: Date MS Priority [Category] (Thread:NDC) Message\n
+        <param name="ConversionPattern" value="%d %-5r %-5p [%c] (%t:%x) %m%n"/>
+         -->
+      </layout>
+   </appender>
+
+   <!-- ============================== -->
+   <!-- Append messages to the console -->
+   <!-- ============================== -->
+
+   <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
+      <param name="Threshold" value="TRACE"/>
+      <param name="Target" value="System.out"/>
+
+      <layout class="org.apache.log4j.PatternLayout">
+         <!-- The default pattern: Date Priority [Category] Message\n -->
+         <param name="ConversionPattern" value="%d %-5p [%c{1}] (%t) %m%n"/>
+      </layout>
+   </appender>
+
+
+   <!-- ================ -->
+   <!-- Limit categories -->
+   <!-- ================ -->
+
+   <category name="org.jboss.cache.demo">
+      <priority value="WARN"/>
+   </category>
+
+   <category name="org.jboss.cache">
+      <priority value="WARN"/>
+   </category>
+
+   <category name="org.jboss">
+      <priority value="WARN"/>
+   </category>
+
+   <category name="org.jgroups">
+      <priority value="WARN"/>
+   </category>
+
+   <!-- ======================= -->
+   <!-- Setup the Root category -->
+   <!-- ======================= -->
+
+   <root>
+      <appender-ref ref="CONSOLE"/>
+      <!--<appender-ref ref="FILE"/>-->
+   </root>
+
+</log4j:configuration>




More information about the jbosscache-commits mailing list