Clover coverage report -
Coverage timestamp: Thu Jul 5 2007 20:02:32 EDT
file stats: LOC: 1,123   Methods: 64
NCLOC: 878   Classes: 10
 
 Source file Conditionals Statements Methods TOTAL
TreeCacheView.java 0% 0% 0% 0%
coverage
 1    /*
 2    * JBoss, the OpenSource J2EE webOS
 3    *
 4    * Distributable under LGPL license.
 5    * See terms of license at gnu.org.
 6    * Created on March 25 2003
 7    */
 8    package org.jboss.cache;
 9   
 10    import org.apache.commons.logging.Log;
 11    import org.apache.commons.logging.LogFactory;
 12    import org.jboss.cache.config.Configuration;
 13    import org.jboss.cache.jmx.CacheJmxWrapper;
 14    import org.jboss.cache.jmx.CacheJmxWrapperMBean;
 15    import org.jboss.cache.notifications.annotation.CacheListener;
 16    import org.jboss.cache.notifications.annotation.NodeCreated;
 17    import org.jboss.cache.notifications.annotation.NodeEvicted;
 18    import org.jboss.cache.notifications.annotation.NodeLoaded;
 19    import org.jboss.cache.notifications.annotation.NodeRemoved;
 20    import org.jboss.cache.notifications.annotation.ViewChanged;
 21    import org.jboss.cache.notifications.event.NodeEvent;
 22    import org.jboss.cache.notifications.event.ViewChangedEvent;
 23   
 24    import javax.management.MBeanServer;
 25    import javax.management.MBeanServerFactory;
 26    import javax.management.ObjectName;
 27    import javax.swing.*;
 28    import javax.swing.event.TableModelEvent;
 29    import javax.swing.event.TableModelListener;
 30    import javax.swing.event.TreeSelectionEvent;
 31    import javax.swing.event.TreeSelectionListener;
 32    import javax.swing.table.DefaultTableModel;
 33    import javax.swing.table.TableColumn;
 34    import javax.swing.tree.DefaultMutableTreeNode;
 35    import javax.swing.tree.DefaultTreeModel;
 36    import javax.swing.tree.TreeNode;
 37    import javax.swing.tree.TreePath;
 38    import javax.swing.tree.TreeSelectionModel;
 39    import java.awt.*;
 40    import java.awt.event.ActionEvent;
 41    import java.awt.event.MouseAdapter;
 42    import java.awt.event.MouseEvent;
 43    import java.awt.event.MouseListener;
 44    import java.awt.event.WindowEvent;
 45    import java.awt.event.WindowListener;
 46    import java.io.File;
 47    import java.util.ArrayList;
 48    import java.util.HashMap;
 49    import java.util.Iterator;
 50    import java.util.List;
 51    import java.util.Map;
 52    import java.util.Set;
 53    import java.util.Vector;
 54   
 55    /**
 56    * Graphical view of a ReplicatedTree (using the MVC paradigm). An instance of this class needs to be given a
 57    * reference to the underlying model (ReplicatedTree) and needs to registers as a ReplicatedTreeListener. Changes
 58    * to the cache structure are propagated from the model to the view (via ReplicatedTreeListener), changes from the
 59    * GUI (e.g. by a user) are executed on the cache model (which will broadcast the changes to all replicas).<p>
 60    * The view itself caches only the nodes, but doesn't cache any of the data (HashMap) associated with it. When
 61    * data needs to be displayed, the underlying cache will be accessed directly.
 62    *
 63    * @author Bela Ban
 64    * @version $Revision: 1.29 $
 65    */
 66    public class TreeCacheView implements TreeCacheViewMBean
 67    {
 68    /**
 69    * Reference to the CacheImpl MBean (the model for this view)
 70    */
 71    CacheJmxWrapperMBean cache_service = null;
 72    TreeCacheGui gui = null;
 73    CacheSPI cache;
 74    Log log = LogFactory.getLog(TreeCacheView.class);
 75   
 76   
 77  0 public TreeCacheView() throws Exception
 78    {
 79  0 super();
 80    }
 81   
 82  0 public TreeCacheView(Cache cache) throws Exception
 83    {
 84  0 setCache(cache);
 85    }
 86   
 87  0 public TreeCacheView(CacheJmxWrapper mbean) throws Exception
 88    {
 89  0 setCacheService(mbean);
 90    }
 91   
 92   
 93  0 public void create()
 94    {
 95    }
 96   
 97  0 public void start() throws Exception
 98    {
 99  0 if (gui == null)
 100    {
 101  0 log.info("start(): creating the GUI");
 102  0 gui = new TreeCacheGui(cache);
 103    }
 104    }
 105   
 106  0 public void stop()
 107    {
 108  0 if (gui != null)
 109    {
 110  0 log.info("stop(): disposing the GUI");
 111  0 gui.dispose();
 112  0 gui = null;
 113    }
 114    }
 115   
 116    /**
 117    */
 118  0 public void destroy()
 119    {
 120    }
 121   
 122   
 123  0 public Cache getCache()
 124    {
 125  0 return cache;
 126    }
 127   
 128  0 public void setCache(Cache cache)
 129    {
 130  0 this.cache = (CacheSPI) cache;
 131  0 System.out.println("Cache " + cache);
 132  0 if (cache != null)
 133    {
 134  0 gui = new TreeCacheGui(this.cache);
 135    }
 136    else
 137    {
 138  0 gui = null;
 139    }
 140    }
 141   
 142  0 public CacheJmxWrapperMBean getCacheService()
 143    {
 144  0 return cache_service;
 145    }
 146   
 147    /**
 148    * @param cache_service
 149    * @throws Exception
 150    */
 151  0 public void setCacheService(CacheJmxWrapperMBean cache_service)
 152    {
 153  0 this.cache_service = cache_service;
 154  0 setCache(cache_service == null ? null : cache_service.getCache());
 155    }
 156   
 157   
 158  0 void populateTree(String dir) throws Exception
 159    {
 160  0 File file = new File(dir);
 161   
 162  0 if (!file.exists()) return;
 163   
 164  0 put(Fqn.fromString(dir), null);
 165   
 166  0 if (file.isDirectory())
 167    {
 168  0 String[] children = file.list();
 169  0 if (children != null && children.length > 0)
 170    {
 171  0 for (int i = 0; i < children.length; i++)
 172    {
 173  0 populateTree(dir + "/" + children[i]);
 174    }
 175    }
 176    }
 177    }
 178   
 179  0 void put(Fqn fqn, Map m)
 180    {
 181  0 try
 182    {
 183  0 cache.put(fqn, m);
 184    }
 185    catch (Throwable t)
 186    {
 187  0 log.error("TreeCacheView.put(): " + t);
 188    }
 189    }
 190   
 191   
 192  0 public static void main(String args[])
 193    {
 194  0 CacheImpl cache = null;
 195  0 TreeCacheView demo;
 196  0 String start_directory = null;
 197  0 String mbean_name = "jboss.cache:service=CacheImpl";
 198  0 String props = getDefaultProps();
 199  0 MBeanServer srv;
 200  0 Log log;
 201  0 boolean use_queue = false;
 202  0 int queue_interval = 5000;
 203  0 int queue_max_elements = 100;
 204   
 205   
 206  0 for (int i = 0; i < args.length; i++)
 207    {
 208  0 if (args[i].equals("-mbean_name"))
 209    {
 210  0 mbean_name = args[++i];
 211  0 continue;
 212    }
 213  0 if (args[i].equals("-props"))
 214    {
 215  0 props = args[++i];
 216  0 continue;
 217    }
 218  0 if (args[i].equals("-start_directory"))
 219    {
 220  0 start_directory = args[++i];
 221  0 continue;
 222    }
 223  0 if (args[i].equals("-use_queue"))
 224    {
 225  0 use_queue = true;
 226  0 continue;
 227    }
 228  0 if (args[i].equals("-queue_interval"))
 229    {
 230  0 queue_interval = Integer.parseInt(args[++i]);
 231  0 use_queue = true;
 232  0 continue;
 233    }
 234  0 if (args[i].equals("-queue_max_elements"))
 235    {
 236  0 queue_max_elements = Integer.parseInt(args[++i]);
 237  0 use_queue = true;
 238  0 continue;
 239    }
 240  0 help();
 241  0 return;
 242    }
 243   
 244  0 try
 245    {
 246  0 log = LogFactory.getLog(CacheImpl.class);
 247  0 srv = MBeanServerFactory.createMBeanServer();
 248   
 249    // String FACTORY="org.jboss.cache.transaction.DummyContextFactory";
 250    // System.setProperty(Context.INITIAL_CONTEXT_FACTORY, FACTORY);
 251    //
 252    // DummyTransactionManager.getInstance();
 253   
 254   
 255  0 cache = (CacheImpl) DefaultCacheFactory.getInstance().createCache(false);
 256  0 Configuration c = cache.getConfiguration();
 257  0 c.setClusterName("TreeCacheGroup");
 258  0 c.setClusterConfig(props);
 259  0 c.setStateRetrievalTimeout(10000);
 260  0 c.setCacheMode("REPL_ASYNC");
 261   
 262  0 if (use_queue)
 263    {
 264  0 c.setUseReplQueue(true);
 265  0 c.setReplQueueInterval(queue_interval);
 266  0 c.setReplQueueMaxElements(queue_max_elements);
 267    }
 268   
 269    //cache.getNotifier().addCacheListener(new AbstractCacheListener(){});
 270   
 271  0 log.info("registering the cache as " + mbean_name);
 272  0 CacheJmxWrapper mbean = new CacheJmxWrapper(cache);
 273  0 srv.registerMBean(mbean, new ObjectName(mbean_name));
 274   
 275  0 mbean.start();
 276   
 277  0 Runtime.getRuntime().addShutdownHook(new ShutdownThread(cache));
 278   
 279    // cache.put("/a/b/c", null);
 280    // cache.put("/a/b/c1", null);
 281    // cache.put("/a/b/c2", null);
 282    // cache.put("/a/b1/chat", null);
 283    // cache.put("/a/b1/chat2", null);
 284    // cache.put("/a/b1/chat5", null);
 285   
 286  0 demo = new TreeCacheView(mbean);
 287  0 demo.create();
 288  0 demo.start();
 289  0 if (start_directory != null && start_directory.length() > 0)
 290    {
 291  0 demo.populateTree(start_directory);
 292    }
 293    }
 294    catch (Exception ex)
 295    {
 296  0 ex.printStackTrace();
 297    }
 298    }
 299   
 300    static class ShutdownThread extends Thread
 301    {
 302    CacheImpl cache = null;
 303   
 304  0 ShutdownThread(CacheImpl cache)
 305    {
 306  0 this.cache = cache;
 307    }
 308   
 309  0 public void run()
 310    {
 311  0 cache.stop();
 312    }
 313    }
 314   
 315  0 private static String getDefaultProps()
 316    {
 317  0 return
 318    "UDP(ip_mcast=true;ip_ttl=64;loopback=false;mcast_addr=228.1.2.3;" +
 319    "mcast_port=45566;mcast_recv_buf_size=80000;mcast_send_buf_size=150000;" +
 320    "ucast_recv_buf_size=80000;ucast_send_buf_size=150000):" +
 321    "PING(down_thread=true;num_initial_members=3;timeout=2000;up_thread=true):" +
 322    "MERGE2(max_interval=20000;min_interval=10000):" +
 323    "FD(down_thread=true;shun=true;up_thread=true):" +
 324    "VERIFY_SUSPECT(down_thread=true;timeout=1500;up_thread=true):" +
 325    "pbcast.NAKACK(down_thread=true;gc_lag=50;retransmit_timeout=600,1200,2400,4800;" +
 326    "up_thread=true):" +
 327    "pbcast.STABLE(desired_avg_gossip=20000;down_thread=true;up_thread=true):" +
 328    "UNICAST(down_thread=true;min_threshold=10;timeout=600,1200,2400;window_size=100):" +
 329    "FRAG(down_thread=true;frag_size=8192;up_thread=true):" +
 330    "pbcast.GMS(join_retry_timeout=2000;join_timeout=5000;print_local_addr=true;shun=true):" +
 331    "pbcast.STATE_TRANSFER(down_thread=true;up_thread=true)";
 332    }
 333   
 334   
 335  0 static void help()
 336    {
 337  0 System.out.println("TreeCacheView [-help] " +
 338    "[-mbean_name <name of CacheImpl MBean>] " +
 339    "[-start_directory <dirname>] [-props <props>] " +
 340    "[-use_queue <true/false>] [-queue_interval <ms>] " +
 341    "[-queue_max_elements <num>]");
 342    }
 343    }
 344   
 345   
 346    @CacheListener
 347    class TreeCacheGui extends JFrame implements WindowListener, TreeSelectionListener, TableModelListener
 348    {
 349    private static final long serialVersionUID = 8576324868563647538L;
 350    CacheSPI cache;
 351    DefaultTreeModel tree_model = null;
 352    Log log = LogFactory.getLog(getClass());
 353    JTree jtree = null;
 354    DefaultTableModel table_model = new DefaultTableModel();
 355    JTable table = new JTable(table_model);
 356    MyNode root = new MyNode(SEP.getLastElementAsString());
 357    Fqn selected_node = null;
 358    JPanel tablePanel = null;
 359    JMenu operationsMenu = null;
 360    JPopupMenu operationsPopup = null;
 361    JMenuBar menubar = null;
 362    static final Fqn SEP = Fqn.ROOT;
 363    private static final int KEY_COL_WIDTH = 20;
 364    private static final int VAL_COL_WIDTH = 300;
 365   
 366   
 367  0 public TreeCacheGui(CacheSPI cache)
 368    {
 369  0 this.cache = cache;
 370   
 371    //server.invoke(cache_service, "addTreeCacheListener",
 372    // new Object[]{this},
 373    // new String[]{TreeCacheListener.class.getLastElementAsString()});
 374  0 cache.getNotifier().addCacheListener(this);
 375  0 addNotify();
 376  0 setTitle("TreeCacheGui: mbr=" + getLocalAddress());
 377   
 378  0 tree_model = new DefaultTreeModel(root);
 379  0 jtree = new JTree(tree_model);
 380  0 jtree.setDoubleBuffered(true);
 381  0 jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
 382   
 383  0 JScrollPane scroll_pane = new JScrollPane(jtree);
 384   
 385  0 populateTree();
 386   
 387  0 getContentPane().add(scroll_pane, BorderLayout.CENTER);
 388  0 addWindowListener(this);
 389   
 390  0 table_model.setColumnIdentifiers(new String[]{"Name", "Value"});
 391  0 table_model.addTableModelListener(this);
 392   
 393  0 setTableColumnWidths();
 394   
 395  0 tablePanel = new JPanel();
 396  0 tablePanel.setLayout(new BorderLayout());
 397  0 tablePanel.add(table.getTableHeader(), BorderLayout.NORTH);
 398  0 tablePanel.add(table, BorderLayout.CENTER);
 399   
 400  0 getContentPane().add(tablePanel, BorderLayout.SOUTH);
 401   
 402  0 jtree.addTreeSelectionListener(this);//REVISIT
 403   
 404  0 MouseListener ml = new MouseAdapter()
 405    {
 406  0 public void mouseClicked(MouseEvent e)
 407    {
 408  0 int selRow = jtree.getRowForLocation(e.getX(), e.getY());
 409  0 TreePath selPath = jtree.getPathForLocation(e.getX(), e.getY());
 410  0 if (selRow != -1)
 411    {
 412  0 selected_node = makeFQN(selPath.getPath());
 413  0 jtree.setSelectionPath(selPath);
 414   
 415  0 if (e.getModifiers() == java.awt.event.InputEvent.BUTTON3_MASK)
 416    {
 417  0 operationsPopup.show(e.getComponent(),
 418    e.getX(), e.getY());
 419    }
 420    }
 421    }
 422    };
 423   
 424  0 jtree.addMouseListener(ml);
 425   
 426  0 createMenus();
 427  0 setLocation(50, 50);
 428  0 setSize(getInsets().left + getInsets().right + 485,
 429    getInsets().top + getInsets().bottom + 367);
 430   
 431  0 init();
 432  0 setVisible(true);
 433    }
 434   
 435  0 void setSystemExit(boolean flag)
 436    {
 437    }
 438   
 439  0 public void windowClosed(WindowEvent event)
 440    {
 441    }
 442   
 443  0 public void windowDeiconified(WindowEvent event)
 444    {
 445    }
 446   
 447  0 public void windowIconified(WindowEvent event)
 448    {
 449    }
 450   
 451  0 public void windowActivated(WindowEvent event)
 452    {
 453    }
 454   
 455  0 public void windowDeactivated(WindowEvent event)
 456    {
 457    }
 458   
 459  0 public void windowOpened(WindowEvent event)
 460    {
 461    }
 462   
 463  0 public void windowClosing(WindowEvent event)
 464    {
 465  0 dispose();
 466    }
 467   
 468   
 469  0 public void tableChanged(TableModelEvent evt)
 470    {
 471  0 int row, col;
 472  0 String key, val;
 473   
 474  0 if (evt.getType() == TableModelEvent.UPDATE)
 475    {
 476  0 row = evt.getFirstRow();
 477  0 col = evt.getColumn();
 478  0 if (col == 0)
 479    {// set()
 480  0 key = (String) table_model.getValueAt(row, col);
 481  0 val = (String) table_model.getValueAt(row, col + 1);
 482  0 if (key != null && val != null)
 483    {
 484    // cache.put(selected_node, key, val);
 485   
 486    // server.invoke(cache_service, "put",
 487    // new Object[]{selected_node, key, val},
 488    // new String[]{String.class.getLastElementAsString(),
 489    // String.class.getLastElementAsString(), Object.class.getLastElementAsString()});
 490  0 try
 491    {
 492  0 cache.put(selected_node, key, val);
 493    }
 494    catch (Exception e)
 495    {
 496  0 e.printStackTrace();
 497    }
 498   
 499    }
 500    }
 501    else
 502    {// add()
 503  0 key = (String) table_model.getValueAt(row, col - 1);
 504  0 val = (String) table.getValueAt(row, col);
 505  0 if (key != null && val != null)
 506    {
 507  0 cache.put(selected_node, key, val);
 508    }
 509    }
 510    }
 511    }
 512   
 513   
 514  0 public void valueChanged(TreeSelectionEvent evt)
 515    {
 516  0 TreePath path = evt.getPath();
 517  0 Fqn fqn = SEP;
 518  0 Object component_name;
 519  0 Map data = null;
 520   
 521  0 for (int i = 0; i < path.getPathCount(); i++)
 522    {
 523  0 component_name = ((MyNode) path.getPathComponent(i)).name;
 524  0 if (component_name.equals("/"))
 525    {
 526  0 continue;
 527    }
 528  0 fqn = new Fqn(fqn, component_name);
 529    }
 530  0 data = getData(fqn);
 531  0 if (data != null)
 532    {
 533  0 getContentPane().add(tablePanel, BorderLayout.SOUTH);
 534  0 populateTable(data);
 535  0 validate();
 536    }
 537    else
 538    {
 539  0 clearTable();
 540  0 getContentPane().remove(tablePanel);
 541  0 validate();
 542    }
 543    }
 544   
 545    /* ------------------ ReplicatedTree.ReplicatedTreeListener interface ------------ */
 546   
 547  0 @NodeCreated
 548    @NodeLoaded
 549    public void nodeCreated(NodeEvent e)
 550    {
 551  0 if (!e.isPre())
 552    {
 553  0 MyNode n, p;
 554   
 555  0 n = root.add(e.getFqn());
 556  0 if (n != null)
 557    {
 558  0 p = (MyNode) n.getParent();
 559  0 tree_model.reload(p);
 560  0 jtree.scrollPathToVisible(new TreePath(n.getPath()));
 561    }
 562    }
 563    }
 564   
 565  0 @NodeRemoved
 566    @NodeEvicted
 567    public void nodeRemoved(NodeEvent e)
 568    {
 569  0 if (!e.isPre())
 570    {
 571  0 MyNode n;
 572  0 TreeNode par;
 573   
 574  0 n = root.findNode(e.getFqn());
 575  0 if (n != null)
 576    {
 577  0 n.removeAllChildren();
 578  0 par = n.getParent();
 579  0 n.removeFromParent();
 580  0 tree_model.reload(par);
 581    }
 582    }
 583    }
 584   
 585  0 @ViewChanged
 586    public void viewChange(final ViewChangedEvent e)
 587    {
 588  0 new Thread()
 589    {
 590  0 public void run()
 591    {
 592  0 Vector mbrship;
 593  0 if (e.getNewView() != null && (mbrship = e.getNewView().getMembers()) != null)
 594    {
 595  0 put(SEP, "members", mbrship);
 596  0 put(SEP, "coordinator", mbrship.firstElement());
 597    }
 598    }
 599    }.start();
 600    }
 601   
 602    /* ---------------- End of ReplicatedTree.ReplicatedTreeListener interface -------- */
 603   
 604    /*----------------- Runnable implementation to make View change calles in AWT Thread ---*/
 605   
 606  0 public void run()
 607    {
 608   
 609    }
 610   
 611    /* ----------------------------- Private Methods ---------------------------------- */
 612   
 613    /**
 614    * Fetches all data from underlying cache model and display it graphically
 615    */
 616  0 void init()
 617    {
 618  0 Vector mbrship = null;
 619   
 620  0 addGuiNode(SEP);
 621   
 622  0 mbrship = getMembers() != null ? (Vector) getMembers().clone() : null;
 623  0 if (mbrship != null && mbrship.size() > 0)
 624    {
 625  0 put(SEP, "members", mbrship);
 626  0 put(SEP, "coordinator", mbrship.firstElement());
 627    }
 628    }
 629   
 630   
 631    /**
 632    * Fetches all data from underlying cache model and display it graphically
 633    */
 634  0 private void populateTree()
 635    {
 636  0 addGuiNode(SEP);
 637    }
 638   
 639   
 640    /**
 641    * Recursively adds GUI nodes starting from fqn
 642    */
 643  0 void addGuiNode(Fqn fqn)
 644    {
 645  0 Set children;
 646   
 647  0 if (fqn == null) return;
 648   
 649    // 1 . Add myself
 650  0 root.add(fqn);
 651   
 652    // 2. Then add my children
 653  0 children = getChildrenNames(fqn);
 654  0 for (Object o : children)
 655    {
 656  0 addGuiNode(new Fqn(fqn, o));
 657    }
 658    }
 659   
 660   
 661  0 Fqn makeFQN(Object[] opath)
 662    {
 663  0 List l = new ArrayList();
 664  0 for (Object o : opath)
 665    {
 666  0 MyNode node = (MyNode) o;
 667  0 Object name = node.name;
 668  0 if (name.equals(Fqn.SEPARATOR))
 669    {
 670  0 continue;
 671    }
 672  0 l.add(name);
 673    }
 674  0 System.out.println(" L " + l);
 675  0 return new Fqn(l);
 676    }
 677   
 678  0 void clearTable()
 679    {
 680  0 int num_rows = table.getRowCount();
 681   
 682  0 if (num_rows > 0)
 683    {
 684  0 for (int i = 0; i < num_rows; i++)
 685    {
 686  0 table_model.removeRow(0);
 687    }
 688  0 table_model.fireTableRowsDeleted(0, num_rows - 1);
 689  0 repaint();
 690    }
 691    }
 692   
 693   
 694  0 void populateTable(Map data)
 695    {
 696  0 String key, strval = "<null>";
 697  0 Object val;
 698  0 int num_rows = 0;
 699  0 Map.Entry entry;
 700   
 701  0 if (data == null) return;
 702  0 num_rows = data.size();
 703  0 clearTable();
 704   
 705  0 if (num_rows > 0)
 706    {
 707  0 for (Iterator it = data.entrySet().iterator(); it.hasNext();)
 708    {
 709  0 entry = (Map.Entry) it.next();
 710  0 key = (String) entry.getKey();
 711  0 val = entry.getValue();
 712  0 if (val != null) strval = val.toString();
 713  0 table_model.addRow(new Object[]{key, strval});
 714    }
 715  0 table_model.fireTableRowsInserted(0, num_rows - 1);
 716  0 validate();
 717    }
 718    }
 719   
 720  0 private void setTableColumnWidths()
 721    {
 722  0 table.sizeColumnsToFit(JTable.AUTO_RESIZE_NEXT_COLUMN);
 723  0 TableColumn column = null;
 724  0 column = table.getColumnModel().getColumn(0);
 725  0 column.setMinWidth(KEY_COL_WIDTH);
 726  0 column.setPreferredWidth(KEY_COL_WIDTH);
 727  0 column = table.getColumnModel().getColumn(1);
 728  0 column.setPreferredWidth(VAL_COL_WIDTH);
 729    }
 730   
 731  0 private void createMenus()
 732    {
 733  0 menubar = new JMenuBar();
 734  0 operationsMenu = new JMenu("Operations");
 735  0 AddNodeAction addNode = new AddNodeAction();
 736  0 addNode.putValue(AbstractAction.NAME, "Add to this node");
 737  0 RemoveNodeAction removeNode = new RemoveNodeAction();
 738  0 removeNode.putValue(AbstractAction.NAME, "Remove this node");
 739  0 AddModifyDataForNodeAction addModAction = new AddModifyDataForNodeAction();
 740  0 addModAction.putValue(AbstractAction.NAME, "Add/Modify data");
 741  0 PrintLockInfoAction print_locks = new PrintLockInfoAction();
 742  0 print_locks.putValue(AbstractAction.NAME, "Print lock information (stdout)");
 743  0 ReleaseAllLocksAction release_locks = new ReleaseAllLocksAction();
 744  0 release_locks.putValue(AbstractAction.NAME, "Release all locks");
 745  0 ExitAction exitAction = new ExitAction();
 746  0 exitAction.putValue(AbstractAction.NAME, "Exit");
 747  0 operationsMenu.add(addNode);
 748  0 operationsMenu.add(removeNode);
 749  0 operationsMenu.add(addModAction);
 750  0 operationsMenu.add(print_locks);
 751  0 operationsMenu.add(release_locks);
 752  0 operationsMenu.add(exitAction);
 753  0 menubar.add(operationsMenu);
 754  0 setJMenuBar(menubar);
 755   
 756  0 operationsPopup = new JPopupMenu();
 757  0 operationsPopup.add(addNode);
 758  0 operationsPopup.add(removeNode);
 759  0 operationsPopup.add(addModAction);
 760    }
 761   
 762  0 Object getLocalAddress()
 763    {
 764  0 try
 765    {
 766  0 return cache.getLocalAddress();
 767    }
 768    catch (Throwable t)
 769    {
 770  0 log.error("TreeCacheGui.getLocalAddress(): " + t);
 771  0 return null;
 772    }
 773    }
 774   
 775  0 Map getData(Fqn fqn)
 776    {
 777  0 Node n = cache.getRoot().getChild(fqn);
 778  0 if (n == null)
 779    {
 780  0 return null;
 781    }
 782  0 return n.getData();
 783    }
 784   
 785   
 786  0 void put(Fqn fqn, Map m)
 787    {
 788  0 try
 789    {
 790  0 cache.put(fqn, m);
 791    }
 792    catch (Throwable t)
 793    {
 794  0 log.error("TreeCacheGui.put(): " + t);
 795    }
 796    }
 797   
 798   
 799  0 void put(Fqn fqn, String key, Object value)
 800    {
 801  0 try
 802    {
 803  0 cache.put(fqn, key, value);
 804    }
 805    catch (Throwable t)
 806    {
 807  0 log.error("TreeCacheGui.put(): " + t);
 808    }
 809    }
 810   
 811  0 Set getKeys(Fqn fqn)
 812    {
 813  0 try
 814    {
 815  0 return cache.getRoot().getChild(fqn).getKeys();
 816    }
 817    catch (Throwable t)
 818    {
 819  0 log.error("TreeCacheGui.getKeys(): " + t);
 820  0 return null;
 821    }
 822    }
 823   
 824  0 Object get(Fqn fqn, String key)
 825    {
 826  0 try
 827    {
 828  0 return cache.getRoot().getChild(fqn).getData().get(key);
 829    }
 830    catch (Throwable t)
 831    {
 832  0 log.error("TreeCacheGui.get(): " + t);
 833  0 return null;
 834    }
 835    }
 836   
 837  0 Set getChildrenNames(Fqn fqn)
 838    {
 839  0 try
 840    {
 841  0 Node n = cache.getRoot().getChild(fqn);
 842  0 return n.getChildrenNames();
 843    }
 844    catch (Throwable t)
 845    {
 846  0 log.error("TreeCacheGui.getChildrenNames(): " + t);
 847  0 return null;
 848    }
 849    }
 850   
 851  0 Vector getMembers()
 852    {
 853  0 try
 854    {
 855  0 return new Vector();
 856    // return cache.getMembers();
 857    }
 858    catch (Throwable t)
 859    {
 860  0 log.error("TreeCacheGui.getMembers(): " + t);
 861  0 return null;
 862    }
 863    }
 864   
 865    /* -------------------------- End of Private Methods ------------------------------ */
 866   
 867    /*----------------------- Actions ---------------------------*/
 868   
 869    class ExitAction extends AbstractAction
 870    {
 871    private static final long serialVersionUID = 8895044368299888998L;
 872   
 873  0 public void actionPerformed(ActionEvent e)
 874    {
 875  0 dispose();
 876    }
 877    }
 878   
 879    class AddNodeAction extends AbstractAction
 880    {
 881    private static final long serialVersionUID = 5568518714172267901L;
 882   
 883  0 public void actionPerformed(ActionEvent e)
 884    {
 885  0 JTextField fqnTextField = new JTextField();
 886  0 if (selected_node != null)
 887    {
 888  0 fqnTextField.setText(selected_node.toString());
 889    }
 890  0 Object[] information = {"Enter fully qualified name",
 891    fqnTextField};
 892  0 final String btnString1 = "OK";
 893  0 final String btnString2 = "Cancel";
 894  0 Object[] options = {btnString1, btnString2};
 895  0 int userChoice = JOptionPane.showOptionDialog(null,
 896    information,
 897    "Add DataNode",
 898    JOptionPane.YES_NO_OPTION,
 899    JOptionPane.PLAIN_MESSAGE,
 900    null,
 901    options,
 902    options[0]);
 903  0 if (userChoice == 0)
 904    {
 905  0 String userInput = fqnTextField.getText();
 906  0 put(Fqn.fromString(userInput), null);
 907    }
 908    }
 909    }
 910   
 911   
 912    class PrintLockInfoAction extends AbstractAction
 913    {
 914    private static final long serialVersionUID = 5577441016277949170L;
 915   
 916  0 public void actionPerformed(ActionEvent e)
 917    {
 918  0 System.out.println("\n*** lock information ****\n" + cache.getLockTable());
 919    }
 920    }
 921   
 922    class ReleaseAllLocksAction extends AbstractAction
 923    {
 924    private static final long serialVersionUID = 3796901116451916116L;
 925   
 926  0 public void actionPerformed(ActionEvent e)
 927    {
 928  0 System.out.println("TODO :-)");
 929    }
 930    }
 931   
 932    class RemoveNodeAction extends AbstractAction
 933    {
 934    private static final long serialVersionUID = 8985697625953238855L;
 935   
 936  0 public void actionPerformed(ActionEvent e)
 937    {
 938  0 try
 939    {
 940  0 cache.getRoot().removeChild(selected_node);
 941    }
 942    catch (Throwable t)
 943    {
 944  0 log.error("RemoveNodeAction.actionPerformed(): " + t);
 945    }
 946    }
 947    }
 948   
 949    class AddModifyDataForNodeAction extends AbstractAction
 950    {
 951    private static final long serialVersionUID = 3593129982953807846L;
 952   
 953  0 public void actionPerformed(ActionEvent e)
 954    {
 955  0 Map data = getData(selected_node);
 956  0 if (data != null)
 957    {
 958    }
 959    else
 960    {
 961  0 clearTable();
 962  0 data = new HashMap();
 963  0 data.put("Add Key", "Add Value");
 964   
 965    }
 966  0 populateTable(data);
 967  0 getContentPane().add(tablePanel, BorderLayout.SOUTH);
 968  0 validate();
 969   
 970    }
 971    }
 972   
 973   
 974    class MyNode extends DefaultMutableTreeNode
 975    {
 976    private static final long serialVersionUID = 1578599138419577069L;
 977    Object name = "<unnamed>";
 978   
 979   
 980  0 MyNode(Object name)
 981    {
 982  0 this.name = name;
 983    }
 984   
 985   
 986    /**
 987    * Adds a new node to the view. Intermediary nodes will be created if they don't yet exist.
 988    * Returns the first node that was created or null if node already existed
 989    */
 990  0 public MyNode add(Fqn fqn)
 991    {
 992  0 MyNode curr, n, ret = null;
 993   
 994  0 if (fqn == null) return null;
 995  0 curr = this;
 996  0 for (Object o : fqn.peekElements())
 997    {
 998  0 n = curr.findChild(o);
 999  0 if (n == null)
 1000    {
 1001  0 n = new MyNode(o.toString());
 1002  0 if (ret == null) ret = n;
 1003  0 curr.add(n);
 1004    }
 1005  0 curr = n;
 1006    }
 1007  0 return ret;
 1008    }
 1009   
 1010   
 1011    /**
 1012    * Removes a node from the view. Child nodes will be removed as well
 1013    */
 1014  0 public void remove(String fqn)
 1015    {
 1016  0 removeFromParent();
 1017    }
 1018   
 1019   
 1020  0 MyNode findNode(Fqn fqn)
 1021    {
 1022  0 MyNode curr, n;
 1023   
 1024  0 if (fqn == null) return null;
 1025  0 curr = this;
 1026  0 for (Object o : fqn.peekElements())
 1027    {
 1028  0 n = curr.findChild(o);
 1029  0 if (n == null)
 1030    {
 1031  0 return null;
 1032    }
 1033  0 curr = n;
 1034    }
 1035  0 return curr;
 1036    }
 1037   
 1038   
 1039  0 MyNode findChild(Object relative_name)
 1040    {
 1041  0 MyNode child;
 1042   
 1043  0 if (relative_name == null || getChildCount() == 0)
 1044    {
 1045  0 return null;
 1046    }
 1047  0 for (int i = 0; i < getChildCount(); i++)
 1048    {
 1049  0 child = (MyNode) getChildAt(i);
 1050  0 if (child.name == null)
 1051    {
 1052  0 continue;
 1053    }
 1054   
 1055  0 if (child.name.equals(relative_name))
 1056    {
 1057  0 return child;
 1058    }
 1059    }
 1060  0 return null;
 1061    }
 1062   
 1063   
 1064  0 String print(int indent)
 1065    {
 1066  0 StringBuffer sb = new StringBuffer();
 1067   
 1068  0 for (int i = 0; i < indent; i++)
 1069    {
 1070  0 sb.append(" ");
 1071    }
 1072  0 if (!isRoot())
 1073    {
 1074  0 if (name == null)
 1075    {
 1076  0 sb.append("/<unnamed>");
 1077    }
 1078    else
 1079    {
 1080  0 sb.append(TreeCacheGui.SEP.toString() + name);
 1081    }
 1082    }
 1083  0 sb.append("\n");
 1084  0 if (getChildCount() > 0)
 1085    {
 1086  0 if (isRoot())
 1087    {
 1088  0 indent = 0;
 1089    }
 1090    else
 1091    {
 1092  0 indent += 4;
 1093    }
 1094  0 for (int i = 0; i < getChildCount(); i++)
 1095    {
 1096  0 sb.append(((MyNode) getChildAt(i)).print(indent));
 1097    }
 1098    }
 1099  0 return sb.toString();
 1100    }
 1101   
 1102   
 1103  0 public String toString()
 1104    {
 1105  0 return name.toString();
 1106    }
 1107   
 1108    }
 1109   
 1110   
 1111    }
 1112   
 1113   
 1114   
 1115   
 1116   
 1117   
 1118   
 1119   
 1120   
 1121   
 1122   
 1123