Package org.rioproject.tools.ui.browser

Source Code of org.rioproject.tools.ui.browser.ServiceEditor$JoinMenuBar

/*
* 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.rioproject.tools.ui.browser;

import com.sun.jini.admin.DestroyAdmin;
import com.sun.jini.config.Config;
import com.sun.jini.logging.Levels;
import com.sun.jini.proxy.BasicProxyTrustVerifier;
import net.jini.admin.JoinAdmin;
import net.jini.config.ConfigurationException;
import net.jini.core.discovery.LookupLocator;
import net.jini.core.entry.Entry;
import net.jini.core.event.EventRegistration;
import net.jini.core.event.RemoteEvent;
import net.jini.core.event.RemoteEventListener;
import net.jini.core.lease.Lease;
import net.jini.core.lookup.*;
import net.jini.export.Exporter;
import net.jini.jeri.BasicILFactory;
import net.jini.jeri.BasicJeriExporter;
import net.jini.jeri.tcp.TcpServerEndpoint;
import net.jini.lookup.DiscoveryAdmin;
import net.jini.lookup.entry.UIDescriptor;
import net.jini.security.TrustVerifier;
import net.jini.security.proxytrust.ServerProxyTrust;

import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.rmi.server.ExportException;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* ServiceEditor is a gui-based utility to add/modify
* attributes, groups and lookup locators.
* And also supports some well known admin interfaces.
* (DestroyAdmin, DiscoveryAdmin)
* <p/>
* <p/>
* current issues<br>
* <ul>
* <li> can't operate(add/remove/modify) array elements in an entry.
* <li> does not support EntryBean.
* <li> field modification is not based on EditableTree
* </ul>
*/
class ServiceEditor extends JPanel {
    private static final Logger logger = Browser.logger;

    private Browser browser;
    private ServiceItem item;
    private ServiceRegistrar registrar;
    protected Object admin;
    private ServiceTemplate stmpl;
    private NotifyReceiver receiver;
    private Lease elease = null;
    private long eventID = 0;
    private long seqNo = Long.MAX_VALUE;
    private AttributeTreePanel attrPanel;
    private static JDialog dialog;

    private final static int MINIMUM_WINDOW_WIDTH = 320;

