http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/licences/epl-v10.html ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/licences/epl-v10.html b/zookeeper-contrib/zookeeper-contrib-zooinspector/licences/epl-v10.html new file mode 100644 index 0000000..fd39122 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/licences/epl-v10.html @@ -0,0 +1,261 @@ +<?xml version="1.0" encoding="ISO-8859-1" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> + +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> +<title>Eclipse Public License - Version 1.0</title> +<style type="text/css"> + body { + size: 8.5in 11.0in; + margin: 0.25in 0.5in 0.25in 0.5in; + tab-interval: 0.5in; + } + p { + margin-left: auto; + margin-top: 0.5em; + margin-bottom: 0.5em; + } + p.list { + margin-left: 0.5in; + margin-top: 0.05em; + margin-bottom: 0.05em; + } + </style> + +</head> + +<body lang="EN-US"> + +<h2>Eclipse Public License - v 1.0</h2> + +<p>THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE +PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR +DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS +AGREEMENT.</p> + +<p><b>1. DEFINITIONS</b></p> + +<p>"Contribution" means:</p> + +<p class="list">a) in the case of the initial Contributor, the initial +code and documentation distributed under this Agreement, and</p> +<p class="list">b) in the case of each subsequent Contributor:</p> +<p class="list">i) changes to the Program, and</p> +<p class="list">ii) additions to the Program;</p> +<p class="list">where such changes and/or additions to the Program +originate from and are distributed by that particular Contributor. A +Contribution 'originates' from a Contributor if it was added to the +Program by such Contributor itself or anyone acting on such +Contributor's behalf. Contributions do not include additions to the +Program which: (i) are separate modules of software distributed in +conjunction with the Program under their own license agreement, and (ii) +are not derivative works of the Program.</p> + +<p>"Contributor" means any person or entity that distributes +the Program.</p> + +<p>"Licensed Patents" mean patent claims licensable by a +Contributor which are necessarily infringed by the use or sale of its +Contribution alone or when combined with the Program.</p> + +<p>"Program" means the Contributions distributed in accordance +with this Agreement.</p> + +<p>"Recipient" means anyone who receives the Program under +this Agreement, including all Contributors.</p> + +<p><b>2. GRANT OF RIGHTS</b></p> + +<p class="list">a) Subject to the terms of this Agreement, each +Contributor hereby grants Recipient a non-exclusive, worldwide, +royalty-free copyright license to reproduce, prepare derivative works +of, publicly display, publicly perform, distribute and sublicense the +Contribution of such Contributor, if any, and such derivative works, in +source code and object code form.</p> + +<p class="list">b) Subject to the terms of this Agreement, each +Contributor hereby grants Recipient a non-exclusive, worldwide, +royalty-free patent license under Licensed Patents to make, use, sell, +offer to sell, import and otherwise transfer the Contribution of such +Contributor, if any, in source code and object code form. This patent +license shall apply to the combination of the Contribution and the +Program if, at the time the Contribution is added by the Contributor, +such addition of the Contribution causes such combination to be covered +by the Licensed Patents. The patent license shall not apply to any other +combinations which include the Contribution. No hardware per se is +licensed hereunder.</p> + +<p class="list">c) Recipient understands that although each Contributor +grants the licenses to its Contributions set forth herein, no assurances +are provided by any Contributor that the Program does not infringe the +patent or other intellectual property rights of any other entity. Each +Contributor disclaims any liability to Recipient for claims brought by +any other entity based on infringement of intellectual property rights +or otherwise. As a condition to exercising the rights and licenses +granted hereunder, each Recipient hereby assumes sole responsibility to +secure any other intellectual property rights needed, if any. For +example, if a third party patent license is required to allow Recipient +to distribute the Program, it is Recipient's responsibility to acquire +that license before distributing the Program.</p> + +<p class="list">d) Each Contributor represents that to its knowledge it +has sufficient copyright rights in its Contribution, if any, to grant +the copyright license set forth in this Agreement.</p> + +<p><b>3. REQUIREMENTS</b></p> + +<p>A Contributor may choose to distribute the Program in object code +form under its own license agreement, provided that:</p> + +<p class="list">a) it complies with the terms and conditions of this +Agreement; and</p> + +<p class="list">b) its license agreement:</p> + +<p class="list">i) effectively disclaims on behalf of all Contributors +all warranties and conditions, express and implied, including warranties +or conditions of title and non-infringement, and implied warranties or +conditions of merchantability and fitness for a particular purpose;</p> + +<p class="list">ii) effectively excludes on behalf of all Contributors +all liability for damages, including direct, indirect, special, +incidental and consequential damages, such as lost profits;</p> + +<p class="list">iii) states that any provisions which differ from this +Agreement are offered by that Contributor alone and not by any other +party; and</p> + +<p class="list">iv) states that source code for the Program is available +from such Contributor, and informs licensees how to obtain it in a +reasonable manner on or through a medium customarily used for software +exchange.</p> + +<p>When the Program is made available in source code form:</p> + +<p class="list">a) it must be made available under this Agreement; and</p> + +<p class="list">b) a copy of this Agreement must be included with each +copy of the Program.</p> + +<p>Contributors may not remove or alter any copyright notices contained +within the Program.</p> + +<p>Each Contributor must identify itself as the originator of its +Contribution, if any, in a manner that reasonably allows subsequent +Recipients to identify the originator of the Contribution.</p> + +<p><b>4. COMMERCIAL DISTRIBUTION</b></p> + +<p>Commercial distributors of software may accept certain +responsibilities with respect to end users, business partners and the +like. While this license is intended to facilitate the commercial use of +the Program, the Contributor who includes the Program in a commercial +product offering should do so in a manner which does not create +potential liability for other Contributors. Therefore, if a Contributor +includes the Program in a commercial product offering, such Contributor +("Commercial Contributor") hereby agrees to defend and +indemnify every other Contributor ("Indemnified Contributor") +against any losses, damages and costs (collectively "Losses") +arising from claims, lawsuits and other legal actions brought by a third +party against the Indemnified Contributor to the extent caused by the +acts or omissions of such Commercial Contributor in connection with its +distribution of the Program in a commercial product offering. The +obligations in this section do not apply to any claims or Losses +relating to any actual or alleged intellectual property infringement. In +order to qualify, an Indemnified Contributor must: a) promptly notify +the Commercial Contributor in writing of such claim, and b) allow the +Commercial Contributor to control, and cooperate with the Commercial +Contributor in, the defense and any related settlement negotiations. The +Indemnified Contributor may participate in any such claim at its own +expense.</p> + +<p>For example, a Contributor might include the Program in a commercial +product offering, Product X. That Contributor is then a Commercial +Contributor. If that Commercial Contributor then makes performance +claims, or offers warranties related to Product X, those performance +claims and warranties are such Commercial Contributor's responsibility +alone. Under this section, the Commercial Contributor would have to +defend claims against the other Contributors related to those +performance claims and warranties, and if a court requires any other +Contributor to pay any damages as a result, the Commercial Contributor +must pay those damages.</p> + +<p><b>5. NO WARRANTY</b></p> + +<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS +PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS +OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, +ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY +OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely +responsible for determining the appropriateness of using and +distributing the Program and assumes all risks associated with its +exercise of rights under this Agreement , including but not limited to +the risks and costs of program errors, compliance with applicable laws, +damage to or loss of data, programs or equipment, and unavailability or +interruption of operations.</p> + +<p><b>6. DISCLAIMER OF LIABILITY</b></p> + +<p>EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT +NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING +WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR +DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED +HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p> + +<p><b>7. GENERAL</b></p> + +<p>If any provision of this Agreement is invalid or unenforceable under +applicable law, it shall not affect the validity or enforceability of +the remainder of the terms of this Agreement, and without further action +by the parties hereto, such provision shall be reformed to the minimum +extent necessary to make such provision valid and enforceable.</p> + +<p>If Recipient institutes patent litigation against any entity +(including a cross-claim or counterclaim in a lawsuit) alleging that the +Program itself (excluding combinations of the Program with other +software or hardware) infringes such Recipient's patent(s), then such +Recipient's rights granted under Section 2(b) shall terminate as of the +date such litigation is filed.</p> + +<p>All Recipient's rights under this Agreement shall terminate if it +fails to comply with any of the material terms or conditions of this +Agreement and does not cure such failure in a reasonable period of time +after becoming aware of such noncompliance. If all Recipient's rights +under this Agreement terminate, Recipient agrees to cease use and +distribution of the Program as soon as reasonably practicable. However, +Recipient's obligations under this Agreement and any licenses granted by +Recipient relating to the Program shall continue and survive.</p> + +<p>Everyone is permitted to copy and distribute copies of this +Agreement, but in order to avoid inconsistency the Agreement is +copyrighted and may only be modified in the following manner. The +Agreement Steward reserves the right to publish new versions (including +revisions) of this Agreement from time to time. No one other than the +Agreement Steward has the right to modify this Agreement. The Eclipse +Foundation is the initial Agreement Steward. The Eclipse Foundation may +assign the responsibility to serve as the Agreement Steward to a +suitable separate entity. Each new version of the Agreement will be +given a distinguishing version number. The Program (including +Contributions) may always be distributed subject to the version of the +Agreement under which it was received. In addition, after a new version +of the Agreement is published, Contributor may elect to distribute the +Program (including its Contributions) under the new version. Except as +expressly stated in Sections 2(a) and 2(b) above, Recipient receives no +rights or licenses to the intellectual property of any Contributor under +this Agreement, whether expressly, by implication, estoppel or +otherwise. All rights in the Program not expressly granted under this +Agreement are reserved.</p> + +<p>This Agreement is governed by the laws of the State of New York and +the intellectual property laws of the United States of America. No party +to this Agreement will bring a legal action under this Agreement more +than one year after the cause of action arose. Each party waives its +rights to a jury trial in any resulting litigation.</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/ZooInspector.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java new file mode 100644 index 0000000..b637bfd --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java @@ -0,0 +1,66 @@ +/** + * 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; + +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.UIManager; + +import org.apache.zookeeper.inspector.gui.ZooInspectorPanel; +import org.apache.zookeeper.inspector.logger.LoggerFactory; +import org.apache.zookeeper.inspector.manager.ZooInspectorManagerImpl; + +/** + * + */ +public class ZooInspector { + /** + * @param args + * - not used. The value of these parameters will have no effect + * on the application + */ + public static void main(String[] args) { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + JFrame frame = new JFrame("ZooInspector"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + final ZooInspectorPanel zooInspectorPanel = new ZooInspectorPanel( + new ZooInspectorManagerImpl()); + frame.addWindowListener(new WindowAdapter() { + @Override + public void windowClosed(WindowEvent e) { + super.windowClosed(e); + zooInspectorPanel.disconnect(true); + } + }); + + frame.setContentPane(zooInspectorPanel); + frame.setSize(1024, 768); + frame.setVisible(true); + } catch (Exception e) { + LoggerFactory.getLogger().error( + "Error occurred loading ZooInspector", e); + JOptionPane.showMessageDialog(null, + "ZooInspector failed to start: " + e.getMessage(), "Error", + JOptionPane.ERROR_MESSAGE); + } + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java new file mode 100644 index 0000000..a9e5ac4 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java @@ -0,0 +1,50 @@ +/** + * 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.encryption; + +/** + * + */ +public class BasicDataEncryptionManager implements DataEncryptionManager { + + /* + * (non-Javadoc) + * + * @see + * org.apache.zookeeper.inspector.encryption.DataEncryptionManager#decryptData + * (byte[]) + */ + public String decryptData(byte[] encrypted) throws Exception { + return new String(encrypted); + } + + /* + * (non-Javadoc) + * + * @see + * org.apache.zookeeper.inspector.encryption.DataEncryptionManager#encryptData + * (java.lang.String) + */ + public byte[] encryptData(String data) throws Exception { + if (data == null) { + return new byte[0]; + } + return data.getBytes(); + } + +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java new file mode 100644 index 0000000..15a9ee4 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java @@ -0,0 +1,39 @@ +/** + * 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.encryption; + +/** + * A class which describes how data should be encrypted and decrypted + */ +public interface DataEncryptionManager { + /** + * @param data + * - the data to be encrypted + * @return the encrypted data + * @throws Exception + */ + public byte[] encryptData(String data) throws Exception; + + /** + * @param encrypted + * - the data to be decrypted + * @return the decrypted data + * @throws Exception + */ + public String decryptData(byte[] encrypted) throws Exception; +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java new file mode 100644 index 0000000..b0b1e98 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.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.gui; + +import java.util.List; + +import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer; + +/** + * A Listener for changes to the configuration of which node viewers are shown + */ +public interface NodeViewersChangeListener { + /** + * Called when the node viewers configuration is changed (i.e node viewers + * are added, removed or the order of the node viewers is changed) + * + * @param newViewers + * - a {@link List} of {@link ZooInspectorNodeViewer}s which are + * to be shown + */ + public void nodeViewersChanged(List<ZooInspectorNodeViewer> newViewers); +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java new file mode 100644 index 0000000..fbae8f1 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java @@ -0,0 +1,80 @@ +/** + * 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.Dimension; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JEditorPane; +import javax.swing.JPanel; + +import org.apache.zookeeper.inspector.logger.LoggerFactory; + +/** + * The About Dialog for the application + */ +public class ZooInspectorAboutDialog extends JDialog { + /** + * @param frame + * - the Frame from which the dialog is displayed + */ + public ZooInspectorAboutDialog(Frame frame) { + super(frame); + this.setLayout(new BorderLayout()); + this.setIconImage(ZooInspectorIconResources.getInformationIcon() + .getImage()); + this.setTitle("About ZooInspector"); + this.setModal(true); + this.setAlwaysOnTop(true); + this.setResizable(false); + JPanel panel = new JPanel(); + panel.setLayout(new BorderLayout()); + JEditorPane aboutPane = new JEditorPane(); + aboutPane.setEditable(false); + aboutPane.setOpaque(false); + java.net.URL aboutURL = ZooInspectorAboutDialog.class + .getResource("about.html"); + try { + aboutPane.setPage(aboutURL); + } catch (IOException e) { + LoggerFactory.getLogger().error( + "Error loading about.html, file may be corrupt", e); + } + panel.add(aboutPane, BorderLayout.CENTER); + panel.setPreferredSize(new Dimension(600, 200)); + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); + JButton okButton = new JButton("OK"); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ZooInspectorAboutDialog.this.dispose(); + } + }); + buttonsPanel.add(okButton); + this.add(panel, BorderLayout.CENTER); + this.add(buttonsPanel, BorderLayout.SOUTH); + this.pack(); + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java new file mode 100644 index 0000000..c7db524 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java @@ -0,0 +1,321 @@ +/** + * 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.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Map.Entry; + +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import org.apache.zookeeper.inspector.logger.LoggerFactory; +import org.apache.zookeeper.inspector.manager.Pair; + +/** + * The connection properties dialog. This is used to determine the settings for + * connecting to a zookeeper instance + */ +public class ZooInspectorConnectionPropertiesDialog extends JDialog { + + private final HashMap<String, JComponent> components; + + /** + * @param lastConnectionProps + * - the last connection properties used. if this is the first + * conneciton since starting the applications this will be the + * default settings + * @param connectionPropertiesTemplateAndLabels + * - the connection properties and labels to show in this dialog + * @param zooInspectorPanel + * - the {@link ZooInspectorPanel} linked to this dialog + */ + public ZooInspectorConnectionPropertiesDialog( + Properties lastConnectionProps, + Pair<Map<String, List<String>>, Map<String, String>> connectionPropertiesTemplateAndLabels, + final ZooInspectorPanel zooInspectorPanel) { + final Map<String, List<String>> connectionPropertiesTemplate = connectionPropertiesTemplateAndLabels + .getKey(); + final Map<String, String> connectionPropertiesLabels = connectionPropertiesTemplateAndLabels + .getValue(); + this.setLayout(new BorderLayout()); + this.setTitle("Connection Settings"); + this.setModal(true); + this.setAlwaysOnTop(true); + this.setResizable(false); + final JPanel options = new JPanel(); + final JFileChooser fileChooser = new JFileChooser(); + options.setLayout(new GridBagLayout()); + int i = 0; + components = new HashMap<String, JComponent>(); + for (Entry<String, List<String>> entry : connectionPropertiesTemplate + .entrySet()) { + int rowPos = 2 * i + 1; + JLabel label = new JLabel(connectionPropertiesLabels.get(entry + .getKey())); + 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; + options.add(label, c1); + if (entry.getValue().size() == 0) { + JTextField text = new JTextField(); + 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; + options.add(text, c2); + components.put(entry.getKey(), text); + } else if (entry.getValue().size() == 1) { + JTextField text = new JTextField(entry.getValue().get(0)); + 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; + options.add(text, c2); + components.put(entry.getKey(), text); + } else { + List<String> list = entry.getValue(); + JComboBox combo = new JComboBox(list.toArray(new String[list + .size()])); + combo.setSelectedItem(list.get(0)); + 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; + options.add(combo, c2); + components.put(entry.getKey(), combo); + } + i++; + } + loadConnectionProps(lastConnectionProps); + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new GridBagLayout()); + JButton loadPropsFileButton = new JButton("Load from file"); + loadPropsFileButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + int result = fileChooser + .showOpenDialog(ZooInspectorConnectionPropertiesDialog.this); + if (result == JFileChooser.APPROVE_OPTION) { + File propsFilePath = fileChooser.getSelectedFile(); + Properties props = new Properties(); + try { + FileReader reader = new FileReader(propsFilePath); + try { + props.load(reader); + loadConnectionProps(props); + } finally { + reader.close(); + } + } catch (IOException ex) { + LoggerFactory + .getLogger() + .error( + "An Error occurred loading connection properties from file", + ex); + JOptionPane + .showMessageDialog( + ZooInspectorConnectionPropertiesDialog.this, + "An Error occurred loading connection properties from file", + "Error", JOptionPane.ERROR_MESSAGE); + } + options.revalidate(); + options.repaint(); + } + + } + }); + GridBagConstraints c3 = new GridBagConstraints(); + c3.gridx = 0; + c3.gridy = 0; + c3.gridwidth = 1; + c3.gridheight = 1; + c3.weightx = 0; + c3.weighty = 1; + c3.anchor = GridBagConstraints.SOUTHWEST; + c3.fill = GridBagConstraints.NONE; + c3.insets = new Insets(5, 5, 5, 5); + c3.ipadx = 0; + c3.ipady = 0; + buttonsPanel.add(loadPropsFileButton, c3); + JButton saveDefaultPropsFileButton = new JButton("Set As Default"); + saveDefaultPropsFileButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + + Properties connectionProps = getConnectionProps(); + try { + zooInspectorPanel + .setdefaultConnectionProps(connectionProps); + } catch (IOException ex) { + LoggerFactory + .getLogger() + .error( + "An Error occurred saving the default connection properties file", + ex); + JOptionPane + .showMessageDialog( + ZooInspectorConnectionPropertiesDialog.this, + "An Error occurred saving the default connection properties file", + "Error", JOptionPane.ERROR_MESSAGE); + } + } + }); + GridBagConstraints c6 = new GridBagConstraints(); + c6.gridx = 1; + c6.gridy = 0; + c6.gridwidth = 1; + c6.gridheight = 1; + c6.weightx = 1; + c6.weighty = 1; + c6.anchor = GridBagConstraints.SOUTHWEST; + c6.fill = GridBagConstraints.NONE; + c6.insets = new Insets(5, 5, 5, 5); + c6.ipadx = 0; + c6.ipady = 0; + buttonsPanel.add(saveDefaultPropsFileButton, c6); + JButton okButton = new JButton("OK"); + okButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + ZooInspectorConnectionPropertiesDialog.this.dispose(); + Properties connectionProps = getConnectionProps(); + zooInspectorPanel.connect(connectionProps); + } + }); + GridBagConstraints c4 = new GridBagConstraints(); + c4.gridx = 2; + c4.gridy = 0; + c4.gridwidth = 1; + c4.gridheight = 1; + c4.weightx = 0; + c4.weighty = 1; + c4.anchor = GridBagConstraints.SOUTH; + c4.fill = GridBagConstraints.HORIZONTAL; + c4.insets = new Insets(5, 5, 5, 5); + c4.ipadx = 0; + c4.ipady = 0; + buttonsPanel.add(okButton, c4); + JButton cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + ZooInspectorConnectionPropertiesDialog.this.dispose(); + } + }); + GridBagConstraints c5 = new GridBagConstraints(); + c5.gridx = 3; + c5.gridy = 0; + c5.gridwidth = 1; + c5.gridheight = 1; + c5.weightx = 0; + c5.weighty = 1; + c5.anchor = GridBagConstraints.SOUTH; + c5.fill = GridBagConstraints.HORIZONTAL; + c5.insets = new Insets(5, 5, 5, 5); + c5.ipadx = 0; + c5.ipady = 0; + buttonsPanel.add(cancelButton, c5); + this.add(options, BorderLayout.CENTER); + this.add(buttonsPanel, BorderLayout.SOUTH); + this.pack(); + } + + private void loadConnectionProps(Properties props) { + if (props != null) { + for (Object key : props.keySet()) { + String propsKey = (String) key; + if (components.containsKey(propsKey)) { + JComponent component = components.get(propsKey); + String value = props.getProperty(propsKey); + if (component instanceof JTextField) { + ((JTextField) component).setText(value); + } else if (component instanceof JComboBox) { + ((JComboBox) component).setSelectedItem(value); + } + } + } + } + } + + private Properties getConnectionProps() { + Properties connectionProps = new Properties(); + for (Entry<String, JComponent> entry : components.entrySet()) { + String value = null; + JComponent component = entry.getValue(); + if (component instanceof JTextField) { + value = ((JTextField) component).getText(); + } else if (component instanceof JComboBox) { + value = ((JComboBox) component).getSelectedItem().toString(); + } + connectionProps.put(entry.getKey(), value); + } + return 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/ZooInspectorIconResources.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorIconResources.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorIconResources.java new file mode 100644 index 0000000..fa45ab3 --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorIconResources.java @@ -0,0 +1,118 @@ +/** + * 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 javax.swing.ImageIcon; + +/** + * A class containing static methods for retrieving {@link ImageIcon}s used in + * the application + */ +public class ZooInspectorIconResources { + + /** + * @return file icon + */ + public static ImageIcon getTreeLeafIcon() { + return new ImageIcon("icons/file_obj.gif"); //$NON-NLS-1$ + } + + /** + * @return folder open icon + */ + public static ImageIcon getTreeOpenIcon() { + return new ImageIcon("icons/fldr_obj.gif"); //$NON-NLS-1$ + } + + /** + * @return folder closed icon + */ + public static ImageIcon getTreeClosedIcon() { + return new ImageIcon("icons/fldr_obj.gif"); //$NON-NLS-1$ + } + + /** + * @return connect icon + */ + public static ImageIcon getConnectIcon() { + return new ImageIcon("icons/launch_run.gif"); //$NON-NLS-1$ + } + + /** + * @return disconnect icon + */ + public static ImageIcon getDisconnectIcon() { + return new ImageIcon("icons/launch_stop.gif"); //$NON-NLS-1$ + } + + /** + * @return save icon + */ + public static ImageIcon getSaveIcon() { + return new ImageIcon("icons/save_edit.gif"); //$NON-NLS-1$ + } + + /** + * @return add icon + */ + public static ImageIcon getAddNodeIcon() { + return new ImageIcon("icons/new_con.gif"); //$NON-NLS-1$ + } + + /** + * @return delete icon + */ + public static ImageIcon getDeleteNodeIcon() { + return new ImageIcon("icons/trash.gif"); //$NON-NLS-1$ + } + + /** + * @return refresh icon + */ + public static ImageIcon getRefreshIcon() { + return new ImageIcon("icons/refresh.gif"); //$NON-NLS-1$ + } + + /** + * @return information icon + */ + public static ImageIcon getInformationIcon() { + return new ImageIcon("icons/info_obj.gif"); //$NON-NLS-1$ + } + + /** + * @return node viewers icon + */ + public static ImageIcon getChangeNodeViewersIcon() { + return new ImageIcon("icons/edtsrclkup_co.gif"); //$NON-NLS-1$ + } + + /** + * @return up icon + */ + public static ImageIcon getUpIcon() { + return new ImageIcon("icons/search_prev.gif"); //$NON-NLS-1$ + } + + /** + * @return down icon + */ + public static ImageIcon getDownIcon() { + return new ImageIcon("icons/search_next.gif"); //$NON-NLS-1$ + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java new file mode 100644 index 0000000..fd0b00a --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java @@ -0,0 +1,605 @@ +/** + * 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.Component; +import java.awt.FlowLayout; +import java.awt.Frame; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.datatransfer.Transferable; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.DropMode; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; +import javax.swing.ListSelectionModel; +import javax.swing.TransferHandler; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer; +import org.apache.zookeeper.inspector.logger.LoggerFactory; +import org.apache.zookeeper.inspector.manager.ZooInspectorManager; + +/** + * A {@link JDialog} for configuring which {@link ZooInspectorNodeViewer}s to + * show in the application + */ +public class ZooInspectorNodeViewersDialog extends JDialog implements + ListSelectionListener { + + private final JButton upButton; + private final JButton downButton; + private final JButton removeButton; + private final JButton addButton; + private final JList viewersList; + private final JButton saveFileButton; + private final JButton loadFileButton; + private final JButton setDefaultsButton; + private final JFileChooser fileChooser = new JFileChooser(new File(".")); + + /** + * @param frame + * - the Frame from which the dialog is displayed + * @param currentViewers + * - the {@link ZooInspectorNodeViewer}s to show + * @param listeners + * - the {@link NodeViewersChangeListener}s which need to be + * notified of changes to the node viewers configuration + * @param manager + * - the {@link ZooInspectorManager} for the application + * + */ + public ZooInspectorNodeViewersDialog(Frame frame, + final List<ZooInspectorNodeViewer> currentViewers, + final Collection<NodeViewersChangeListener> listeners, + final ZooInspectorManager manager) { + super(frame); + final List<ZooInspectorNodeViewer> newViewers = new ArrayList<ZooInspectorNodeViewer>( + currentViewers); + this.setLayout(new BorderLayout()); + this.setIconImage(ZooInspectorIconResources.getChangeNodeViewersIcon() + .getImage()); + this.setTitle("About ZooInspector"); + this.setModal(true); + this.setAlwaysOnTop(true); + this.setResizable(true); + final JPanel panel = new JPanel(); + panel.setLayout(new GridBagLayout()); + viewersList = new JList(); + DefaultListModel model = new DefaultListModel(); + for (ZooInspectorNodeViewer viewer : newViewers) { + model.addElement(viewer); + } + viewersList.setModel(model); + viewersList.setCellRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, + Object value, int index, boolean isSelected, + boolean cellHasFocus) { + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) value; + JLabel label = (JLabel) super.getListCellRendererComponent( + list, value, index, isSelected, cellHasFocus); + label.setText(viewer.getTitle()); + return label; + } + }); + viewersList.setDropMode(DropMode.INSERT); + viewersList.enableInputMethods(true); + viewersList.setDragEnabled(true); + viewersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + viewersList.getSelectionModel().addListSelectionListener(this); + viewersList.setTransferHandler(new TransferHandler() { + + @Override + public boolean canImport(TransferHandler.TransferSupport info) { + // we only import NodeViewers + if (!info + .isDataFlavorSupported(ZooInspectorNodeViewer.nodeViewerDataFlavor)) { + return false; + } + + JList.DropLocation dl = (JList.DropLocation) info + .getDropLocation(); + if (dl.getIndex() == -1) { + return false; + } + return true; + } + + @Override + public boolean importData(TransferHandler.TransferSupport info) { + JList.DropLocation dl = (JList.DropLocation) info + .getDropLocation(); + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + int index = dl.getIndex(); + boolean insert = dl.isInsert(); + // Get the string that is being dropped. + Transferable t = info.getTransferable(); + String data; + try { + data = (String) t + .getTransferData(ZooInspectorNodeViewer.nodeViewerDataFlavor); + } catch (Exception e) { + return false; + } + try { + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) Class + .forName(data).newInstance(); + if (listModel.contains(viewer)) { + listModel.removeElement(viewer); + } + if (insert) { + listModel.add(index, viewer); + } else { + listModel.set(index, viewer); + } + return true; + } catch (Exception e) { + LoggerFactory.getLogger().error( + "Error instantiating class: " + data, e); + return false; + } + + } + + @Override + public int getSourceActions(JComponent c) { + return MOVE; + } + + @Override + protected Transferable createTransferable(JComponent c) { + JList list = (JList) c; + ZooInspectorNodeViewer value = (ZooInspectorNodeViewer) list + .getSelectedValue(); + return value; + } + }); + JScrollPane scroller = new JScrollPane(viewersList); + GridBagConstraints c1 = new GridBagConstraints(); + c1.gridx = 0; + c1.gridy = 0; + c1.gridwidth = 3; + c1.gridheight = 3; + c1.weightx = 0; + c1.weighty = 1; + c1.anchor = GridBagConstraints.CENTER; + c1.fill = GridBagConstraints.BOTH; + c1.insets = new Insets(5, 5, 5, 5); + c1.ipadx = 0; + c1.ipady = 0; + panel.add(scroller, c1); + upButton = new JButton(ZooInspectorIconResources.getUpIcon()); + downButton = new JButton(ZooInspectorIconResources.getDownIcon()); + removeButton = new JButton(ZooInspectorIconResources + .getDeleteNodeIcon()); + addButton = new JButton(ZooInspectorIconResources.getAddNodeIcon()); + upButton.setEnabled(false); + downButton.setEnabled(false); + removeButton.setEnabled(false); + addButton.setEnabled(true); + upButton.setToolTipText("Move currently selected node viewer up"); + downButton.setToolTipText("Move currently selected node viewer down"); + removeButton.setToolTipText("Remove currently selected node viewer"); + addButton.setToolTipText("Add node viewer"); + final JTextField newViewerTextField = new JTextField(); + GridBagConstraints c2 = new GridBagConstraints(); + c2.gridx = 3; + c2.gridy = 0; + c2.gridwidth = 1; + c2.gridheight = 1; + c2.weightx = 0; + c2.weighty = 0; + c2.anchor = GridBagConstraints.NORTH; + c2.fill = GridBagConstraints.HORIZONTAL; + c2.insets = new Insets(5, 5, 5, 5); + c2.ipadx = 0; + c2.ipady = 0; + panel.add(upButton, c2); + GridBagConstraints c3 = new GridBagConstraints(); + c3.gridx = 3; + c3.gridy = 2; + c3.gridwidth = 1; + c3.gridheight = 1; + c3.weightx = 0; + c3.weighty = 0; + c3.anchor = GridBagConstraints.NORTH; + c3.fill = GridBagConstraints.HORIZONTAL; + c3.insets = new Insets(5, 5, 5, 5); + c3.ipadx = 0; + c3.ipady = 0; + panel.add(downButton, c3); + GridBagConstraints c4 = new GridBagConstraints(); + c4.gridx = 3; + c4.gridy = 1; + c4.gridwidth = 1; + c4.gridheight = 1; + c4.weightx = 0; + c4.weighty = 0; + c4.anchor = GridBagConstraints.NORTH; + c4.fill = GridBagConstraints.HORIZONTAL; + c4.insets = new Insets(5, 5, 5, 5); + c4.ipadx = 0; + c4.ipady = 0; + panel.add(removeButton, c4); + GridBagConstraints c5 = new GridBagConstraints(); + c5.gridx = 0; + c5.gridy = 3; + c5.gridwidth = 3; + c5.gridheight = 1; + c5.weightx = 0; + c5.weighty = 0; + c5.anchor = GridBagConstraints.CENTER; + c5.fill = GridBagConstraints.BOTH; + c5.insets = new Insets(5, 5, 5, 5); + c5.ipadx = 0; + c5.ipady = 0; + panel.add(newViewerTextField, c5); + GridBagConstraints c6 = new GridBagConstraints(); + c6.gridx = 3; + c6.gridy = 3; + c6.gridwidth = 1; + c6.gridheight = 1; + c6.weightx = 0; + c6.weighty = 0; + c6.anchor = GridBagConstraints.CENTER; + c6.fill = GridBagConstraints.BOTH; + c6.insets = new Insets(5, 5, 5, 5); + c6.ipadx = 0; + c6.ipady = 0; + panel.add(addButton, c6); + upButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) viewersList + .getSelectedValue(); + int index = viewersList.getSelectedIndex(); + if (listModel.contains(viewer)) { + listModel.removeElementAt(index); + listModel.insertElementAt(viewer, index - 1); + viewersList.setSelectedValue(viewer, true); + } + } + }); + downButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) viewersList + .getSelectedValue(); + int index = viewersList.getSelectedIndex(); + if (listModel.contains(viewer)) { + listModel.removeElementAt(index); + listModel.insertElementAt(viewer, index + 1); + viewersList.setSelectedValue(viewer, true); + } + } + }); + removeButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) viewersList + .getSelectedValue(); + int index = viewersList.getSelectedIndex(); + if (listModel.contains(viewer)) { + listModel.removeElement(viewer); + viewersList + .setSelectedIndex(index == listModel.size() ? index - 1 + : index); + } + } + }); + addButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + String className = newViewerTextField.getText(); + if (className == null || className.length() == 0) { + JOptionPane + .showMessageDialog( + ZooInspectorNodeViewersDialog.this, + "Please enter the full class name for a Node Viewer and click the add button", + "Input Error", JOptionPane.ERROR_MESSAGE); + } else { + try { + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) Class + .forName(className).newInstance(); + if (listModel.contains(viewer)) { + JOptionPane + .showMessageDialog( + ZooInspectorNodeViewersDialog.this, + "Node viewer already exists. Each node viewer can only be added once.", + "Input Error", + JOptionPane.ERROR_MESSAGE); + } else { + listModel.addElement(viewer); + } + } catch (Exception ex) { + LoggerFactory + .getLogger() + .error( + "An error occurred while instaniating the node viewer. ", + ex); + JOptionPane.showMessageDialog( + ZooInspectorNodeViewersDialog.this, + "An error occurred while instaniating the node viewer: " + + ex.getMessage(), "Error", + JOptionPane.ERROR_MESSAGE); + } + } + } + }); + saveFileButton = new JButton("Save"); + loadFileButton = new JButton("Load"); + setDefaultsButton = new JButton("Set As Defaults"); + saveFileButton + .setToolTipText("Save current node viewer configuration to file"); + loadFileButton + .setToolTipText("Load node viewer configuration frm file"); + setDefaultsButton + .setToolTipText("Set current configuration asd defaults"); + GridBagConstraints c7 = new GridBagConstraints(); + c7.gridx = 0; + c7.gridy = 4; + c7.gridwidth = 1; + c7.gridheight = 1; + c7.weightx = 1; + c7.weighty = 0; + c7.anchor = GridBagConstraints.WEST; + c7.fill = GridBagConstraints.VERTICAL; + c7.insets = new Insets(5, 5, 5, 5); + c7.ipadx = 0; + c7.ipady = 0; + panel.add(saveFileButton, c7); + GridBagConstraints c8 = new GridBagConstraints(); + c8.gridx = 1; + c8.gridy = 4; + c8.gridwidth = 1; + c8.gridheight = 1; + c8.weightx = 0; + c8.weighty = 0; + c8.anchor = GridBagConstraints.WEST; + c8.fill = GridBagConstraints.VERTICAL; + c8.insets = new Insets(5, 5, 5, 5); + c8.ipadx = 0; + c8.ipady = 0; + panel.add(loadFileButton, c8); + GridBagConstraints c9 = new GridBagConstraints(); + c9.gridx = 2; + c9.gridy = 4; + c9.gridwidth = 1; + c9.gridheight = 1; + c9.weightx = 0; + c9.weighty = 0; + c9.anchor = GridBagConstraints.WEST; + c9.fill = GridBagConstraints.VERTICAL; + c9.insets = new Insets(5, 5, 5, 5); + c9.ipadx = 0; + c9.ipady = 0; + panel.add(setDefaultsButton, c9); + saveFileButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + int result = fileChooser + .showSaveDialog(ZooInspectorNodeViewersDialog.this); + if (result == JFileChooser.APPROVE_OPTION) { + File selectedFile = fileChooser.getSelectedFile(); + int answer = JOptionPane.YES_OPTION; + if (selectedFile.exists()) { + answer = JOptionPane + .showConfirmDialog( + ZooInspectorNodeViewersDialog.this, + "The specified file already exists. do you want to overwrite it?", + "Confirm Overwrite", + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE); + } + if (answer == JOptionPane.YES_OPTION) { + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + List<String> nodeViewersClassNames = new ArrayList<String>(); + Object[] modelContents = listModel.toArray(); + for (Object o : modelContents) { + nodeViewersClassNames + .add(((ZooInspectorNodeViewer) o) + .getClass().getCanonicalName()); + } + try { + manager.saveNodeViewersFile(selectedFile, + nodeViewersClassNames); + } catch (IOException ex) { + LoggerFactory + .getLogger() + .error( + "Error saving node veiwer configuration from file.", + ex); + JOptionPane.showMessageDialog( + ZooInspectorNodeViewersDialog.this, + "Error saving node veiwer configuration from file: " + + ex.getMessage(), "Error", + JOptionPane.ERROR_MESSAGE); + } + } + } + } + }); + loadFileButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + int result = fileChooser + .showOpenDialog(ZooInspectorNodeViewersDialog.this); + if (result == JFileChooser.APPROVE_OPTION) { + try { + List<String> nodeViewersClassNames = manager + .loadNodeViewersFile(fileChooser + .getSelectedFile()); + List<ZooInspectorNodeViewer> nodeViewers = new ArrayList<ZooInspectorNodeViewer>(); + for (String nodeViewersClassName : nodeViewersClassNames) { + ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) Class + .forName(nodeViewersClassName) + .newInstance(); + nodeViewers.add(viewer); + } + DefaultListModel model = new DefaultListModel(); + for (ZooInspectorNodeViewer viewer : nodeViewers) { + model.addElement(viewer); + } + viewersList.setModel(model); + panel.revalidate(); + panel.repaint(); + } catch (Exception ex) { + LoggerFactory + .getLogger() + .error( + "Error loading node veiwer configuration from file.", + ex); + JOptionPane.showMessageDialog( + ZooInspectorNodeViewersDialog.this, + "Error loading node veiwer configuration from file: " + + ex.getMessage(), "Error", + JOptionPane.ERROR_MESSAGE); + } + } + } + }); + setDefaultsButton.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + int answer = JOptionPane + .showConfirmDialog( + ZooInspectorNodeViewersDialog.this, + "Are you sure you want to save this configuration as the default?", + "Confirm Set Defaults", + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE); + if (answer == JOptionPane.YES_OPTION) { + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + List<String> nodeViewersClassNames = new ArrayList<String>(); + Object[] modelContents = listModel.toArray(); + for (Object o : modelContents) { + nodeViewersClassNames.add(((ZooInspectorNodeViewer) o) + .getClass().getCanonicalName()); + } + try { + manager + .setDefaultNodeViewerConfiguration(nodeViewersClassNames); + } catch (IOException ex) { + LoggerFactory + .getLogger() + .error( + "Error setting default node veiwer configuration.", + ex); + JOptionPane.showMessageDialog( + ZooInspectorNodeViewersDialog.this, + "Error setting default node veiwer configuration: " + + ex.getMessage(), "Error", + JOptionPane.ERROR_MESSAGE); + } + } + } + }); + + JPanel buttonsPanel = new JPanel(); + buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); + JButton okButton = new JButton("OK"); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ZooInspectorNodeViewersDialog.this.dispose(); + DefaultListModel listModel = (DefaultListModel) viewersList + .getModel(); + newViewers.clear(); + Object[] modelContents = listModel.toArray(); + for (Object o : modelContents) { + newViewers.add((ZooInspectorNodeViewer) o); + } + currentViewers.clear(); + currentViewers.addAll(newViewers); + for (NodeViewersChangeListener listener : listeners) { + listener.nodeViewersChanged(currentViewers); + } + } + }); + buttonsPanel.add(okButton); + JButton cancelButton = new JButton("Cancel"); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + ZooInspectorNodeViewersDialog.this.dispose(); + } + }); + buttonsPanel.add(cancelButton); + this.add(panel, BorderLayout.CENTER); + this.add(buttonsPanel, BorderLayout.SOUTH); + this.pack(); + } + + /* + * (non-Javadoc) + * + * @see + * javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event + * .ListSelectionEvent) + */ + public void valueChanged(ListSelectionEvent e) { + int index = viewersList.getSelectedIndex(); + if (index == -1) { + removeButton.setEnabled(false); + upButton.setEnabled(false); + downButton.setEnabled(false); + } else { + removeButton.setEnabled(true); + if (index == 0) { + upButton.setEnabled(false); + } else { + upButton.setEnabled(true); + } + if (index == ((DefaultListModel) viewersList.getModel()).getSize()) { + downButton.setEnabled(false); + } else { + downButton.setEnabled(true); + } + } + } +} http://git-wip-us.apache.org/repos/asf/zookeeper/blob/63aaf0a1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java ---------------------------------------------------------------------- diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java new file mode 100644 index 0000000..05c256b --- /dev/null +++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java @@ -0,0 +1,140 @@ +/** + * 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.util.ArrayList; +import java.util.List; + +import javax.swing.JPanel; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreePath; + +import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer; +import org.apache.zookeeper.inspector.manager.ZooInspectorManager; +import org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager; + +/** + * This is the {@link JPanel} which contains the {@link ZooInspectorNodeViewer}s + */ +public class ZooInspectorNodeViewersPanel extends JPanel implements + TreeSelectionListener, ChangeListener { + + private final List<ZooInspectorNodeViewer> nodeVeiwers = new ArrayList<ZooInspectorNodeViewer>(); + private final List<Boolean> needsReload = new ArrayList<Boolean>(); + private final JTabbedPane tabbedPane; + private final List<String> selectedNodes = new ArrayList<String>(); + private final ZooInspectorNodeManager zooInspectorManager; + + /** + * @param zooInspectorManager + * - the {@link ZooInspectorManager} for the application + * @param nodeVeiwers + * - the {@link ZooInspectorNodeViewer}s to show + */ + public ZooInspectorNodeViewersPanel( + ZooInspectorNodeManager zooInspectorManager, + List<ZooInspectorNodeViewer> nodeVeiwers) { + this.zooInspectorManager = zooInspectorManager; + this.setLayout(new BorderLayout()); + tabbedPane = new JTabbedPane(JTabbedPane.TOP, + JTabbedPane.WRAP_TAB_LAYOUT); + setNodeViewers(nodeVeiwers); + tabbedPane.addChangeListener(this); + this.add(tabbedPane, BorderLayout.CENTER); + reloadSelectedViewer(); + } + + /** + * @param nodeViewers + * - the {@link ZooInspectorNodeViewer}s to show + */ + public void setNodeViewers(List<ZooInspectorNodeViewer> nodeViewers) { + this.nodeVeiwers.clear(); + this.nodeVeiwers.addAll(nodeViewers); + needsReload.clear(); + tabbedPane.removeAll(); + for (ZooInspectorNodeViewer nodeViewer : nodeVeiwers) { + nodeViewer.setZooInspectorManager(zooInspectorManager); + needsReload.add(true); + tabbedPane.add(nodeViewer.getTitle(), nodeViewer); + } + this.revalidate(); + this.repaint(); + } + + private void reloadSelectedViewer() { + int index = this.tabbedPane.getSelectedIndex(); + if (index != -1 && this.needsReload.get(index)) { + ZooInspectorNodeViewer viewer = this.nodeVeiwers.get(index); + viewer.nodeSelectionChanged(selectedNodes); + this.needsReload.set(index, false); + } + } + + /* + * (non-Javadoc) + * + * @see + * javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event + * .TreeSelectionEvent) + */ + public void valueChanged(TreeSelectionEvent e) { + TreePath[] paths = e.getPaths(); + selectedNodes.clear(); + for (TreePath path : paths) { + boolean appended = false; + StringBuilder sb = new StringBuilder(); + Object[] pathArray = path.getPath(); + for (Object o : pathArray) { + if (o != null) { + String nodeName = o.toString(); + if (nodeName != null) { + if (nodeName.length() > 0) { + appended = true; + sb.append("/"); //$NON-NLS-1$ + sb.append(o.toString()); + } + } + } + } + if (appended) { + selectedNodes.add(sb.toString()); + } + } + for (int i = 0; i < needsReload.size(); i++) { + this.needsReload.set(i, true); + } + reloadSelectedViewer(); + } + + /* + * (non-Javadoc) + * + * @see + * javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent + * ) + */ + public void stateChanged(ChangeEvent e) { + reloadSelectedViewer(); + } +}
