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.Component;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.awt.event.MouseAdapter;
25 import java.awt.event.MouseEvent;
26 import java.awt.event.MouseListener;
27 import java.awt.event.WindowAdapter;
28 import java.awt.event.WindowEvent;
29 import java.awt.event.WindowListener;
30 import java.io.IOException;
31 import java.io.ObjectStreamException;
32 import java.io.ObjectStreamField;
33 import java.io.Serializable;
34 import java.lang.reflect.Field;
35 import java.lang.reflect.InvocationHandler;
36 import java.lang.reflect.InvocationTargetException;
37 import java.lang.reflect.Method;
38 import java.lang.reflect.Modifier;
39 import java.lang.reflect.Proxy;
40 import java.net.MalformedURLException;
41 import java.security.AccessController;
42 import java.security.PrivilegedActionException;
43 import java.security.PrivilegedExceptionAction;
44 import java.util.Arrays;
45 import java.util.HashSet;
46 import java.util.Iterator;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.Set;
50 import java.util.StringTokenizer;
51 import java.util.logging.Level;
52 import java.util.logging.Logger;
53 import javax.security.auth.Subject;
54 import javax.security.auth.login.LoginContext;
55 import javax.security.auth.login.LoginException;
56 import javax.swing.BorderFactory;
57 import javax.swing.DefaultListModel;
58 import javax.swing.Icon;
59 import javax.swing.JCheckBoxMenuItem;
60 import javax.swing.JFrame;
61 import javax.swing.JLabel;
62 import javax.swing.JList;
63 import javax.swing.JMenu;
64 import javax.swing.JMenuBar;
65 import javax.swing.JMenuItem;
66 import javax.swing.JOptionPane;
67 import javax.swing.JPanel;
68 import javax.swing.JPopupMenu;
69 import javax.swing.JRadioButtonMenuItem;
70 import javax.swing.JScrollPane;
71 import javax.swing.JTextArea;
72 import javax.swing.ListCellRenderer;
73 import javax.swing.SwingUtilities;
74 import javax.swing.border.TitledBorder;
75 import javax.swing.event.MenuEvent;
76 import javax.swing.event.MenuListener;
77 import javax.swing.event.PopupMenuEvent;
78 import javax.swing.event.PopupMenuListener;
79 import net.jini.admin.Administrable;
80 import net.jini.admin.JoinAdmin;
81 import net.jini.config.Configuration;
82 import net.jini.config.ConfigurationException;
83 import net.jini.config.ConfigurationProvider;
84 import net.jini.config.EmptyConfiguration;
85 import net.jini.config.NoSuchEntryException;
86 import net.jini.core.constraint.MethodConstraints;
87 import net.jini.core.discovery.LookupLocator;
88 import net.jini.core.entry.Entry;
89 import net.jini.core.event.EventRegistration;
90 import net.jini.core.event.RemoteEvent;
91 import net.jini.core.event.RemoteEventListener;
92 import net.jini.core.lease.Lease;
93 import net.jini.core.lookup.ServiceID;
94 import net.jini.core.lookup.ServiceItem;
95 import net.jini.core.lookup.ServiceMatches;
96 import net.jini.core.lookup.ServiceRegistrar;
97 import net.jini.core.lookup.ServiceTemplate;
98 import net.jini.discovery.Constants;
99 import net.jini.discovery.ConstrainableLookupLocator;
100 import net.jini.discovery.DiscoveryEvent;
101 import net.jini.discovery.DiscoveryGroupManagement;
102 import net.jini.discovery.DiscoveryListener;
103 import net.jini.discovery.DiscoveryLocatorManagement;
104 import net.jini.discovery.DiscoveryManagement;
105 import net.jini.discovery.LookupDiscoveryManager;
106 import net.jini.export.Exporter;
107 import net.jini.jeri.BasicILFactory;
108 import net.jini.jeri.BasicJeriExporter;
109 import net.jini.jeri.tcp.TcpServerEndpoint;
110 import net.jini.lease.LeaseListener;
111 import net.jini.lease.LeaseRenewalEvent;
112 import net.jini.lease.LeaseRenewalManager;
113 import net.jini.lookup.DiscoveryAdmin;
114 import net.jini.lookup.SafeServiceRegistrar;
115 import net.jini.lookup.entry.UIDescriptor;
116 import net.jini.lookup.ui.factory.JFrameFactory;
117 import net.jini.security.BasicProxyPreparer;
118 import net.jini.security.ProxyPreparer;
119 import net.jini.security.Security;
120 import net.jini.security.SecurityContext;
121 import net.jini.security.TrustVerifier;
122 import net.jini.security.proxytrust.ServerProxyTrust;
123 import net.jini.space.JavaSpace;
124 import net.jini.space.JavaSpace05;
125 import org.apache.river.admin.DestroyAdmin;
126 import org.apache.river.api.util.Startable;
127 import org.apache.river.config.Config;
128 import org.apache.river.logging.Levels;
129 import org.apache.river.admin.JavaSpaceAdmin;
130 import org.apache.river.proxy.BasicProxyTrustVerifier;
131 import org.apache.river.start.lifecycle.LifeCycle;
132
133
134
135
136
137
138
139
140
141
142
143 public class Browser extends JFrame implements Startable {
144 private static final long serialVersionUID = 2218152788101871451L;
145
146
147
148
149 private static final ObjectStreamField[] serialPersistentFields = {};
150
151 static final String BROWSER = "org.apache.river.example.browser";
152 static final Logger logger = Logger.getLogger(BROWSER);
153
154 private final SecurityContext ctx;
155 private final ClassLoader ccl;
156 final Configuration config;
157 private final DiscoveryGroupManagement disco;
158 private SafeServiceRegistrar lookup;
159 private Object eventSource;
160 private long eventID;
161 private long seqNo;
162 private final ActionListener exiter;
163 private final ServiceTemplate tmpl;
164 private final Listener listen;
165 private final LookupListener adder;
166 private Lease elease;
167 final ProxyPreparer leasePreparer;
168 final ProxyPreparer servicePreparer;
169 final ProxyPreparer adminPreparer;
170 private final MethodConstraints locatorConstraints;
171 final LeaseRenewalManager leaseMgr;
172 private final LeaseListener lnotify;
173 private final List ignoreInterfaces;
174 private final JTextArea text;
175 private final JMenu registrars;
176 private final JCheckBoxMenuItem esuper;
177 private final JCheckBoxMenuItem ssuper;
178 private final JCheckBoxMenuItem sclass;
179 private final boolean isAdmin;
180 private final boolean autoConfirm;
181 private final JList list;
182 private final DefaultListModel listModel;
183 private final DefaultListModel dummyModel = new DefaultListModel();
184 private final JScrollPane listScrollPane;
185
186
187
188
189
190
191
192
193
194
195
196
197 public Browser(Configuration config)
198 throws ConfigurationException, IOException
199 {
200 this(new Initializer(null, config == null ? EmptyConfiguration.INSTANCE : config));
201 }
202
203 private static class Initializer {
204 private SecurityContext ctx;
205 private ClassLoader ccl;
206 private Configuration config;
207 private DiscoveryGroupManagement disco;
208 private SafeServiceRegistrar lookup;
209 private Object eventSource;
210 private ActionListener exiter;
211 private ServiceTemplate tmpl;
212 private ProxyPreparer leasePreparer;
213 private ProxyPreparer servicePreparer;
214 private ProxyPreparer adminPreparer;
215 private MethodConstraints locatorConstraints;
216 private LeaseRenewalManager leaseMgr;
217 private List ignoreInterfaces;
218 private boolean isAdmin;
219 private boolean autoConfirm;
220 private final Exporter listenerExporter;
221 private final LifeCycle lc;
222
223 public Initializer(LifeCycle lc, Configuration config) throws ConfigurationException, IOException {
224 this.lc = lc;
225 this.exiter =
226 Config.getNonNullEntry(config, BROWSER, "exitActionListener",
227 ActionListener.class, null);
228 this.config = config;
229 ctx = Security.getContext();
230 ccl = Thread.currentThread().getContextClassLoader();
231 leaseMgr =
232 Config.getNonNullEntry(config, BROWSER, "leaseManager",
233 LeaseRenewalManager.class,
234 new LeaseRenewalManager(config));
235 isAdmin = config.getEntry(
236 BROWSER, "folderView",
237 boolean.class, Boolean.TRUE);
238 leasePreparer =
239 Config.getNonNullEntry(config, BROWSER, "leasePreparer",
240 ProxyPreparer.class,
241 new BasicProxyPreparer());
242 servicePreparer =
243 Config.getNonNullEntry(config, BROWSER, "servicePreparer",
244 ProxyPreparer.class,
245 new BasicProxyPreparer());
246 adminPreparer =
247 Config.getNonNullEntry(config, BROWSER, "adminPreparer",
248 ProxyPreparer.class,
249 new BasicProxyPreparer());
250 locatorConstraints =
251 config.getEntry(BROWSER, "locatorConstraints",
252 MethodConstraints.class, null);
253 ignoreInterfaces = Arrays.asList((String[])
254 Config.getNonNullEntry(config, BROWSER, "uninterestingInterfaces",
255 String[].class,
256 new String[]{
257 "java.io.Serializable",
258 "java.rmi.Remote",
259 "net.jini.admin.Administrable",
260 "net.jini.core.constraint.RemoteMethodControl",
261 "net.jini.id.ReferentUuid",
262 "net.jini.security.proxytrust.TrustEquivalence"}));
263 autoConfirm = config.getEntry(
264 BROWSER, "autoConfirm", boolean.class,
265 Boolean.FALSE);
266 listenerExporter =
267 Config.getNonNullEntry(config, BROWSER, "listenerExporter",
268 Exporter.class,
269 new BasicJeriExporter(
270 TcpServerEndpoint.getInstance(0),
271 new BasicILFactory(),
272 false, false));
273 try {
274 DiscoveryManagement discoMan =
275 Config.getNonNullEntry(config, BROWSER, "discoveryManager",
276 DiscoveryManagement.class);
277 if (!(discoMan instanceof DiscoveryGroupManagement)) {
278 throw new ConfigurationException(
279 "discoveryManager does not " +
280 " support DiscoveryGroupManagement");
281 } else if (!(discoMan instanceof DiscoveryLocatorManagement)) {
282 throw new ConfigurationException(
283 "discoveryManager does not " +
284 " support DiscoveryLocatorManagement");
285 }
286 this.disco = (DiscoveryGroupManagement) discoMan;
287 String[] groups = this.disco.getGroups();
288 if (groups == null || groups.length > 0) {
289 throw new ConfigurationException(
290 "discoveryManager cannot have initial groups");
291 }
292 if (((DiscoveryLocatorManagement) discoMan).getLocators().length > 0)
293 {
294 throw new ConfigurationException(
295 "discoveryManager cannot have initial locators");
296 }
297 } catch (NoSuchEntryException e) {
298 disco = new LookupDiscoveryManager(new String[0],
299 new LookupLocator[0], null,
300 config);
301 }
302 disco.setGroups((String[]) config.getEntry(BROWSER,
303 "initialLookupGroups",
304 String[].class,
305 null));
306 ((DiscoveryLocatorManagement) disco).setLocators((LookupLocator[])
307 Config.getNonNullEntry(config, BROWSER, "initialLookupLocators",
308 LookupLocator[].class,
309 new LookupLocator[0]));
310 tmpl = new ServiceTemplate(null, new Class[0], new Entry[0]);
311 }
312 }
313
314 private Browser(Initializer init){
315 this.elease = null;
316 this.seqNo = Long.MAX_VALUE;
317 this.eventID = 0;
318 ctx = init.ctx;
319 ccl = init.ccl;
320 config = init.config;
321 disco = init.disco;
322 lookup = init.lookup;
323 eventSource = init.eventSource;
324 final LifeCycle lc = init.lc;
325 exiter = wrap(
326 init.exiter == null ?
327 lc != null ?
328 new ActionListener() {
329 public void actionPerformed(ActionEvent ev) {
330 Browser.this.dispose();
331 cancelLease();
332 listen.unexport();
333 lc.unregister(Browser.this);
334 }
335 }
336 : new Exit()
337 :
338 init.exiter
339 );
340 tmpl = init.tmpl;
341 leasePreparer = init.leasePreparer;
342 servicePreparer = init.servicePreparer;
343 adminPreparer = init.adminPreparer;
344 locatorConstraints = init.locatorConstraints;
345 leaseMgr = init.leaseMgr;
346 ignoreInterfaces = init.ignoreInterfaces;
347 isAdmin = init.isAdmin;
348 autoConfirm = init.autoConfirm;
349 listen = new Listener(init.listenerExporter);
350 setTitle("Service Browser");
351 JMenuBar bar = new JMenuBar();
352 JMenu file = new JMenu("File");
353 JMenuItem allfind = new JMenuItem("Find All");
354 allfind.addActionListener(wrap(new AllFind()));
355 file.add(allfind);
356 JMenuItem pubfind = new JMenuItem("Find Public");
357 pubfind.addActionListener(wrap(new PubFind()));
358 file.add(pubfind);
359 JMenuItem multifind = new JMenuItem("Find By Group...");
360 multifind.addActionListener(wrap(new MultiFind()));
361 file.add(multifind);
362 JMenuItem unifind = new JMenuItem("Find By Address...");
363 unifind.addActionListener(wrap(new UniFind()));
364 file.add(unifind);
365 if(! isAdmin){
366 JMenuItem show = new JMenuItem("Show Matches");
367 show.addActionListener(wrap(new Show()));
368 file.add(show);
369 }
370 JMenuItem reset = new JMenuItem("Reset");
371 reset.addActionListener(wrap(new Reset()));
372 file.add(reset);
373 JMenuItem exit = new JMenuItem("Exit");
374 exit.addActionListener(exiter);
375 file.add(exit);
376 bar.add(file);
377 addWindowListener(new Exiter());
378 registrars = new JMenu("Registrar");
379 addNone(registrars);
380 bar.add(registrars);
381 JMenu options = new JMenu("Options");
382 esuper = new JCheckBoxMenuItem("Attribute supertypes", false);
383 options.add(esuper);
384 ssuper = new JCheckBoxMenuItem("Service supertypes", false);
385 options.add(ssuper);
386 sclass = new JCheckBoxMenuItem("Service classes", false);
387 options.add(sclass);
388 bar.add(options);
389 JMenu services = new JMenu("Services");
390 services.addMenuListener(wrap(new Services(services)));
391 bar.add(services);
392 JMenu attrs = new JMenu("Attributes");
393 attrs.addMenuListener(wrap(new Entries(attrs)));
394 bar.add(attrs);
395 setJMenuBar(bar);
396
397 getContentPane().setLayout(new BorderLayout());
398 int textRows = 8;
399 if(isAdmin){
400 textRows = 4;
401 JPanel bpanel = new JPanel();
402 bpanel.setLayout(new BorderLayout());
403
404 TitledBorder border = BorderFactory.createTitledBorder("Matching Services");
405 border.setTitlePosition(TitledBorder.TOP);
406 border.setTitleJustification(TitledBorder.LEFT);
407 bpanel.setBorder(border);
408
409 listModel = new DefaultListModel();
410 list = new JList(listModel);
411 list.setFixedCellHeight(20);
412 list.setCellRenderer((ListCellRenderer)
413 wrap(new ServiceItemRenderer(), ListCellRenderer.class));
414 list.addMouseListener(
415 wrap(new MouseReceiver(new ServiceListPopup())));
416 listScrollPane = new JScrollPane(list);
417 bpanel.add(listScrollPane, "Center");
418 getContentPane().add(bpanel, "South");
419 } else {
420 list = null;
421 listModel = null;
422 listScrollPane = null;
423 }
424 text = new JTextArea(genText(false), textRows, 40);
425 text.setEditable(false);
426 JScrollPane scroll = new JScrollPane(text);
427 getContentPane().add(scroll, "Center");
428 validate();
429 adder = new LookupListener();
430 lnotify = new LeaseNotify();
431 }
432
433 public void start() throws Exception {
434 listen.start();
435 SwingUtilities.invokeLater(wrap(new Runnable() {
436 public void run() {
437 pack();
438 setVisible(true);
439 }
440 }));
441 ((DiscoveryManagement) disco).addDiscoveryListener(adder);
442 }
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 public Browser(String[] args, final LifeCycle lc)
462 throws ConfigurationException, LoginException, IOException
463 {
464 this(init(args, lc));
465 }
466
467 private static Initializer init(String[] args, final LifeCycle lc)
468 throws ConfigurationException, IOException, LoginException
469 {
470 final Configuration config =
471 ConfigurationProvider.getInstance(
472 args, Browser.class.getClassLoader());
473 LoginContext login =
474 (LoginContext) config.getEntry(BROWSER, "loginContext",
475 LoginContext.class, null);
476 if (login == null) {
477 return new Initializer(lc, config);
478 } else {
479 login.login();
480 try {
481 return Subject.doAsPrivileged(
482 login.getSubject(),
483 new PrivilegedExceptionAction<Initializer>() {
484 public Initializer run()
485 throws ConfigurationException, IOException
486 {
487 return new Initializer(lc, config);
488 }
489 },
490 null);
491 } catch (PrivilegedActionException pae) {
492 Exception e = pae.getException();
493 if (e instanceof ConfigurationException)
494 throw (ConfigurationException) e;
495 throw (IOException) e;
496 }
497 }
498 }
499
500 private static String typeName(Class type) {
501 String name = type.getName();
502 int i = name.lastIndexOf('.');
503 if (i >= 0)
504 name = name.substring(i + 1);
505 return name;
506 }
507
508 private void setText(boolean match) {
509 text.setText(genText(match));
510 }
511
512 private String genText(boolean match) {
513 StringBuffer buf = new StringBuffer();
514 if (tmpl.serviceTypes.length > 0) {
515 for (int i = 0, l = tmpl.serviceTypes.length ; i < l ; i++) {
516 buf.append(tmpl.serviceTypes[i].getName());
517 buf.append("\n");
518 }
519 }
520 if (tmpl.attributeSetTemplates.length > 0)
521 genEntries(buf, tmpl.attributeSetTemplates, false);
522 genMatches(buf, match);
523 return buf.toString();
524 }
525
526 private void genEntries(StringBuffer buf,
527 Entry[] entries,
528 boolean showNulls)
529 {
530 for (int i = 0, l = entries.length; i < l; i++) {
531 Entry ent = entries[i];
532 if (ent == null) {
533 buf.append("null\n");
534 continue;
535 }
536 buf.append(typeName(ent.getClass()));
537 buf.append(": ");
538 try {
539 Field[] fields = ent.getClass().getFields();
540 for (int j = 0, len = fields.length; j < len; j++) {
541 if (!valid(fields[j]))
542 continue;
543 Object val = fields[j].get(ent);
544 if (val != null || showNulls) {
545 buf.append(fields[j].getName());
546 buf.append("=");
547 buf.append(val);
548 buf.append(" ");
549 }
550 }
551 } catch (Exception e) {
552 logger.log(Level.FINE, "Exception thrown: ", e);
553 }
554 buf.append("\n");
555 }
556 }
557
558 private static boolean valid(Field f) {
559 return (f.getModifiers() & (Modifier.STATIC|Modifier.FINAL)) == 0;
560 }
561
562 private void genMatches(StringBuffer buf, boolean match) {
563 if(isAdmin) {
564 list.setModel(dummyModel);
565
566 listModel.removeAllElements();
567 list.clearSelection();
568 list.ensureIndexIsVisible(0);
569 list.repaint();
570 list.revalidate();
571 listScrollPane.validate();
572 }
573 SafeServiceRegistrar lookup;
574 synchronized (Browser.this){
575 lookup = this.lookup;
576 }
577 if (lookup == null) {
578 String[] groups = disco.getGroups();
579 if (groups == null) {
580 buf.append("Groups: <all>\n");
581 } else if (groups.length > 0) {
582 buf.append("Groups:");
583 for (int i = 0, l = groups.length; i < l; i++) {
584 String group = groups[i];
585 if (group.length() == 0)
586 group = "public";
587 buf.append(" ");
588 buf.append(group);
589 }
590 buf.append("\n");
591 }
592 LookupLocator[] locators =
593 ((DiscoveryLocatorManagement) disco).getLocators();
594 if (locators.length > 0) {
595 buf.append("Addresses:");
596 for (int i = 0; i < locators.length; i++) {
597 buf.append(" ");
598 buf.append(locators[i].getHost());
599 if (locators[i].getPort() != Constants.discoveryPort) {
600 buf.append(":");
601 buf.append(locators[i].getPort());
602 }
603 }
604 buf.append("\n");
605 }
606 if (!(registrars.getMenuComponent(0) instanceof
607 JRadioButtonMenuItem))
608 {
609 buf.append("No registrars to select");
610 return;
611 }
612 int n = registrars.getMenuComponentCount();
613 if (n == 1) {
614 buf.append("1 registrar, not selected");
615 } else {
616 buf.append(n);
617 buf.append(" registrars, none selected");
618 }
619 return;
620 }
621 ServiceMatches matches;
622 try {
623 matches = lookup.lookup(tmpl, (match || isAdmin) ? 1000 : 0);
624 } catch (Throwable t) {
625 logger.log(Level.INFO, "lookup failed", t);
626 return;
627 }
628
629 if (matches.items != null) {
630 for (int i = 0, l = matches.items.length ; i < l ; i++) {
631 if (matches.items[i].service != null) {
632 try {
633 matches.items[i].service =
634 servicePreparer.prepareProxy(
635 matches.items[i].service);
636 } catch (Throwable t) {
637 logger.log(Level.INFO, "proxy preparation failed", t);
638 matches.items[i].service = null;
639 }
640 }
641 }
642 }
643
644 if(isAdmin){
645 for (int i = 0, l = matches.items.length ; i < l; i++)
646 listModel.addElement(new ServiceListItem(matches.items[i]));
647 list.setModel(listModel);
648 list.clearSelection();
649 list.ensureIndexIsVisible(0);
650 list.repaint();
651 list.revalidate();
652 listScrollPane.validate();
653 }
654
655 if (!match &&
656 tmpl.serviceTypes.length == 0 &&
657 tmpl.attributeSetTemplates.length == 0)
658 {
659 buf.append("Total services registered: ");
660 buf.append(matches.totalMatches);
661 return;
662 }
663 buf.append("\nMatching services: ");
664 buf.append(matches.totalMatches);
665
666 if(! isAdmin){
667 if (!match)
668 return;
669 buf.append("\n\n");
670 for (int i = 0, l = matches.items.length; i < l; i++) {
671 ServiceItem item = matches.items[i];
672 buf.append("Service ID: ");
673 buf.append(item.serviceID);
674 buf.append("\n");
675 buf.append("Service instance: ");
676 buf.append(item.service);
677 buf.append("\n");
678 genEntries(buf, item.attributeSets, true);
679 buf.append("\n");
680 }
681 }
682 }
683
684 private static void addNone(JMenu menu) {
685 JMenuItem item = new JMenuItem("(none)");
686 item.setEnabled(false);
687 menu.add(item);
688 }
689
690 private void addOne(ServiceRegistrar registrar) {
691 if(!(registrar instanceof SafeServiceRegistrar)) return;
692 LookupLocator loc;
693 try {
694 loc = registrar.getLocator();
695 } catch (Throwable t) {
696 logger.log(Level.INFO, "obtaining locator failed", t);
697 return;
698 }
699 String host = loc.getHost();
700 if (loc.getPort() != Constants.discoveryPort)
701 host += ":" + loc.getPort();
702 JRadioButtonMenuItem reg =
703 new RegistrarMenuItem(host, registrar.getServiceID());
704 reg.addActionListener(wrap(new Lookup((SafeServiceRegistrar)registrar)));
705 if (!(registrars.getMenuComponent(0)
706 instanceof JRadioButtonMenuItem))
707 registrars.removeAll();
708 registrars.add(reg);
709 }
710
711 private static class RegistrarMenuItem extends JRadioButtonMenuItem {
712 ServiceID id;
713
714 RegistrarMenuItem(String host, ServiceID id) {
715 super(host);
716 this.id = id;
717 }
718 }
719
720 static Class[] getInterfaces(Class c) {
721 Set<Class> set = new HashSet<Class>();
722 for ( ; c != null; c = c.getSuperclass()) {
723 Class[] ifs = c.getInterfaces();
724 for (int i = ifs.length; --i >= 0; )
725 set.add(ifs[i]);
726 }
727 return set.toArray(new Class[set.size()]);
728 }
729
730 private class Services implements MenuListener {
731 private final JMenu menu;
732
733 public Services(JMenu menu) {
734 this.menu = menu;
735 }
736
737 public void menuSelected(MenuEvent ev) {
738 SafeServiceRegistrar lookup;
739 synchronized (Browser.this){
740 lookup = Browser.this.lookup;
741 }
742 if (lookup == null) {
743 addNone(menu);
744 return;
745 }
746 List all = new LinkedList();
747 Class[] types = tmpl.serviceTypes;
748 for (int i = 0; i < types.length; i++) {
749 all.add(types[i]);
750 JCheckBoxMenuItem item =
751 new JCheckBoxMenuItem(types[i].getName(), true);
752 item.addActionListener(wrap(new Service(types[i], i)));
753 menu.add(item);
754 }
755 try {
756 types = lookup.getServiceTypes(tmpl, "");
757 } catch (Throwable t) {
758 failure(t);
759 return;
760 }
761 if (types == null) {
762 if (all.isEmpty())
763 addNone(menu);
764 return;
765 }
766 for (int i = 0, len = types.length; i < len; i++) {
767 Class[] stypes;
768 if (types[i] == null) {
769 all.add(new JMenuItem("null"));
770 continue;
771 }
772 if (types[i].isInterface() || sclass.getState()) {
773 stypes = new Class[]{types[i]};
774 } else {
775 stypes = getInterfaces(types[i]);
776 }
777 for (int j = 0, l = stypes.length; j < l; j++) {
778 addType(stypes[j], all);
779 }
780 }
781 }
782
783 private void addType(Class type, List all) {
784 if (all.contains(type))
785 return;
786 all.add(type);
787 JCheckBoxMenuItem item =
788 new JCheckBoxMenuItem(type.getName(), false);
789 item.addActionListener(wrap(new Service(type, -1)));
790 menu.add(item);
791 if (!ssuper.getState())
792 return;
793 if (sclass.getState() && type.getSuperclass() != null)
794 addType(type.getSuperclass(), all);
795 Class[] stypes = type.getInterfaces();
796 for (int i = 0, l = stypes.length; i < l; i++) {
797 addType(stypes[i], all);
798 }
799 }
800
801 public void menuDeselected(MenuEvent ev) {
802 menu.removeAll();
803 }
804
805 public void menuCanceled(MenuEvent ev) {
806 menu.removeAll();
807 }
808 }
809
810
811
812
813
814
815
816
817
818
819
820 boolean isAutoConfirm() {
821 return autoConfirm;
822 }
823
824 final ActionListener wrap(ActionListener l) {
825 return (ActionListener) wrap((Object) l, ActionListener.class);
826 }
827
828 final MenuListener wrap(MenuListener l) {
829 return (MenuListener) wrap((Object) l, MenuListener.class);
830 }
831
832 final MouseListener wrap(MouseListener l) {
833 return (MouseListener) wrap((Object) l, MouseListener.class);
834 }
835
836 WindowListener wrap(WindowListener a) {
837 return (WindowListener) wrap((Object) a, WindowListener.class);
838 }
839
840 final Runnable wrap(Runnable r) {
841 return (Runnable) wrap((Object) r, Runnable.class);
842 }
843
844 private Object wrap(Object obj, Class iface) {
845 return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
846 new Class[]{iface}, new Handler(obj));
847 }
848
849 private class Handler implements InvocationHandler {
850 private final Object obj;
851
852 Handler(Object obj) {
853 this.obj = obj;
854 }
855
856 public Object invoke(Object proxy,
857 final Method method,
858 final Object[] args)
859 throws Throwable
860 {
861 if (method.getDeclaringClass() == Object.class) {
862 if ("equals".equals(method.getName()))
863 return proxy == args[0];
864 else if ("hashCode".equals(method.getName()))
865 return System.identityHashCode(proxy);
866 }
867 try {
868 return AccessController.doPrivileged(
869 ctx.wrap(new PrivilegedExceptionAction() {
870 public Object run() throws Exception {
871 Thread t = Thread.currentThread();
872 ClassLoader occl = t.getContextClassLoader();
873 try {
874 t.setContextClassLoader(ccl);
875 try {
876 return method.invoke(obj, args);
877 } catch (InvocationTargetException e) {
878 Throwable tt = e.getCause();
879 if (tt instanceof Error)
880 throw (Error) tt;
881 throw (Exception) tt;
882 }
883 } finally {
884 t.setContextClassLoader(occl);
885 }
886 }
887 }), ctx.getAccessControlContext());
888 } catch (PrivilegedActionException e) {
889 throw e.getCause();
890 }
891 }
892 }
893
894 private class Show implements ActionListener {
895
896 public void actionPerformed(ActionEvent ev) {
897 setText(true);
898 }
899 }
900
901 private void resetTmpl() {
902 tmpl.serviceTypes = new Class[0];
903 tmpl.attributeSetTemplates = new Entry[0];
904 update();
905 }
906
907 private void reset() {
908 ssuper.setState(false);
909 esuper.setState(false);
910 sclass.setState(false);
911 resetTmpl();
912 }
913
914 private class Reset implements ActionListener {
915
916 public void actionPerformed(ActionEvent ev) {
917 reset();
918 }
919 }
920
921 private class Service implements ActionListener {
922 private final Class type;
923 private final int index;
924
925 public Service(Class type, int index) {
926 this.type = type;
927 this.index = index;
928 }
929
930 public void actionPerformed(ActionEvent ev) {
931 int z = tmpl.serviceTypes.length;
932 Class[] newTypes;
933 if (index < 0) {
934 newTypes = new Class[z + 1];
935 System.arraycopy(tmpl.serviceTypes, 0, newTypes, 0, z);
936 newTypes[z] = type;
937 } else {
938 newTypes = new Class[z - 1];
939 System.arraycopy(tmpl.serviceTypes, 0,
940 newTypes, 0, index);
941 System.arraycopy(tmpl.serviceTypes, index + 1,
942 newTypes, index, z - index - 1);
943 }
944 tmpl.serviceTypes = newTypes;
945 update();
946 }
947 }
948
949 private class Entries implements MenuListener {
950 private final JMenu menu;
951
952 public Entries(JMenu menu) {
953 this.menu = menu;
954 }
955
956 public void menuSelected(MenuEvent ev) {
957 SafeServiceRegistrar lookup;
958 synchronized (Browser.this){
959 lookup = Browser.this.lookup;
960 }
961 if (lookup == null) {
962 addNone(menu);
963 return;
964 }
965 Entry[] attrs = tmpl.attributeSetTemplates;
966 for (int i = 0; i < attrs.length; i++) {
967 Class type = attrs[i].getClass();
968 JMenu item = new JMenu(typeName(type));
969 item.addMenuListener(new Fields(item, i));
970 menu.add(item);
971 }
972 Class[] types;
973 try {
974 types = lookup.getEntryClasses(tmpl);
975 } catch (Throwable t) {
976 failure(t);
977 return;
978 }
979 if (types == null) {
980 if (attrs.length == 0)
981 addNone(menu);
982 return;
983 }
984 List all = new LinkedList();
985 for (int i = 0, l = types.length; i < l; i++) {
986 if (types[i] == null)
987 menu.add(new JMenuItem("null"));
988 else
989 addType(types[i], all);
990 }
991 }
992
993 private void addType(Class type, List all) {
994 if (all.contains(type))
995 return;
996 all.add(type);
997 JCheckBoxMenuItem item =
998 new JCheckBoxMenuItem(typeName(type), false);
999 item.addActionListener(wrap(new AttrSet(type)));
1000 menu.add(item);
1001 if (esuper.getState() &&
1002 Entry.class.isAssignableFrom(type.getSuperclass()))
1003 addType(type.getSuperclass(), all);
1004 }
1005
1006 public void menuDeselected(MenuEvent ev) {
1007 menu.removeAll();
1008 }
1009
1010 public void menuCanceled(MenuEvent ev) {
1011 menu.removeAll();
1012 }
1013 }
1014
1015 private class AttrSet implements ActionListener {
1016 private final Class type;
1017
1018 public AttrSet(Class type) {
1019 this.type = type;
1020 }
1021
1022 public void actionPerformed(ActionEvent ev) {
1023 Entry ent;
1024 try {
1025 ent = (Entry)type.newInstance();
1026 } catch (Throwable t) {
1027 logger.log(Level.INFO, "creating entry failed", t);
1028 return;
1029 }
1030 int z = tmpl.attributeSetTemplates.length;
1031 Entry[] newSets = new Entry[z + 1];
1032 System.arraycopy(tmpl.attributeSetTemplates, 0, newSets, 0, z);
1033 newSets[z] = ent;
1034 tmpl.attributeSetTemplates = newSets;
1035 update();
1036 }
1037 }
1038
1039 private class Fields implements MenuListener {
1040 private final JMenu menu;
1041 private final int index;
1042
1043 public Fields(JMenu menu, int index) {
1044 this.menu = menu;
1045 this.index = index;
1046 }
1047
1048 public void menuSelected(MenuEvent ev) {
1049 JRadioButtonMenuItem match = new JRadioButtonMenuItem("(match)");
1050 match.setSelected(true);
1051 match.addActionListener(wrap(new Unmatch(index)));
1052 menu.add(match);
1053 Entry ent = tmpl.attributeSetTemplates[index];
1054 Field[] fields = ent.getClass().getFields();
1055 for (int i = 0, l = fields.length; i < l; i++) {
1056 Field field = fields[i];
1057 if (!valid(field))
1058 continue;
1059 try {
1060 if (field.get(ent) != null) {
1061 JCheckBoxMenuItem item =
1062 new JCheckBoxMenuItem(field.getName(), true);
1063 item.addActionListener(
1064 wrap(new Value(index, field, null)));
1065 menu.add(item);
1066 } else {
1067 JMenu item = new JMenu(field.getName());
1068 item.addMenuListener(
1069 wrap(new Values(item, index, field)));
1070 menu.add(item);
1071 }
1072 } catch (Throwable t) {
1073 logger.log(Level.INFO, "getting fields failed", t);
1074 }
1075 }
1076 }
1077
1078 public void menuDeselected(MenuEvent ev) {
1079 menu.removeAll();
1080 }
1081
1082 public void menuCanceled(MenuEvent ev) {
1083 menu.removeAll();
1084 }
1085 }
1086
1087 private class Unmatch implements ActionListener {
1088 private final int index;
1089
1090 public Unmatch(int index) {
1091 this.index = index;
1092 }
1093
1094 public void actionPerformed(ActionEvent ev) {
1095 int z = tmpl.attributeSetTemplates.length;
1096 Entry[] newSets = new Entry[z - 1];
1097 System.arraycopy(tmpl.attributeSetTemplates, 0,
1098 newSets, 0, index);
1099 System.arraycopy(tmpl.attributeSetTemplates, index + 1,
1100 newSets, index, z - index - 1);
1101 tmpl.attributeSetTemplates = newSets;
1102 update();
1103 }
1104 }
1105
1106 private class Values implements MenuListener {
1107 private final JMenu menu;
1108 private final int index;
1109 private final Field field;
1110
1111 public Values(JMenu menu, int index, Field field) {
1112 this.menu = menu;
1113 this.index = index;
1114 this.field = field;
1115 }
1116
1117 public void menuSelected(MenuEvent ev) {
1118 SafeServiceRegistrar lookup;
1119 synchronized (Browser.this){
1120 lookup = Browser.this.lookup;
1121 }
1122 Object[] values;
1123 try {
1124 values = lookup.getFieldValues(tmpl, index, field.getName());
1125 } catch (Throwable t) {
1126 failure(t);
1127 return;
1128 }
1129 if (values == null) {
1130 addNone(menu);
1131 return;
1132 }
1133 for (int i = 0; i < values.length; i++) {
1134 JMenuItem item = new JMenuItem(values[i].toString());
1135 item.addActionListener(
1136 wrap(new Value(index, field, values[i])));
1137 menu.add(item);
1138 }
1139 }
1140
1141 public void menuDeselected(MenuEvent ev) {
1142 menu.removeAll();
1143 }
1144
1145 public void menuCanceled(MenuEvent ev) {
1146 menu.removeAll();
1147 }
1148 }
1149
1150 private class Value implements ActionListener {
1151 private final int index;
1152 private final Field field;
1153 private final Object value;
1154
1155 public Value(int index, Field field, Object value) {
1156 this.index = index;
1157 this.field = field;
1158 this.value = value;
1159 }
1160
1161 public void actionPerformed(ActionEvent ev) {
1162 try {
1163 field.set(tmpl.attributeSetTemplates[index], value);
1164 } catch (Throwable t) {
1165 logger.log(Level.INFO, "setting attribute value failed", t);
1166 }
1167 update();
1168 }
1169 }
1170
1171 private class Listener implements RemoteEventListener, ServerProxyTrust,
1172 Startable, Serializable
1173 {
1174 private final Exporter exporter;
1175 RemoteEventListener proxy;
1176
1177 public Listener(Exporter exporter) {
1178 this.exporter = exporter;
1179 }
1180
1181 public void notify(final RemoteEvent ev) {
1182 SwingUtilities.invokeLater(wrap(new Runnable() {
1183 public void run() {
1184 synchronized (Browser.this){
1185 if (eventID == ev.getID() &&
1186 seqNo < ev.getSequenceNumber() &&
1187 eventSource != null &&
1188 eventSource.equals(ev.getSource()))
1189 {
1190 seqNo = ev.getSequenceNumber();
1191 setText(false);
1192 }
1193 }
1194 }
1195 }));
1196 }
1197
1198 public synchronized TrustVerifier getProxyVerifier() {
1199 return new BasicProxyTrustVerifier(proxy);
1200 }
1201
1202 void unexport() {
1203 exporter.unexport(true);
1204 }
1205
1206 @Override
1207 public synchronized void start() throws Exception {
1208 proxy = (RemoteEventListener) exporter.export(this);
1209 }
1210
1211 private synchronized Object writeReplace() throws ObjectStreamException {
1212 return proxy;
1213 }
1214 }
1215
1216 private class LookupListener implements DiscoveryListener {
1217
1218 public void discovered(DiscoveryEvent e) {
1219 final ServiceRegistrar[] newregs = e.getRegistrars();
1220 SwingUtilities.invokeLater(wrap(new Runnable() {
1221 public void run() {
1222 for (int i = 0, l = newregs.length; i < l; i++) {
1223 addOne(newregs[i]);
1224 }
1225 synchronized (Browser.this){
1226 if (lookup == null)
1227 setText(false);
1228 }
1229 }
1230 }));
1231 }
1232
1233 public void discarded(DiscoveryEvent e) {
1234 final ServiceRegistrar[] regs = e.getRegistrars();
1235 SwingUtilities.invokeLater(wrap(new Runnable() {
1236 public void run() {
1237 for (int i = 0, l = regs.length; i < l; i++) {
1238 ServiceID id = regs[i].getServiceID();
1239 synchronized (Browser.this){
1240 if (lookup != null &&
1241 id.equals(lookup.getServiceID()))
1242 {
1243 lookup = null;
1244 seqNo = Long.MAX_VALUE;
1245 }
1246 }
1247 for (int j = 0;
1248 j < registrars.getMenuComponentCount();
1249 j++)
1250 {
1251 JMenuItem item =
1252 (JMenuItem) registrars.getMenuComponent(j);
1253 if (item instanceof RegistrarMenuItem &&
1254 id.equals(((RegistrarMenuItem) item).id))
1255 {
1256 item.setSelected(false);
1257 registrars.remove(item);
1258 if (registrars.getMenuComponentCount() == 0)
1259 addNone(registrars);
1260 break;
1261 }
1262 }
1263 }
1264 synchronized (Browser.this){
1265 if (lookup == null)
1266 resetTmpl();
1267 }
1268 }
1269 }));
1270 }
1271 }
1272
1273 private void setGroups(String[] groups) {
1274 ((DiscoveryLocatorManagement) disco).setLocators(new LookupLocator[0]);
1275 try {
1276 disco.setGroups(groups);
1277 } catch (Throwable t) {
1278 logger.log(Level.INFO, "setting groups failed", t);
1279 }
1280 resetTmpl();
1281 }
1282
1283 private class AllFind implements ActionListener {
1284
1285 public void actionPerformed(ActionEvent ev) {
1286 setGroups(null);
1287 }
1288 }
1289
1290 private class PubFind implements ActionListener {
1291
1292 public void actionPerformed(ActionEvent ev) {
1293 setGroups(new String[]{""});
1294 }
1295 }
1296
1297 private class MultiFind implements ActionListener {
1298
1299 public void actionPerformed(ActionEvent ev) {
1300 String names = JOptionPane.showInputDialog(Browser.this,
1301 "Enter group names");
1302 if (names == null)
1303 return;
1304 setGroups(parseList(names, true));
1305 }
1306 }
1307
1308 private class UniFind implements ActionListener {
1309
1310 public void actionPerformed(ActionEvent ev) {
1311 String list =
1312 JOptionPane.showInputDialog(Browser.this,
1313 "Enter host[:port] addresses");
1314 if (list == null)
1315 return;
1316 String[] addrs = parseList(list, false);
1317 LookupLocator[] locs = new LookupLocator[addrs.length];
1318 for (int i = 0; i < addrs.length; i++) {
1319 try {
1320 locs[i] = new ConstrainableLookupLocator(
1321 "jini://" + addrs[i], locatorConstraints);
1322 } catch (MalformedURLException e) {
1323 JOptionPane.showMessageDialog(Browser.this,
1324 "\"" + addrs[i] + "\": " +
1325 e.getMessage(),
1326 "Bad Address",
1327 JOptionPane.ERROR_MESSAGE);
1328 return;
1329 }
1330 }
1331 try {
1332 disco.setGroups(new String[0]);
1333 } catch (Throwable t) {
1334 logger.log(Levels.HANDLED, "setting groups failed", t);
1335 }
1336 ((DiscoveryLocatorManagement) disco).setLocators(locs);
1337 resetTmpl();
1338 }
1339 }
1340
1341 private class Lookup implements ActionListener {
1342 private final SafeServiceRegistrar registrar;
1343
1344 public Lookup(SafeServiceRegistrar registrar) {
1345 this.registrar = registrar;
1346 }
1347
1348 public void actionPerformed(ActionEvent ev) {
1349 synchronized (Browser.this){
1350 if (lookup == registrar) {
1351 lookup = null;
1352 } else {
1353 lookup = registrar;
1354 }
1355 seqNo = Long.MAX_VALUE;
1356 }
1357 for (int i = 0; i < registrars.getMenuComponentCount(); i++) {
1358 JMenuItem item = (JMenuItem)registrars.getMenuComponent(i);
1359 if (item != ev.getSource())
1360 item.setSelected(false);
1361 }
1362 resetTmpl();
1363 }
1364 }
1365
1366 static class LeaseNotify implements LeaseListener {
1367 public void notify(LeaseRenewalEvent ev) {
1368 if (ev.getException() != null)
1369 logger.log(Level.INFO, "lease renewal failed",
1370 ev.getException());
1371 else
1372 logger.log(Level.INFO, "lease renewal failed");
1373 }
1374 }
1375
1376 private static String[] parseList(String names, boolean groups) {
1377 StringTokenizer st = new StringTokenizer(names, " \t\n\r\f,");
1378 String[] elts = new String[st.countTokens()];
1379 for (int i = 0; st.hasMoreTokens(); i++) {
1380 elts[i] = st.nextToken();
1381 if (groups && elts[i].equalsIgnoreCase("public"))
1382 elts[i] = "";
1383 }
1384 return elts;
1385 }
1386
1387 private void cancelLease() {
1388 Lease lease = null;
1389 synchronized (Browser.this){
1390 if (elease != null){
1391 lease = elease;
1392 elease = null;
1393 eventSource = null;
1394 }
1395 }
1396 if (lease != null) {
1397 try {
1398 leaseMgr.cancel(lease);
1399 } catch (Throwable t) {
1400 logger.log(Levels.HANDLED, "lease cancellation failed", t);
1401 }
1402 }
1403 }
1404
1405 private void update() {
1406 setText(false);
1407 cancelLease();
1408 synchronized (Browser.this){
1409 if (lookup == null)
1410 return;
1411 }
1412 try {
1413 EventRegistration reg =
1414 lookup.notiFy(tmpl,
1415 ServiceRegistrar.TRANSITION_MATCH_NOMATCH |
1416 ServiceRegistrar.TRANSITION_NOMATCH_MATCH |
1417 ServiceRegistrar.TRANSITION_MATCH_MATCH,
1418 listen, null, Lease.ANY);
1419 Lease lease = (Lease) leasePreparer.prepareProxy(reg.getLease());
1420 leaseMgr.renewUntil(lease, Lease.ANY, lnotify);
1421 synchronized(Browser.this){
1422 elease = lease;
1423 eventSource = reg.getSource();
1424 eventID = reg.getID();
1425 seqNo = reg.getSequenceNumber();
1426 }
1427 } catch (Throwable t) {
1428 failure(t);
1429 }
1430 }
1431
1432 private void failure(Throwable t) {
1433 logger.log(Level.INFO, "call to lookup service failed", t);
1434 SafeServiceRegistrar lookup;
1435 synchronized (Browser.this){
1436 lookup = Browser.this.lookup;
1437 }
1438 ((DiscoveryManagement) disco).discard(lookup);
1439 }
1440
1441 class ServiceItemRenderer implements ListCellRenderer {
1442 private JLabel label;
1443
1444 public ServiceItemRenderer() {
1445 label = new JLabel();
1446 label.setOpaque(true);
1447 }
1448
1449 public Component getListCellRendererComponent(JList list,
1450 Object value,
1451 int index,
1452 boolean isSelected,
1453 boolean cellHasFocus){
1454 ServiceListItem item = null;
1455 if(value instanceof ServiceListItem)
1456 item = (ServiceListItem) value;
1457
1458 label.setFont(list.getFont());
1459
1460 if(isSelected){
1461 label.setBackground(list.getSelectionBackground());
1462 label.setForeground(list.getSelectionForeground());
1463 } else {
1464 label.setBackground(list.getBackground());
1465 label.setForeground(list.getForeground());
1466 }
1467 if(item != null){
1468
1469 label.setIcon(item.getIcon());
1470 label.setText(item.getTitle());
1471 } else
1472 label.setText(value.toString());
1473
1474 return label;
1475 }
1476 }
1477
1478 private static Icon[] icons = new Icon[3];
1479 static {
1480
1481 icons[0] = MetalIcons.getBlueFolderIcon();
1482
1483 icons[1] = MetalIcons.getGrayFolderIcon();
1484
1485 icons[2] = MetalIcons.getUnusableFolderIcon();
1486 }
1487
1488 private class ServiceListItem {
1489 private final ServiceItem item;
1490 private boolean isAccessible;
1491 private Object admin = null;
1492
1493 public ServiceListItem(ServiceItem item) {
1494 this.item = item;
1495 isAccessible = (item.service != null);
1496 }
1497
1498 public String getTitle() {
1499 if(item.service == null)
1500 return "Unknown service";
1501
1502 HashSet set = new HashSet();
1503 Class[] infs = getInterfaces(item.service.getClass());
1504 for(int j = 0, l = infs.length; j < l; j++)
1505 set.add(infs[j].getName());
1506
1507
1508 set.removeAll(ignoreInterfaces);
1509
1510 String title;
1511 if(set.size() == 1) {
1512 Iterator iter = set.iterator();
1513 title = (String) iter.next();
1514 } else {
1515 title = item.service.getClass().getName();
1516 title += " [";
1517 for (Iterator iter = set.iterator(); iter.hasNext();) {
1518 title += (String) iter.next();
1519 if (iter.hasNext())
1520 title += ", ";
1521 }
1522 title += "]";
1523 }
1524 if(! isAccessible)
1525 title += " (Stale service)";
1526 return title;
1527 }
1528
1529 public boolean isAccessible() {
1530 getAdmin();
1531 return isAccessible;
1532 }
1533
1534 public Object getAdmin() {
1535 if(admin == null &&
1536 isAccessible &&
1537 item.service instanceof Administrable)
1538 {
1539 try {
1540 admin = adminPreparer.prepareProxy(
1541 ((Administrable) item.service).getAdmin());
1542 } catch (Throwable t) {
1543 logger.log(Levels.HANDLED, "failed to get admin proxy", t);
1544 isAccessible = false;
1545 }
1546 }
1547 return admin;
1548 }
1549
1550 public boolean isAdministrable() {
1551 getAdmin();
1552 return (admin instanceof DestroyAdmin ||
1553 admin instanceof JoinAdmin ||
1554 admin instanceof DiscoveryAdmin);
1555 }
1556
1557 public boolean isSpaceBrowsable() {
1558 return (item.service instanceof JavaSpace05 ||
1559 (item.service instanceof JavaSpace &&
1560 getAdmin() instanceof JavaSpaceAdmin));
1561 }
1562
1563 private boolean isUI() {
1564 Entry[] attrs = item.attributeSets;
1565 if ((attrs != null) && (attrs.length != 0)) {
1566 for (int i = 0, l = attrs.length; i < l; i++) {
1567 if (attrs[i] instanceof UIDescriptor) {
1568 return true;
1569 }
1570 }
1571 }
1572
1573 return false;
1574 }
1575
1576 public ServiceItem getServiceItem() {
1577 return item;
1578 }
1579
1580 public Entry[] getAttributes() {
1581 return item.attributeSets;
1582 }
1583
1584 public Icon getIcon() {
1585 if(! isAccessible())
1586 return icons[2];
1587 else if(isAdministrable())
1588 return icons[0];
1589 else
1590 return icons[1];
1591 }
1592
1593 @Override
1594 public String toString() {
1595 return isAccessible() ?
1596 item.service.getClass().getName() : "Unknown service";
1597 }
1598 }
1599
1600 private class MouseReceiver extends MouseAdapter {
1601 private final ServiceListPopup popup;
1602
1603 public MouseReceiver(ServiceListPopup popup) {
1604 this.popup = popup;
1605 }
1606
1607 @Override
1608 public void mouseClicked(MouseEvent ev) {
1609 if(ev.getClickCount() >= 2){
1610 ServiceListItem listItem = getTargetListItem(ev);
1611 if(listItem != null) {
1612 SafeServiceRegistrar lookup;
1613 synchronized (Browser.this){
1614 lookup = Browser.this.lookup;
1615 }
1616 ServiceItem item = listItem.getServiceItem();
1617 if(listItem.isAdministrable())
1618 new ServiceEditor(item, listItem.getAdmin(), lookup,
1619 Browser.this).setVisible(true);
1620 else if(listItem.isAccessible())
1621 new ServiceBrowser(item, lookup,
1622 Browser.this).setVisible(true);
1623 }
1624 }
1625 }
1626
1627 @Override
1628 public void mouseReleased(MouseEvent ev) {
1629 if(ev.isPopupTrigger() && (getTargetListItem(ev) != null)) {
1630 popup.setServiceItem(getTargetListItem(ev));
1631 popup.show(ev.getComponent(), ev.getX(), ev.getY());
1632 }
1633 }
1634
1635 @Override
1636 public void mousePressed(MouseEvent ev) {
1637 if(ev.isPopupTrigger() && (getTargetListItem(ev) != null)) {
1638 popup.setServiceItem(getTargetListItem(ev));
1639 popup.show(ev.getComponent(), ev.getX(), ev.getY());
1640 }
1641 }
1642
1643 private ServiceListItem getTargetListItem(MouseEvent ev) {
1644 int index = list.locationToIndex(ev.getPoint());
1645 if(index >= 0)
1646 return (ServiceListItem) listModel.getElementAt(index);
1647 else
1648 return null;
1649 }
1650 }
1651
1652 private class ServiceListPopup
1653 extends JPopupMenu
1654 implements ActionListener, PopupMenuListener
1655 {
1656 protected JMenuItem infoItem;
1657 protected JMenuItem browseItem;
1658 protected JMenuItem adminItem;
1659 protected JMenuItem spaceItem;
1660 protected ServiceListItem listItem;
1661 protected JMenuItem uiItem;
1662 protected ServiceItem item;
1663
1664 public ServiceListPopup() {
1665 super();
1666
1667 ActionListener me = wrap(this);
1668 infoItem = new JMenuItem("Show Info");
1669 infoItem.addActionListener(me);
1670 infoItem.setActionCommand("showInfo");
1671 add(infoItem);
1672
1673 browseItem = new JMenuItem("Browse Service");
1674 browseItem.addActionListener(me);
1675 browseItem.setActionCommand("browseService");
1676 add(browseItem);
1677
1678 adminItem = new JMenuItem("Admin Service");
1679 adminItem.addActionListener(me);
1680 adminItem.setActionCommand("adminService");
1681 add(adminItem);
1682
1683 spaceItem = new JMenuItem("Browse Entries");
1684 spaceItem.addActionListener(me);
1685 spaceItem.setActionCommand("browseEntry");
1686 add(spaceItem);
1687
1688 uiItem = new JMenuItem("Show UI");
1689 uiItem.addActionListener(me);
1690 uiItem.setActionCommand("showUI");
1691 add(uiItem);
1692
1693 addPopupMenuListener(this);
1694 setOpaque(true);
1695 setLightWeightPopupEnabled(true);
1696 }
1697
1698 public void setServiceItem(ServiceListItem listItem) {
1699 this.listItem = listItem;
1700 item = listItem.getServiceItem();
1701 infoItem.setEnabled(listItem.isAccessible());
1702 browseItem.setEnabled(listItem.isAccessible());
1703 adminItem.setEnabled(listItem.isAdministrable());
1704 spaceItem.setEnabled(listItem.isSpaceBrowsable());
1705 uiItem.setEnabled(listItem.isUI());
1706 }
1707
1708 public void actionPerformed(ActionEvent ev) {
1709 String command = ev.getActionCommand();
1710 SafeServiceRegistrar lookup;
1711 synchronized (Browser.this){
1712 lookup = Browser.this.lookup;
1713 }
1714 if(command.equals("showInfo")){
1715 Class[] infs = getInterfaces(item.service.getClass());
1716 String[] msg = new String[3 + infs.length];
1717 msg[0] = "ServiceID: " + item.serviceID;
1718 msg[1] = ("Service Instance: " +
1719 item.service.getClass().getName());
1720 if(infs.length == 1)
1721 msg[2] = "Implemented Interface:";
1722 else
1723 msg[2] = "Implemented Interfaces:";
1724 for(int i = 0; i < infs.length; i++)
1725 msg[3 + i] = infs[i].getName();
1726
1727 JOptionPane.showMessageDialog(Browser.this,
1728 msg,
1729 "ServiceItem Information",
1730 JOptionPane.INFORMATION_MESSAGE);
1731 } else if(command.equals("browseService")){
1732 new ServiceBrowser(item, lookup,
1733 Browser.this).setVisible(true);
1734 } else if(command.equals("adminService")){
1735 new ServiceEditor(item, listItem.getAdmin(),
1736 lookup, Browser.this).setVisible(true);
1737 } else if(command.equals("browseEntry")){
1738 new SpaceBrowser(item.service instanceof JavaSpace05 ?
1739 item.service : listItem.getAdmin(),
1740 Browser.this).setVisible(true);
1741 }
1742 else if(command.equals("showUI")){
1743 UIDescriptor uiDescriptor = getSelectedUIDescriptor();
1744
1745 if (uiDescriptor == null) {
1746 return;
1747 }
1748
1749 try {
1750 JFrameFactory uiFactory = (JFrameFactory)
1751 uiDescriptor.getUIFactory(
1752 Thread.currentThread().getContextClassLoader());
1753 JFrame frame = uiFactory.getJFrame(item);
1754
1755 frame.validate();
1756 frame.setVisible(true);
1757 }
1758 catch (Exception e) {
1759 logger.log(Level.INFO, "show ui failed", e);
1760 JOptionPane.showMessageDialog(Browser.this,
1761 e.getMessage(),
1762 e.getClass().getName(),
1763 JOptionPane.WARNING_MESSAGE);
1764 }
1765 }
1766 }
1767
1768 public void popupMenuWillBecomeVisible(PopupMenuEvent ev) {
1769 }
1770
1771 public void popupMenuWillBecomeInvisible(PopupMenuEvent ev) {
1772 }
1773
1774 public void popupMenuCanceled(PopupMenuEvent ev) {
1775 }
1776
1777 private UIDescriptor getSelectedUIDescriptor() {
1778
1779 if (!(new ServiceListItem(item)).isUI()) {
1780 return null;
1781 }
1782
1783 Entry[] attrs = item.attributeSets;
1784 if ((attrs != null) && (attrs.length != 0)) {
1785 for (int i = 0, l = attrs.length; i < l; i++) {
1786 if (attrs[i] instanceof UIDescriptor) {
1787 UIDescriptor desc = (UIDescriptor) attrs[i];
1788 if (!"javax.swing".equals(desc.toolkit)) {
1789 continue;
1790 }
1791 return desc;
1792 }
1793 }
1794 }
1795 return null;
1796 }
1797 }
1798
1799 private class Exiter extends WindowAdapter {
1800
1801 @Override
1802 public void windowClosing(WindowEvent e) {
1803 Browser.this.exiter.actionPerformed(
1804 new ActionEvent(e.getSource(), e.getID(),
1805 "Exit", System.currentTimeMillis(), 0));
1806 }
1807 }
1808
1809
1810
1811
1812
1813 public static class Exit implements ActionListener {
1814
1815
1816
1817
1818
1819
1820 public void actionPerformed(ActionEvent ev) {
1821 Object src = ev.getSource();
1822 while (!(src instanceof Browser) && src instanceof Component) {
1823 if (src instanceof JPopupMenu)
1824 src = ((JPopupMenu) src).getInvoker();
1825 else
1826 src = ((Component) src).getParent();
1827 }
1828 if (src instanceof Browser) {
1829 ((Browser) src).cancelLease();
1830 }
1831 System.exit(0);
1832 }
1833 }
1834
1835
1836
1837
1838
1839
1840 public static void main (String[] args) {
1841 if (System.getSecurityManager() == null)
1842 System.setSecurityManager(new SecurityManager());
1843 try {
1844 final Configuration config =
1845 ConfigurationProvider.getInstance(
1846 args, Browser.class.getClassLoader());
1847 LoginContext login =
1848 (LoginContext) config.getEntry(BROWSER, "loginContext",
1849 LoginContext.class, null);
1850 if (login != null) {
1851 login.login();
1852 }
1853 PrivilegedExceptionAction action =
1854 new PrivilegedExceptionAction() {
1855 public Object run() throws Exception {
1856 Browser b = new Browser(config);
1857 b.start();
1858 return b;
1859 }
1860 };
1861 if (login != null) {
1862 Subject.doAsPrivileged(login.getSubject(), action, null);
1863 } else {
1864 action.run();
1865 }
1866 } catch (Throwable t) {
1867 if (t instanceof PrivilegedActionException)
1868 t = t.getCause();
1869 logger.log(Level.SEVERE, "browser initialization failed", t);
1870 }
1871 }
1872 }