    private ServiceEditor(final ServiceItem item,
                          final Object admin,
                          final ServiceRegistrar registrar,
                          final Browser browser) {
        super(new BorderLayout());
        this.item = item;
        this.admin = admin;
        this.registrar = registrar;
        this.browser = browser;

        // init main components
        attrPanel = new AttributeTreePanel();

        // setup notify
        try {
            stmpl = new ServiceTemplate(item.serviceID,
                                        new Class[]{item.service.getClass()},
                                        new Entry[]{});
            receiver = new NotifyReceiver();

            setupNotify();
        } catch (Throwable t) {
            logger.log(Level.INFO, "event registration failed", t);
            cancelNotify();
        }

        dialog.addWindowListener(browser.wrap(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                cleanup();
            }
        }));

        // add menu and attr panel
        add(new JoinMenuBar(), BorderLayout.NORTH);
        add(attrPanel, BorderLayout.CENTER);

        validate();

        // center in parent frame
        Rectangle bounds = browser.getBounds();
        Dimension dialogSize = getPreferredSize();
        int xpos = bounds.x + (bounds.width - dialogSize.width) / 2;
        int ypos = bounds.y + (bounds.height - dialogSize.height) / 2;

        setLocation((xpos < 0) ? 0 : xpos,
                    (ypos < 0) ? 0 : ypos);
    }

    static JDialog getDialog(ServiceItem item,
                             Object admin,
                             ServiceRegistrar registrar,
                             Browser browser) {
        dialog = new JDialog(browser, "ServiceItem Editor", true);
        ServiceEditor serviceEditor = new ServiceEditor(item, admin, registrar, browser);
        dialog.getContentPane().add(serviceEditor);
        dialog.pack();
        dialog.setSize(((dialog.getSize().width < MINIMUM_WINDOW_WIDTH) ?
                        MINIMUM_WINDOW_WIDTH :
                        dialog.getSize().width),
                       dialog.getSize().height);
        dialog.setModal(false);
        dialog.setLocationRelativeTo(browser);
        return (dialog);
    }

    void cleanup() {
        // cancel lease
        cancelNotify();
        // release resources and close all child frames
        receiver.unexport();
        dialog.dispose();
    }

    protected void cancelNotify() {
        if (elease != null) {
            try {
                browser.getLeaseManager().cancel(elease);
            } catch (Throwable t) {
                logger.log(Levels.HANDLED, "event cancellation failed", t);
            }
            elease = null;
            seqNo = Long.MAX_VALUE;
        }
    }

    protected void setupNotify() {
        if (registrar != null) {
            try {
                EventRegistration reg =
                    registrar.notify(stmpl,
                                     ServiceRegistrar.TRANSITION_MATCH_NOMATCH |
                                     ServiceRegistrar.TRANSITION_NOMATCH_MATCH |
                                     ServiceRegistrar.TRANSITION_MATCH_MATCH,
                                     receiver.proxy,
                                     null,
                                     Lease.ANY);
                elease = (Lease) browser.getLeasePreparer().prepareProxy(reg.getLease());
                browser.getLeaseManager().renewUntil(elease, Lease.ANY,
                                                     new Browser.LeaseNotify());
                eventID = reg.getID();
                seqNo = reg.getSequenceNumber();
            } catch (Throwable t) {
                logger.log(Level.INFO, "event registration failed", t);
            }
        }
    }

    private class NotifyReceiver implements RemoteEventListener, ServerProxyTrust {
        private final Exporter exporter;
        final RemoteEventListener proxy;

        public NotifyReceiver() throws ConfigurationException, ExportException {
            exporter = (Exporter)
                           Config.getNonNullEntry(browser.getConfiguration(),
                                                  Browser.BROWSER,
                                                  "listenerExporter",
                                                  Exporter.class,
                                                  new BasicJeriExporter(TcpServerEndpoint.getInstance(0),
                                                                        new BasicILFactory(),
                                                                        false, false));
            proxy = (RemoteEventListener) exporter.export(this);
        }

        public void notify(final RemoteEvent ev) {
            SwingUtilities.invokeLater(browser.wrap(new Runnable() {
                public void run() {
                    if (eventID == ev.getID() && seqNo < ev.getSequenceNumber()) {
                        seqNo = ev.getSequenceNumber();
                        attrPanel.receiveNotify(((ServiceEvent) ev).getTransition());
                    }
                }
            }));
        }

        public TrustVerifier getProxyVerifier() {
            return new BasicProxyTrustVerifier(proxy);
        }

        void unexport() {
            exporter.unexport(true);
        }
    }

    class JoinMenuBar extends JMenuBar {
        public JoinMenuBar() {
            JMenuItem mitem;

            // "File" Menu
            JMenu fileMenu = add(new JMenu("File"));
            mitem = fileMenu.add(new JMenuItem("Show Info"));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    Class[] infs = Browser.getInterfaces(item.service.getClass());
                    String[] msg = new String[3 + infs.length];
                    msg[0] = "ServiceID: " + item.serviceID;
                    msg[1] = "Service Instance: " + item.service.getClass().getName();
                    if (infs.length == 1)
                        msg[2] = "Implemented Interface:";
                    else
                        msg[2] = "Implemented Interfaces:";
                    for (int i = 0; i < infs.length; i++)
                        msg[3 + i] = "    " + infs[i].getName();

                    JOptionPane.showMessageDialog(ServiceEditor.this,
                                                  msg,
                                                  "ServiceItem Information",
                                                  JOptionPane.INFORMATION_MESSAGE);
                }
            }));
            mitem = fileMenu.add(new JMenuItem("Refresh"));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    attrPanel.refreshPanel();
                }
            }));
            mitem = fileMenu.add(new JMenuItem("Close"));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    cleanup();
                }
            }));

            // "Edit" Menu
            JMenu editMenu = add(new JMenu("Edit"));
            mitem = editMenu.add(new JMenuItem("Add Attribute..."));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    attrPanel.addAttr();
                }
            }));
            if (!(admin instanceof JoinAdmin))
                mitem.setEnabled(false);
            mitem = editMenu.add(new JMenuItem("Remove Attribute"));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    attrPanel.removeAttr();
                }
            }));
            if (!(admin instanceof JoinAdmin))
                mitem.setEnabled(false);

            // "Admin" Menu
            JMenu adminMenu = add(new JMenu("Admin"));

            // Group (JoinAdmin)
            mitem = adminMenu.add(new JMenuItem("Joining groups..."));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    new GroupLister("Joining Groups").showFrame();
                }
            }));
            if (!(admin instanceof JoinAdmin))
                mitem.setEnabled(false);

            // Locator (JoinAdmin)
            mitem = adminMenu.add(new JMenuItem("Joining locators..."));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    new LocatorLister("Joining Locators").showFrame();
                }
            }));
            if (!(admin instanceof JoinAdmin))
                mitem.setEnabled(false);

            // separator
            adminMenu.addSeparator();

            // Group (DiscoveryAdmin)
            mitem = adminMenu.add(new JMenuItem("Member groups..."));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    new MemberGroupLister("Member Groups").showFrame();
                }
            }));
            if (!(admin instanceof DiscoveryAdmin))
                mitem.setEnabled(false);

            // Unicast port (DiscoveryAdmin)
            mitem = adminMenu.add(new JMenuItem("Unicast port..."));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    try {
                        String[] msg = {"Current port is " + ((DiscoveryAdmin) admin).getUnicastPort(),
                                        "Input a new value"};
                        String result = JOptionPane.showInputDialog(ServiceEditor.this,
                                                                    msg,
                                                                    "Unicast Port",
                                                                    JOptionPane.QUESTION_MESSAGE);

                        if (result == null)
                            return;

                        try {
                            int port = Integer.parseInt(result);
                            ((DiscoveryAdmin) admin).setUnicastPort(port);
                        } catch (NumberFormatException e) {
                            JOptionPane.showMessageDialog(ServiceEditor.this,
                                                          result + " is not acceptable.",
                                                          "Error",
                                                          JOptionPane.ERROR_MESSAGE);
                        } catch (Throwable t) {
                            logger.log(Level.INFO, "setting unicast port failed", t);
                            JOptionPane.showMessageDialog(ServiceEditor.this,
                                                          t.getMessage(),
                                                          t.getClass().getName(),
                                                          JOptionPane.ERROR_MESSAGE);
                        }
                    } catch (Throwable t) {
                        logger.log(Level.INFO, "getting unicast port failed", t);
                        JOptionPane.showMessageDialog(ServiceEditor.this,
                                                      t.getMessage(),
                                                      t.getClass().getName(),
                                                      JOptionPane.ERROR_MESSAGE);
                    }
                }
            }));
            if (!(admin instanceof DiscoveryAdmin))
                mitem.setEnabled(false);

            // separator
            adminMenu.addSeparator();

            // DestroyAdmin
            mitem = adminMenu.add(new JMenuItem("Destroy"));
            mitem.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    if (JOptionPane.showConfirmDialog(ServiceEditor.this,
                                                      "Are you sure to destroy this service?",
                                                      "Query",
                                                      JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
                        try {
                            ((DestroyAdmin) admin).destroy();
                            cleanup();
                        } catch (Throwable t) {
                            logger.log(Level.INFO, "service destroy failed", t);
                            JOptionPane.showMessageDialog(ServiceEditor.this,
                                                          t.getMessage(),
                                                          t.getClass().getName(),
                                                          JOptionPane.ERROR_MESSAGE);
                        }
                }
            }));
            if (!(admin instanceof DestroyAdmin))
                mitem.setEnabled(false);
        }
    }

    class AttributeTreePanel extends EntryTreePanel {

        public AttributeTreePanel() {
            super(admin instanceof JoinAdmin);

            if (admin instanceof JoinAdmin) {
                tree.addMouseListener(browser.wrap(new DoubleClicker(this)));
            }
            tree.addMouseListener(browser.wrap(new MouseReceiver(item, uiDescriptorPopup())));

            refreshPanel();
        }

        protected Entry[] getEntryArray() {
            if (admin instanceof JoinAdmin) {
                try {
                    item.attributeSets = ((JoinAdmin) admin).getLookupAttributes();
                } catch (Throwable t) {
                    logger.log(Level.INFO, "obtaining attributes failed", t);
                }
            } else {
                try {
                    ServiceMatches matches = registrar.lookup(stmpl, 1);
                    if (matches.totalMatches != 1)
                        Browser.logger.log(Level.INFO, "unexpected lookup matches: {0}",
                                           matches.totalMatches);
                    else
                        item.attributeSets = matches.items[0].attributeSets;
                } catch (Throwable t) {
                    Browser.logger.log(Level.INFO, "lookup failed", t);
                }
            }
            return item.attributeSets;
        }

        protected void receiveNotify(int transition) {

            if (browser.isAutoConfirm()) {
                if (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH)
                    cleanup();
                else
                    refreshPanel();

                return;
            }

            String[] msg =
                (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH) ?
                new String[]{
                                "Service has been removed from lookup service.",
                                "Do you want to close the service editor window ?"} :
                new String[]{
                                "Attributes have been modified by another client or the service itself.",
                                "Do you want to refresh the attributes ?"};
            int result = JOptionPane.showConfirmDialog(AttributeTreePanel.this,
                                                       msg,
                                                       "Query",
                                                       JOptionPane.YES_NO_OPTION);

            if (result == JOptionPane.YES_OPTION) {
                if (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH)
                    cleanup();
                else
                    refreshPanel();
            }
        }

        public void editField(ObjectNode node) {

            String result = JOptionPane.showInputDialog(this,
                                                        "Input a new value",
                                                        "Modify a field",
                                                        JOptionPane.QUESTION_MESSAGE);

            if (result != null) {
                // Save current value as template
                Entry template = cloneEntry((Entry) node.getEntryTop());
                Object oldVal;

                if (result.length() == 0) {
                    oldVal = node.setValue(null);
                } else {
                    oldVal = node.setValue(result);
                }
                // modifyAttribute
                try {
                    node.setObjectRecursive();
                    Entry attr = (Entry) node.getEntryTop();
                    //Entry template = (Entry) generateTemplate(attr);

                    // cancel notify while adding an attribute
                    cancelNotify();

                    ((JoinAdmin) admin).modifyLookupAttributes(new Entry[]{template}, new Entry[]{attr});

                    setupNotify();

                    // Redraw node value
                    model.nodeChanged(node);
                } catch (Throwable t) {
                    logger.log(Level.INFO, "attribute modification failed", t);
                    // recover tree node
                    try {
                        node.setValue(oldVal);
                        node.setObjectRecursive();
                    } catch (Throwable tt) {
                        logger.log(Levels.HANDLED, "node reset failed", tt);
                    }
                    model.nodeChanged(node);
                    //model.nodeStructureChanged(node);

                    // show dialog
                    JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                  t.getMessage(),
                                                  t.getClass().getName(),
                                                  JOptionPane.ERROR_MESSAGE);
                }
            }
        }

        public void addAttr() {

            String result = JOptionPane.showInputDialog(this,
                                                        "Input an entry class name",
                                                        "Add an attribute",
                                                        JOptionPane.QUESTION_MESSAGE);

            if (!(result == null || result.length() == 0)) {
                try {
                    Class clazz = Class.forName(result);
                    Object attr = clazz.newInstance();

                    if (!(attr instanceof Entry)) {
                        JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                      "Does not implement Entry interface",
                                                      "Unacceptable Class",
                                                      JOptionPane.WARNING_MESSAGE);

                    } else if (attr instanceof net.jini.lookup.entry.ServiceControlled) {
                        JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                      "Implements ServiceControlled interface",
                                                      "Unacceptable Class",
                                                      JOptionPane.WARNING_MESSAGE);
                    } else {
                        // cancel notify while adding an attribute
                        cancelNotify();

                        ((JoinAdmin) admin).addLookupAttributes(
                                                                   new Entry[]{(Entry) attr});
                        // add node of this attribute
                        ObjectNode node = new ObjectNode(attr, true);
                        root.add(node);
                        recursiveObjectTree(node);

                        //
                        setupNotify();

                        // refresh view
                        model.nodesWereInserted(root,
                                                new int[]{model.getIndexOfChild(root, node)});
                    }
                } catch (ClassNotFoundException e) {
                    JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                  e.getMessage(),
                                                  "Class Not Found",
                                                  JOptionPane.WARNING_MESSAGE);
                } catch (Throwable t) {
                    logger.log(Level.INFO, "adding attribute failed", t);
                    JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                  t.getMessage(),
                                                  t.getClass().getName(),
                                                  JOptionPane.WARNING_MESSAGE);
                }
            }
        }

        public void removeAttr() {

            ObjectNode node = (ObjectNode) tree.getLastSelectedPathComponent();
            if (node == null) {
                JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                              "Select an attribute folder to remove.",
                                              "Warning",
                                              JOptionPane.WARNING_MESSAGE);

                return;
            } else if (!node.isControllable()) {
                JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                              "This attribute is under service provider's control.",
                                              "Warning",
                                              JOptionPane.WARNING_MESSAGE);

                return;
            } else if (!node.isEntryTop()) {
                JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                              "Select a top of attribute folder.",
                                              "Warning",
                                              JOptionPane.WARNING_MESSAGE);

                return;
            }

            Entry target = (Entry) node.getObject();
            int result = JOptionPane.showConfirmDialog(AttributeTreePanel.this,
                                                       new String[]{"Remove attribute:",
                                                                    target.toString()},
                                                       "Query",
                                                       JOptionPane.YES_NO_OPTION);

            if (result == JOptionPane.YES_OPTION) {
                // Remote Attribute
                try {

                    // cancel notify while adding an attribute
                    cancelNotify();

                    ((JoinAdmin) admin).modifyLookupAttributes(
                                                                  new Entry[]{target}, new Entry[]{null});

                    //
                    setupNotify();

                    int index = root.getIndex(node);
                    root.remove(node);
                    model.nodesWereRemoved(root, new int[]{index}, new Object[]{node});
                } catch (Throwable t) {
                    logger.log(Level.INFO, "attribute removal failed", t);
                    JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                  t.getMessage(),
                                                  t.getClass().getName(),
                                                  JOptionPane.ERROR_MESSAGE);
                }
            }
        }

        private Entry cloneEntry(final Entry attr) {
            try {
                Class realClass = attr.getClass();
                Entry template = (Entry) realClass.newInstance();

                Field[] f = realClass.getFields();
                for (Field field : f) {
                    if (!usableField(field))
                        continue;
                    field.set(template, field.get(attr));
                }

                return template;
            } catch (Throwable t) {
                logger.log(Level.INFO, "duplicating entry failed", t);
            }
            return null;
        }

        // from EntryRep
        private boolean usableField(final Field field) {
            Class desc = field.getDeclaringClass();

            if (desc.isPrimitive()) {
                throw new IllegalArgumentException("primitive types not allowed in an Entry");
            }

            // skip anything that isn't a public per-object mutable field
            int mods = field.getModifiers();
            return (0 == (mods & (Modifier.TRANSIENT | Modifier.STATIC | Modifier.FINAL)));
        }

        class DoubleClicker extends MouseAdapter {
            AttributeTreePanel parent;

            public DoubleClicker(final AttributeTreePanel parent) {
                this.parent = parent;
            }

            public void mouseClicked(final MouseEvent ev) {
                if (ev.getClickCount() >= 2) {
                    JTree tree = (JTree) ev.getSource();
                    TreePath path = tree.getPathForLocation(ev.getX(), ev.getY());
                    if (path == null)
                        return;
                    ObjectNode node = (ObjectNode) path.getLastPathComponent();

                    if (node.isLeaf()) {
                        if (!node.isControllable()) {
                            JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                          "This attribute is under service provider's control.",
                                                          "Warning",
                                                          JOptionPane.WARNING_MESSAGE);
                        } else if (node.isEditable() &&
                                   ((ObjectNode) node.getParent()).isEntryTop()) {
                            parent.editField(node);
                        } else {
                            JOptionPane.showMessageDialog(AttributeTreePanel.this,
                                                          "This field is not editable.",
                                                          "Warning",
                                                          JOptionPane.WARNING_MESSAGE);
                        }
                    }

                    tree.scrollPathToVisible(path);
                }
            }
        }
    }

    abstract class ListerFrame extends JFrame {

        private JList listBox;
        private JScrollPane scrollPane;
        protected DefaultListModel model = new DefaultListModel();
        private DefaultListModel dummyModel = new DefaultListModel();    // to keep away from Swing's bug

        private JButton addButton;
        private JButton removeButton;
        private JButton closeButton;

        public ListerFrame(final String title) {
            super(title);

            getContentPane().setLayout(new BorderLayout());

            // create the initial list
            listBox = new JList(model);
            listBox.setFixedCellHeight(20);
            scrollPane = new JScrollPane(listBox);
            getContentPane().add(scrollPane, "Center");
            //resetListModel();

            // Create the controls
            JPanel buttonPanel = new JPanel();
            addButton = new JButton("Add");
            addButton.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    String result = JOptionPane.showInputDialog(ListerFrame.this, getAddMessage());

                    if (result != null) {
                        StringTokenizer st = new StringTokenizer(result);
                        String[] tokens = new String[st.countTokens()];
                        for (int i = 0; i < tokens.length; i++)
                            tokens[i] = st.nextToken().trim();

                        addItems(tokens);
                        resetListModel();
                        scrollPane.validate();
                    }
                }
            }));
            buttonPanel.add(addButton);

            removeButton = new JButton("Remove");
            removeButton.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    Object[] selected = listBox.getSelectedValues();

                    if (selected == null || selected.length == 0) {
                        // no items are selected
                        JOptionPane.showMessageDialog(ListerFrame.this,
                                                      "No items are selected",
                                                      "Warning",
                                                      JOptionPane.WARNING_MESSAGE);
                        return;
                    }

                    int result = JOptionPane.showConfirmDialog(ListerFrame.this,
                                                               getRemoveMessage(selected),
                                                               "Query",
                                                               JOptionPane.YES_NO_OPTION);

                    if (result == JOptionPane.YES_OPTION) {
                        removeItems(selected);
                        resetListModel();
                        scrollPane.validate();
                    }
                }
            }));
            buttonPanel.add(removeButton);

            closeButton = new JButton("Close");
            closeButton.addActionListener(browser.wrap(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    setVisible(false);
                }
            }));
            buttonPanel.add(closeButton);
            getContentPane().add(buttonPanel, "South");

            pack();
        }

        public void showFrame() {
            // init list data
            resetListModel();
            setLocationRelativeTo(browser);
            setVisible(true);
        }

        private void resetListModel() {
            //listBox.setModel(null);
            listBox.setModel(dummyModel);    // to keep away from NullException (Swing's bug)

            model.removeAllElements();
            initListModel();

            listBox.setModel(model);
            listBox.clearSelection();
            listBox.ensureIndexIsVisible(0);
            listBox.repaint();
            listBox.revalidate();
        }

        protected abstract void initListModel();

        protected abstract String getAddMessage();

        protected abstract String getRemoveMessage(Object[] items);

        protected abstract void addItems(String[] items);

        protected abstract void removeItems(Object[] items);
    }

    class GroupLister extends ListerFrame {

        public GroupLister(final String title) {
            super(title);
        }

        protected void initListModel() {
            if (!(admin instanceof JoinAdmin)) {
                return;
            }

            try {
                String[] groups = ((JoinAdmin) admin).getLookupGroups();
                for (String group : groups) {
                    model.addElement(new GroupItem(group));
                }
            } catch (Throwable t) {
                logger.log(Level.INFO, "obtaining groups failed", t);
            }
        }

        protected String getAddMessage() {
            return "Enter adding group(s)";
        }

        protected String getRemoveMessage(final Object[] items) {
            StringBuffer msg = new StringBuffer();
            if (items.length > 1)
                msg.append("Remove these groups : ");
            else
                msg.append("Remove a group : ");
            for (int i = 0; i < items.length; i++) {
                if (i != 0)
                    msg.append(", ");
                msg.append((items[i]).toString());
            }
            return msg.toString();
        }

        protected void addItems(final String[] items) {
            // check "public"
            String[] grps = new String[items.length];
            for (int i = 0; i < items.length; i++)
                grps[i] = new GroupItem(items[i]).group;

            try {
                ((JoinAdmin) admin).addLookupGroups(grps);
            } catch (Throwable t) {
                logger.log(Level.INFO, "adding groups failed", t);
            }
        }

        protected void removeItems(final Object[] items) {
            String[] grps = new String[items.length];
            for (int i = 0; i < items.length; i++)
                grps[i] = ((GroupItem) items[i]).group;

            try {
                ((JoinAdmin) admin).removeLookupGroups(grps);
            } catch (Throwable t) {
                logger.log(Level.INFO, "removing groups failed", t);
            }
        }
    }

    class MemberGroupLister extends ListerFrame {

        public MemberGroupLister(final String title) {
            super(title);
        }

        protected void initListModel() {
            try {
                String[] groups = ((DiscoveryAdmin) admin).getMemberGroups();
                for (String group : groups) {
                    model.addElement(new GroupItem(group));
                }
            } catch (Throwable t) {
                logger.log(Level.INFO, "obtaining groups failed", t);
            }
        }

        protected String getAddMessage() {
            return "Enter adding group(s)";
        }

        protected String getRemoveMessage(final Object[] items) {
            StringBuilder msg = new StringBuilder();
            if (items.length > 1)
                msg.append("Remove these groups : ");
            else
                msg.append("Remove a group : ");
            for (int i = 0; i < items.length; i++) {
                if (i != 0)
                    msg.append(", ");
                msg.append((items[i]).toString());
            }
            return msg.toString();
        }

        protected void addItems(final String[] items) {
            // check "public"
            String[] grps = new String[items.length];
            for (int i = 0; i < items.length; i++)
                grps[i] = new GroupItem(items[i]).group;

            try {
                ((DiscoveryAdmin) admin).addMemberGroups(grps);
            } catch (Throwable t) {
                logger.log(Level.INFO, "adding groups failed", t);
            }
        }

        protected void removeItems(final Object[] items) {
            String[] grps = new String[items.length];
            for (int i = 0; i < items.length; i++)
                grps[i] = ((GroupItem) items[i]).group;

            try {
                ((DiscoveryAdmin) admin).removeMemberGroups(grps);
            } catch (Throwable t) {
                logger.log(Level.INFO, "removing groups failed", t);
            }
        }
    }

    class GroupItem {
        public String group;

        public GroupItem(final String group) {
            if (group.equals("public"))
                this.group = "";
            else
                this.group = group;
        }

        public String toString() {
            if ("".equals(group))
                return "public";
            else
                return group;
        }
    }

    class LocatorLister extends ListerFrame {

        public LocatorLister(final String title) {
            super(title);
        }

        protected void initListModel() {
            if (!(admin instanceof JoinAdmin)) {
                return;
            }

            try {
                LookupLocator[] locators = ((JoinAdmin) admin).getLookupLocators();
                for (LookupLocator locator : locators) {
                    model.addElement(locator);
                }
            } catch (Throwable t) {
                logger.log(Level.INFO, "obtaining locators failed", t);
            }
        }

        protected String getAddMessage() {
            return "Enter a new locator's URL";
        }

        protected String getRemoveMessage(final Object[] items) {
            StringBuilder msg = new StringBuilder();
            if (items.length > 1)
                msg.append("Remove these locators : ");
            else
                msg.append("Remove a locator : ");
            for (int i = 0; i < items.length; i++) {
                if (i != 0)
                    msg.append(", ");
                msg.append(items[i].toString());
            }
            return msg.toString();
        }

        protected void addItems(final String[] items) {
            LookupLocator[] locs = new LookupLocator[items.length];
            for (int i = 0; i < items.length; i++) {
                try {
                    locs[i] = new LookupLocator(items[i]);
                } catch (MalformedURLException e) {
                    JOptionPane.showMessageDialog(LocatorLister.this,
                                                  "\"" + items[i] + "\": " +
                                                  e.getMessage(),
                                                  "Bad Locator",
                                                  JOptionPane.WARNING_MESSAGE);
                    return;
                }
            }

            try {
                ((JoinAdmin) admin).addLookupLocators(locs);
            } catch (Throwable t) {
                logger.log(Level.INFO, "adding locators failed", t);
            }
        }

        protected void removeItems(final Object[] items) {
            LookupLocator[] locs = new LookupLocator[items.length];
            for (int i = 0; i < items.length; i++)
                locs[i] = (LookupLocator) items[i];

            try {
                ((JoinAdmin) admin).removeLookupLocators(locs);
            } catch (Throwable t) {
                logger.log(Level.INFO, "removing locators failed", t);
            }
        }
    }

    // provides support for ServiceUI
    public class UIDescriptorPopup extends JPopupMenu implements ActionListener,
                                                                 PopupMenuListener {

        protected transient JMenuItem showUIItem;
        protected transient ServiceItem serviceItem;

        public UIDescriptorPopup() {
            super();

            showUIItem = new JMenuItem("Show UI");

            showUIItem.addActionListener(this);
            showUIItem.setActionCommand("showUI");
            add(showUIItem);

            addPopupMenuListener(this);
            setOpaque(true);
            setLightWeightPopupEnabled(true);
        }

        public void actionPerformed(final ActionEvent anEvent) {

            UIDescriptor uiDescriptor = getSelectedUIDescriptor();

            if (uiDescriptor == null) {
                return;
            }
            ServiceUIHelper.handle(uiDescriptor, serviceItem, dialog);
        }

        public void popupMenuWillBecomeVisible(final PopupMenuEvent ev) {
        }

        public void popupMenuWillBecomeInvisible(final PopupMenuEvent ev) {
        }

        public void popupMenuCanceled(final PopupMenuEvent ev) {
        }

        public void setServiceItem(final ServiceItem anItem) {
            serviceItem = anItem;
        }
    }

    class MouseReceiver extends MouseAdapter {

        private ServiceEditor.UIDescriptorPopup popup;
        private ServiceItem serviceItem;

        public MouseReceiver(final ServiceItem aServiceItem,
                             final ServiceEditor.UIDescriptorPopup popup) {
            this.popup = popup;
            serviceItem = aServiceItem;
        }

        public void mouseReleased(final MouseEvent ev) {

            higlightSelection(ev);

            if (!ev.isPopupTrigger()) {
                return;
            }

            UIDescriptor selectedDescriptor = getSelectedUIDescriptor();

            if (selectedDescriptor == null) {
                return;
            }

            if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
                return;
            }

            popup.setServiceItem(serviceItem);
            popup.show(ev.getComponent(), ev.getX(), ev.getY());
        }

        public void mousePressed(final MouseEvent ev) {

            higlightSelection(ev);

            if (!ev.isPopupTrigger()) {
                return;
            }

            UIDescriptor selectedDescriptor = getSelectedUIDescriptor();

            if (selectedDescriptor == null) {
                return;
            }

            if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
                return;
            }

            popup.setServiceItem(serviceItem);
            popup.show(ev.getComponent(), ev.getX(), ev.getY());
        }
    }

    private UIDescriptor getSelectedUIDescriptor() {

        ObjectNode selectedNode =
            (ObjectNode) attrPanel.tree.getLastSelectedPathComponent();

        if (selectedNode == null) {
            return null;
        }

        Object selectedObject = selectedNode.getObject();

        try {
            return (UIDescriptor) selectedObject;
        } catch (ClassCastException e) {
            return null;
        }
    }

    private void higlightSelection(final MouseEvent event) {
        attrPanel.tree.setSelectionPath(attrPanel.tree.getPathForLocation(event.getX(), event.getY()));
    }

    private ServiceEditor.UIDescriptorPopup uiDescriptorPopup() {
        return new ServiceEditor.UIDescriptorPopup();
    }

}
TOP

Related Classes of org.rioproject.tools.ui.browser.ServiceEditor$JoinMenuBar

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.