1
15
16 package gate.gui;
17
18 import java.awt.*;
19 import java.awt.GridBagConstraints;
20 import java.awt.GridBagLayout;
21 import java.awt.event.*;
22 import java.awt.event.ActionEvent;
23 import java.awt.event.ActionListener;
24 import java.io.File;
25 import java.io.IOException;
26 import java.net.MalformedURLException;
27 import java.net.URL;
28 import java.util.*;
29 import java.util.ArrayList;
30 import java.util.List;
31 import javax.swing.*;
32 import javax.swing.border.TitledBorder;
33 import javax.swing.event.ListSelectionEvent;
34 import javax.swing.event.ListSelectionListener;
35 import javax.swing.table.*;
36 import javax.swing.table.AbstractTableModel;
37 import javax.swing.table.TableCellRenderer;
38 import org.jdom.*;
39 import org.jdom.Element;
40 import org.jdom.JDOMException;
41 import org.jdom.input.SAXBuilder;
42 import gate.Gate;
43 import gate.GateConstants;
44 import gate.event.CreoleListener;
45 import gate.swing.XJTable;
46 import gate.util.*;
47 import gate.util.Err;
48 import gate.util.GateRuntimeException;
49
50
53 public class PluginManagerUI extends JDialog implements GateConstants{
54
55 public PluginManagerUI(Frame owner){
56 super(owner);
57 initLocalData();
58 initGUI();
59 initListeners();
60 }
61
62
63 protected void initLocalData(){
64 loadNowByURL = new HashMap();
65 loadAlwaysByURL = new HashMap();
66 }
67
68 protected void initGUI(){
69 setTitle("Plugin Management Console");
70 mainTableModel = new MainTableModel();
71 mainTable = new XJTable();
72 mainTable.setModel(mainTableModel);
74 mainTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
76 DeleteColumnCellRendererEditor rendererEditor = new DeleteColumnCellRendererEditor();
77 mainTable.getColumnModel().getColumn(DELETE_COLUMN).
78 setCellEditor(rendererEditor);
79 mainTable.getColumnModel().getColumn(DELETE_COLUMN).
80 setCellRenderer(rendererEditor);
81
82 resourcesListModel = new ResourcesListModel();
83 resourcesList = new JList(resourcesListModel);
84 resourcesList.setCellRenderer(new ResourcesListCellRenderer());
85 resourcesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
86 ToolTipManager.sharedInstance().registerComponent(resourcesList);
88
89 mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
90 mainSplit.setResizeWeight(.75);
91 JScrollPane scroller = new JScrollPane(mainTable);
92 scroller.setBorder(BorderFactory.createTitledBorder(
93 scroller.getBorder(),
94 "Known CREOLE directories",
95 TitledBorder.LEFT, TitledBorder.ABOVE_TOP));
96 mainSplit.setLeftComponent(scroller);
97
98 scroller = new JScrollPane(resourcesList);
99 scroller.setBorder(BorderFactory.createTitledBorder(
100 scroller.getBorder(),
101 "CREOLE resources in directory",
102 TitledBorder.LEFT, TitledBorder.ABOVE_TOP));
103 mainSplit.setRightComponent(scroller);
104
105 getContentPane().setLayout(new GridBagLayout());
106 GridBagConstraints constraints = new GridBagConstraints();
107 constraints.insets = new Insets(2, 2, 2, 2);
108 constraints.fill = GridBagConstraints.BOTH;
109 constraints.anchor = GridBagConstraints.WEST;
110 constraints.gridy = 0;
111 constraints.weightx = 1;
112 constraints.weighty = 1;
113 getContentPane().add(mainSplit, constraints);
114
115 constraints.gridy = 1;
116 constraints.weighty = 0;
117 Box hBox = Box.createHorizontalBox();
118 hBox.add(new JLabel("You can also "));
119 hBox.add(new JButton(new AddCreoleRepositoryAction()));
120 hBox.add(Box.createHorizontalGlue());
121 getContentPane().add(hBox, constraints);
122
123 constraints.gridy = 2;
124 constraints.anchor = GridBagConstraints.CENTER;
125 constraints.fill = GridBagConstraints.NONE;
126 hBox = Box.createHorizontalBox();
127 hBox.add(new JButton(new OkAction()));
128 hBox.add(Box.createHorizontalStrut(20));
129 hBox.add(new JButton(new CancelAction()));
130 getContentPane().add(hBox, constraints);
131 }
132
133 protected void initListeners(){
134 mainTable.getSelectionModel().addListSelectionListener(
135 new ListSelectionListener(){
136 public void valueChanged(ListSelectionEvent e){
137 resourcesListModel.dataChanged();
138 }
139 });
140 mainSplit.addComponentListener(new ComponentAdapter(){
141 public void componentShown(ComponentEvent e){
142 mainSplit.setDividerLocation(-100);
144 }
145 });
146 }
147
148 protected Boolean getLoadNow(URL url){
149 Boolean res = (Boolean)loadNowByURL.get(url);
150 if(res == null){
151 res = new Boolean(Gate.getCreoleRegister().getDirectories().contains(url));
152 loadNowByURL.put(url, res);
153 }
154 return res;
155 }
156
157 protected Boolean getLoadAlways(URL url){
158 Boolean res = (Boolean)loadAlwaysByURL.get(url);
159 if(res == null){
160 res = new Boolean(Gate.getAutoloadPlugins().contains(url));
161 loadAlwaysByURL.put(url, res);
162 }
163 return res;
164 }
165
166 protected class MainTableModel extends AbstractTableModel{
167 public MainTableModel(){
168 localIcon = MainFrame.getIcon("loadFile.gif");
169 remoteIcon = MainFrame.getIcon("internet.gif");
170 invalidIcon = MainFrame.getIcon("param.gif");
171 }
172 public int getRowCount(){
173 return Gate.getKnownPlugins().size();
174 }
175
176 public int getColumnCount(){
177 return 6;
178 }
179
180 public String getColumnName(int column){
181 switch (column){
182 case NAME_COLUMN: return "Name";
183 case ICON_COLUMN: return "";
184 case URL_COLUMN: return "URL";
185 case LOAD_NOW_COLUMN: return "Load now";
186 case LOAD_ALWAYS_COLUMN: return "Load always";
187 case DELETE_COLUMN: return "Delete";
188 default: return "?";
189 }
190 }
191
192 public Class getColumnClass(int columnIndex){
193 switch (columnIndex){
194 case NAME_COLUMN: return String.class;
195 case ICON_COLUMN: return Icon.class;
196 case URL_COLUMN: return String.class;
197 case LOAD_NOW_COLUMN: return Boolean.class;
198 case LOAD_ALWAYS_COLUMN: return Boolean.class;
199 case DELETE_COLUMN: return Object.class;
200 default: return Object.class;
201 }
202 }
203
204 public Object getValueAt(int row, int column){
205 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
206 (URL)Gate.getKnownPlugins().get(row));
207 switch (column){
208 case NAME_COLUMN: return new File(dInfo.getUrl().getFile()).getName();
209 case ICON_COLUMN: return
210 dInfo.isValid() ? (
211 dInfo.getUrl().getProtocol().equalsIgnoreCase("file") ?
212 localIcon : remoteIcon) :
213 invalidIcon;
214 case URL_COLUMN: return dInfo.getUrl().toString();
215 case LOAD_NOW_COLUMN: return getLoadNow(dInfo.getUrl());
216 case LOAD_ALWAYS_COLUMN: return getLoadAlways(dInfo.getUrl());
217 case DELETE_COLUMN: return null;
218 default: return null;
219 }
220 }
221
222 public boolean isCellEditable(int rowIndex, int columnIndex){
223 return columnIndex == LOAD_NOW_COLUMN ||
224 columnIndex == LOAD_ALWAYS_COLUMN ||
225 columnIndex == DELETE_COLUMN;
226 }
227
228 public void setValueAt(Object aValue, int rowIndex, int columnIndex){
229 Boolean valueBoolean = (Boolean)aValue;
230 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
231 (URL)Gate.getKnownPlugins().get(rowIndex));
232 switch(columnIndex){
233 case LOAD_NOW_COLUMN:
234 loadNowByURL.put(dInfo.getUrl(), valueBoolean);
235 break;
236 case LOAD_ALWAYS_COLUMN:
237 loadAlwaysByURL.put(dInfo.getUrl(), valueBoolean);
238 break;
239 }
240 }
241
242 protected Icon localIcon;
243 protected Icon remoteIcon;
244 protected Icon invalidIcon;
245 }
246
247 protected class ResourcesListModel extends AbstractListModel{
248 public Object getElementAt(int index){
249 int row = mainTable.getSelectedRow();
250 if(row == -1) return null;
251 row = mainTable.rowViewToModel(row);
252 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
253 (URL)Gate.getKnownPlugins().get(row));
254 return (Gate.ResourceInfo)dInfo.getResourceInfoList().get(index);
255 }
256
257 public int getSize(){
258
259 int row = mainTable.getSelectedRow();
260 if(row == -1) return 0;
261 row = mainTable.rowViewToModel(row);
262 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
263 (URL)Gate.getKnownPlugins().get(row));
264 return dInfo.getResourceInfoList().size();
265 }
266
267 public void dataChanged(){
268 fireContentsChanged(this, 0, getSize() - 1);
271 }
272 }
273
274
278 protected class DeleteColumnCellRendererEditor extends AbstractCellEditor
279 implements TableCellRenderer, TableCellEditor{
280
281 public DeleteColumnCellRendererEditor(){
282 label = new JLabel();
283 rendererDeleteButton = new JButton(MainFrame.getIcon("delete.gif"));
284 rendererDeleteButton.setMaximumSize(rendererDeleteButton.getPreferredSize());
285 rendererDeleteButton.setMargin(new Insets(2, 5, 2, 5));
286 rendererBox = new JPanel();
287 rendererBox.setLayout(new GridBagLayout());
288 rendererBox.setOpaque(false);
289 GridBagConstraints constraints = new GridBagConstraints();
290 constraints.fill = GridBagConstraints.NONE;
291 constraints.gridy = 0;
292 constraints.gridx = GridBagConstraints.RELATIVE;
293 constraints.weightx = 1;
294 rendererBox.add(Box.createGlue(), constraints);
295 constraints.weightx = 0;
296 rendererBox.add(rendererDeleteButton, constraints);
297 constraints.weightx = 1;
298 rendererBox.add(Box.createGlue(), constraints);
299
300 editorDeleteButton = new JButton(MainFrame.getIcon("delete.gif"));
301 editorDeleteButton.setMargin(new Insets(2, 5, 2, 5));
302 editorDeleteButton.addActionListener(new ActionListener(){
303 public void actionPerformed(ActionEvent evt){
304 int row = mainTable.getEditingRow();
305 TableCellEditor currentEditor = mainTable.getCellEditor();
309 if(currentEditor != null) {
310 currentEditor.cancelCellEditing();
311 }
312 row = mainTable.rowViewToModel(row);
313 URL toDelete = (URL)Gate.getKnownPlugins().get(row);
314 Gate.removeKnownPlugin(toDelete);
315 loadAlwaysByURL.remove(toDelete);
316 loadNowByURL.remove(toDelete);
317 mainTableModel.fireTableDataChanged();
318 resourcesListModel.dataChanged();
319 }
320 });
321 editorDeleteButton.setMaximumSize(editorDeleteButton.getPreferredSize());
322 editorBox = new JPanel();
323 editorBox.setLayout(new GridBagLayout());
324 editorBox.setOpaque(false);
325 constraints.weightx = 1;
326 editorBox.add(Box.createGlue(), constraints);
327 constraints.weightx = 0;
328 editorBox.add(editorDeleteButton, constraints);
329 constraints.weightx = 1;
330 editorBox.add(Box.createGlue(), constraints);
331 }
332
333 public Component getTableCellRendererComponent(JTable table,
334 Object value,
335 boolean isSelected,
336 boolean hasFocus,
337 int row,
338 int column){
339 switch(column){
341 case DELETE_COLUMN:
342 return rendererBox;
344 default: return null;
345 }
346 }
347
348 public Component getTableCellEditorComponent(JTable table,
349 Object value,
350 boolean isSelected,
351 int row,
352 int column){
353 switch(column){
354 case DELETE_COLUMN:
355 return editorBox;
356 default: return null;
357 }
358 }
359
360 public Object getCellEditorValue(){
361 return null;
362 }
363
364 JButton editorDeleteButton;
365 JButton rendererDeleteButton;
366 JPanel rendererBox;
367 JPanel editorBox;
368 JLabel label;
369 }
370
371 protected class ResourcesListCellRenderer extends DefaultListCellRenderer{
372 public Component getListCellRendererComponent(JList list,
373 Object value,
374 int index,
375 boolean isSelected,
376 boolean cellHasFocus){
377 Gate.ResourceInfo rInfo = (Gate.ResourceInfo)value;
378 super.getListCellRendererComponent(list,
380 rInfo.getResourceName(), index, isSelected, cellHasFocus);
381 setToolTipText(rInfo.getResourceComment());
383 return this;
384 }
385 }
386
387
388 protected class OkAction extends AbstractAction {
389 public OkAction(){
390 super("OK");
391 }
392 public void actionPerformed(ActionEvent evt){
393 setVisible(false);
394 Iterator pluginIter = loadNowByURL.keySet().iterator();
396 while(pluginIter.hasNext()){
397 URL aPluginURL = (URL)pluginIter.next();
398 boolean load = ((Boolean)loadNowByURL.get(aPluginURL)).booleanValue();
399 boolean loaded = Gate.getCreoleRegister().
400 getDirectories().contains(aPluginURL);
401 if(load && !loaded){
402 try{
404 Gate.getCreoleRegister().registerDirectories(aPluginURL);
405 }catch(GateException ge){
406 throw new GateRuntimeException(ge);
407 }
408 }
409 if(!load && loaded){
410 Gate.getCreoleRegister().removeDirectory(aPluginURL);
412 }
413 }
414
415
416 pluginIter = loadAlwaysByURL.keySet().iterator();
417 while(pluginIter.hasNext()){
418 URL aPluginURL = (URL)pluginIter.next();
419 boolean load = ((Boolean)loadAlwaysByURL.get(aPluginURL)).booleanValue();
420 boolean loaded = Gate.getAutoloadPlugins().contains(aPluginURL);
421 if(load && !loaded){
422 Gate.addAutoloadPlugin(aPluginURL);
424 }
425 if(!load && loaded){
426 Gate.removeAutoloadPlugin(aPluginURL);
428 }
429 }
430 loadNowByURL.clear();
431 loadAlwaysByURL.clear();
432 }
433 }
434
435
438 public void setVisible(boolean visible){
439 if(visible){
440 loadNowByURL.clear();
441 loadAlwaysByURL.clear();
442 mainTableModel.fireTableDataChanged();
443 }
444 super.setVisible(visible);
445 }
446 protected class CancelAction extends AbstractAction {
447 public CancelAction(){
448 super("Cancel");
449 }
450
451 public void actionPerformed(ActionEvent evt){
452 setVisible(false);
453 loadNowByURL.clear();
454 loadAlwaysByURL.clear();
455 }
456 }
457
458 protected class AddCreoleRepositoryAction extends AbstractAction {
459 public AddCreoleRepositoryAction(){
460 super("Add a new CREOLE repository");
461 putValue(SHORT_DESCRIPTION,"Load a new CREOLE repository");
462 }
463
464 public void actionPerformed(ActionEvent e) {
465 Box messageBox = Box.createHorizontalBox();
466 Box leftBox = Box.createVerticalBox();
467 JTextField urlTextField = new JTextField(20);
468 leftBox.add(new JLabel("Type an URL"));
469 leftBox.add(urlTextField);
470 messageBox.add(leftBox);
471
472 messageBox.add(Box.createHorizontalStrut(10));
473 messageBox.add(new JLabel("or"));
474 messageBox.add(Box.createHorizontalStrut(10));
475
476 class URLfromFileAction extends AbstractAction{
477 URLfromFileAction(JTextField textField){
478 super(null, MainFrame.getIcon("loadFile.gif"));
479 putValue(SHORT_DESCRIPTION,"Click to select a directory");
480 this.textField = textField;
481 }
482
483 public void actionPerformed(ActionEvent e){
484 JFileChooser fileChooser = MainFrame.getFileChooser();
485 fileChooser.setMultiSelectionEnabled(false);
486 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
487 fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
488 int result = fileChooser.showOpenDialog(PluginManagerUI.this);
489 if(result == JFileChooser.APPROVE_OPTION){
490 try{
491 textField.setText(fileChooser.getSelectedFile().
492 toURL().toExternalForm());
493 }catch(MalformedURLException mue){
494 throw new GateRuntimeException(mue.toString());
495 }
496 }
497 }
498 JTextField textField;
499 };
501 Box rightBox = Box.createVerticalBox();
502 rightBox.add(new JLabel("Select a directory"));
503 JButton fileBtn = new JButton(new URLfromFileAction(urlTextField));
504 rightBox.add(fileBtn);
505 messageBox.add(rightBox);
506
507 int res = JOptionPane.showOptionDialog(
508 PluginManagerUI.this, messageBox,
509 "Enter an URL to the directory containing the " +
510 "\"creole.xml\" file", JOptionPane.OK_CANCEL_OPTION,
511 JOptionPane.QUESTION_MESSAGE, null, null, null);
512 if(res == JOptionPane.OK_OPTION){
513 try{
514 URL creoleURL = new URL(urlTextField.getText());
515 Gate.addKnownPlugin(creoleURL);
516 mainTableModel.fireTableDataChanged();
517 }catch(Exception ex){
518 JOptionPane.showMessageDialog(
519 PluginManagerUI.this,
520 "There was a problem with your selection:\n" +
521 ex.toString() ,
522 "GATE", JOptionPane.ERROR_MESSAGE);
523 ex.printStackTrace(Err.getPrintWriter());
524 }
525 }
526 }
527 }
529 protected XJTable mainTable;
530 protected JSplitPane mainSplit;
531 protected MainTableModel mainTableModel;
532 protected ResourcesListModel resourcesListModel;
533 protected JList resourcesList;
534
535
538 protected Map loadNowByURL;
539
543 protected Map loadAlwaysByURL;
544
545 protected static final int ICON_COLUMN = 0;
546 protected static final int NAME_COLUMN = 1;
547 protected static final int URL_COLUMN = 2;
548 protected static final int LOAD_NOW_COLUMN = 3;
549 protected static final int LOAD_ALWAYS_COLUMN = 4;
550 protected static final int DELETE_COLUMN = 5;
551
552 }
553