001: /* This file is *not* under GPL or any other public license
002: * Copyright 2005 Ugo Taddei
003: */
004: package de.latlon.deejump.plugin.manager;
005:
006: import java.awt.Component;
007: import java.awt.Dimension;
008: import java.awt.HeadlessException;
009: import java.awt.LayoutManager;
010: import java.awt.event.ActionEvent;
011: import java.awt.event.ActionListener;
012: import java.awt.event.MouseAdapter;
013: import java.awt.event.MouseEvent;
014: import java.awt.event.MouseListener;
015: import java.awt.event.WindowAdapter;
016: import java.awt.event.WindowEvent;
017: import java.io.File;
018: import java.net.MalformedURLException;
019: import java.net.URL;
020: import java.util.ArrayList;
021: import java.util.Arrays;
022: import java.util.Iterator;
023: import java.util.List;
024:
025: import javax.swing.BorderFactory;
026: import javax.swing.Box;
027: import javax.swing.BoxLayout;
028: import javax.swing.JButton;
029: import javax.swing.JComponent;
030: import javax.swing.JDialog;
031: import javax.swing.JFrame;
032: import javax.swing.JOptionPane;
033: import javax.swing.JPanel;
034: import javax.swing.JScrollPane;
035: import javax.swing.JTabbedPane;
036: import javax.swing.JTextArea;
037: import javax.swing.ScrollPaneConstants;
038: import javax.swing.WindowConstants;
039: import javax.swing.border.BevelBorder;
040:
041: import com.vividsolutions.jump.I18N;
042: import com.vividsolutions.jump.task.TaskMonitor;
043: import com.vividsolutions.jump.workbench.WorkbenchContext;
044: import com.vividsolutions.jump.workbench.plugin.Extension;
045: import com.vividsolutions.jump.workbench.plugin.PlugInManager;
046:
047: public class ExtensionManagerDialog extends JDialog {
048:
049: private PlugInManager manager;
050:
051: private WorkbenchContext workbenchContext;
052:
053: private List remoteExtensions;
054:
055: private List installedExtensions;
056:
057: private JTextArea descripTextArea;
058:
059: private static final String extensionCatalogFile = "extensioncatalog.xml";
060:
061: private String extensionSite;
062:
063: private boolean okClicked = false;
064:
065: private final MouseListener descriptionDisplayListener = new MouseAdapter() {
066: /*public void mouseClicked(MouseEvent e) {
067: CatalogExtensionPanel cep = (CatalogExtensionPanel) e
068: .getSource();
069: setDescriptionText(cep.getExtensionText());
070: }*/
071:
072: public void mouseEntered(MouseEvent e) {
073: ExtensionPanel cep = (ExtensionPanel) e.getSource();
074: setDescriptionText(cep.getExtensionText());
075: }
076: };
077:
078: private JPanel managePanel;
079:
080: private JPanel installPanel;
081:
082: private JPanel newVersionsPanel;
083:
084: public ExtensionManagerDialog(JFrame parent,
085: WorkbenchContext workbenchContext, String extensionSite)
086: throws Exception {
087: super (
088: parent,
089: I18N
090: .get("deejump.pluging.manager.ExtensionManagerDialog.Extension-Manager"));
091: setSize(350, 500);
092: setResizable(false);
093: setModal(true);
094: addWindowListener(new WindowAdapter() {
095: public void windowClosed(WindowEvent e) {
096: //
097: }
098: });
099: setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
100:
101: this .workbenchContext = workbenchContext;
102: this .manager = workbenchContext.getWorkbench()
103: .getPlugInManager();
104:
105: this .extensionSite = extensionSite;
106: //FIXME remove extensionCatalogFile class memebr
107: //TODO check if URL is valid...
108: URL catalog = new URL(this .extensionSite + extensionCatalogFile);
109: //ExtensionManagerDialog.class.getResource( extensionCatalogFile );
110:
111: setRemoteExtensions(readCatalog(catalog));
112: setInstalledExtensions(listInstalledExtensions());
113: synchronizeExtensions();
114: initGUI();
115: // setVisible(true);
116: }
117:
118: private ExtensionManagerDialog(JFrame parent,
119: List fakeInstalledExtensions) throws HeadlessException {
120: super (
121: parent,
122: I18N
123: .get("deejump.pluging.manager.ExtensionManagerDialog.Extension-Manager"));
124: setSize(350, 500);
125: addWindowListener(new WindowAdapter() {
126: public void windowClosed(WindowEvent e) {
127: //
128: }
129: });
130: // setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
131: extensionSite = "http://";
132: URL catalog = ExtensionManagerDialog.class
133: .getResource("plugincatalog.xml");
134:
135: setRemoteExtensions(readCatalog(catalog));
136: setInstalledExtensions(fakeInstalledExtensions);
137: synchronizeExtensions();
138:
139: initGUI();
140: setVisible(true);
141: }
142:
143: private void setInstalledExtensions(List installedExt) {
144: // must check if !null
145: this .installedExtensions = installedExt;
146:
147: }
148:
149: private void setRemoteExtensions(List remoteExt) {
150: // must check if !null
151: this .remoteExtensions = remoteExt;
152:
153: }
154:
155: private void initGUI() {
156: LayoutManager layout = new BoxLayout(this .getContentPane(),
157: BoxLayout.PAGE_AXIS);
158: getContentPane().setLayout(layout);
159:
160: getContentPane().add(createTabbedPane());
161: getContentPane().add(createTextArea());
162: getContentPane().add(createButtons());
163:
164: }
165:
166: private Component createTextArea() {
167: descripTextArea = new JTextArea();
168: descripTextArea.setRows(6);
169: descripTextArea.setEditable(false);
170: descripTextArea.setLineWrap(true);
171: descripTextArea.setWrapStyleWord(false);
172: /*descripTextArea.setBorder(BorderFactory.createCompoundBorder(
173: BorderFactory.createEmptyBorder(5, 5, 5, 5), BorderFactory
174: .createLineBorder(Color.DARK_GRAY)));
175: */
176: JScrollPane pane = new JScrollPane(descripTextArea,
177: ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
178: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
179: pane.setBorder(BorderFactory.createCompoundBorder(BorderFactory
180: .createEmptyBorder(20, 15, 20, 15), BorderFactory
181: .createBevelBorder(BevelBorder.LOWERED)));
182: return pane;
183: }
184:
185: private void setDescriptionText(String txt) {
186: descripTextArea.setText(txt);
187: descripTextArea.setCaretPosition(0);
188: }
189:
190: private Component createTabbedPane() {
191: JTabbedPane panes = new JTabbedPane();
192: panes.setBorder(BorderFactory.createEmptyBorder(10, 15, 0, 15));
193: panes.setPreferredSize(new Dimension(300, 400));
194:
195: managePanel = new JPanel();
196: managePanel.setLayout(new BoxLayout(managePanel,
197: BoxLayout.PAGE_AXIS));
198: JScrollPane pane = new JScrollPane(managePanel,
199: ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
200: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
201: panes
202: .addTab(
203: I18N
204: .get("deejump.pluging.manager.ExtensionManagerDialog.Installed-Extensions"),
205: pane);
206:
207: refreshExtensionsPanel(managePanel, installedExtensions, true);
208:
209: /*
210: for (Iterator iter = installedExtensions.iterator(); iter.hasNext();) {
211: CataloguedExtension ext = (CataloguedExtension) iter.next();
212: CatalogExtensionPanel cep = new CatalogExtensionPanel(ext);
213: ext.setInstalled( true );
214: managePanel.add(cep);
215:
216: cep.addMouseListener( descriptionDisplayListener );
217: }*/
218:
219: newVersionsPanel = new JPanel();
220: panes
221: .add(
222: I18N
223: .get("deejump.pluging.manager.ExtensionManagerDialog.New-Versions"),
224: newVersionsPanel);
225: panes.setEnabledAt(1, false);
226:
227: JComponent c = new JComponent() {
228: public Dimension getMaximumSize() {
229: return new Dimension(350, 200);
230: }
231: };
232:
233: installPanel = new JPanel();
234: installPanel.setLayout(new BoxLayout(installPanel,
235: BoxLayout.PAGE_AXIS));
236: pane = new JScrollPane(installPanel,
237: ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
238: ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
239: panes
240: .add(
241: I18N
242: .get("deejump.pluging.manager.ExtensionManagerDialog.Install"),
243: pane);
244:
245: refreshExtensionsPanel(installPanel, remoteExtensions, false);
246:
247: return panes;
248: }
249:
250: private Component createButtons() {
251: JComponent c = Box.createHorizontalBox();
252: int bSize = 20;
253: c.setBorder(BorderFactory.createEmptyBorder(bSize, bSize,
254: bSize, bSize));
255:
256: JButton button = new JButton(
257: I18N
258: .get("deejump.pluging.manager.ExtensionManagerDialog.Configure"));
259: button.addActionListener(new ActionListener() {
260: public void actionPerformed(ActionEvent e) {
261:
262: String input = JOptionPane
263: .showInputDialog(
264: ExtensionManagerDialog.this ,
265: I18N
266: .get("deejump.pluging.manager.ExtensionManagerDialog.Catalog-site-URL"),
267: extensionSite);
268:
269: extensionSite = input != null ? input : extensionSite;
270: //make sure it finishes as a dir
271: extensionSite = extensionSite.endsWith("/") ? extensionSite
272: : extensionSite + "/";
273: reReadCatalog();
274: }
275: });
276:
277: c.add(button);
278: c.add(Box.createHorizontalStrut(20));
279:
280: button = new JButton(
281: I18N
282: .get("deejump.pluging.manager.ExtensionManagerDialog.OK"));
283: button.addActionListener(new ActionListener() {
284: public void actionPerformed(ActionEvent e) {
285: // updateExtensions();
286: okClicked = true;
287: setVisible(false);
288:
289: }
290: });
291:
292: c.add(button);
293: c.add(Box.createHorizontalStrut(20));
294:
295: button = new JButton(
296: I18N
297: .get("deejump.pluging.manager.ExtensionManagerDialog.Cancel"));
298: button.addActionListener(new ActionListener() {
299: public void actionPerformed(ActionEvent e) {
300: // updateExtensions();
301: okClicked = false;
302: setVisible(false);
303:
304: }
305: });
306:
307: c.add(button);
308:
309: return c;
310: }
311:
312: private void reReadCatalog() {
313: try {
314: URL u = new URL(extensionSite + extensionCatalogFile);
315: setRemoteExtensions(readCatalog(u));
316: setInstalledExtensions(listInstalledExtensions());
317: synchronizeExtensions();
318: refreshExtensionsPanel(managePanel, installedExtensions,
319: true);
320: refreshExtensionsPanel(installPanel, remoteExtensions,
321: false);
322: } catch (MalformedURLException e1) {
323: JOptionPane
324: .showMessageDialog(
325: ExtensionManagerDialog.this ,
326: I18N
327: .get("deejump.pluging.manager.ExtensionManagerDialog.You-entered-a-malformed-URL"),
328: I18N
329: .get("deejump.pluging.manager.ExtensionManagerDialog.Disgraceful-Error"),
330: JOptionPane.ERROR_MESSAGE);
331: }
332: }
333:
334: private List listInstalledExtensions() {
335: if (manager == null) {
336: return new ArrayList(0);
337: }
338:
339: // make a copy, manager.getConfigurations() is unmodifiable
340: List tmpInstalledExtensions = new ArrayList(manager
341: .getConfigurations().size());
342: for (Iterator iter = manager.getConfigurations().iterator(); iter
343: .hasNext();) {
344: tmpInstalledExtensions.add(wrapExtension((Extension) iter
345: .next()));
346: }
347:
348: return tmpInstalledExtensions;
349: }
350:
351: private ExtensionWrapper wrapExtension(Extension pluggedInExt) {
352:
353: for (Iterator iter = remoteExtensions.iterator(); iter
354: .hasNext();) {
355: ExtensionWrapper remExt = (ExtensionWrapper) iter.next();
356:
357: if (remExt.getName().equals(pluggedInExt.getName())) {
358: return remExt;
359: }
360: }
361:
362: final String desc = I18N
363: .get("deejump.pluging.manager.ExtensionManagerDialog.This-extension-has-not-been-found-in-the-catalogue")
364: + "\n"
365: + I18N
366: .get("deejump.pluging.manager.ExtensionManagerDialog.It-may-have-been-added-by-copying-into-the-lib/ext-directory");
367: final String unknownCat = I18N
368: .get("deejump.pluging.manager.ExtensionManagerDialog.unknown-category");
369: final String unknownAuthor = I18N
370: .get("deejump.pluging.manager.ExtensionManagerDialog.unknown-author");
371:
372: return new ExtensionWrapper(
373: pluggedInExt.getName(),
374: pluggedInExt.getName()
375: + "("
376: + I18N
377: .get("deejump.pluging.manager.ExtensionManagerDialog.uncatalogued")
378: + ")",
379: unknownAuthor,
380: pluggedInExt.getVersion(),
381: I18N
382: .get("deejump.pluging.manager.ExtensionManagerDialog.unknown-JUMP-version"),
383: unknownCat, desc, new ArrayList(0));
384: }
385:
386: private void synchronizeExtensions() {
387: }
388:
389: private void _synchronizeExtensions() {
390:
391: List tmpRemoteExtensions = new ArrayList(remoteExtensions);
392: for (Iterator iter = installedExtensions.iterator(); iter
393: .hasNext();) {
394: // Extension configuration = (Extension) iter.next();
395: ExtensionWrapper configuration = (ExtensionWrapper) iter
396: .next();
397:
398: for (Iterator iter2 = remoteExtensions.iterator(); iter2
399: .hasNext();) {
400: ExtensionWrapper ext = (ExtensionWrapper) iter2.next();
401:
402: if (configuration.getName().equals(ext.getName())) {
403:
404: // remote ext match local, add to temp list
405: // temp list wil only list the remote extensions
406: // that are not yet locally installed
407:
408: // tmpRemoteExtensions.remove(ext);
409: }
410: }
411: }
412:
413: setRemoteExtensions(tmpRemoteExtensions);
414: }
415:
416: private void refreshExtensionsPanel(JComponent extensionPanel,
417: List extensionList, boolean selected) {
418:
419: extensionPanel.removeAll();
420: //FIXME are you sure the listeners are being removed too?
421: for (Iterator iter = extensionList.iterator(); iter.hasNext();) {
422: ExtensionWrapper ext = (ExtensionWrapper) iter.next();
423: ext.setInstalled(selected);
424:
425: ExtensionPanel cep = new ExtensionPanel(ext);
426:
427: if (extensionList == remoteExtensions) {
428: if (installedExtensions.contains(ext)) {
429: cep.setSelected(true);
430: cep.setEnabled(false);
431: }
432: }
433: cep.addMouseListener(descriptionDisplayListener);
434: extensionPanel.add(cep);
435: }
436: }
437:
438: public void updateExtensions(TaskMonitor monitor) throws Exception {
439:
440: List recentlyAddedExtensions = new ArrayList();
441: //install remote extensions
442: for (Iterator iter = remoteExtensions.iterator(); iter
443: .hasNext();) {
444: ExtensionWrapper ext = (ExtensionWrapper) iter.next();
445: if (ext.isInstalled() && !installedExtensions.contains(ext)) {//isInstalled means here: "is to be installed"
446:
447: ExtensionHelper.install(this , workbenchContext, ext,
448: monitor);
449: recentlyAddedExtensions.add(ext);
450: }
451: }
452: installedExtensions.addAll(recentlyAddedExtensions);
453:
454: //remove installed extensions
455: for (Iterator iter = installedExtensions.iterator(); iter
456: .hasNext();) {
457: ExtensionWrapper ext = (ExtensionWrapper) iter.next();
458: if (!ext.isInstalled()) {
459: System.out
460: .println("must : manager.getPlugInDirectory()");
461: System.out.println("pi dir: : "
462: + manager.getPlugInDirectory());
463: File pluginDir =
464: // new File("C:/temp/");
465: manager.getPlugInDirectory();
466: List fileList = Arrays.asList(pluginDir.listFiles());
467:
468: ExtensionHelper.remove(fileList, ext, monitor);
469: }
470: }
471: }
472:
473: public void setVisible(boolean vis) {
474: if (vis) {
475: okClicked = false;
476: // setInstalledExtensions( listInstalledExtensions() );
477: System.out.println("listInstalledExtensions(): "
478: + listInstalledExtensions());
479: // synchronizeExtensions();
480: //FIXME
481: //there's a bug here making the installed and cataloge exts being wrongly clicked
482: refreshExtensionsPanel(managePanel, installedExtensions,
483: true);
484: refreshExtensionsPanel(installPanel, remoteExtensions,
485: false);
486: }
487: super .setVisible(vis);
488:
489: }
490:
491: /**
492: * Reads an extensions catalog from the XML at catalog, and builds list of
493: * remotely available extensions
494: *
495: * @param catalog
496: */
497: private List readCatalog(URL catalog) {
498:
499: CatalogParser catParser = new CatalogParser(catalog);
500: return catParser.getExtensionList();
501:
502: }
503:
504: // test
505: public static void main(String[] args) throws Exception {
506:
507: List resources = new ArrayList(1);
508: resources.add("PrintLayoutAlpha0.1-i18n.jar");
509:
510: List remoteExt = new ArrayList(2);
511: remoteExt.add(new ExtensionWrapper("Print Layout", " some",
512: "ut", "123", "456", "cat", "desc", resources));
513:
514: resources.clear();
515: resources.add("dummy_ext.jar");
516:
517: remoteExt.add(new ExtensionWrapper("Dummy extension",
518: "The dummy extension", "ut", "123", "456", "cat",
519: "desc 1", resources));
520: final ExtensionManagerDialog managerDialog = new ExtensionManagerDialog(
521: new JFrame(), remoteExt);
522:
523: managerDialog.addWindowListener(new WindowAdapter() {
524: public void windowClosing(WindowEvent e) {
525: try {
526: managerDialog.updateExtensions(null);
527: } catch (Exception e1) {
528: e1.printStackTrace();
529: }
530: System.exit(0);
531: }
532: });
533: // managerDialog.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
534:
535: }
536:
537: public String getExtensionSite() {
538: return extensionSite;
539: }
540:
541: public boolean isOkClicked() {
542: return okClicked;
543: }
544:
545: }
|