/**
* 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);
}
}