001: // ServerBrowser.java
002: // $Id: ServerBrowser.java,v 1.27 2000/08/17 10:09:19 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1997.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.jigadm.gui;
007:
008: import java.awt.BorderLayout;
009: import java.awt.Button;
010: import java.awt.Color;
011: import java.awt.Component;
012: import java.awt.Container;
013: import java.awt.Cursor;
014: import java.awt.Dimension;
015: import java.awt.Frame;
016: import java.awt.GridBagConstraints;
017: import java.awt.GridBagLayout;
018: import java.awt.GridLayout;
019: import java.awt.Image;
020: import java.awt.Insets;
021: import java.awt.Label;
022: import java.awt.Menu;
023: import java.awt.MenuBar;
024: import java.awt.MenuComponent;
025: import java.awt.MenuItem;
026: import java.awt.Panel;
027: import java.awt.Scrollbar;
028: import java.awt.TextComponent;
029: import java.awt.TextField;
030: import java.awt.Toolkit;
031: import java.awt.Window;
032:
033: import java.awt.event.ActionEvent;
034: import java.awt.event.ActionListener;
035: import java.awt.event.WindowAdapter;
036: import java.awt.event.WindowEvent;
037:
038: import java.util.EventObject;
039: import java.util.Hashtable;
040: import java.util.Properties;
041:
042: import java.io.PrintStream;
043:
044: import java.net.URL;
045:
046: import org.w3c.jigadm.PropertyManager;
047: import org.w3c.jigadm.RemoteResourceWrapper;
048:
049: import org.w3c.jigsaw.admin.AdminContext;
050: import org.w3c.jigsaw.admin.RemoteAccessException;
051: import org.w3c.jigsaw.admin.RemoteResource;
052:
053: import org.w3c.tools.sorter.Sorter;
054:
055: import org.w3c.tools.widgets.MessagePopup;
056: import org.w3c.tools.widgets.NodeHandler;
057: import org.w3c.tools.widgets.TreeBrowser;
058: import org.w3c.tools.widgets.TreeNode;
059:
060: class UrlPopup extends Frame implements ActionListener {
061: ServerBrowser browser = null;
062: Frame frame = null;
063: TextField url = null;
064: Button okB = null;
065: Button cancelB = null;
066: boolean keepOnCancel = true;
067:
068: private class Openner extends Thread {
069: ServerBrowser browser = null;
070: AdminContext ac = null;
071:
072: public void run() {
073: browser.open(ac);
074: }
075:
076: private Openner(ServerBrowser browser, AdminContext ac) {
077: this .browser = browser;
078: this .ac = ac;
079: }
080: }
081:
082: private String getAdminUrl() {
083: String adminUrl = url.getText();
084: if (adminUrl.length() < 1)
085: return null;
086: else if (!adminUrl.startsWith("http")) {
087: adminUrl = "http://" + adminUrl;
088: }
089: return adminUrl;
090: }
091:
092: public void actionPerformed(ActionEvent evt) {
093: Object target = evt.getSource();
094: if ((target == url) || (target == okB)) {
095: String adminUrl = getAdminUrl();
096: if (adminUrl != null) {
097: AdminContext ac = null;
098: try {
099: ac = new AdminContext(new URL(adminUrl));
100: } catch (RemoteAccessException ex) {
101: browser.errorPopup("RemoteAccessException", ex);
102: // (new MessagePopup("RemoteAccessException : "+
103: // ex.getMessage())).show();
104: ex.printStackTrace();
105: return;
106: } catch (java.net.MalformedURLException ex) {
107: browser.errorPopup("MalformedURLException", ex);
108: // (new MessagePopup("MalformedURL : "+adminUrl)).show();
109: return;
110: }
111: dispose();
112: frame.setTitle("Server Browser: " + adminUrl);
113: frame.show();
114: (new Openner(browser, ac)).start();
115: }
116: } else if (target == cancelB) {
117: if (!keepOnCancel) {
118: frame.dispose();
119: WindowCloser.windows--;
120: if (WindowCloser.windows < 0) {
121: dispose();
122: System.exit(0);
123: }
124: }
125: dispose();
126: }
127: }
128:
129: /**
130: * create the URL popup
131: */
132:
133: UrlPopup(String title, ServerBrowser browser, Frame frame,
134: boolean keepOnCancel) {
135: super (title);
136: setBackground(Color.lightGray);
137: this .browser = browser;
138: this .frame = frame;
139: this .keepOnCancel = keepOnCancel;
140: Label label = new Label("Location :");
141: url = new TextField(20);
142: url.addActionListener(this );
143: okB = new Button("Ok");
144: okB.addActionListener(this );
145: cancelB = new Button("Cancel");
146: cancelB.addActionListener(this );
147:
148: GridBagLayout gbl = new GridBagLayout();
149: GridBagConstraints gbc = new GridBagConstraints();
150:
151: setLayout(gbl);
152: gbc.insets = new Insets(10, 0, 10, 0);
153: gbc.fill = GridBagConstraints.NONE;
154: gbc.gridwidth = GridBagConstraints.RELATIVE;
155: gbl.setConstraints(label, gbc);
156: add(label);
157:
158: gbc.gridwidth = GridBagConstraints.REMAINDER;
159: gbl.setConstraints(url, gbc);
160: add(url);
161:
162: gbc.gridwidth = GridBagConstraints.RELATIVE;
163: gbc.anchor = GridBagConstraints.EAST;
164: gbl.setConstraints(okB, gbc);
165: add(okB);
166:
167: gbc.gridwidth = GridBagConstraints.REMAINDER;
168: gbc.anchor = GridBagConstraints.WEST;
169: gbl.setConstraints(cancelB, gbc);
170: add(cancelB);
171:
172: pack();
173: show();
174:
175: url.requestFocus();
176: }
177: }
178:
179: class WindowCloser extends WindowAdapter {
180:
181: protected static int windows = 0;
182:
183: Frame window = null;
184:
185: public void windowClosing(WindowEvent e) {
186: if (e.getWindow() == window) {
187: window.setVisible(false);
188: window.dispose();
189: windows--;
190: if (windows < 0)
191: System.exit(0);
192: }
193: }
194:
195: WindowCloser(Frame window) {
196: this .window = window;
197: }
198:
199: }
200:
201: class ServerMenu extends MenuBar implements ActionListener {
202:
203: ServerBrowser browser = null;
204:
205: public void actionPerformed(ActionEvent evt) {
206: String command = evt.getActionCommand();
207: if (command.equals("open")) {
208: new UrlPopup("Open new Admin-server", browser,
209: (Frame) getParent(), true);
210: } else if (command.equals("new")) {
211: try {
212: Frame f = new Frame("New Server Browser");
213: f.setBackground(Color.lightGray);
214: Panel editor = new Panel();
215: Panel newbrowser = new Panel(new BorderLayout());
216: TreeListener tl = new TreeListener(editor);
217: ServerBrowser sb = null;
218: sb = new ServerBrowser(f, tl);
219: Scrollbar sv = new Scrollbar(Scrollbar.VERTICAL);
220: sb.setVerticalScrollbar(sv);
221: Scrollbar sh = new Scrollbar(Scrollbar.HORIZONTAL);
222: sb.setHorizontalScrollbar(sh);
223: newbrowser.add("Center", sb);
224: newbrowser.add("East", sv);
225: newbrowser.add("South", sh);
226: editor.setLayout(new BorderLayout());
227: // Add a menubar
228: ServerMenu menu = new ServerMenu(sb);
229: GridLayout g = new GridLayout(1, 2);
230: f.setLayout(g);
231: f.setMenuBar(menu);
232: f.add(newbrowser);
233: f.add(editor);
234: f.setSize(new Dimension(850, 600));
235: WindowCloser.windows++;
236: f.addWindowListener(new WindowCloser(f));
237: } catch (Exception ex) {
238: ex.printStackTrace();
239: }
240: } else if (command.equals("close")) {
241: Frame cont = (Frame) getParent();
242: cont.setVisible(false);
243: cont.dispose();
244: WindowCloser.windows--;
245: if (WindowCloser.windows < 0)
246: System.exit(0);
247: } else if (command.equals("quit")) {
248: Frame cont = (Frame) getParent();
249: cont.setVisible(false);
250: cont.dispose();
251: WindowCloser.windows = 0;
252: System.exit(0);
253: }
254: }
255:
256: ServerMenu(ServerBrowser browser) {
257: super ();
258: this .browser = browser;
259: Menu server = new Menu("Admin-Server");
260: add(server);
261: MenuItem open = new MenuItem("Open");
262: open.setActionCommand("open");
263: open.addActionListener(this );
264: server.add(open);
265: MenuItem newOpen = new MenuItem("Open in new window");
266: newOpen.setActionCommand("new");
267: newOpen.addActionListener(this );
268: server.add(newOpen);
269: server.addSeparator();
270: MenuItem close = new MenuItem("Close window");
271: close.setActionCommand("close");
272: close.addActionListener(this );
273: server.add(close);
274: MenuItem quit = new MenuItem("Exit");
275: quit.setActionCommand("quit");
276: quit.addActionListener(this );
277: server.add(quit);
278: }
279: }
280:
281: public class ServerBrowser extends TreeBrowser implements NodeHandler {
282:
283: class Expander extends Thread {
284: TreeBrowser browser;
285: TreeNode nd;
286:
287: public void run() {
288: if (getLock()) {
289: notifyExpander(browser, nd);
290: unlock();
291: }
292: }
293:
294: Expander(TreeBrowser browser, TreeNode nd) {
295: this .browser = browser;
296: this .nd = nd;
297: }
298: }
299:
300: public static final boolean debug = false;
301: Image diricon = null;
302: Image diropenedicon = null;
303: Image fileicon = null;
304: AdminContext admin = null;
305: TreeListener tl = null;
306: TreeNode lastn = null;
307: RemoteResourceWrapper rootResource;
308: boolean locked;
309: private Frame popup = null;
310:
311: protected void errorPopup(String name, Exception ex) {
312: (new MessagePopup(name + " : " + ex.getMessage())).show();
313: }
314:
315: /**
316: * gets a lock to avoid adding node while removing other nodes
317: * it sets also the Cursor to WAIT_CURSOR
318: */
319:
320: protected synchronized boolean getLock() {
321: if (locked)
322: return false;
323: setCursor(Frame.WAIT_CURSOR);
324: locked = true;
325: return true;
326: }
327:
328: /**
329: * release the lock and sets the Cursor to the default
330: */
331:
332: protected synchronized void unlock() {
333: locked = false;
334: setCursor(Frame.DEFAULT_CURSOR);
335: }
336:
337: // get rid of the Auth Popup
338:
339: protected void dispose(boolean Ok) {
340: if (!Ok) {
341: Frame f = getFrame(this );
342: if (f != null)
343: f.dispose();
344: WindowCloser.windows--;
345: popup.dispose();
346: if (WindowCloser.windows < 0)
347: System.exit(0);
348: } else if (popup != null) {
349: popup.dispose();
350: popup = null;
351: }
352: }
353:
354: // pops up a new Auth popup
355:
356: public void popupDialog(String name) {
357: if (popup == null) {
358: AuthPopup ap = new AuthPopup(this , name);
359: popup = new Frame("Authorization for jigadm");
360: popup.setBackground(Color.lightGray);
361: popup.setSize(new Dimension(300, 200));
362: popup.setLayout(new BorderLayout());
363: popup.add("Center", ap);
364: popup.show();
365: ap.user.requestFocus();
366: while (!ap.waitForCompletion())
367: ;
368: }
369: }
370:
371: /**
372: * give the Root Resource of the browser
373: */
374:
375: public RemoteResourceWrapper getRootWrapper() {
376: return rootResource;
377: }
378:
379: public void renameNode(RemoteResourceWrapper rw, String label) {
380: try {
381: if (rw.getResource().isContainer()) {
382: (new MessagePopup(
383: "WARNING: you have changed the identifier. "
384: + "To access the sons, close and reopen the node"))
385: .show();
386: }
387: } catch (RemoteAccessException ex) {
388: // ??
389: }
390: TreeNode tn = getNode(rw);
391: // if it is a visible node, change the label and repaint
392: if (tn != null) {
393: tn.setLabel(label);
394: repaint();
395: }
396: }
397:
398: public void removeNode(RemoteResourceWrapper rw) {
399: if (getLock()) {
400: if (getNode(rw) != null) {
401: removeBranch(getNode(rw));
402: tl.nodeRemoved(rw);
403: }
404: unlock();
405: repaint();
406: }
407: }
408:
409: public void insertNode(RemoteResourceWrapper father,
410: RemoteResourceWrapper son, String name) {
411: TreeNode fatherNode;
412: boolean ic = false;
413:
414: if (father == null)
415: System.out.println("Error null father");
416: fatherNode = getNode(father);
417: if (fatherNode.getChildren() == TreeNode.NOCHILD)
418: return;
419:
420: if (fatherNode == null)
421: return; // this should never happen, but...
422: try {
423: ic = son.getResource().isContainer();
424: } catch (RemoteAccessException ex) {
425: // fancy thing
426: errorPopup("RemoteAccessException", ex);
427: }
428:
429: if (ic)
430: insert(fatherNode, son, this , name, diricon);
431: else
432: insert(fatherNode, son, this , name, fileicon);
433: repaint();
434: }
435:
436: protected RemoteResourceWrapper getResources(
437: RemoteResourceWrapper rw, String name) {
438:
439: RemoteResource resource = null;
440: if (rw != null) {
441: try {
442: resource = rw.getResource().loadResource(name);
443: } catch (RemoteAccessException ex) {
444: errorPopup("RemoteAccessException", ex);
445: ex.printStackTrace();
446: }
447: }
448: return new RemoteResourceWrapper(rw, resource, this );
449: }
450:
451: private final Image getImage(String name) {
452: Image img;
453: img = Toolkit.getDefaultToolkit().getImage(name);
454: return img;
455: }
456:
457: private final Frame getFrame(Component c) {
458: while (!(c instanceof Frame)) {
459: c = c.getParent();
460: if (c == null)
461: return null;
462: }
463: return (Frame) c;
464: }
465:
466: /* private final*/public void setCursor(int cursor) {
467: getFrame(this ).setCursor(new Cursor(cursor));
468: Toolkit.getDefaultToolkit().sync();
469: }
470:
471: protected void open(AdminContext ac) {
472: RemoteResource rr = null;
473: admin = ac;
474: locked = false;
475: boolean authorized = false;
476:
477: if (rootResource != null)
478: removeNode(rootResource);
479: tl.focusChanged(null);
480: while (!authorized) {
481: try {
482: authorized = true;
483: ac.initialize();
484: } catch (RemoteAccessException ex) {
485: if (ex.getMessage().equals("Unauthorized")) {
486: authorized = false;
487: } else {
488: ex.printStackTrace();
489: }
490: } finally {
491: if (!authorized) {
492: popupDialog("admin");
493: }
494: }
495: }
496: try {
497: rr = ac.getAdminResource();
498: } catch (RemoteAccessException ex) {
499: errorPopup("RemoteAccessException", ex);
500: //( new MessagePopup("RemoteAccessException : "+
501: //ex.getMessage())).show();
502: return;
503: }
504: rootResource = new RemoteResourceWrapper(rr, this );
505: initialize(rootResource, "Root", this , diricon);
506: tl.focusChanged(rootResource);
507: repaint();
508: }
509:
510: public ServerBrowser(Frame frame, TreeListener tl) {
511: PropertyManager pm = PropertyManager.getPropertyManager();
512: this .tl = tl;
513:
514: diricon = getImage(pm.getIconLocation("smalldir"));
515: fileicon = getImage(pm.getIconLocation("smallfile"));
516: diropenedicon = getImage(pm.getIconLocation("smalldiropened"));
517:
518: new UrlPopup("Open Admin Server : ", this , frame, false);
519: }
520:
521: public ServerBrowser(AdminContext ac, TreeListener tl) {
522: boolean authorized = false;
523: RemoteResource rr = null;
524: PropertyManager pm = PropertyManager.getPropertyManager();
525: admin = ac;
526: this .tl = tl;
527:
528: locked = false;
529: diricon = getImage(pm.getIconLocation("smalldir"));
530: fileicon = getImage(pm.getIconLocation("smallfile"));
531: diropenedicon = getImage(pm.getIconLocation("smalldiropened"));
532: while (!authorized) {
533: try {
534: authorized = true;
535: ac.initialize();
536: } catch (RemoteAccessException ex) {
537: if (ex.getMessage().equals("Unauthorized")) {
538: authorized = false;
539: } else {
540: ex.printStackTrace();
541: }
542: } finally {
543: if (!authorized) {
544: popupDialog("admin");
545: }
546: }
547: }
548: try {
549: rr = ac.getAdminResource();
550: } catch (RemoteAccessException ex) {
551: // Unable to connect for whatever reason... exit!
552: ex.printStackTrace();
553: System.exit(0);
554: }
555: rootResource = new RemoteResourceWrapper(rr, this );
556: initialize(rootResource, "Root", this , diricon);
557: }
558:
559: public void notifySelect(TreeBrowser browser, TreeNode nd) {
560: if (tl != null) {
561: tl
562: .editedChanged(this , (RemoteResourceWrapper) nd
563: .getItem());
564: }
565: browser.unselect(lastn);
566: browser.select(nd);
567: browser.repaint();
568: lastn = nd;
569: }
570:
571: /**
572: * Handles Select notifications.
573: *
574: * we simply select the node and redraw the browser.
575: */
576: public void notifyExecute(TreeBrowser browser, TreeNode node) {
577: if (tl != null) {
578: tl.focusChanged((RemoteResourceWrapper) node.getItem());
579: }
580: if (!node.equals(lastn)) {
581: browser.unselect(lastn);
582: lastn = null;
583: }
584: browser.repaint();
585: }
586:
587: public void notifyExpand(TreeBrowser browser, TreeNode nd) {
588: (new Expander(browser, nd)).start();
589: }
590:
591: /**
592: * Handles Expand notifications
593: *
594: * if the node is a directory, we list its content and insert the
595: * directories and files in the browser.
596: */
597: public void notifyExpander(TreeBrowser browser, TreeNode nd) {
598: if (tl != null) {
599: tl.focusChanged((RemoteResourceWrapper) nd.getItem());
600: }
601: RemoteResourceWrapper rrw = null;
602: RemoteResource rr = null;
603: boolean ic = false;
604: boolean authorized;
605:
606: rrw = (RemoteResourceWrapper) nd.getItem();
607: if (rrw == null)
608: return;
609: rr = rrw.getResource();
610: try {
611: ic = rr.isContainer();
612: } catch (Exception ex) {
613: ex.printStackTrace();
614: }
615: if (ic) {
616: String names[] = null;
617: setCursor(Frame.WAIT_CURSOR);
618: authorized = false;
619: while (!authorized) {
620: authorized = true;
621: try {
622: names = rr.enumerateResourceIdentifiers();
623: } catch (RemoteAccessException ex) {
624: if (ex.getMessage().equals("Unauthorized")) {
625: authorized = false;
626: } else {
627: names = new String[0];
628: errorPopup("RemoteAccessException", ex);
629: ex.printStackTrace();
630: }
631: } finally {
632: if (!authorized) {
633: popupDialog("admin");
634: }
635: }
636: }
637: Sorter.sortStringArray(names, true);
638: if (debug)
639: System.out.println("Found " + names.length
640: + " identifiers");
641: for (int i = 0; i < names.length; i++) {
642: boolean nic = false;
643: RemoteResourceWrapper nrrw = getResources(rrw, names[i]);
644: RemoteResource nrr = nrrw.getResource();
645: try {
646: nic = nrr.isContainer();
647: } catch (Exception ex) {
648: ex.printStackTrace();
649: }
650: if (nic) {
651: browser.insert(nd, nrrw, this , names[i], diricon);
652: } else {
653: browser.insert(nd, nrrw, this , names[i], fileicon);
654: }
655: }
656: if (!nd.equals(lastn)) {
657: browser.unselect(lastn);
658: lastn = null;
659: }
660: setCursor(Frame.DEFAULT_CURSOR);
661: browser.repaint();
662: }
663: if (isDirectory(this , nd))
664: nd.setIcon(diropenedicon);
665: }
666:
667: public boolean isDirectory(TreeBrowser browser, TreeNode nd) {
668: RemoteResourceWrapper rrw = null;
669: boolean ic = false;
670: rrw = (RemoteResourceWrapper) nd.getItem();
671: if (rrw == null)
672: return false;
673: try {
674: return rrw.getResource().isContainer();
675: } catch (Exception ex) {
676: ex.printStackTrace();
677: }
678: return false;
679: }
680:
681: /**
682: * Handles Collapse notifications
683: *
684: * we simply collapse the given node and repaint the browser.
685: */
686: public void notifyCollapse(TreeBrowser browser, TreeNode node) {
687: if (getLock()) {
688: if (tl != null) {
689: tl.focusChanged((RemoteResourceWrapper) node.getItem());
690: }
691: browser.collapse(node);
692: if (!node.equals(lastn)) {
693: browser.unselect(lastn);
694: lastn = null;
695: }
696: unlock();
697: browser.repaint();
698: node.setIcon(diricon);
699: }
700: }
701:
702: static public void main(String args[]) {
703: String baseURL = null;
704: String jigadmRoot = null;
705:
706: for (int i = 0; i < args.length; i++) {
707: if (args[i].equals("-root")) {
708: Properties p = System.getProperties();
709: jigadmRoot = args[++i];
710: p.put(PropertyManager.ROOT_P, jigadmRoot);
711: System.setProperties(p);
712: }
713: baseURL = args[i];
714: }
715: try {
716: Frame f = new Frame("Server Browser: " + baseURL);
717: f.setBackground(Color.lightGray);
718: Panel editor = new Panel();
719: Panel browser = new Panel(new BorderLayout());
720: TreeListener tl = new TreeListener(editor);
721: ServerBrowser sb = null;
722: Scrollbar sv = new Scrollbar(Scrollbar.VERTICAL);
723: Scrollbar sh = new Scrollbar(Scrollbar.HORIZONTAL);
724: try {
725: AdminContext ac = new AdminContext(new URL(baseURL));
726: sb = new ServerBrowser(ac, tl);
727: sb.setVerticalScrollbar(sv);
728: sb.setHorizontalScrollbar(sh);
729: browser.add("Center", sb);
730: browser.add("East", sv);
731: browser.add("South", sh);
732: editor.setLayout(new BorderLayout());
733: ServerMenu menu = new ServerMenu(sb);
734:
735: GridLayout g = new GridLayout(1, 2);
736: f.setLayout(g);
737: f.setMenuBar(menu);
738: f.add(browser);
739: f.add(editor);
740: f.setSize(new Dimension(850, 600));
741: f.addWindowListener(new WindowCloser(f));
742: f.show();
743:
744: } catch (java.net.MalformedURLException ex) {
745: sb = new ServerBrowser(f, tl);
746: sb.setVerticalScrollbar(sv);
747: sb.setHorizontalScrollbar(sh);
748: browser.add("Center", sb);
749: browser.add("East", sv);
750: browser.add("South", sh);
751: editor.setLayout(new BorderLayout());
752: ServerMenu menu = new ServerMenu(sb);
753: GridLayout g = new GridLayout(1, 2);
754: f.setLayout(g);
755: f.setMenuBar(menu);
756: f.add(browser);
757: f.add(editor);
758: f.setSize(new Dimension(850, 600));
759: }
760: } catch (Exception ex) {
761: ex.printStackTrace();
762: }
763: }
764: }
|