1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.river.example.browser;
19
20 import java.awt.BorderLayout;
21 import java.awt.Dimension;
22 import java.awt.Rectangle;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.MouseAdapter;
26 import java.awt.event.MouseEvent;
27 import java.awt.event.WindowAdapter;
28 import java.awt.event.WindowEvent;
29 import java.lang.reflect.Field;
30 import java.lang.reflect.Modifier;
31 import java.net.MalformedURLException;
32 import java.rmi.server.ExportException;
33 import java.util.StringTokenizer;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36 import javax.swing.DefaultListModel;
37 import javax.swing.JButton;
38 import javax.swing.JFrame;
39 import javax.swing.JList;
40 import javax.swing.JMenu;
41 import javax.swing.JMenuBar;
42 import javax.swing.JMenuItem;
43 import javax.swing.JOptionPane;
44 import javax.swing.JPanel;
45 import javax.swing.JPopupMenu;
46 import javax.swing.JScrollPane;
47 import javax.swing.JTree;
48 import javax.swing.SwingUtilities;
49 import javax.swing.event.PopupMenuEvent;
50 import javax.swing.event.PopupMenuListener;
51 import javax.swing.tree.TreePath;
52 import net.jini.admin.JoinAdmin;
53 import net.jini.config.ConfigurationException;
54 import net.jini.core.discovery.LookupLocator;
55 import net.jini.core.entry.Entry;
56 import net.jini.core.event.EventRegistration;
57 import net.jini.core.event.RemoteEvent;
58 import net.jini.core.event.RemoteEventListener;
59 import net.jini.core.lease.Lease;
60 import net.jini.core.lookup.ServiceEvent;
61 import net.jini.core.lookup.ServiceItem;
62 import net.jini.core.lookup.ServiceMatches;
63 import net.jini.core.lookup.ServiceRegistrar;
64 import net.jini.core.lookup.ServiceTemplate;
65 import net.jini.export.Exporter;
66 import net.jini.jeri.BasicILFactory;
67 import net.jini.jeri.BasicJeriExporter;
68 import net.jini.jeri.tcp.TcpServerEndpoint;
69 import net.jini.lookup.DiscoveryAdmin;
70 import net.jini.lookup.SafeServiceRegistrar;
71 import net.jini.lookup.entry.UIDescriptor;
72 import net.jini.lookup.ui.factory.JFrameFactory;
73 import net.jini.security.TrustVerifier;
74 import net.jini.security.proxytrust.ServerProxyTrust;
75 import org.apache.river.admin.DestroyAdmin;
76 import org.apache.river.config.Config;
77 import org.apache.river.logging.Levels;
78 import org.apache.river.proxy.BasicProxyTrustVerifier;
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 class ServiceEditor extends JFrame {
97 private static final Logger logger = Browser.logger;
98
99 private Browser browser;
100 private ServiceItem item;
101 private SafeServiceRegistrar registrar;
102 protected Object admin;
103 private ServiceTemplate stmpl;
104 private NotifyReceiver receiver;
105 private Lease elease = null;
106 private long eventID = 0;
107 private long seqNo = Long.MAX_VALUE;
108 private AttributeTreePanel attrPanel;
109
110 private final static int MINIMUM_WINDOW_WIDTH = 320;
111
112 public ServiceEditor(ServiceItem item,
113 Object admin,
114 SafeServiceRegistrar registrar,
115 Browser browser)
116 {
117 super("ServiceItem Editor");
118
119 this.item = item;
120 this.admin = admin;
121 this.registrar = registrar;
122 this.browser = browser;
123
124
125 attrPanel = new AttributeTreePanel();
126
127
128 try {
129 stmpl = new ServiceTemplate(item.serviceID,
130 new Class[] { item.service.getClass() },
131 new Entry[] {});
132 receiver = new NotifyReceiver();
133
134 setupNotify();
135 } catch (Throwable t) {
136 logger.log(Level.INFO, "event registration failed", t);
137 cancelNotify();
138 }
139
140 addWindowListener(browser.wrap(new WindowAdapter() {
141 public void windowClosing(WindowEvent e) {
142 cleanup();
143 }
144 }));
145
146 getContentPane().setLayout(new BorderLayout());
147 getContentPane().add(new JoinMenuBar(), "North");
148 getContentPane().add(attrPanel, "Center");
149
150 validate();
151 pack();
152 setSize(((getSize().width < MINIMUM_WINDOW_WIDTH) ? MINIMUM_WINDOW_WIDTH : getSize().width),
153 getSize().height);
154
155
156 Rectangle bounds = browser.getBounds();
157 Dimension dialogSize = getPreferredSize();
158 int xpos = bounds.x + (bounds.width - dialogSize.width)/ 2;
159 int ypos = bounds.y + (bounds.height - dialogSize.height)/2;
160 setLocation((xpos < 0) ? 0 : xpos,
161 (ypos < 0) ? 0 : ypos);
162 }
163
164 void cleanup() {
165
166 cancelNotify();
167
168 dispose();
169 receiver.unexport();
170 }
171
172 protected void cancelNotify() {
173 if(elease != null) {
174 try {
175 browser.leaseMgr.cancel(elease);
176 } catch (Throwable t) {
177 logger.log(Levels.HANDLED, "event cancellation failed", t);
178 }
179 elease = null;
180 seqNo = Long.MAX_VALUE;
181 }
182 }
183
184 protected void setupNotify() {
185 if(registrar != null) {
186 try {
187 EventRegistration reg =
188 registrar.notiFy(stmpl,
189 ServiceRegistrar.TRANSITION_MATCH_NOMATCH |
190 ServiceRegistrar.TRANSITION_NOMATCH_MATCH |
191 ServiceRegistrar.TRANSITION_MATCH_MATCH,
192 receiver.proxy,
193 null,
194 Lease.ANY);
195 elease = (Lease) browser.leasePreparer.prepareProxy(reg.getLease());
196 browser.leaseMgr.renewUntil(elease, Lease.ANY,
197 new Browser.LeaseNotify());
198 eventID = reg.getID();
199 seqNo = reg.getSequenceNumber();
200 } catch (Throwable t) {
201 logger.log(Level.INFO, "event registration failed", t);
202 }
203 }
204 }
205
206 private class NotifyReceiver implements RemoteEventListener, ServerProxyTrust
207 {
208 private final Exporter exporter;
209 final RemoteEventListener proxy;
210
211 public NotifyReceiver() throws ConfigurationException, ExportException {
212 exporter = (Exporter)
213 Config.getNonNullEntry(browser.config, Browser.BROWSER,
214 "listenerExporter", Exporter.class,
215 new BasicJeriExporter(
216 TcpServerEndpoint.getInstance(0),
217 new BasicILFactory(),
218 false, false));
219 proxy = (RemoteEventListener) exporter.export(this);
220 }
221
222 public void notify(final RemoteEvent ev) {
223 SwingUtilities.invokeLater(browser.wrap(new Runnable() {
224 public void run() {
225 if (eventID == ev.getID() && seqNo < ev.getSequenceNumber()) {
226 seqNo = ev.getSequenceNumber();
227 attrPanel.receiveNotify(((ServiceEvent) ev).getTransition());
228 }
229 }
230 }));
231 }
232
233 public TrustVerifier getProxyVerifier() {
234 return new BasicProxyTrustVerifier(proxy);
235 }
236
237 void unexport() {
238 exporter.unexport(true);
239 }
240 }
241
242 class JoinMenuBar extends JMenuBar {
243 public JoinMenuBar() {
244 JMenuItem mitem;
245
246
247 JMenu fileMenu = (JMenu) add(new JMenu("File"));
248 mitem = (JMenuItem) fileMenu.add(new JMenuItem("Show Info"));
249 mitem.addActionListener(browser.wrap(new ActionListener() {
250 public void actionPerformed(ActionEvent ev) {
251 Class[] infs = Browser.getInterfaces(item.service.getClass());
252 String[] msg = new String[3 + infs.length];
253 msg[0] = "ServiceID: " + item.serviceID;
254 msg[1] = "Service Instance: " + item.service.getClass().getName();
255 if(infs.length == 1)
256 msg[2] = "Implemented Interface:";
257 else
258 msg[2] = "Implemented Interfaces:";
259 for(int i = 0; i < infs.length; i++)
260 msg[3 + i] = " " + infs[i].getName();
261
262 JOptionPane.showMessageDialog(ServiceEditor.this,
263 msg,
264 "ServiceItem Information",
265 JOptionPane.INFORMATION_MESSAGE);
266 }
267 }));
268 mitem = (JMenuItem) fileMenu.add(new JMenuItem("Refresh"));
269 mitem.addActionListener(browser.wrap(new ActionListener() {
270 public void actionPerformed(ActionEvent ev) {
271 attrPanel.refreshPanel();
272 }
273 }));
274 mitem = (JMenuItem) fileMenu.add(new JMenuItem("Close"));
275 mitem.addActionListener(browser.wrap(new ActionListener() {
276 public void actionPerformed(ActionEvent ev) {
277 cleanup();
278 }
279 }));
280
281
282 JMenu editMenu = (JMenu) add(new JMenu("Edit"));
283 mitem = (JMenuItem) editMenu.add(new JMenuItem("Add Attribute..."));
284 mitem.addActionListener(browser.wrap(new ActionListener() {
285 public void actionPerformed(ActionEvent ev) {
286 attrPanel.addAttr();
287 }
288 }));
289 if(! (admin instanceof JoinAdmin))
290 mitem.setEnabled(false);
291 mitem = (JMenuItem) editMenu.add(new JMenuItem("Remove Attribute"));
292 mitem.addActionListener(browser.wrap(new ActionListener() {
293 public void actionPerformed(ActionEvent ev) {
294 attrPanel.removeAttr();
295 }
296 }));
297 if(! (admin instanceof JoinAdmin))
298 mitem.setEnabled(false);
299
300
301 JMenu adminMenu = (JMenu) add(new JMenu("Admin"));
302
303
304 mitem = (JMenuItem) adminMenu.add(new JMenuItem("Joining groups..."));
305 mitem.addActionListener(browser.wrap(new ActionListener() {
306 public void actionPerformed(ActionEvent ev) {
307 new GroupLister("Joining Groups").showFrame();
308 }
309 }));
310 if(! (admin instanceof JoinAdmin))
311 mitem.setEnabled(false);
312
313
314 mitem = (JMenuItem) adminMenu.add(new JMenuItem("Joining locators..."));
315 mitem.addActionListener(browser.wrap(new ActionListener() {
316 public void actionPerformed(ActionEvent ev) {
317 new LocatorLister("Joining Locators").showFrame();
318 }
319 }));
320 if(! (admin instanceof JoinAdmin))
321 mitem.setEnabled(false);
322
323
324 adminMenu.addSeparator();
325
326
327 mitem = (JMenuItem) adminMenu.add(new JMenuItem("Member groups..."));
328 mitem.addActionListener(browser.wrap(new ActionListener() {
329 public void actionPerformed(ActionEvent ev) {
330 new MemberGroupLister("Member Groups").showFrame();
331 }
332 }));
333 if(! (admin instanceof DiscoveryAdmin))
334 mitem.setEnabled(false);
335
336
337 mitem = (JMenuItem) adminMenu.add(new JMenuItem("Unicast port..."));
338 mitem.addActionListener(browser.wrap(new ActionListener() {
339 public void actionPerformed(ActionEvent ev) {
340 try {
341 String[] msg = { "Current port is " + ((DiscoveryAdmin) admin).getUnicastPort(),
342 "Input a new value" };
343 String result = JOptionPane.showInputDialog(ServiceEditor.this,
344 msg,
345 "Unicast Port",
346 JOptionPane.QUESTION_MESSAGE);
347
348 if(result == null)
349 return;
350
351 try {
352 int port = Integer.parseInt(result);
353 ((DiscoveryAdmin) admin).setUnicastPort(port);
354 } catch (NumberFormatException e) {
355 JOptionPane.showMessageDialog(ServiceEditor.this,
356 result + " is not acceptable.",
357 "Error",
358 JOptionPane.ERROR_MESSAGE);
359 } catch (Throwable t) {
360 logger.log(Level.INFO, "setting unicast port failed", t);
361 JOptionPane.showMessageDialog(ServiceEditor.this,
362 t.getMessage(),
363 t.getClass().getName(),
364 JOptionPane.ERROR_MESSAGE);
365 }
366 } catch (Throwable t) {
367 logger.log(Level.INFO, "getting unicast port failed", t);
368 JOptionPane.showMessageDialog(ServiceEditor.this,
369 t.getMessage(),
370 t.getClass().getName(),
371 JOptionPane.ERROR_MESSAGE);
372 }
373 }
374 }));
375 if(! (admin instanceof DiscoveryAdmin))
376 mitem.setEnabled(false);
377
378
379 adminMenu.addSeparator();
380
381
382 mitem = (JMenuItem) adminMenu.add(new JMenuItem("Destroy"));
383 mitem.addActionListener(browser.wrap(new ActionListener() {
384 public void actionPerformed(ActionEvent ev) {
385 if(JOptionPane.showConfirmDialog(ServiceEditor.this,
386 "Are you sure to destroy this service?",
387 "Query",
388 JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
389 try {
390 ((DestroyAdmin) admin).destroy();
391 cleanup();
392 } catch (Throwable t) {
393 logger.log(Level.INFO, "service destroy failed", t);
394 JOptionPane.showMessageDialog(ServiceEditor.this,
395 t.getMessage(),
396 t.getClass().getName(),
397 JOptionPane.ERROR_MESSAGE);
398 }
399 }
400 }));
401 if(! (admin instanceof DestroyAdmin))
402 mitem.setEnabled(false);
403 }
404 }
405
406 class AttributeTreePanel extends EntryTreePanel {
407
408 public AttributeTreePanel() {
409 super(admin instanceof JoinAdmin);
410
411 if(admin instanceof JoinAdmin) {
412 tree.addMouseListener(browser.wrap(new DoubleClicker(this)));
413 }
414 tree.addMouseListener(browser.wrap(new MouseReceiver(item, uiDescriptorPopup())));
415
416 refreshPanel();
417 }
418
419 protected Entry[] getEntryArray() {
420 if(admin instanceof JoinAdmin) {
421 try {
422 item.attributeSets = ((JoinAdmin) admin).getLookupAttributes();
423 } catch (Throwable t) {
424 logger.log(Level.INFO, "obtaining attributes failed", t);
425 }
426 } else {
427 try{
428 ServiceMatches matches = registrar.lookup(stmpl, 1);
429 if(matches.totalMatches != 1)
430 Browser.logger.log(Level.INFO, "unexpected lookup matches: {0}",
431 Integer.valueOf(matches.totalMatches));
432 else
433 item.attributeSets = matches.items[0].attributeSets;
434 } catch (Throwable t) {
435 Browser.logger.log(Level.INFO, "lookup failed", t);
436 }
437 }
438 return item.attributeSets;
439 }
440
441 protected void receiveNotify(int transition) {
442
443 if (browser.isAutoConfirm()) {
444 if (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH)
445 cleanup();
446 else
447 refreshPanel();
448
449 return;
450 }
451
452 String[] msg =
453 (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH) ?
454 new String[]{
455 "Service has been removed from lookup service.",
456 "Do you want to close the service editor window ?"} :
457 new String[]{
458 "Attributes have been modified by another client or the service itself.",
459 "Do you want to refresh the attributes ?"};
460 int result = JOptionPane.showConfirmDialog(AttributeTreePanel.this,
461 msg,
462 "Query",
463 JOptionPane.YES_NO_OPTION);
464
465 if(result == JOptionPane.YES_OPTION) {
466 if (transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH)
467 cleanup();
468 else
469 refreshPanel();
470 }
471 }
472
473 public void editField(ObjectNode node) {
474
475 String result = JOptionPane.showInputDialog(this,
476 "Input a new value",
477 "Modify a field",
478 JOptionPane.QUESTION_MESSAGE);
479
480 if(result == null){
481 } else {
482
483 Entry template = cloneEntry((Entry) node.getEntryTop());
484 Object oldVal = null;
485
486 if(result.length() == 0){
487 oldVal = node.setValue(null);
488 } else {
489 oldVal = node.setValue(result);
490 }
491
492 try {
493 node.setObjectRecursive();
494 Entry attr = (Entry) node.getEntryTop();
495
496
497
498 cancelNotify();
499
500 ((JoinAdmin) admin).modifyLookupAttributes(
501 new Entry[] { template }, new Entry[] { attr });
502
503 setupNotify();
504
505
506 model.nodeChanged(node);
507 } catch (Throwable t) {
508 logger.log(Level.INFO, "attribute modification failed", t);
509
510 try {
511 node.setValue(oldVal);
512 node.setObjectRecursive();
513 } catch (Throwable tt) {
514 logger.log(Levels.HANDLED, "node reset failed", tt);
515 }
516 model.nodeChanged(node);
517
518
519
520 JOptionPane.showMessageDialog(AttributeTreePanel.this,
521 t.getMessage(),
522 t.getClass().getName(),
523 JOptionPane.ERROR_MESSAGE);
524 }
525 }
526 }
527
528 public void addAttr() {
529
530 String result = JOptionPane.showInputDialog(this,
531 "Input an entry class name",
532 "Add an attribute",
533 JOptionPane.QUESTION_MESSAGE);
534
535 if(result == null || result.length() == 0){
536 } else {
537 try {
538 Class clazz = Class.forName(result);
539 Object attr = clazz.newInstance();
540
541 if(! (attr instanceof Entry)){
542 JOptionPane.showMessageDialog(AttributeTreePanel.this,
543 "Does not implement Entry interface",
544 "Unacceptable Class",
545 JOptionPane.WARNING_MESSAGE);
546
547 } else if(attr instanceof net.jini.lookup.entry.ServiceControlled){
548 JOptionPane.showMessageDialog(AttributeTreePanel.this,
549 "Implements ServiceControlled interface",
550 "Unacceptable Class",
551 JOptionPane.WARNING_MESSAGE);
552 } else {
553
554 cancelNotify();
555
556 ((JoinAdmin) admin).addLookupAttributes(
557 new Entry[] { (Entry) attr });
558
559 ObjectNode node = new ObjectNode(attr, true);
560 root.add(node);
561 recursiveObjectTree(node);
562
563
564 setupNotify();
565
566
567 model.nodesWereInserted(root,
568 new int[] { model.getIndexOfChild(root, node) });
569 }
570 } catch (ClassNotFoundException e) {
571 JOptionPane.showMessageDialog(AttributeTreePanel.this,
572 e.getMessage(),
573 "Class Not Found",
574 JOptionPane.WARNING_MESSAGE);
575 } catch (Throwable t) {
576 logger.log(Level.INFO, "adding attribute failed", t);
577 JOptionPane.showMessageDialog(AttributeTreePanel.this,
578 t.getMessage(),
579 t.getClass().getName(),
580 JOptionPane.WARNING_MESSAGE);
581 }
582 }
583 }
584
585 public void removeAttr() {
586
587 ObjectNode node = (ObjectNode) tree.getLastSelectedPathComponent();
588 if(node == null){
589 JOptionPane.showMessageDialog(AttributeTreePanel.this,
590 "Select an attribute folder to remove.",
591 "Warning",
592 JOptionPane.WARNING_MESSAGE);
593
594 return;
595 } else if(! node.isControllable()){
596 JOptionPane.showMessageDialog(AttributeTreePanel.this,
597 "This attribute is under service provider's control.",
598 "Warning",
599 JOptionPane.WARNING_MESSAGE);
600
601 return;
602 } else if(! node.isEntryTop()){
603 JOptionPane.showMessageDialog(AttributeTreePanel.this,
604 "Select a top of attribute folder.",
605 "Warning",
606 JOptionPane.WARNING_MESSAGE);
607
608 return;
609 }
610
611 Entry target = (Entry) node.getObject();
612 int result = JOptionPane.showConfirmDialog(AttributeTreePanel.this,
613 new String[] {"Remove attribute:",
614 target.toString() },
615 "Query",
616 JOptionPane.YES_NO_OPTION);
617
618 if(result == JOptionPane.YES_OPTION){
619
620 try {
621
622
623 cancelNotify();
624
625 ((JoinAdmin) admin).modifyLookupAttributes(
626 new Entry[] { target }, new Entry[] { null });
627
628
629 setupNotify();
630
631 int index = root.getIndex(node);
632 root.remove(node);
633 model.nodesWereRemoved(root, new int[] {index}, new Object[] {node});
634 node = null;
635 } catch (Throwable t) {
636 logger.log(Level.INFO, "attribute removal failed", t);
637 JOptionPane.showMessageDialog(AttributeTreePanel.this,
638 t.getMessage(),
639 t.getClass().getName(),
640 JOptionPane.ERROR_MESSAGE);
641 }
642 }
643 }
644
645 private Entry cloneEntry(Entry attr) {
646 try {
647 Class realClass = attr.getClass();
648 Entry template = (Entry) realClass.newInstance();
649
650 Field[] f = realClass.getFields();
651 for(int i = 0; i < f.length; i++) {
652 if(! usableField(f[i]))
653 continue;
654 f[i].set(template, f[i].get(attr));
655 }
656
657 return template;
658 } catch (Throwable t) {
659 logger.log(Level.INFO, "duplicating entry failed", t);
660 }
661 return null;
662 }
663
664
665 private boolean usableField(Field field) {
666 Class desc = field.getDeclaringClass();
667
668 if(desc.isPrimitive()) {
669 throw new IllegalArgumentException("primitive types not allowed in an Entry");
670 }
671
672
673 int mods = field.getModifiers();
674 return (0 == (mods & (Modifier.TRANSIENT | Modifier.STATIC | Modifier.FINAL)));
675 }
676
677 private Entry generateTemplate(Entry attr) {
678 try {
679 Class realClass = attr.getClass();
680 Entry template = (Entry) realClass.newInstance();
681
682 Field[] f = realClass.getFields();
683 for(int i = 0; i < f.length; i++)
684 f[i].set(template, null);
685
686 return template;
687 } catch (Throwable t) {
688 logger.log(Level.INFO, "instantiating template failed", t);
689 }
690 return null;
691 }
692
693 class DoubleClicker extends MouseAdapter {
694 AttributeTreePanel parent;
695
696 public DoubleClicker(AttributeTreePanel parent){
697 this.parent = parent;
698 }
699
700 public void mouseClicked(MouseEvent ev){
701 if(ev.getClickCount() >= 2){
702 JTree tree = (JTree) ev.getSource();
703 TreePath path = tree.getPathForLocation(ev.getX(), ev.getY());
704 if(path == null)
705 return;
706 ObjectNode node = (ObjectNode) path.getLastPathComponent();
707
708 if(node.isLeaf()){
709 if(! node.isControllable()){
710 JOptionPane.showMessageDialog(AttributeTreePanel.this,
711 "This attribute is under service provider's control.",
712 "Warning",
713 JOptionPane.WARNING_MESSAGE);
714 } else if(node.isEditable() &&
715 ((ObjectNode) node.getParent()).isEntryTop())
716 {
717 parent.editField(node);
718 } else {
719 JOptionPane.showMessageDialog(AttributeTreePanel.this,
720 "This field is not editable.",
721 "Warning",
722 JOptionPane.WARNING_MESSAGE);
723 }
724 }
725
726 tree.scrollPathToVisible(path);
727 }
728 }
729 }
730 }
731
732 abstract class ListerFrame extends JFrame {
733
734 private JList listBox;
735 private JScrollPane scrollPane;
736 protected DefaultListModel model = new DefaultListModel();
737 private DefaultListModel dummyModel = new DefaultListModel();
738
739 private JButton addButton;
740 private JButton removeButton;
741 private JButton closeButton;
742
743 public ListerFrame(String title) {
744 super(title);
745
746 getContentPane().setLayout(new BorderLayout());
747
748
749 listBox = new JList(model);
750 listBox.setFixedCellHeight(20);
751 scrollPane = new JScrollPane(listBox);
752 getContentPane().add(scrollPane, "Center");
753
754
755
756 JPanel buttonPanel = new JPanel();
757 addButton = new JButton("Add");
758 addButton.addActionListener(browser.wrap(new ActionListener() {
759 public void actionPerformed(ActionEvent ev) {
760 String result = JOptionPane.showInputDialog(ListerFrame.this, getAddMessage());
761
762 if(result != null){
763 StringTokenizer st = new StringTokenizer(result);
764 String[] tokens = new String[st.countTokens()];
765 for(int i = 0; i < tokens.length; i++)
766 tokens[i] = st.nextToken().trim();
767
768 addItems(tokens);
769 resetListModel();
770 scrollPane.validate();
771 }
772 }
773 }));
774 buttonPanel.add(addButton);
775
776 removeButton = new JButton("Remove");
777 removeButton.addActionListener(browser.wrap(new ActionListener() {
778 public void actionPerformed(ActionEvent ev) {
779 Object[] selected = listBox.getSelectedValues();
780
781 if(selected == null || selected.length == 0){
782
783 JOptionPane.showMessageDialog(ListerFrame.this,
784 "No items are selected",
785 "Warning",
786 JOptionPane.WARNING_MESSAGE);
787 return;
788 }
789
790 int result = JOptionPane.showConfirmDialog(ListerFrame.this,
791 getRemoveMessage(selected),
792 "Query",
793 JOptionPane.YES_NO_OPTION);
794
795 if(result == JOptionPane.YES_OPTION){
796 removeItems(selected);
797 resetListModel();
798 scrollPane.validate();
799 }
800 }
801 }));
802 buttonPanel.add(removeButton);
803
804 closeButton = new JButton("Close");
805 closeButton.addActionListener(browser.wrap(new ActionListener() {
806 public void actionPerformed(ActionEvent ev) {
807 setVisible(false);
808 }
809 }));
810 buttonPanel.add(closeButton);
811 getContentPane().add(buttonPanel, "South");
812
813 pack();
814 }
815
816 public void showFrame() {
817
818 resetListModel();
819
820
821 Rectangle bounds = ServiceEditor.this.getBounds();
822 Dimension dialogSize = getPreferredSize();
823
824 setLocation(bounds.x + (bounds.width - dialogSize.width)/ 2,
825 bounds.y + (bounds.height - dialogSize.height)/2);
826
827 setVisible(true);
828 }
829
830 private void resetListModel() {
831
832 listBox.setModel(dummyModel);
833
834 model.removeAllElements();
835 initListModel();
836
837 listBox.setModel(model);
838 listBox.clearSelection();
839 listBox.ensureIndexIsVisible(0);
840 listBox.repaint();
841 listBox.revalidate();
842 }
843
844 protected abstract void initListModel();
845
846 protected abstract String getAddMessage();
847
848 protected abstract String getRemoveMessage(Object[] items);
849
850 protected abstract void addItems(String[] items);
851
852 protected abstract void removeItems(Object[] items);
853 }
854
855 class GroupLister extends ListerFrame {
856
857 public GroupLister(String title) {
858 super(title);
859 }
860
861 protected void initListModel() {
862 if (!(admin instanceof JoinAdmin)) {
863 return;
864 }
865
866 try {
867 String[] groups = ((JoinAdmin) admin).getLookupGroups();
868 for(int i = 0; i < groups.length; i++) {
869 model.addElement(new GroupItem(groups[i]));
870 }
871 } catch (Throwable t) {
872 logger.log(Level.INFO, "obtaining groups failed", t);
873 }
874 }
875
876 protected String getAddMessage() {
877 return "Enter adding group(s)";
878 }
879
880 protected String getRemoveMessage(Object[] items) {
881 StringBuffer msg = new StringBuffer();
882 if(items.length > 1)
883 msg.append("Remove these groups : ");
884 else
885 msg.append("Remove a group : ");
886 for(int i = 0; i < items.length; i++) {
887 if(i != 0)
888 msg.append(", ");
889 msg.append(((GroupItem) items[i]).toString());
890 }
891 return msg.toString();
892 }
893
894 protected void addItems(String[] items) {
895
896 String[] grps = new String[items.length];
897 for(int i = 0; i < items.length; i++)
898 grps[i] = new GroupItem(items[i]).group;
899
900 try {
901 ((JoinAdmin) admin).addLookupGroups(grps);
902 } catch (Throwable t) {
903 logger.log(Level.INFO, "adding groups failed", t);
904 }
905 }
906
907 protected void removeItems(Object[] items) {
908 String[] grps = new String[items.length];
909 for(int i = 0; i < items.length; i++)
910 grps[i] = ((GroupItem) items[i]).group;
911
912 try {
913 ((JoinAdmin) admin).removeLookupGroups(grps);
914 } catch (Throwable t) {
915 logger.log(Level.INFO, "removing groups failed", t);
916 }
917 }
918 }
919
920 class MemberGroupLister extends ListerFrame {
921
922 public MemberGroupLister(String title) {
923 super(title);
924 }
925
926 protected void initListModel() {
927 try {
928 String[] groups = ((DiscoveryAdmin) admin).getMemberGroups();
929 for(int i = 0; i < groups.length; i++) {
930 model.addElement(new GroupItem(groups[i]));
931 }
932 } catch (Throwable t) {
933 logger.log(Level.INFO, "obtaining groups failed", t);
934 }
935 }
936
937 protected String getAddMessage() {
938 return "Enter adding group(s)";
939 }
940
941 protected String getRemoveMessage(Object[] items) {
942 StringBuffer msg = new StringBuffer();
943 if(items.length > 1)
944 msg.append("Remove these groups : ");
945 else
946 msg.append("Remove a group : ");
947 for(int i = 0; i < items.length; i++) {
948 if(i != 0)
949 msg.append(", ");
950 msg.append(((GroupItem) items[i]).toString());
951 }
952 return msg.toString();
953 }
954
955 protected void addItems(String[] items) {
956
957 String[] grps = new String[items.length];
958 for(int i = 0; i < items.length; i++)
959 grps[i] = new GroupItem(items[i]).group;
960
961 try {
962 ((DiscoveryAdmin) admin).addMemberGroups(grps);
963 } catch (Throwable t) {
964 logger.log(Level.INFO, "adding groups failed", t);
965 }
966 }
967
968 protected void removeItems(Object[] items) {
969 String[] grps = new String[items.length];
970 for(int i = 0; i < items.length; i++)
971 grps[i] = ((GroupItem) items[i]).group;
972
973 try {
974 ((DiscoveryAdmin) admin).removeMemberGroups(grps);
975 } catch (Throwable t){
976 logger.log(Level.INFO, "removing groups failed", t);
977 }
978 }
979 }
980
981 class GroupItem {
982 public String group;
983
984 public GroupItem(String group) {
985 if(group.equals("public"))
986 this.group = "";
987 else
988 this.group = group;
989 }
990
991 public String toString() {
992 if("".equals(group))
993 return "public";
994 else
995 return group;
996 }
997 }
998
999 class LocatorLister extends ListerFrame {
1000
1001 public LocatorLister(String title) {
1002 super(title);
1003 }
1004
1005 protected void initListModel() {
1006 if (!(admin instanceof JoinAdmin)) {
1007 return;
1008 }
1009
1010 try {
1011 LookupLocator[] locators = ((JoinAdmin) admin).getLookupLocators();
1012 for(int i = 0; i < locators.length; i++) {
1013 model.addElement(locators[i]);
1014 }
1015 } catch (Throwable t) {
1016 logger.log(Level.INFO, "obtaining locators failed", t);
1017 }
1018 }
1019
1020 protected String getAddMessage() {
1021 return "Enter a new locator's URL";
1022 }
1023
1024 protected String getRemoveMessage(Object[] items) {
1025 StringBuffer msg = new StringBuffer();
1026 if(items.length > 1)
1027 msg.append("Remove these locators : ");
1028 else
1029 msg.append("Remove a locator : ");
1030 for(int i = 0; i < items.length; i++) {
1031 if(i != 0)
1032 msg.append(", ");
1033 msg.append(items[i].toString());
1034 }
1035 return msg.toString();
1036 }
1037
1038 protected void addItems(String[] items) {
1039 LookupLocator[] locs = new LookupLocator[items.length];
1040 for(int i = 0; i < items.length; i++) {
1041 try {
1042 locs[i] = new LookupLocator(items[i]);
1043 } catch (MalformedURLException e) {
1044 JOptionPane.showMessageDialog(LocatorLister.this,
1045 "\"" + items[i] + "\": " +
1046 e.getMessage(),
1047 "Bad Locator",
1048 JOptionPane.WARNING_MESSAGE);
1049 return;
1050 }
1051 }
1052
1053 try {
1054 ((JoinAdmin) admin).addLookupLocators(locs);
1055 } catch (Throwable t){
1056 logger.log(Level.INFO, "adding locators failed", t);
1057 }
1058 }
1059
1060 protected void removeItems(Object[] items) {
1061 LookupLocator[] locs = new LookupLocator[items.length];
1062 for(int i = 0; i < items.length; i++)
1063 locs[i] = (LookupLocator) items[i];
1064
1065 try {
1066 ((JoinAdmin) admin).removeLookupLocators(locs);
1067 } catch (Throwable t) {
1068 logger.log(Level.INFO, "removing locators failed", t);
1069 }
1070 }
1071 }
1072
1073
1074 public class UIDescriptorPopup extends JPopupMenu implements ActionListener,
1075 PopupMenuListener {
1076
1077 protected transient JMenuItem showUIItem;
1078 protected transient ServiceItem serviceItem;
1079
1080 public UIDescriptorPopup() {
1081 super();
1082
1083 showUIItem = new JMenuItem("Show UI");
1084
1085 showUIItem.addActionListener(this);
1086 showUIItem.setActionCommand("showUI");
1087 add(showUIItem);
1088
1089 addPopupMenuListener(this);
1090 setOpaque(true);
1091 setLightWeightPopupEnabled(true);
1092 }
1093
1094 public void actionPerformed(ActionEvent anEvent) {
1095
1096 UIDescriptor uiDescriptor = getSelectedUIDescriptor();
1097
1098 if (uiDescriptor == null) {
1099 return;
1100 }
1101
1102 try {
1103 JFrameFactory uiFactory = (JFrameFactory)
1104 uiDescriptor.getUIFactory(Thread.currentThread().getContextClassLoader());
1105 JFrame frame = uiFactory.getJFrame(serviceItem);
1106
1107 frame.validate();
1108 frame.setVisible(true);
1109 }
1110 catch (Exception e) {
1111 e.printStackTrace();
1112
1113 return;
1114 }
1115 }
1116
1117 public void popupMenuWillBecomeVisible(PopupMenuEvent ev) {
1118 }
1119
1120 public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) {
1121 }
1122
1123 public void popupMenuCanceled(PopupMenuEvent ev) {
1124 }
1125
1126 public void setServiceItem(ServiceItem anItem) {
1127 serviceItem = anItem;
1128 }
1129 }
1130
1131 class MouseReceiver extends MouseAdapter {
1132
1133 private ServiceEditor.UIDescriptorPopup popup;
1134 private ServiceItem serviceItem;
1135
1136 public MouseReceiver(ServiceItem aServiceItem,
1137 ServiceEditor.UIDescriptorPopup popup) {
1138 this.popup = popup;
1139 serviceItem = aServiceItem;
1140 }
1141
1142 public void mouseReleased(MouseEvent ev) {
1143
1144 higlightSelection(ev);
1145
1146 if (!ev.isPopupTrigger()) {
1147 return;
1148 }
1149
1150 UIDescriptor selectedDescriptor = getSelectedUIDescriptor();
1151
1152 if (selectedDescriptor == null) {
1153 return;
1154 }
1155
1156 if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
1157 return;
1158 }
1159
1160 popup.setServiceItem(serviceItem);
1161 popup.show(ev.getComponent(), ev.getX(), ev.getY());
1162 }
1163
1164 public void mousePressed(MouseEvent ev) {
1165
1166 higlightSelection(ev);
1167
1168 if (!ev.isPopupTrigger()) {
1169 return;
1170 }
1171
1172 UIDescriptor selectedDescriptor = getSelectedUIDescriptor();
1173
1174 if (selectedDescriptor == null) {
1175 return;
1176 }
1177
1178 if (!"javax.swing".equals(selectedDescriptor.toolkit)) {
1179 return;
1180 }
1181
1182 popup.setServiceItem(serviceItem);
1183 popup.show(ev.getComponent(), ev.getX(), ev.getY());
1184 }
1185 }
1186
1187 private UIDescriptor getSelectedUIDescriptor() {
1188
1189 ObjectNode selectedNode =
1190 (ObjectNode) attrPanel.tree.getLastSelectedPathComponent();
1191
1192 if (selectedNode == null) {
1193 return null;
1194 }
1195
1196 Object selectedObject = selectedNode.getObject();
1197
1198 try {
1199 return (UIDescriptor) selectedObject;
1200 }
1201 catch (ClassCastException e) {
1202 return null;
1203 }
1204 }
1205
1206 private void higlightSelection(MouseEvent event) {
1207 attrPanel.tree.setSelectionPath(attrPanel.tree.getPathForLocation(
1208 event.getX(), event.getY()));
1209 }
1210
1211 private ServiceEditor.UIDescriptorPopup uiDescriptorPopup() {
1212 return new ServiceEditor.UIDescriptorPopup();
1213 }
1214 }