zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From an...@apache.org
Subject [02/44] zookeeper git commit: ZOOKEEPER-3030: MAVEN MIGRATION 3.4 - Step 1.3 - move contrib directories
Date Tue, 07 Aug 2018 09:42:48 GMT
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
new file mode 100644
index 0000000..7a4efaf
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
@@ -0,0 +1,361 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JToolBar;
+import javax.swing.SwingWorker;
+
+import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+
+/**
+ * The parent {@link JPanel} for the whole application
+ */
+public class ZooInspectorPanel extends JPanel implements
+        NodeViewersChangeListener {
+    private final JButton refreshButton;
+    private final JButton disconnectButton;
+    private final JButton connectButton;
+    private final ZooInspectorNodeViewersPanel nodeViewersPanel;
+    private final ZooInspectorTreeViewer treeViewer;
+    private final ZooInspectorManager zooInspectorManager;
+    private final JButton addNodeButton;
+    private final JButton deleteNodeButton;
+    private final JButton nodeViewersButton;
+    private final JButton aboutButton;
+    private final List<NodeViewersChangeListener> listeners = new ArrayList<NodeViewersChangeListener>();
+    {
+        listeners.add(this);
+    }
+
+    /**
+     * @param zooInspectorManager
+     *            - the {@link ZooInspectorManager} for the application
+     */
+    public ZooInspectorPanel(final ZooInspectorManager zooInspectorManager) {
+        this.zooInspectorManager = zooInspectorManager;
+        final ArrayList<ZooInspectorNodeViewer> nodeViewers = new ArrayList<ZooInspectorNodeViewer>();
+        try {
+            List<String> defaultNodeViewersClassNames = this.zooInspectorManager
+                    .getDefaultNodeViewerConfiguration();
+            for (String className : defaultNodeViewersClassNames) {
+                nodeViewers.add((ZooInspectorNodeViewer) Class.forName(
+                        className).newInstance());
+            }
+        } catch (Exception ex) {
+            LoggerFactory.getLogger().error(
+                    "Error loading default node viewers.", ex);
+            JOptionPane.showMessageDialog(ZooInspectorPanel.this,
+                    "Error loading default node viewers: " + ex.getMessage(),
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
+        nodeViewersPanel = new ZooInspectorNodeViewersPanel(
+                zooInspectorManager, nodeViewers);
+        treeViewer = new ZooInspectorTreeViewer(zooInspectorManager,
+                nodeViewersPanel);
+        this.setLayout(new BorderLayout());
+        JToolBar toolbar = new JToolBar();
+        toolbar.setFloatable(false);
+        connectButton = new JButton(ZooInspectorIconResources.getConnectIcon());
+        disconnectButton = new JButton(ZooInspectorIconResources
+                .getDisconnectIcon());
+        refreshButton = new JButton(ZooInspectorIconResources.getRefreshIcon());
+        addNodeButton = new JButton(ZooInspectorIconResources.getAddNodeIcon());
+        deleteNodeButton = new JButton(ZooInspectorIconResources
+                .getDeleteNodeIcon());
+        nodeViewersButton = new JButton(ZooInspectorIconResources
+                .getChangeNodeViewersIcon());
+        aboutButton = new JButton(ZooInspectorIconResources
+                .getInformationIcon());
+        toolbar.add(connectButton);
+        toolbar.add(disconnectButton);
+        toolbar.add(refreshButton);
+        toolbar.add(addNodeButton);
+        toolbar.add(deleteNodeButton);
+        toolbar.add(nodeViewersButton);
+        toolbar.add(aboutButton);
+        aboutButton.setEnabled(true);
+        connectButton.setEnabled(true);
+        disconnectButton.setEnabled(false);
+        refreshButton.setEnabled(false);
+        addNodeButton.setEnabled(false);
+        deleteNodeButton.setEnabled(false);
+        nodeViewersButton.setEnabled(true);
+        nodeViewersButton.setToolTipText("Change Node Viewers");
+        aboutButton.setToolTipText("About ZooInspector");
+        connectButton.setToolTipText("Connect");
+        disconnectButton.setToolTipText("Disconnect");
+        refreshButton.setToolTipText("Refresh");
+        addNodeButton.setToolTipText("Add Node");
+        deleteNodeButton.setToolTipText("Delete Node");
+        connectButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorConnectionPropertiesDialog zicpd = new ZooInspectorConnectionPropertiesDialog(
+                        zooInspectorManager.getLastConnectionProps(),
+                        zooInspectorManager.getConnectionPropertiesTemplate(),
+                        ZooInspectorPanel.this);
+                zicpd.setVisible(true);
+            }
+        });
+        disconnectButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                disconnect();
+            }
+        });
+        refreshButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                treeViewer.refreshView();
+            }
+        });
+        addNodeButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                final List<String> selectedNodes = treeViewer
+                        .getSelectedNodes();
+                if (selectedNodes.size() == 1) {
+                    final String nodeName = JOptionPane.showInputDialog(
+                            ZooInspectorPanel.this,
+                            "Please Enter a name for the new node",
+                            "Create Node", JOptionPane.INFORMATION_MESSAGE);
+                    if (nodeName != null && nodeName.length() > 0) {
+                        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+                            @Override
+                            protected Boolean doInBackground() throws Exception {
+                                return ZooInspectorPanel.this.zooInspectorManager
+                                        .createNode(selectedNodes.get(0),
+                                                nodeName);
+                            }
+
+                            @Override
+                            protected void done() {
+                                treeViewer.refreshView();
+                            }
+                        };
+                        worker.execute();
+                    }
+                } else {
+                    JOptionPane.showMessageDialog(ZooInspectorPanel.this,
+                            "Please select 1 parent node for the new node.");
+                }
+            }
+        });
+        deleteNodeButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                final List<String> selectedNodes = treeViewer
+                        .getSelectedNodes();
+                if (selectedNodes.size() == 0) {
+                    JOptionPane.showMessageDialog(ZooInspectorPanel.this,
+                            "Please select at least 1 node to be deleted");
+                } else {
+                    int answer = JOptionPane.showConfirmDialog(
+                            ZooInspectorPanel.this,
+                            "Are you sure you want to delete the selected nodes?"
+                                    + "(This action cannot be reverted)",
+                            "Confirm Delete", JOptionPane.YES_NO_OPTION,
+                            JOptionPane.WARNING_MESSAGE);
+                    if (answer == JOptionPane.YES_OPTION) {
+                        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+                            @Override
+                            protected Boolean doInBackground() throws Exception {
+                                for (String nodePath : selectedNodes) {
+                                    ZooInspectorPanel.this.zooInspectorManager
+                                            .deleteNode(nodePath);
+                                }
+                                return true;
+                            }
+
+                            @Override
+                            protected void done() {
+                                treeViewer.refreshView();
+                            }
+                        };
+                        worker.execute();
+                    }
+                }
+            }
+        });
+        nodeViewersButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorNodeViewersDialog nvd = new ZooInspectorNodeViewersDialog(
+                        JOptionPane.getRootFrame(), nodeViewers, listeners,
+                        zooInspectorManager);
+                nvd.setVisible(true);
+            }
+        });
+        aboutButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorAboutDialog zicpd = new ZooInspectorAboutDialog(
+                        JOptionPane.getRootFrame());
+                zicpd.setVisible(true);
+            }
+        });
+        JScrollPane treeScroller = new JScrollPane(treeViewer);
+        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+                treeScroller, nodeViewersPanel);
+        splitPane.setResizeWeight(0.25);
+        this.add(splitPane, BorderLayout.CENTER);
+        this.add(toolbar, BorderLayout.NORTH);
+    }
+
+    /**
+     * @param connectionProps
+     *            the {@link Properties} for connecting to the zookeeper
+     *            instance
+     */
+    public void connect(final Properties connectionProps) {
+        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+            @Override
+            protected Boolean doInBackground() throws Exception {
+                zooInspectorManager.setLastConnectionProps(connectionProps);
+                return zooInspectorManager.connect(connectionProps);
+            }
+
+            @Override
+            protected void done() {
+                try {
+                    if (get()) {
+                        treeViewer.refreshView();
+                        connectButton.setEnabled(false);
+                        disconnectButton.setEnabled(true);
+                        refreshButton.setEnabled(true);
+                        addNodeButton.setEnabled(true);
+                        deleteNodeButton.setEnabled(true);
+                    } else {
+                        JOptionPane.showMessageDialog(ZooInspectorPanel.this,
+                                "Unable to connect to zookeeper", "Error",
+                                JOptionPane.ERROR_MESSAGE);
+                    }
+                } catch (InterruptedException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while connecting to ZooKeeper server",
+                                    e);
+                } catch (ExecutionException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while connecting to ZooKeeper server",
+                                    e);
+                }
+            }
+
+        };
+        worker.execute();
+    }
+
+    /**
+	 * 
+	 */
+    public void disconnect() {
+        disconnect(false);
+    }
+
+    /**
+     * @param wait
+     *            - set this to true if the method should only return once the
+     *            application has successfully disconnected
+     */
+    public void disconnect(boolean wait) {
+        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+            @Override
+            protected Boolean doInBackground() throws Exception {
+                return ZooInspectorPanel.this.zooInspectorManager.disconnect();
+            }
+
+            @Override
+            protected void done() {
+                try {
+                    if (get()) {
+                        treeViewer.clearView();
+                        connectButton.setEnabled(true);
+                        disconnectButton.setEnabled(false);
+                        refreshButton.setEnabled(false);
+                        addNodeButton.setEnabled(false);
+                        deleteNodeButton.setEnabled(false);
+                    }
+                } catch (InterruptedException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while disconnecting from ZooKeeper server",
+                                    e);
+                } catch (ExecutionException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while disconnecting from ZooKeeper server",
+                                    e);
+                }
+            }
+
+        };
+        worker.execute();
+        if (wait) {
+            while (!worker.isDone()) {
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while disconnecting from ZooKeeper server",
+                                    e);
+                }
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @seeorg.apache.zookeeper.inspector.gui.NodeViewersChangeListener#
+     * nodeViewersChanged(java.util.List)
+     */
+    public void nodeViewersChanged(List<ZooInspectorNodeViewer> newViewers) {
+        this.nodeViewersPanel.setNodeViewers(newViewers);
+    }
+
+    /**
+     * @param connectionProps
+     * @throws IOException
+     */
+    public void setdefaultConnectionProps(Properties connectionProps)
+            throws IOException {
+        this.zooInspectorManager.saveDefaultConnectionFile(connectionProps);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java
new file mode 100644
index 0000000..128b358
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorTreeViewer.java
@@ -0,0 +1,362 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JTree;
+import javax.swing.SwingWorker;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+
+import org.apache.zookeeper.inspector.manager.NodeListener;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+
+import com.nitido.utils.toaster.Toaster;
+
+/**
+ * A {@link JPanel} for showing the tree view of all the nodes in the zookeeper
+ * instance
+ */
+public class ZooInspectorTreeViewer extends JPanel implements NodeListener {
+    private final ZooInspectorManager zooInspectorManager;
+    private final JTree tree;
+    private final Toaster toasterManager;
+
+    /**
+     * @param zooInspectorManager
+     *            - the {@link ZooInspectorManager} for the application
+     * @param listener
+     *            - the {@link TreeSelectionListener} to listen for changes in
+     *            the selected node on the node tree
+     */
+    public ZooInspectorTreeViewer(
+            final ZooInspectorManager zooInspectorManager,
+            TreeSelectionListener listener) {
+        this.zooInspectorManager = zooInspectorManager;
+        this.setLayout(new BorderLayout());
+        final JPopupMenu popupMenu = new JPopupMenu();
+        final JMenuItem addNotify = new JMenuItem("Add Change Notification");
+        this.toasterManager = new Toaster();
+        this.toasterManager.setBorderColor(Color.BLACK);
+        this.toasterManager.setMessageColor(Color.BLACK);
+        this.toasterManager.setToasterColor(Color.WHITE);
+        addNotify.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                List<String> selectedNodes = getSelectedNodes();
+                zooInspectorManager.addWatchers(selectedNodes,
+                        ZooInspectorTreeViewer.this);
+            }
+        });
+        final JMenuItem removeNotify = new JMenuItem(
+                "Remove Change Notification");
+        removeNotify.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                List<String> selectedNodes = getSelectedNodes();
+                zooInspectorManager.removeWatchers(selectedNodes);
+            }
+        });
+        tree = new JTree(new DefaultMutableTreeNode());
+        tree.setCellRenderer(new ZooInspectorTreeCellRenderer());
+        tree.setEditable(false);
+        tree.getSelectionModel().addTreeSelectionListener(listener);
+        tree.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                if (e.isPopupTrigger() || e.getButton() == MouseEvent.BUTTON3) {
+                    // TODO only show add if a selected node isn't being
+                    // watched, and only show remove if a selected node is being
+                    // watched
+                    popupMenu.removeAll();
+                    popupMenu.add(addNotify);
+                    popupMenu.add(removeNotify);
+                    popupMenu.show(ZooInspectorTreeViewer.this, e.getX(), e
+                            .getY());
+                }
+            }
+        });
+        this.add(tree, BorderLayout.CENTER);
+    }
+
+    /**
+     * Refresh the tree view
+     */
+    public void refreshView() {
+        final Set<TreePath> expandedNodes = new LinkedHashSet<TreePath>();
+        int rowCount = tree.getRowCount();
+        for (int i = 0; i < rowCount; i++) {
+            TreePath path = tree.getPathForRow(i);
+            if (tree.isExpanded(path)) {
+                expandedNodes.add(path);
+            }
+        }
+        final TreePath[] selectedNodes = tree.getSelectionPaths();
+        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+            @Override
+            protected Boolean doInBackground() throws Exception {
+                tree.setModel(new DefaultTreeModel(new ZooInspectorTreeNode(
+                        "/", null)));
+                return true;
+            }
+
+            @Override
+            protected void done() {
+                for (TreePath path : expandedNodes) {
+                    tree.expandPath(path);
+                }
+                tree.getSelectionModel().setSelectionPaths(selectedNodes);
+            }
+        };
+        worker.execute();
+    }
+
+    /**
+     * clear the tree view of all nodes
+     */
+    public void clearView() {
+        tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode()));
+    }
+
+    /**
+     * @author Colin
+     * 
+     */
+    private static class ZooInspectorTreeCellRenderer extends
+            DefaultTreeCellRenderer {
+        public ZooInspectorTreeCellRenderer() {
+            setLeafIcon(ZooInspectorIconResources.getTreeLeafIcon());
+            setOpenIcon(ZooInspectorIconResources.getTreeOpenIcon());
+            setClosedIcon(ZooInspectorIconResources.getTreeClosedIcon());
+        }
+    }
+
+    /**
+     * @author Colin
+     * 
+     */
+    private class ZooInspectorTreeNode implements TreeNode {
+        private final String nodePath;
+        private final String nodeName;
+        private final ZooInspectorTreeNode parent;
+
+        public ZooInspectorTreeNode(String nodePath, ZooInspectorTreeNode parent) {
+            this.parent = parent;
+            this.nodePath = nodePath;
+            int index = nodePath.lastIndexOf("/");
+            if (index == -1) {
+                throw new IllegalArgumentException("Invalid node path"
+                        + nodePath);
+            }
+            this.nodeName = nodePath.substring(index + 1);
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#children()
+         */
+        public Enumeration<TreeNode> children() {
+            List<String> children = zooInspectorManager
+                    .getChildren(this.nodePath);
+            Collections.sort(children);
+            List<TreeNode> returnChildren = new ArrayList<TreeNode>();
+            for (String child : children) {
+                returnChildren.add(new ZooInspectorTreeNode((this.nodePath
+                        .equals("/") ? "" : this.nodePath)
+                        + "/" + child, this));
+            }
+            return Collections.enumeration(returnChildren);
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#getAllowsChildren()
+         */
+        public boolean getAllowsChildren() {
+            return zooInspectorManager.isAllowsChildren(this.nodePath);
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#getChildAt(int)
+         */
+        public TreeNode getChildAt(int childIndex) {
+            String child = zooInspectorManager.getNodeChild(this.nodePath,
+                    childIndex);
+            if (child != null) {
+                return new ZooInspectorTreeNode((this.nodePath.equals("/") ? ""
+                        : this.nodePath)
+                        + "/" + child, this);
+            }
+            return null;
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#getChildCount()
+         */
+        public int getChildCount() {
+            return zooInspectorManager.getNumChildren(this.nodePath);
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#getIndex(javax.swing.tree.TreeNode)
+         */
+        public int getIndex(TreeNode node) {
+            return zooInspectorManager.getNodeIndex(this.nodePath);
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#getParent()
+         */
+        public TreeNode getParent() {
+            return this.parent;
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.swing.tree.TreeNode#isLeaf()
+         */
+        public boolean isLeaf() {
+            return !zooInspectorManager.hasChildren(this.nodePath);
+        }
+
+        @Override
+        public String toString() {
+            return this.nodeName;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + getOuterType().hashCode();
+            result = prime * result
+                    + ((nodePath == null) ? 0 : nodePath.hashCode());
+            result = prime * result
+                    + ((parent == null) ? 0 : parent.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            ZooInspectorTreeNode other = (ZooInspectorTreeNode) obj;
+            if (!getOuterType().equals(other.getOuterType()))
+                return false;
+            if (nodePath == null) {
+                if (other.nodePath != null)
+                    return false;
+            } else if (!nodePath.equals(other.nodePath))
+                return false;
+            if (parent == null) {
+                if (other.parent != null)
+                    return false;
+            } else if (!parent.equals(other.parent))
+                return false;
+            return true;
+        }
+
+        private ZooInspectorTreeViewer getOuterType() {
+            return ZooInspectorTreeViewer.this;
+        }
+
+    }
+
+    /**
+     * @return {@link List} of the currently selected nodes
+     */
+    public List<String> getSelectedNodes() {
+        TreePath[] paths = tree.getSelectionPaths();
+        List<String> selectedNodes = new ArrayList<String>();
+        if (paths != null) {
+            for (TreePath path : paths) {
+                StringBuilder sb = new StringBuilder();
+                Object[] pathArray = path.getPath();
+                for (Object o : pathArray) {
+                    String nodeName = o.toString();
+                    if (nodeName.length() > 0) {
+                        sb.append("/");
+                        sb.append(o.toString());
+                    }
+                }
+                selectedNodes.add(sb.toString());
+            }
+        }
+        return selectedNodes;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.manager.NodeListener#processEvent(java
+     * .lang.String, java.lang.String, java.util.Map)
+     */
+    public void processEvent(String nodePath, String eventType,
+            Map<String, String> eventInfo) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Node: ");
+        sb.append(nodePath);
+        sb.append("\nEvent: ");
+        sb.append(eventType);
+        if (eventInfo != null) {
+            for (Map.Entry<String, String> entry : eventInfo.entrySet()) {
+                sb.append("\n");
+                sb.append(entry.getKey());
+                sb.append(": ");
+                sb.append(entry.getValue());
+            }
+        }
+        this.toasterManager.showToaster(ZooInspectorIconResources
+                .getInformationIcon(), sb.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/about.html
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/about.html b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/about.html
new file mode 100644
index 0000000..17fb3dc
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/about.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>ZooInspector v0.1</title>
+</head>
+<body>
+<p>ZooInspector was developed by Colin Goodheart-Smithe and is
+available under the Apache Software Licence v2.0.</p>
+<p>The Icons used were sourced from the Eclipse project (<a
+	href="http://www.eclipse.org">http://www.eclipse.org</a>) and licensed
+under the Eclipse Public Licence v1.0. [<a
+	href="http://www.eclipse.org/org/documents/epl-v10.php">http://www.eclipse.org/org/documents/epl-v10.php</a>]
+</p>
+<p>ZooKeeper is available from <a
+	href="http://zookeeper.apache.org/">http://zookeeper.apache.org/</a>
+and is licensed under an Apache Software Licence v2.0</p>
+<p>The ApacheSoftware Licence v2.0 can be found at <a
+	href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a></p>
+</body>
+</html>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerACL.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerACL.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerACL.java
new file mode 100644
index 0000000..5ac203c
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerACL.java
@@ -0,0 +1,187 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui.nodeviewer;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.SwingWorker;
+
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager;
+
+/**
+ * A node viewer for displaying the ACLs currently applied to the selected node
+ */
+public class NodeViewerACL extends ZooInspectorNodeViewer {
+    private ZooInspectorNodeManager zooInspectorManager;
+    private final JPanel aclDataPanel;
+    private String selectedNode;
+
+    /**
+	 * 
+	 */
+    public NodeViewerACL() {
+        this.setLayout(new BorderLayout());
+        this.aclDataPanel = new JPanel();
+        this.aclDataPanel.setBackground(Color.WHITE);
+        JScrollPane scroller = new JScrollPane(this.aclDataPanel);
+        this.add(scroller, BorderLayout.CENTER);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * getTitle()
+     */
+    @Override
+    public String getTitle() {
+        return "Node ACLs";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * nodeSelectionChanged(java.util.Set)
+     */
+    @Override
+    public void nodeSelectionChanged(List<String> selectedNodes) {
+        this.aclDataPanel.removeAll();
+        if (selectedNodes.size() > 0) {
+            this.selectedNode = selectedNodes.get(0);
+            SwingWorker<List<Map<String, String>>, Void> worker = new SwingWorker<List<Map<String, String>>, Void>() {
+
+                @Override
+                protected List<Map<String, String>> doInBackground()
+                        throws Exception {
+                    return NodeViewerACL.this.zooInspectorManager
+                            .getACLs(NodeViewerACL.this.selectedNode);
+                }
+
+                @Override
+                protected void done() {
+                    List<Map<String, String>> acls = null;
+                    try {
+                        acls = get();
+                    } catch (InterruptedException e) {
+                        acls = new ArrayList<Map<String, String>>();
+                        LoggerFactory.getLogger().error(
+                                "Error retrieving ACL Information for node: "
+                                        + NodeViewerACL.this.selectedNode, e);
+                    } catch (ExecutionException e) {
+                        acls = new ArrayList<Map<String, String>>();
+                        LoggerFactory.getLogger().error(
+                                "Error retrieving ACL Information for node: "
+                                        + NodeViewerACL.this.selectedNode, e);
+                    }
+                    aclDataPanel.setLayout(new GridBagLayout());
+                    int j = 0;
+                    for (Map<String, String> data : acls) {
+                        int rowPos = 2 * j + 1;
+                        JPanel aclPanel = new JPanel();
+                        aclPanel.setBorder(BorderFactory
+                                .createLineBorder(Color.BLACK));
+                        aclPanel.setBackground(Color.WHITE);
+                        aclPanel.setLayout(new GridBagLayout());
+                        int i = 0;
+                        for (Map.Entry<String, String> entry : data.entrySet()) {
+                            int rowPosACL = 2 * i + 1;
+                            JLabel label = new JLabel(entry.getKey());
+                            JTextField text = new JTextField(entry.getValue());
+                            text.setEditable(false);
+                            GridBagConstraints c1 = new GridBagConstraints();
+                            c1.gridx = 1;
+                            c1.gridy = rowPosACL;
+                            c1.gridwidth = 1;
+                            c1.gridheight = 1;
+                            c1.weightx = 0;
+                            c1.weighty = 0;
+                            c1.anchor = GridBagConstraints.NORTHWEST;
+                            c1.fill = GridBagConstraints.BOTH;
+                            c1.insets = new Insets(5, 5, 5, 5);
+                            c1.ipadx = 0;
+                            c1.ipady = 0;
+                            aclPanel.add(label, c1);
+                            GridBagConstraints c2 = new GridBagConstraints();
+                            c2.gridx = 3;
+                            c2.gridy = rowPosACL;
+                            c2.gridwidth = 1;
+                            c2.gridheight = 1;
+                            c2.weightx = 0;
+                            c2.weighty = 0;
+                            c2.anchor = GridBagConstraints.NORTHWEST;
+                            c2.fill = GridBagConstraints.BOTH;
+                            c2.insets = new Insets(5, 5, 5, 5);
+                            c2.ipadx = 0;
+                            c2.ipady = 0;
+                            aclPanel.add(text, c2);
+                            i++;
+                        }
+                        GridBagConstraints c = new GridBagConstraints();
+                        c.gridx = 1;
+                        c.gridy = rowPos;
+                        c.gridwidth = 1;
+                        c.gridheight = 1;
+                        c.weightx = 1;
+                        c.weighty = 1;
+                        c.anchor = GridBagConstraints.NORTHWEST;
+                        c.fill = GridBagConstraints.NONE;
+                        c.insets = new Insets(5, 5, 5, 5);
+                        c.ipadx = 0;
+                        c.ipady = 0;
+                        aclDataPanel.add(aclPanel, c);
+                    }
+                    NodeViewerACL.this.aclDataPanel.revalidate();
+                    NodeViewerACL.this.aclDataPanel.repaint();
+                }
+            };
+            worker.execute();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * setZooInspectorManager
+     * (org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager)
+     */
+    @Override
+    public void setZooInspectorManager(
+            ZooInspectorNodeManager zooInspectorManager) {
+        this.zooInspectorManager = zooInspectorManager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerData.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerData.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerData.java
new file mode 100644
index 0000000..001cb7b
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerData.java
@@ -0,0 +1,146 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui.nodeviewer;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextPane;
+import javax.swing.JToolBar;
+import javax.swing.SwingWorker;
+
+import org.apache.zookeeper.inspector.gui.ZooInspectorIconResources;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager;
+
+/**
+ * A node viewer for displaying the data for the currently selected node
+ */
+public class NodeViewerData extends ZooInspectorNodeViewer {
+    private ZooInspectorNodeManager zooInspectorManager;
+    private final JTextPane dataArea;
+    private final JToolBar toolbar;
+    private String selectedNode;
+
+    /**
+	 * 
+	 */
+    public NodeViewerData() {
+        this.setLayout(new BorderLayout());
+        this.dataArea = new JTextPane();
+        this.toolbar = new JToolBar();
+        this.toolbar.setFloatable(false);
+        JScrollPane scroller = new JScrollPane(this.dataArea);
+        scroller
+                .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+        this.add(scroller, BorderLayout.CENTER);
+        this.add(this.toolbar, BorderLayout.NORTH);
+        JButton saveButton = new JButton(ZooInspectorIconResources
+                .getSaveIcon());
+        saveButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                if (selectedNode != null) {
+                    if (JOptionPane.showConfirmDialog(NodeViewerData.this,
+                            "Are you sure you want to save this node?"
+                                    + " (this action cannot be reverted)",
+                            "Confirm Save", JOptionPane.YES_NO_OPTION,
+                            JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) {
+                        zooInspectorManager.setData(selectedNode, dataArea
+                                .getText());
+                    }
+                }
+            }
+        });
+        this.toolbar.add(saveButton);
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * getTitle()
+     */
+    @Override
+    public String getTitle() {
+        return "Node Data";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * nodeSelectionChanged(java.util.Set)
+     */
+    @Override
+    public void nodeSelectionChanged(List<String> selectedNodes) {
+        if (selectedNodes.size() > 0) {
+            this.selectedNode = selectedNodes.get(0);
+            SwingWorker<String, Void> worker = new SwingWorker<String, Void>() {
+
+                @Override
+                protected String doInBackground() throws Exception {
+                    return NodeViewerData.this.zooInspectorManager
+                            .getData(NodeViewerData.this.selectedNode);
+                }
+
+                @Override
+                protected void done() {
+                    String data = "";
+                    try {
+                        data = get();
+                    } catch (InterruptedException e) {
+                        LoggerFactory.getLogger().error(
+                                "Error retrieving data for node: "
+                                        + NodeViewerData.this.selectedNode, e);
+                    } catch (ExecutionException e) {
+                        LoggerFactory.getLogger().error(
+                                "Error retrieving data for node: "
+                                        + NodeViewerData.this.selectedNode, e);
+                    }
+                    NodeViewerData.this.dataArea.setText(data);
+                }
+            };
+            worker.execute();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * setZooInspectorManager
+     * (org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager)
+     */
+    @Override
+    public void setZooInspectorManager(
+            ZooInspectorNodeManager zooInspectorManager) {
+        this.zooInspectorManager = zooInspectorManager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerMetaData.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerMetaData.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerMetaData.java
new file mode 100644
index 0000000..5c2df8d
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/NodeViewerMetaData.java
@@ -0,0 +1,186 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui.nodeviewer;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.SwingWorker;
+
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager;
+
+/**
+ * A node viewer for displaying the meta data for the currently selected node.
+ * The meta data is essentially the information from the {@link Stat} for the
+ * node
+ */
+public class NodeViewerMetaData extends ZooInspectorNodeViewer {
+    private ZooInspectorNodeManager zooInspectorManager;
+    private final JPanel metaDataPanel;
+    private String selectedNode;
+
+    /**
+	 * 
+	 */
+    public NodeViewerMetaData() {
+        this.setLayout(new BorderLayout());
+        this.metaDataPanel = new JPanel();
+        this.metaDataPanel.setBackground(Color.WHITE);
+        JScrollPane scroller = new JScrollPane(this.metaDataPanel);
+        this.add(scroller, BorderLayout.CENTER);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * getTitle()
+     */
+    @Override
+    public String getTitle() {
+        return "Node Metadata";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * nodeSelectionChanged(java.util.Set)
+     */
+    @Override
+    public void nodeSelectionChanged(List<String> selectedNodes) {
+        this.metaDataPanel.removeAll();
+        if (selectedNodes.size() > 0) {
+            this.selectedNode = selectedNodes.get(0);
+            SwingWorker<Map<String, String>, Void> worker = new SwingWorker<Map<String, String>, Void>() {
+
+                @Override
+                protected Map<String, String> doInBackground() throws Exception {
+                    return NodeViewerMetaData.this.zooInspectorManager
+                            .getNodeMeta(NodeViewerMetaData.this.selectedNode);
+                }
+
+                @Override
+                protected void done() {
+                    Map<String, String> data = null;
+                    try {
+                        data = get();
+                    } catch (InterruptedException e) {
+                        data = new HashMap<String, String>();
+                        LoggerFactory.getLogger().error(
+                                "Error retrieving meta data for node: "
+                                        + NodeViewerMetaData.this.selectedNode,
+                                e);
+                    } catch (ExecutionException e) {
+                        data = new HashMap<String, String>();
+                        LoggerFactory.getLogger().error(
+                                "Error retrieving meta data for node: "
+                                        + NodeViewerMetaData.this.selectedNode,
+                                e);
+                    }
+                    NodeViewerMetaData.this.metaDataPanel
+                            .setLayout(new GridBagLayout());
+                    JPanel infoPanel = new JPanel();
+                    infoPanel.setBackground(Color.WHITE);
+                    infoPanel.setLayout(new GridBagLayout());
+                    int i = 0;
+                    int rowPos = 0;
+                    for (Map.Entry<String, String> entry : data.entrySet()) {
+                        rowPos = 2 * i + 1;
+                        JLabel label = new JLabel(entry.getKey());
+                        JTextField text = new JTextField(entry.getValue());
+                        text.setEditable(false);
+                        GridBagConstraints c1 = new GridBagConstraints();
+                        c1.gridx = 0;
+                        c1.gridy = rowPos;
+                        c1.gridwidth = 1;
+                        c1.gridheight = 1;
+                        c1.weightx = 0;
+                        c1.weighty = 0;
+                        c1.anchor = GridBagConstraints.WEST;
+                        c1.fill = GridBagConstraints.HORIZONTAL;
+                        c1.insets = new Insets(5, 5, 5, 5);
+                        c1.ipadx = 0;
+                        c1.ipady = 0;
+                        infoPanel.add(label, c1);
+                        GridBagConstraints c2 = new GridBagConstraints();
+                        c2.gridx = 2;
+                        c2.gridy = rowPos;
+                        c2.gridwidth = 1;
+                        c2.gridheight = 1;
+                        c2.weightx = 0;
+                        c2.weighty = 0;
+                        c2.anchor = GridBagConstraints.WEST;
+                        c2.fill = GridBagConstraints.HORIZONTAL;
+                        c2.insets = new Insets(5, 5, 5, 5);
+                        c2.ipadx = 0;
+                        c2.ipady = 0;
+                        infoPanel.add(text, c2);
+                        i++;
+                    }
+                    GridBagConstraints c = new GridBagConstraints();
+                    c.gridx = 1;
+                    c.gridy = rowPos;
+                    c.gridwidth = 1;
+                    c.gridheight = 1;
+                    c.weightx = 1;
+                    c.weighty = 1;
+                    c.anchor = GridBagConstraints.NORTHWEST;
+                    c.fill = GridBagConstraints.NONE;
+                    c.insets = new Insets(5, 5, 5, 5);
+                    c.ipadx = 0;
+                    c.ipady = 0;
+                    NodeViewerMetaData.this.metaDataPanel.add(infoPanel, c);
+                    NodeViewerMetaData.this.metaDataPanel.revalidate();
+                    NodeViewerMetaData.this.metaDataPanel.repaint();
+                }
+            };
+            worker.execute();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer#
+     * setZooInspectorManager
+     * (org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager)
+     */
+    @Override
+    public void setZooInspectorManager(
+            ZooInspectorNodeManager zooInspectorManager) {
+        this.zooInspectorManager = zooInspectorManager;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/ZooInspectorNodeViewer.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/ZooInspectorNodeViewer.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/ZooInspectorNodeViewer.java
new file mode 100644
index 0000000..32119a8
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/nodeviewer/ZooInspectorNodeViewer.java
@@ -0,0 +1,138 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui.nodeviewer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.util.List;
+
+import javax.swing.JPanel;
+
+import org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager;
+
+/**
+ * A {@link JPanel} for displaying information about the currently selected
+ * node(s)
+ */
+public abstract class ZooInspectorNodeViewer extends JPanel implements
+        Transferable {
+    /**
+     * The {@link DataFlavor} used for DnD in the node viewer configuration
+     * dialog
+     */
+    public static final DataFlavor nodeViewerDataFlavor = new DataFlavor(
+            ZooInspectorNodeViewer.class, "nodeviewer");
+
+    /**
+     * @param zooInspectorManager
+     */
+    public abstract void setZooInspectorManager(
+            ZooInspectorNodeManager zooInspectorManager);
+
+    /**
+     * Called whenever the selected nodes in the tree view changes.
+     * 
+     * @param selectedNodes
+     *            - the nodes currently selected in the tree view
+     * 
+     */
+    public abstract void nodeSelectionChanged(List<String> selectedNodes);
+
+    /**
+     * @return the title of the node viewer. this will be shown on the tab for
+     *         this node viewer.
+     */
+    public abstract String getTitle();
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * java.awt.datatransfer.Transferable#getTransferData(java.awt.datatransfer
+     * .DataFlavor)
+     */
+    public Object getTransferData(DataFlavor flavor)
+            throws UnsupportedFlavorException, IOException {
+        if (flavor.equals(nodeViewerDataFlavor)) {
+            return this.getClass().getCanonicalName();
+        } else {
+            return null;
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.awt.datatransfer.Transferable#getTransferDataFlavors()
+     */
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[] { nodeViewerDataFlavor };
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @seejava.awt.datatransfer.Transferable#isDataFlavorSupported(java.awt.
+     * datatransfer.DataFlavor)
+     */
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        return flavor.equals(nodeViewerDataFlavor);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((getTitle() == null) ? 0 : getTitle().hashCode());
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ZooInspectorNodeViewer other = (ZooInspectorNodeViewer) obj;
+        if (getClass().getCanonicalName() != other.getClass()
+                .getCanonicalName()) {
+            return false;
+        }
+        if (getTitle() == null) {
+            if (other.getTitle() != null)
+                return false;
+        } else if (!getTitle().equals(other.getTitle()))
+            return false;
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/logger/LoggerFactory.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/logger/LoggerFactory.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/logger/LoggerFactory.java
new file mode 100644
index 0000000..e4fae41
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/logger/LoggerFactory.java
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.logger;
+
+/**
+ * Provides a {@link Logger} for use across the entire application
+ * 
+ */
+public class LoggerFactory
+{
+	private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger("org.apache.zookeeper.inspector"); //$NON-NLS-1$
+
+	/**
+	 * @return {@link Logger} for ZooInspector
+	 */
+	public static org.slf4j.Logger getLogger()
+	{
+		return logger;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/NodeListener.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/NodeListener.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/NodeListener.java
new file mode 100644
index 0000000..fe55a45
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/NodeListener.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.manager;
+
+import java.util.Map;
+
+/**
+ * A Listener for Events on zookeeper nodes
+ */
+public interface NodeListener {
+    /**
+     * @param nodePath
+     *            - the path of the node
+     * @param eventType
+     *            - the event type
+     * @param eventInfo
+     *            - a {@link Map} containing any other information about this
+     *            event
+     */
+    public void processEvent(String nodePath, String eventType,
+            Map<String, String> eventInfo);
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/Pair.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/Pair.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/Pair.java
new file mode 100644
index 0000000..b72950c
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/Pair.java
@@ -0,0 +1,120 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.manager;
+
+/**
+ * A utility class for storing a pair of objects
+ * 
+ * @param <K>
+ * @param <V>
+ */
+public class Pair<K, V> {
+    private K key;
+    private V value;
+
+    /**
+     * @param key
+     * @param value
+     */
+    public Pair(K key, V value) {
+        this.key = key;
+        this.value = value;
+    }
+
+    /**
+	 * 
+	 */
+    public Pair() {
+        // Do Nothing
+    }
+
+    /**
+     * @return key
+     */
+    public K getKey() {
+        return key;
+    }
+
+    /**
+     * @param key
+     */
+    public void setKey(K key) {
+        this.key = key;
+    }
+
+    /**
+     * @return value
+     */
+    public V getValue() {
+        return value;
+    }
+
+    /**
+     * @param value
+     */
+    public void setValue(V value) {
+        this.value = value;
+    }
+
+    @Override
+    public String toString() {
+        return "Pair [" + key + ", " + value + "]";
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((key == null) ? 0 : key.hashCode());
+        result = prime * result + ((value == null) ? 0 : value.hashCode());
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Pair<?, ?> other = (Pair<?, ?>) obj;
+        if (key == null) {
+            if (other.key != null)
+                return false;
+        } else if (!key.equals(other.key))
+            return false;
+        if (value == null) {
+            if (other.value != null)
+                return false;
+        } else if (!value.equals(other.value))
+            return false;
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/ZooInspectorManager.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/ZooInspectorManager.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/ZooInspectorManager.java
new file mode 100644
index 0000000..74c3cb2
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/manager/ZooInspectorManager.java
@@ -0,0 +1,139 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.manager;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.swing.JComboBox;
+import javax.swing.JTextField;
+
+/**
+ * A Manager for all interactions between the application and the Zookeeper
+ * instance
+ */
+public interface ZooInspectorManager extends ZooInspectorNodeManager,
+        ZooInspectorNodeTreeManager {
+
+    /**
+     * @param connectionProps
+     * @return true if successfully connected
+     */
+    public boolean connect(Properties connectionProps);
+
+    /**
+     * @return true if successfully disconnected
+     */
+    public boolean disconnect();
+
+    /**
+     * @return a {@link Pair} containing the following:
+     *         <ul>
+     *         <li>a {@link Map} of property keys to list of possible values. If
+     *         the list size is 1 the value is taken to be the default value for
+     *         a {@link JTextField}. If the list size is greater than 1, the
+     *         values are taken to be the possible options to show in a
+     *         {@link JComboBox} with the first selected as default.</li>
+     *         <li>a {@link Map} of property keys to the label to show on the UI
+     *         </li>
+     *         <ul>
+     * 
+     */
+    public Pair<Map<String, List<String>>, Map<String, String>> getConnectionPropertiesTemplate();
+
+    /**
+     * @param selectedNodes
+     *            - the nodes to add the watcher to
+     * @param nodeListener
+     *            - the node listener for this watcher
+     */
+    public void addWatchers(Collection<String> selectedNodes,
+            NodeListener nodeListener);
+
+    /**
+     * @param selectedNodes
+     *            - the nodes to remove the watchers from
+     */
+    public void removeWatchers(Collection<String> selectedNodes);
+
+    /**
+     * @param selectedFile
+     *            - the file to load which contains the node viewers
+     *            configuration
+     * @return nodeViewers - the class names of the node viewers from the
+     *         configuration
+     * @throws IOException
+     *             - if the configuration file cannot be loaded
+     */
+    public List<String> loadNodeViewersFile(File selectedFile)
+            throws IOException;
+
+    /**
+     * @param selectedFile
+     *            - the file to save the configuration to
+     * @param nodeViewersClassNames
+     *            - the class names of the node viewers
+     * @throws IOException
+     *             - if the configuration file cannot be saved
+     */
+    public void saveNodeViewersFile(File selectedFile,
+            List<String> nodeViewersClassNames) throws IOException;
+
+    /**
+     * @param nodeViewersClassNames
+     *            - the class names of the node viewers
+     * @throws IOException
+     *             - if the default configuration file cannot be loaded
+     */
+    public void setDefaultNodeViewerConfiguration(
+            List<String> nodeViewersClassNames) throws IOException;
+
+    /**
+     * @return nodeViewers - the class names of the node viewers from the
+     *         configuration
+     * @throws IOException
+     *             - if the default configuration file cannot be loaded
+     */
+    List<String> getDefaultNodeViewerConfiguration() throws IOException;
+
+    /**
+     * @param connectionProps
+     *            - the connection properties last used to connect to the
+     *            zookeeeper instance
+     */
+    public void setLastConnectionProps(Properties connectionProps);
+
+    /**
+     * @return last connection Properties - the connection properties last used
+     *         to connect to the zookeeeper instance
+     */
+    public Properties getLastConnectionProps();
+
+    /**
+     * @param props
+     *            - the properties to use as the default connection settings
+     * @throws IOException
+     *             - if the default configuration file cannot be saved
+     */
+    public void saveDefaultConnectionFile(Properties props) throws IOException;
+
+}


Mime
View raw message