[jboss-cvs] JBossCache/src/org/jboss/cache/demo ...

Galder Zamarreno galder.zamarreno at jboss.com
Wed May 16 08:33:59 EDT 2007


  User: gzamarreno
  Date: 07/05/16 08:33:59

  Added:       src/org/jboss/cache/demo     JBossCacheView.java
                        JBossCacheModelDelegate.java
                        CacheModelDelegate.java JBossCacheGUI.java
  Log:
  [JBCACHE-1000] JBossCache tutorial demo has been refactored to accomodate PojoCache one so that it uses the same embedded beanshell. PojoCache tutorial has been rewritten to have more similarities with JBossCache one, and has been extended with a section on Collections. Person and Address fields have been made private to promote encapsulation. Person no has a setLanguages(List<String>) to be consistent with get operation. This required fixing the ReplicatedPutWithBulkRemoveTest.
  
  Revision  Changes    Path
  1.1      date: 2007/05/16 12:33:59;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/demo/JBossCacheView.java
  
  Index: JBossCacheView.java
  ===================================================================
  /*
   * JBoss, the OpenSource J2EE webOS
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   * Created on March 25 2003
   */
  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.CacheFactory;
  import org.jboss.cache.DefaultCacheFactory;
  
  
  /**
   * Graphical view of a JBoss Cache instance.  Think of it as a view in an MVC model.  An instance of this view
   * needs to be given a reference to the  model ({@link CacheModelDelegate}) and needs to registers as a
   * {@link org.jboss.cache.CacheListener}. Changes to the cache structure are propagated from the model to the
   * view (via the CacheListener interface), changes from the GUI (e.g. by a user) are executed on the cache model
   * which will delegate on the actual Cache instance (which, if clustered, will broadcast the changes to all replicas).
   * <p/>
   * The view itself maintains references to the nodes, but doesn't cache any of the data associated with the nodes. When
   * data needs to be displayed, the underlying cache will be accessed directly.
   *
   * @author Manik Surtani
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   * @version $Revision: 1.1 $
   */
  public class JBossCacheView
  {
     private static Log log = LogFactory.getLog(JBossCacheView.class.getName());
     
     /**
      * A reference to the Swing GUI that displays contents to the user.
      */
     private JBossCacheGUI gui = null;
  
     /**
      * Whether or not to use the embedded BeanShell console.
      */
     private boolean useConsole = false;
  
     /**
      * Cache configuration file.
      */
     private String configurationFile = "META-INF/replSync-service.xml";
  
     /**
      * The cache model. 
      */
     private CacheModelDelegate cacheModelDelegate;
  
     /**
      * Gets the configuration file
      *
      * @return String containing the path to the configuration file
      */
     public String getConfigurationFile()
     {
        return configurationFile;
     }   
  
     /**
      * Sets a reference to the cache model
      *
      * @param cacheModelDelegate cache model instance to associate with this view
      */
     public void setCacheModelDelegate(CacheModelDelegate cacheModelDelegate)
     {
        this.cacheModelDelegate = cacheModelDelegate;
        if (gui != null) gui.setCacheDelegate(cacheModelDelegate);
     }
  
     /**
      * Main code for the view
      *
      * @param args arguments passed via command line
      * @throws Exception if there's any issues starting the cache demo
      */
     public void doMain(String[] args) throws Exception
     {
        parseParameters(args);
  
        CacheModelDelegate cacheModelDelegate = createCacheDelegate();
        startCacheModelDelegate(cacheModelDelegate);
        setCacheModelDelegate(cacheModelDelegate);
        
        start();
     }
  
     /**
      * Starts the view
      *
      * @throws Exception
      */
     public void start() throws Exception
     {
        if (gui == null)
        {
           log.info("start(): creating the GUI");
           System.out.println("start(): creating the GUI");
           gui = createCacheGUI(cacheModelDelegate, useConsole);
        }
     }
  
     /**
      * Stops the view
      */
     public void stop()
     {
        if (gui != null)
        {
           log.info("stop(): disposing the GUI");
           gui.stopGui();
           gui = null;
        }
     }
  
     /**
      * Starts the view
      *
      * @param args valid arguments are: -console to enable using the embedded beanShell console, -config [path/to/config/file] to specify a config file.
      */
     public static void main(String args[])
     {
        try
        {
           JBossCacheView view = new JBossCacheView();
           view.doMain(args);
        }
        catch (Exception ex)
        {
           log.error("Cannot start up!!", ex);
        }
     }
  
     /**
      * Parses the parameters
      *
      * @param args arguments passed via command line
      */
     protected void parseParameters(String[] args)
     {
        for (int i = 0; i < args.length; i++)
        {
           if (args[i].equals("-console"))
           {
              useConsole = true;
              continue;
           }
           if (args[i].equals("-config"))
           {
              configurationFile = args[++i];
              continue;
           }
           help();
           return;
        }
     }
  
     /**
      * Factory method that creates the cache model delegate instance for this demo
      *
      * @return instance of CacheModelDelegate
      * @throws Exception
      */
     protected CacheModelDelegate createCacheDelegate() throws Exception
     {
        CacheFactory<String, String> factory = DefaultCacheFactory.getInstance();
        Cache<String,String> cache = factory.createCache(configurationFile, false);
        // hack to prevent a state transfer for now
        cache.getConfiguration().setFetchInMemoryState(false);
  
        CacheModelDelegate delegate = new JBossCacheModelDelegate();
        delegate.setCacheShellVariable(cache);
  
        return delegate;
     }
  
     /**
      * Factory method that creates a cache GUI instance
      *
      * @param cacheDelegate cache model instance
      * @param useConsole whether to enable the embedded beanshell console 
      * @return instance of cache GUI
      * @throws Exception
      */
     protected JBossCacheGUI createCacheGUI(CacheModelDelegate cacheDelegate, boolean useConsole) throws Exception
     {
        return new JBossCacheGUI(cacheDelegate, useConsole);
     }
     
     /**
      * Starts the cache model
      *
      * @param cacheModelDelegate cache model instance to start
      */
     private void startCacheModelDelegate(CacheModelDelegate cacheModelDelegate)
     {
        cacheModelDelegate.getGenericCache().start();
     }   
  
     private static void help()
     {
        System.out.println("JBossCacheView [-help] " +
                           "[-console] " +
                           "[-config <path to configuration file to use>] ");
  
        System.out.println();
        System.out.println("-console enables the embedded BeanShell console");
        System.out.println("-config allows you to provide a path to the configuration file to use.");
     }
  }
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  1.1      date: 2007/05/16 12:33:59;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/demo/JBossCacheModelDelegate.java
  
  Index: JBossCacheModelDelegate.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.demo;
  
  import org.jboss.cache.Cache;
  
  /**
   * Model delegate implementation for JBossCache demo
   *
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  public class JBossCacheModelDelegate implements CacheModelDelegate
  {
     private Cache<String, String> cache;
  
     public void setCacheShellVariable(Object cache)
     {
        this.cache = (Cache<String, String>) cache;
     }
  
     public Object getCacheShellVariable()
     {
        return cache;
     }
  
     public Cache getGenericCache()
     {
        return cache;
     }
  }
  
  
  
  1.1      date: 2007/05/16 12:33:59;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/demo/CacheModelDelegate.java
  
  Index: CacheModelDelegate.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.demo;
  
  import org.jboss.cache.Cache;
  
  /**
   * Delegate that hides cache model details for the demo GUI 
   *
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  public interface CacheModelDelegate
  {
     /**
      * Sets the cache instance that will be used by users to interact with the real cache via the beanshell console.
      *
      * @param cache either PojoCache or Cache instance
      */
     void setCacheShellVariable(Object cache);
  
     /**
      * Gets the cache instance that will be used by users to interact with the real cache via the beanshell console.
      *
      * @return either PojoCache or Cache instance
      */
     Object getCacheShellVariable();
  
     /**
      * Gets the Cache instance that the GUI will use to populate the fiels in the GUI.
      *
      * @return returns an instance of Cache
      */
     Cache getGenericCache();
  }
  
  
  
  1.1      date: 2007/05/16 12:33:59;  author: gzamarreno;  state: Exp;JBossCache/src/org/jboss/cache/demo/JBossCacheGUI.java
  
  Index: JBossCacheGUI.java
  ===================================================================
  /*
   * JBoss, Home of Professional Open Source
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.cache.demo;
  
  import org.jboss.cache.*;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.jgroups.Address;
  import org.jgroups.View;
  
  import javax.swing.*;
  import javax.swing.table.DefaultTableModel;
  import javax.swing.table.TableColumn;
  import javax.swing.tree.DefaultTreeModel;
  import javax.swing.tree.TreeSelectionModel;
  import javax.swing.tree.TreePath;
  import javax.swing.tree.DefaultMutableTreeNode;
  import javax.swing.event.TreeSelectionListener;
  import javax.swing.event.TableModelListener;
  import javax.swing.event.TableModelEvent;
  import javax.swing.event.TreeSelectionEvent;
  import javax.transaction.TransactionManager;
  import javax.transaction.Transaction;
  import java.awt.event.*;
  import java.awt.*;
  import java.util.*;
  import java.util.List;
  import java.util.concurrent.Executor;
  import java.util.concurrent.Executors;
  
  import bsh.util.JConsole;
  import bsh.Interpreter;
  import bsh.EvalError;
  
  /**
   * JBossCache GUI for the demo
   *
   * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
   * @author <a href="mailto:galder.zamarreno at jboss.com">Galder Zamarreno</a>
   */
  public class JBossCacheGUI extends JFrame implements WindowListener, CacheListener, TreeSelectionListener, TableModelListener
  {
     private static final long serialVersionUID = -1242167331988194987L;
  
     private CacheModelDelegate cacheDelegate;
     private Cache cache;
     private DefaultTreeModel tree_model = null;
     private Log log = LogFactory.getLog(getClass());
     private JTree jtree = null;
     private DefaultTableModel tableModel = new DefaultTableModel();
     private JTable table = new JTable(tableModel);
     private JBossCacheGUI.DisplayNode myNodeRoot = new JBossCacheGUI.DisplayNode(Fqn.SEPARATOR);
     private Node root;
     private Node selected_node = null;
     private JPanel tablePanel = null;
     private JPopupMenu operationsPopup = null, dataModificationsPopup = null;
     private static final int KEY_COL_WIDTH = 20;
     private static final int VAL_COL_WIDTH = 300;
     private TransactionManager tx_mgr = null;
     private Transaction tx = null;
     private JPanel mainPanel;
     private List<Address> membership = new LinkedList<Address>();
     private Address coordinator = null;
     private boolean useConsole = false;
  
  
     public JBossCacheGUI(CacheModelDelegate cacheDelegate, boolean useConsole) throws Exception
     {
        addNotify();
        this.useConsole = useConsole;
        tree_model = new DefaultTreeModel(new JBossCacheGUI.DisplayNode(Fqn.ROOT.toString()));
        jtree = new JTree(tree_model);
        jtree.setDoubleBuffered(true);
        jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
  
        JScrollPane scroll_pane = new JScrollPane(jtree);
        mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        mainPanel.add(scroll_pane, BorderLayout.CENTER);
  
        addWindowListener(this);
  
        tableModel.setColumnIdentifiers(new String[]{"Name", "Value"});
        tableModel.addTableModelListener(this);
  
        // add a mouse listener  to the table model for delete and insert rows.
        MouseListener dataMouseListener = new MouseAdapter()
        {
           public void mouseClicked(MouseEvent e)
           {
              if (rightClick(e.getModifiers()))
              {
                 dataModificationsPopup.show(e.getComponent(), e.getX(), e.getY());
              }
           }
        };
  
        setTableColumnWidths();
  
        tablePanel = new JPanel();
        tablePanel.setLayout(new BorderLayout());
        tablePanel.add(table.getTableHeader(), BorderLayout.NORTH);
        tablePanel.add(table, BorderLayout.CENTER);
  
        table.addMouseListener(dataMouseListener);
  
        mainPanel.add(tablePanel, BorderLayout.SOUTH);
        JSplitPane contentPanel = null;
        if (useConsole)
        {
           String welcomeMessage = getWelcomeMessage();
           
           JConsole bshConsole = new JConsole();
           Interpreter interpreter = new Interpreter(bshConsole);
  
           configureInterpreter(interpreter, cacheDelegate);
           
           interpreter.println(welcomeMessage);
           interpreter.setShowResults(!interpreter.getShowResults());// show() in beanShell
           System.setOut(bshConsole.getOut());
           System.setErr(bshConsole.getErr());
           Thread t = new Thread(interpreter);
           t.start();
  
           contentPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, mainPanel, bshConsole);
           getContentPane().add(contentPanel);
        }
        else
        {
           getContentPane().add(mainPanel);
        }
  
        jtree.addTreeSelectionListener(this);// REVISIT
  
        MouseListener ml = new MouseAdapter()
        {
           public void mouseClicked(MouseEvent e)
           {
              int selRow = jtree.getRowForLocation(e.getX(), e.getY());
              TreePath selPath = jtree.getPathForLocation(e.getX(), e.getY());
              if (selRow != -1)
              {
                 selected_node = getNode(selPath.getPath());
                 jtree.setSelectionPath(selPath);
  
                 if (rightClick(e.getModifiers()))
                 {
                    operationsPopup.show(e.getComponent(), e.getX(), e.getY());
                 }
              }
           }
        };
  
        jtree.addMouseListener(ml);
  
        createMenus();
        setLocation(50, 50);                                  
        setSize(getInsets().left + getInsets().right + 800, getInsets().top + getInsets().bottom + 800);
  
        // make sure we set the cache BEFORE initialising this!!
        setCacheDelegate(cacheDelegate);
        init();
        setVisible(true);
  
        if (useConsole)
        {
           //has to be called after setVisible() otherwise no effect
           contentPanel.setDividerLocation(0.65);
        }
     }
  
     public void setCacheDelegate(final CacheModelDelegate cacheDelegate)
     {
        this.cacheDelegate = cacheDelegate;
        cache = this.cacheDelegate.getGenericCache();
  
        if (this.cacheDelegate != null)
        {
           Runtime.getRuntime().addShutdownHook(
                 new Thread()
                 {
                    public void run()
                    {
                       cache.stop();
                    }
                 });
  
           cache.addCacheListener(this);
           root = cache.getRoot();
           setTitle("JBoss Cache GUI: Local Address=" + getLocalAddress());
           tx_mgr = cache.getConfiguration().getRuntimeConfig().getTransactionManager();
           populateTree();
        }
        else
        {
           setTitle("Cache undefined");
           if (tree_model != null)
           {
              myNodeRoot = new JBossCacheGUI.DisplayNode(Fqn.SEPARATOR);
              tree_model.setRoot(myNodeRoot);
              tree_model.reload();
  
           }
           if (tableModel != null)
           {
              clearTable();
           }
        }
     }
  
     /**
      * Checks whether a click event is considered a "right-click"
      *
      * @param modifiers mouse event mods
      * @return true if deemed a right click
      */
     private boolean rightClick(int modifiers)
     {
        // the simple right click case
        if (modifiers == InputEvent.BUTTON3_MASK) return true;
        // more complex on Mac OS X where a ctrl-click is deemed the same as a right click
        return modifiers == InputEvent.BUTTON1_MASK + InputEvent.CTRL_MASK;
     }
  
     public void windowClosed(WindowEvent event)
     {
     }
  
     public void windowDeiconified(WindowEvent event)
     {
     }
  
     public void windowIconified(WindowEvent event)
     {
     }
  
     public void windowActivated(WindowEvent event)
     {
     }
  
     public void windowDeactivated(WindowEvent event)
     {
     }
  
     public void windowOpened(WindowEvent event)
     {
     }
  
     public void windowClosing(WindowEvent event)
     {
        stopGui();
     }
  
  
     public void tableChanged(TableModelEvent evt)
     {
        int row, col;
        String key, val;
  
        if (evt.getType() == TableModelEvent.UPDATE)
        {
           row = evt.getFirstRow();
           col = evt.getColumn();
  
           key = (String) tableModel.getValueAt(row, col == 0 ? 0 : col - 1);
           val = (String) tableModel.getValueAt(row, col == 0 ? 1 : col);
  
           if (key != null && val != null && !isPlaceHolder(key) && !isPlaceHolder(val))
           {
              try
              {
                 selected_node.put(key, val);
                 Map<String, String> data = selected_node.getData();
                 populateTable(data);
              }
              catch (Exception e)
              {
                 printAndLogStacktrace("Changing table failed: ", e);
              }
           }
        }
     }
  
  
     public void valueChanged(TreeSelectionEvent evt)
     {
        TreePath path = evt.getPath();
        Map<String, String> data;
  
        selected_node = getNode(path.getPath());
        data = selected_node.getData();
        if (data != null)
        {
           mainPanel.add(tablePanel, BorderLayout.SOUTH);
           populateTable(data);
           validate();
        }
        else
        {
           clearTable();
           mainPanel.remove(tablePanel);
           validate();
        }
     }
  
     protected DefaultTableModel getTableModel()
     {
        return tableModel;
     }   
  
     protected String getWelcomeMessage()
     {
        return "Welcome to the BeanShell console.\n\n" +
           "This console gives you a direct shell interface to the GUI above and allows you to manipulate the cache directly. " +
           "Some of the variables initialised in this shell session are:\n\n" +
           "// an instance of org.jboss.cache\n" +
           "    Cache<String, String> cache;\n" +
           "// a reference to the root node\n" +
           "    Node<String, String> root;\n" +
           "// the transaction manager registered with the cache\n" +
           "    TransactionManager transactionManager;\n";
     }
  
     protected void configureInterpreter(Interpreter interpreter, CacheModelDelegate cacheDelegate) throws EvalError
     {
        interpreter.getNameSpace().importPackage("org.jboss.cache");
        interpreter.getNameSpace().importPackage("org.jboss.cache.transaction");
        interpreter.set("cache", cacheDelegate.getGenericCache());
        interpreter.set("root", cacheDelegate.getGenericCache().getRoot());
        interpreter.set("transactionManager", cacheDelegate.getGenericCache().getConfiguration().getRuntimeConfig().getTransactionManager());
     }
  
     /* ------------------ CacheListener interface ------------ */
  
     // run any work that happens in this interface in a separate thread.  This is good practise.
     private Executor executor = Executors.newFixedThreadPool(1);
  
  
     public void nodeCreated(final Fqn fqn, final boolean pre, boolean isLocal)
     {
        Runnable r = new Runnable()
        {
           public void run()
           {
              if (pre)
              {
                 JBossCacheGUI.DisplayNode n;
  
                 n = myNodeRoot.add(fqn);
                 if (n != null)
                 {
                    tree_model.setRoot(myNodeRoot);
                    tree_model.reload();
                    jtree.scrollPathToVisible(new TreePath(n.getPath()));
                 }
              }
           }
        };
        executor.execute(r);
     }
  
     public void nodeModified(final Fqn fqn, final boolean pre, final boolean isLocal, ModificationType modType, final Map data)
     {
        Runnable r = new Runnable()
        {
           public void run()
           {
              if (pre && selected_node != null && selected_node.getFqn().equals(fqn))//&& !isLocal)
              {
                 clearTable();
                 Node n = root.getChild(fqn);
                 if (n != null)
                 {
                    populateTable(n.getData());
                 }
              }
           }
        };
        executor.execute(r);
     }
  
     public void nodeRemoved(final Fqn fqn, final boolean pre, boolean isLocal, Map data)
     {
        Runnable r = new Runnable()
        {
           public void run()
           {
              if (pre)
              {
                 JBossCacheGUI.DisplayNode n;
  
                 n = myNodeRoot.findNode(fqn);
                 if (n != null)
                 {
                    n.removeAllChildren();
                    n.removeFromParent();
                    tree_model.setRoot(myNodeRoot);
                    tree_model.reload();
                 }
              }
           }
        };
        executor.execute(r);
     }
  
     public void nodeVisited(Fqn fqn, boolean pre)
     {
     }
  
     public void nodeEvicted(Fqn fqn, boolean pre, boolean isLocal)
     {
        nodeRemoved(fqn, pre, isLocal, null);
     }
  
     public void nodeLoaded(Fqn fqn, boolean pre, Map data)
     {
        nodeCreated(fqn, pre, true);
     }
  
     public void nodeMoved(Fqn from, Fqn to, boolean pre, boolean isLocal)
     {
     }
  
     public void nodeActivated(Fqn fqn, boolean pre)
     {
     }
  
     public void nodePassivated(Fqn fqn, boolean pre)
     {
     }
  
     public void cacheStarted(CacheSPI cache)
     {
     }
  
     public void cacheStopped(CacheSPI cache)
     {
     }
  
     public void viewChange(final View new_view)
     {
        Runnable r = new Runnable()
        {
           public void run()
           {
              List<Address> mbrship;
              if (new_view != null && (mbrship = new_view.getMembers()) != null)
              {
                 membership.clear();
                 membership.addAll(mbrship);
                 coordinator = mbrship.get(0);
              }
           }
        };
        executor.execute(r);
     }
  
     /* ---------------- End of CacheListener interface -------- */
  
     /*----------------- Runnable implementation to make View change calles in AWT Thread ---*/
  
     public void run()
     {
  
     }
  
     /* ----------------------------- Private Methods ---------------------------------- */
  
     /**
      * Fetches all data from underlying cache model and display it graphically
      */
     private void init()
     {
        List<Address> mbrship;
  
        mbrship = getMembers();
        if (mbrship != null && mbrship.size() > 0)
        {
           membership.clear();
           membership.addAll(mbrship);
           coordinator = mbrship.get(0);
        }
     }
  
  
     /**
      * Fetches all data from underlying cache model and display it graphically
      */
     private void populateTree()
     {
        addGuiNode(Fqn.ROOT);
     }
  
  
     /**
      * Recursively adds GUI nodes starting from fqn
      */
     private void addGuiNode(Fqn<String> fqn)
     {
        Set<Object> children;
  
        if (fqn == null) return;
  
        // 1 . Add myself
        myNodeRoot.add(fqn);
  
        // 2. Then add my children
        children = cache.getRoot().getChild(fqn).getChildrenNames();
        if (children != null)
        {
           for (Object child_name : children)
           {
              addGuiNode(new Fqn<String>(fqn, (String) child_name));
           }
        }
     }
  
  
     private Node getNode(Object[] path)
     {
        Fqn<String> fqnToPath;
        if (path.length == 0) fqnToPath = Fqn.ROOT;
        List<String> elements = convertMyNodeArrayToStringArray(path);
        fqnToPath = new Fqn<String>(elements);
        if (root.hasChild(fqnToPath))
        {
           return root.getChild(fqnToPath);
        }
        else
        {
           // implicit creation
           return root.addChild(fqnToPath);
        }
     }
  
     private List<String> convertMyNodeArrayToStringArray(Object[] path)
     {
        List<String> list = new LinkedList<String>();
        for (Object o : path)
        {
           JBossCacheGUI.DisplayNode n = (JBossCacheGUI.DisplayNode) o;
           if (!n.name.equals(Fqn.SEPARATOR)) list.add(n.name);
        }
        return list;
     }
  
     protected void clearTable()
     {
        int num_rows = table.getRowCount();
  
        if (num_rows > 0)
        {
           for (int i = 0; i < num_rows; i++)
           {
              tableModel.removeRow(0);
           }
           tableModel.fireTableRowsDeleted(0, num_rows - 1);
           repaint();
        }
     }
  
  
     protected void populateTable(Map<String, String> data)
     {
        String key;
        String val;
        int num_rows;
        clearTable();
        if (data == null) return;
        num_rows = data.size();
  
        if (num_rows > 0)
        {
           // sort this according to the natural sort order of keys
           TreeMap<String, String> sortedMap = new TreeMap<String, String>(data);
  
           for (Map.Entry<String, String> entry : sortedMap.entrySet())
           {
              key = entry.getKey();
              val = entry.getValue();
              tableModel.addRow(new Object[]{key, val});
           }
           tableModel.fireTableRowsInserted(0, num_rows - 1);
           validate();
        }
     }
  
     private void setTableColumnWidths()
     {
        table.sizeColumnsToFit(JTable.AUTO_RESIZE_NEXT_COLUMN);
        TableColumn column;
        column = table.getColumnModel().getColumn(0);
        column.setMinWidth(KEY_COL_WIDTH);
        column.setPreferredWidth(KEY_COL_WIDTH);
        column = table.getColumnModel().getColumn(1);
        column.setPreferredWidth(VAL_COL_WIDTH);
     }
  
     private void createMenus()
     {
        JMenuBar menubar = new JMenuBar();
        JMenu operationsMenu = new JMenu("Operations");
        JBossCacheGUI.AddNodeAction addNode = new JBossCacheGUI.AddNodeAction();
        addNode.putValue(AbstractAction.NAME, "Add to this node");
        JBossCacheGUI.LoadAction load_action = new JBossCacheGUI.LoadAction();
        load_action.putValue(AbstractAction.NAME, "Load from the CacheLoader");
        JBossCacheGUI.RemoveNodeAction removeNode = new JBossCacheGUI.RemoveNodeAction();
        removeNode.putValue(AbstractAction.NAME, "Remove this node");
        JBossCacheGUI.EvictAction evict_action = new JBossCacheGUI.EvictAction();
        evict_action.putValue(AbstractAction.NAME, "Evict from the Cache");
        JBossCacheGUI.AddModifyDataForNodeAction addModAction = new JBossCacheGUI.AddModifyDataForNodeAction();
        addModAction.putValue(AbstractAction.NAME, "Add/Modify data");
        JBossCacheGUI.PrintLockInfoAction print_locks = new JBossCacheGUI.PrintLockInfoAction();
        print_locks.putValue(AbstractAction.NAME, "Print lock information (stdout)");
        JBossCacheGUI.ExitAction exitAction = new JBossCacheGUI.ExitAction();
        exitAction.putValue(AbstractAction.NAME, "Exit");
        JBossCacheGUI.StartTransaction start_tx = new JBossCacheGUI.StartTransaction();
        start_tx.putValue(AbstractAction.NAME, "Start TX");
        JBossCacheGUI.CommitTransaction commit_tx = new JBossCacheGUI.CommitTransaction();
        commit_tx.putValue(AbstractAction.NAME, "Commit TX");
        JBossCacheGUI.RollbackTransaction rollback_tx = new JBossCacheGUI.RollbackTransaction();
        rollback_tx.putValue(AbstractAction.NAME, "Rollback TX");
  
        operationsMenu.add(addNode);
        operationsMenu.add(load_action);
        operationsMenu.add(removeNode);
        operationsMenu.add(evict_action);
        operationsMenu.add(addModAction);
        operationsMenu.add(print_locks);
        operationsMenu.add(start_tx);
        operationsMenu.add(commit_tx);
        operationsMenu.add(rollback_tx);
        operationsMenu.add(exitAction);
        menubar.add(operationsMenu);
        setJMenuBar(menubar);
  
        operationsPopup = new JPopupMenu();
        operationsPopup.add(addNode);
        operationsPopup.add(load_action);
        operationsPopup.add(evict_action);
        operationsPopup.add(removeNode);
        operationsPopup.add(addModAction);
  
        JBossCacheGUI.InsertRowAction insertRow = new JBossCacheGUI.InsertRowAction();
        insertRow.putValue(AbstractAction.NAME, "Insert New Row");
        JBossCacheGUI.RemoveLastRowAction removeLastRow = new JBossCacheGUI.RemoveLastRowAction();
        removeLastRow.putValue(AbstractAction.NAME, "Remove Last Row");
  
        dataModificationsPopup = new JPopupMenu();
        dataModificationsPopup.add(insertRow);
        dataModificationsPopup.add(removeLastRow);
     }
  
     private Object getLocalAddress()
     {
        try
        {
           return cache.getLocalAddress();
        }
        catch (Throwable t)
        {
           log.error("JBossCacheGUI.getLocalAddress(): ", t);
           return null;
        }
     }
  
     private void load(Fqn<String> fqn)
     {
        try
        {
           // this will cause the cache to load the relevant node from a cache loader.
           cache.getRoot().getChild(fqn);
        }
        catch (Throwable t)
        {
           log.error("JBossCacheGUI.load(): " + t);
        }
     }
  
     private List<Address> getMembers()
     {
        try
        {
           return new ArrayList<Address>(cache.getMembers());
        }
        catch (Throwable t)
        {
           log.error("TreeCacheGui.getMembers(): ", t);
           return null;
        }
     }
  
     private String[] getRowPlaceHolderData()
     {
        Collection keys = extractKeys(tableModel.getDataVector());
        // try all place holders
  
        int count = 0;
        String placeHolderKey = "{ --- Add Key --- }";
        while (keys.contains(placeHolderKey))
        {
           count++;
           placeHolderKey = "{ --- Add Key " + count + " --- }";
        }
  
        String placeHolderValue = "{ --- Add Value " + (count == 0 ? "" : count) + " --- }";
        return new String[]{placeHolderKey, placeHolderValue};
     }
  
     private boolean isPlaceHolder(String s)
     {
        if (s.startsWith("{ --- Add Key ") && s.endsWith(" --- }")) return true;
        if (s.startsWith("{ --- Add Value ") && s.endsWith(" --- }")) return true;
        return false;
     }
  
     private Collection extractKeys(Vector<Vector> v)
     {
        // very odd data structure.  Entire table is represented as a Vector.  Each row (element in the Vector) is a Vector of 2 elements (key and value)
        List l = new LinkedList();
        for (Vector row : v)
        {
           // just add keys
           l.add(row.get(0));
        }
        return l;
     }
  
     private void printAndLogStacktrace(String message, Throwable t)
     {
        t.printStackTrace();
        log.error(message, t);
     }
  
     /* -------------------------- End of Private Methods ------------------------------ */
  
     /*----------------------- Actions ---------------------------*/
  
     class ExitAction extends AbstractAction
     {
        private static final long serialVersionUID = -5364163916172148038L;
  
        public void actionPerformed(ActionEvent e)
        {
           stopGui();
        }
     }
  
  
     void stopGui()
     {
        if (cache != null)
        {
           try
           {
              cache.stop();
              cache.destroy();
              cache = null;
           }
           catch (Throwable t)
           {
              printAndLogStacktrace("Stopping and destroying cache failed: ", t);
           }
        }
        dispose();
        System.exit(0);
     }
  
  
     class InsertRowAction extends AbstractAction
     {
        private static final long serialVersionUID = 7084928639244438800L;
  
        public void actionPerformed(ActionEvent e)
        {
           tableModel.addRow(getRowPlaceHolderData());
        }
     }
  
     class RemoveLastRowAction extends AbstractAction
     {
        private static final long serialVersionUID = 7084928639244438800L;
  
        public void actionPerformed(ActionEvent e)
        {
           int lastRow = tableModel.getRowCount() - 1;
           if (lastRow > -1)
           {
              String keyToRemove = (String) tableModel.getValueAt(lastRow, 0);
              tableModel.removeRow(lastRow);
              selected_node.remove(keyToRemove);
           }
        }
     }
  
  
     class AddNodeAction extends AbstractAction
     {
        private static final long serialVersionUID = 7084928639244438800L;
  
        public void actionPerformed(ActionEvent e)
        {
           JTextField fqnTextField = new JTextField();
           if (selected_node != null)
           {
              fqnTextField.setText(selected_node.getFqn().toString());
           }
           else
           {
              fqnTextField.setText(Fqn.SEPARATOR);
           }
           Object[] information = {"Enter fully qualified name",
                                   fqnTextField};
           final String btnString1 = "OK";
           final String btnString2 = "Cancel";
           Object[] options = {btnString1, btnString2};
           int userChoice = JOptionPane.showOptionDialog(null,
                                                         information,
                                                         "Add DataNode",
                                                         JOptionPane.YES_NO_OPTION,
                                                         JOptionPane.PLAIN_MESSAGE,
                                                         null,
                                                         options,
                                                         options[0]);
           if (userChoice == 0)
           {
              String userInput = fqnTextField.getText();
              cache.put(Fqn.fromString(userInput), null);
           }
        }
     }
  
     class LoadAction extends AbstractAction
     {
        private static final long serialVersionUID = -6998760732995584428L;
  
        public void actionPerformed(ActionEvent e)
        {
           JTextField fqnTextField = new JTextField();
           if (selected_node != null)
           {
              fqnTextField.setText(selected_node.getFqn().toString());
           }
           else
           {
              fqnTextField.setText(Fqn.SEPARATOR);
           }
  
           Object[] information = {"Enter fully qualified name",
                                   fqnTextField};
           final String btnString1 = "OK";
           final String btnString2 = "Cancel";
           Object[] options = {btnString1, btnString2};
           int userChoice = JOptionPane.showOptionDialog(null,
                                                         information,
                                                         "Load DataNode",
                                                         JOptionPane.YES_NO_OPTION,
                                                         JOptionPane.PLAIN_MESSAGE,
                                                         null,
                                                         options,
                                                         options[0]);
           if (userChoice == 0)
           {
              String userInput = fqnTextField.getText();
              load(Fqn.fromString(userInput));
           }
        }
     }
  
     class EvictAction extends AbstractAction
     {
        private static final long serialVersionUID = 6007500908549034215L;
  
        public void actionPerformed(ActionEvent e)
        {
           JTextField fqnTextField = new JTextField();
           if (selected_node != null)
           {
              fqnTextField.setText(selected_node.getFqn().toString());
           }
           else
           {
              fqnTextField.setText(Fqn.SEPARATOR);
           }
           Object[] information = {"Enter fully qualified name",
                                   fqnTextField};
           final String btnString1 = "OK";
           final String btnString2 = "Cancel";
           Object[] options = {btnString1, btnString2};
           int userChoice = JOptionPane.showOptionDialog(null,
                                                         information,
                                                         "Evict DataNode",
                                                         JOptionPane.YES_NO_OPTION,
                                                         JOptionPane.PLAIN_MESSAGE,
                                                         null,
                                                         options,
                                                         options[0]);
           if (userChoice == 0)
           {
              String userInput = fqnTextField.getText();
              cache.evict(Fqn.fromString(userInput), true);
           }
        }
     }
  
  
     class StartTransaction extends AbstractAction
     {
        private static final long serialVersionUID = 7059131008813144857L;
  
        public void actionPerformed(ActionEvent e)
        {
           if (tx_mgr == null)
           {
              log.error("no TransactionManager specified");
              return;
           }
           if (tx != null)
           {
              log.error("transaction is already running: " + tx);
              return;
           }
           try
           {
              tx_mgr.begin();
              tx = tx_mgr.getTransaction();
           }
           catch (Throwable t)
           {
              printAndLogStacktrace("Creating transaction failed: ", t);
           }
        }
     }
  
     class CommitTransaction extends AbstractAction
     {
        private static final long serialVersionUID = 5426108920883879873L;
  
        public void actionPerformed(ActionEvent e)
        {
           if (tx == null)
           {
              log.error("transaction is not running");
              return;
           }
           try
           {
              tx.commit();
           }
           catch (Throwable t)
           {
              printAndLogStacktrace("Commiting transaction failed: ", t);
           }
           finally
           {
              tx = null;
           }
        }
     }
  
     class RollbackTransaction extends AbstractAction
     {
        private static final long serialVersionUID = -4836748411400541430L;
  
        public void actionPerformed(ActionEvent e)
        {
           if (tx == null)
           {
              log.error("transaction is not running");
              return;
           }
           try
           {
              tx.rollback();
           }
           catch (Throwable t)
           {
              printAndLogStacktrace("Transaction rollback failed: ", t);
           }
           finally
           {
              tx = null;
           }
        }
     }
  
     class PrintLockInfoAction extends AbstractAction
     {
        private static final long serialVersionUID = -2171307516592250436L;
  
        public void actionPerformed(ActionEvent e)
        {
           System.out.println("\n*** lock information ****\n" + ((CacheImpl) cache).printLockInfo());
        }
     }
  
     class RemoveNodeAction extends AbstractAction
     {
        private static final long serialVersionUID = 3746013603940497991L;
  
        public void actionPerformed(ActionEvent e)
        {
           try
           {
              cache.removeNode(selected_node.getFqn());
           }
           catch (Throwable t)
           {
              log.error("RemoveNodeAction.actionPerformed(): " + t);
           }
        }
     }
  
     class AddModifyDataForNodeAction extends AbstractAction
     {
        private static final long serialVersionUID = -7656592171312920825L;
  
        public void actionPerformed(ActionEvent e)
        {
           clearTable();
           Map<String, String> data = selected_node.getData();
           if (data == null || data.isEmpty())
           {
              data = new HashMap<String, String>();
              String[] placeHolder = getRowPlaceHolderData();
              data.put(placeHolder[0], placeHolder[1]);
           }
  
           populateTable(data);
  
           mainPanel.add(tablePanel, BorderLayout.SOUTH);
           validate();
        }
     }
  
  
     class DisplayNode extends DefaultMutableTreeNode
     {
        private static final long serialVersionUID = 4882445905140460053L;
        String name = "<unnamed>";
  
  
        DisplayNode(String name)
        {
           this.name = name;
        }
  
  
        /**
         * Adds a new node to the view. Intermediary nodes will be created if they don't yet exist.
         * Returns the first node that was created or null if node already existed
         */
        public JBossCacheGUI.DisplayNode add(Fqn<String> fqn)
        {
           JBossCacheGUI.DisplayNode curr, n, ret = null;
  
           if (fqn == null) return null;
           curr = this;
  
           for (String child_name : fqn.peekElements())
           {
              n = curr.findChild(child_name);
              if (n == null)
              {
                 n = new JBossCacheGUI.DisplayNode(child_name);
                 if (ret == null) ret = n;
                 curr.add(n);
              }
              curr = n;
           }
           return ret;
        }
  
  
        /**
         * Removes a node from the view. Child nodes will be removed as well
         */
        public void remove()
        {
           removeFromParent();
        }
  
  
        private JBossCacheGUI.DisplayNode findNode(Fqn<String> fqn)
        {
           JBossCacheGUI.DisplayNode curr, n;
  
           if (fqn == null) return null;
           curr = this;
  
           for (String child_name : fqn.peekElements())
           {
              n = curr.findChild(child_name);
              if (n == null)
              {
                 return null;
              }
              curr = n;
           }
           return curr;
        }
  
  
        private JBossCacheGUI.DisplayNode findChild(String relative_name)
        {
           JBossCacheGUI.DisplayNode child;
  
           if (relative_name == null || getChildCount() == 0)
           {
              return null;
           }
           for (int i = 0; i < getChildCount(); i++)
           {
              child = (JBossCacheGUI.DisplayNode) getChildAt(i);
              if (child.name == null)
              {
                 continue;
              }
  
              if (child.name.equals(relative_name))
              {
                 return child;
              }
           }
           return null;
        }
  
        public String toString()
        {
           return name;
        }
  
     }
  }
  
  
  



More information about the jboss-cvs-commits mailing list