blob: ee972dae8e55621c698be21513d94e0178303d6c [file] [log] [blame]
/*
* 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.river.container.examples.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 java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
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;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.tree.TreePath;
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.ServiceEvent;
import net.jini.core.lookup.ServiceItem;
import net.jini.core.lookup.ServiceMatches;
import net.jini.core.lookup.ServiceRegistrar;
import net.jini.core.lookup.ServiceTemplate;
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.lookup.ui.factory.JFrameFactory;
import net.jini.security.TrustVerifier;
import net.jini.security.proxytrust.ServerProxyTrust;
/**
* 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>
* 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>
*
* @author Sun Microsystems, Inc.
*/
class ServiceEditor extends JFrame {
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 final static int MINIMUM_WINDOW_WIDTH = 320;
public ServiceEditor(ServiceItem item,
Object admin,
ServiceRegistrar registrar,
Browser browser)
{
super("ServiceItem Editor");
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();
}
addWindowListener(browser.wrap(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
cleanup();
}
}));
// add menu and attr panel
getContentPane().setLayout(new BorderLayout());
getContentPane().add(new JoinMenuBar(), "North");
getContentPane().add(attrPanel, "Center");
validate();
pack();
setSize(((getSize().width < MINIMUM_WINDOW_WIDTH) ? MINIMUM_WINDOW_WIDTH : getSize().width),
getSize().height);
// 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);
}
void cleanup() {
// cancel lease
cancelNotify();
// release resources and close all child frames
dispose();
receiver.unexport();
}
protected void cancelNotify() {
if(elease != null) {
try {
browser.leaseMgr.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.leasePreparer.prepareProxy(reg.getLease());
browser.leaseMgr.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.config, 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 = (JMenu) add(new JMenu("File"));
mitem = (JMenuItem) 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 = (JMenuItem) fileMenu.add(new JMenuItem("Refresh"));
mitem.addActionListener(browser.wrap(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
attrPanel.refreshPanel();
}
}));
mitem = (JMenuItem) fileMenu.add(new JMenuItem("Close"));
mitem.addActionListener(browser.wrap(new ActionListener() {
public void actionPerformed(ActionEvent ev) {
cleanup();
}
}));
// "Edit" Menu
JMenu editMenu = (JMenu) add(new JMenu("Edit"));
mitem = (JMenuItem) 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 = (JMenuItem) 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 = (JMenu) add(new JMenu("Admin"));
// Group (JoinAdmin)
mitem = (JMenuItem) 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 = (JMenuItem) 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 = (JMenuItem) 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 = (JMenuItem) 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 = (JMenuItem) 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}",
new Integer(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){
} else {
// Save current value as template
Entry template = cloneEntry((Entry) node.getEntryTop());
Object oldVal = null;
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){
} else {
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});
node = null;
} 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(Entry attr) {
try {
Class realClass = attr.getClass();
Entry template = (Entry) realClass.newInstance();
Field[] f = realClass.getFields();
for(int i = 0; i < f.length; i++) {
if(! usableField(f[i]))
continue;
f[i].set(template, f[i].get(attr));
}
return template;
} catch (Throwable t) {
logger.log(Level.INFO, "duplicating entry failed", t);
}
return null;
}
// from EntryRep
private boolean usableField(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)));
}
private Entry generateTemplate(Entry attr) {
try {
Class realClass = attr.getClass();
Entry template = (Entry) realClass.newInstance();
Field[] f = realClass.getFields();
for(int i = 0; i < f.length; i++)
f[i].set(template, null);
return template;
} catch (Throwable t) {
logger.log(Level.INFO, "instantiating template failed", t);
}
return null;
}
class DoubleClicker extends MouseAdapter {
AttributeTreePanel parent;
public DoubleClicker(AttributeTreePanel parent){
this.parent = parent;
}
public void mouseClicked(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(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();
// center in parent frame
Rectangle bounds = ServiceEditor.this.getBounds();
Dimension dialogSize = getPreferredSize();
setLocation(bounds.x + (bounds.width - dialogSize.width)/ 2,
bounds.y + (bounds.height - dialogSize.height)/2);
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(String title) {
super(title);
}
protected void initListModel() {
if (!(admin instanceof JoinAdmin)) {
return;
}
try {
String[] groups = ((JoinAdmin) admin).getLookupGroups();
for(int i = 0; i < groups.length; i++) {
model.addElement(new GroupItem(groups[i]));
}
} catch (Throwable t) {
logger.log(Level.INFO, "obtaining groups failed", t);
}
}
protected String getAddMessage() {
return "Enter adding group(s)";
}
protected String getRemoveMessage(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(((GroupItem) items[i]).toString());
}
return msg.toString();
}
protected void addItems(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(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(String title) {
super(title);
}
protected void initListModel() {
try {
String[] groups = ((DiscoveryAdmin) admin).getMemberGroups();
for(int i = 0; i < groups.length; i++) {
model.addElement(new GroupItem(groups[i]));
}
} catch (Throwable t) {
logger.log(Level.INFO, "obtaining groups failed", t);
}
}
protected String getAddMessage() {
return "Enter adding group(s)";
}
protected String getRemoveMessage(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(((GroupItem) items[i]).toString());
}
return msg.toString();
}
protected void addItems(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(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(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(String title) {
super(title);
}
protected void initListModel() {
if (!(admin instanceof JoinAdmin)) {
return;
}
try {
LookupLocator[] locators = ((JoinAdmin) admin).getLookupLocators();
for(int i = 0; i < locators.length; i++) {
model.addElement(locators[i]);
}
} catch (Throwable t) {
logger.log(Level.INFO, "obtaining locators failed", t);
}
}
protected String getAddMessage() {
return "Enter a new locator's URL";
}
protected String getRemoveMessage(Object[] items) {
StringBuffer msg = new StringBuffer();
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(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(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(ActionEvent anEvent) {
UIDescriptor uiDescriptor = getSelectedUIDescriptor();
if (uiDescriptor == null) {
return;
}
try {
JFrameFactory uiFactory = (JFrameFactory)
uiDescriptor.getUIFactory(Thread.currentThread().getContextClassLoader());
JFrame frame = uiFactory.getJFrame(serviceItem);
frame.validate();
frame.setVisible(true);
}
catch (Exception e) {
e.printStackTrace();
return;
}
}
public void popupMenuWillBecomeVisible(PopupMenuEvent ev) {
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) {
}
public void popupMenuCanceled(PopupMenuEvent ev) {
}
public void setServiceItem(ServiceItem anItem) {
serviceItem = anItem;
}
}
class MouseReceiver extends MouseAdapter {
private ServiceEditor.UIDescriptorPopup popup;
private ServiceItem serviceItem;
public MouseReceiver(ServiceItem aServiceItem,
ServiceEditor.UIDescriptorPopup popup) {
this.popup = popup;
serviceItem = aServiceItem;
}
public void mouseReleased(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(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(MouseEvent event) {
attrPanel.tree.setSelectionPath(attrPanel.tree.getPathForLocation(
event.getX(), event.getY()));
}
private ServiceEditor.UIDescriptorPopup uiDescriptorPopup() {
return new ServiceEditor.UIDescriptorPopup();
}
}