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 JScrollPane scroller = new JScrollPane(mainTable);
91 scroller.setBorder(BorderFactory.createTitledBorder(
92 scroller.getBorder(),
93 "Known CREOLE directories",
94 TitledBorder.LEFT, TitledBorder.ABOVE_TOP));
95 mainSplit.setLeftComponent(scroller);
96
97 scroller = new JScrollPane(resourcesList);
98 scroller.setBorder(BorderFactory.createTitledBorder(
99 scroller.getBorder(),
100 "CREOLE resources in directory",
101 TitledBorder.LEFT, TitledBorder.ABOVE_TOP));
102 mainSplit.setRightComponent(scroller);
103
104 getContentPane().setLayout(new GridBagLayout());
105 GridBagConstraints constraints = new GridBagConstraints();
106 constraints.insets = new Insets(2, 2, 2, 2);
107 constraints.fill = GridBagConstraints.BOTH;
108 constraints.anchor = GridBagConstraints.WEST;
109 constraints.gridy = 0;
110 constraints.weightx = 1;
111 constraints.weighty = 1;
112 getContentPane().add(mainSplit, constraints);
113
114 constraints.gridy = 1;
115 constraints.weighty = 0;
116 Box hBox = Box.createHorizontalBox();
117 hBox.add(new JLabel("You can also "));
118 hBox.add(new JButton(new AddCreoleRepositoryAction()));
119 hBox.add(Box.createHorizontalGlue());
120 getContentPane().add(hBox, constraints);
121
122 constraints.gridy = 2;
123 constraints.anchor = GridBagConstraints.CENTER;
124 constraints.fill = GridBagConstraints.NONE;
125 hBox = Box.createHorizontalBox();
126 hBox.add(new JButton(new OkAction()));
127 hBox.add(Box.createHorizontalStrut(20));
128 hBox.add(new JButton(new CancelAction()));
129 getContentPane().add(hBox, constraints);
130 }
131
132 protected void initListeners(){
133 mainTable.getSelectionModel().addListSelectionListener(
134 new ListSelectionListener(){
135 public void valueChanged(ListSelectionEvent e){
136 resourcesListModel.dataChanged();
137 }
138 });
139 mainSplit.addComponentListener(new ComponentAdapter(){
140 public void componentResized(ComponentEvent e){
141 mainSplit.setDividerLocation(0.75);
142 }
143 });
144 }
145
146 protected Boolean getLoadNow(URL url){
147 Boolean res = (Boolean)loadNowByURL.get(url);
148 if(res == null){
149 res = new Boolean(Gate.getCreoleRegister().getDirectories().contains(url));
150 loadNowByURL.put(url, res);
151 }
152 return res;
153 }
154
155 protected Boolean getLoadAlways(URL url){
156 Boolean res = (Boolean)loadAlwaysByURL.get(url);
157 if(res == null){
158 res = new Boolean(Gate.getAutoloadPlugins().contains(url));
159 loadAlwaysByURL.put(url, res);
160 }
161 return res;
162 }
163
164 protected class MainTableModel extends AbstractTableModel{
165 public MainTableModel(){
166 localIcon = MainFrame.getIcon("loadFile.gif");
167 remoteIcon = MainFrame.getIcon("internet.gif");
168 invalidIcon = MainFrame.getIcon("param.gif");
169 }
170 public int getRowCount(){
171 return Gate.getKnownPlugins().size();
172 }
173
174 public int getColumnCount(){
175 return 6;
176 }
177
178 public String getColumnName(int column){
179 switch (column){
180 case NAME_COLUMN: return "Name";
181 case ICON_COLUMN: return "";
182 case URL_COLUMN: return "URL";
183 case LOAD_NOW_COLUMN: return "Load now";
184 case LOAD_ALWAYS_COLUMN: return "Load always";
185 case DELETE_COLUMN: return "Delete";
186 default: return "?";
187 }
188 }
189
190 public Class getColumnClass(int columnIndex){
191 switch (columnIndex){
192 case NAME_COLUMN: return String.class;
193 case ICON_COLUMN: return Icon.class;
194 case URL_COLUMN: return String.class;
195 case LOAD_NOW_COLUMN: return Boolean.class;
196 case LOAD_ALWAYS_COLUMN: return Boolean.class;
197 case DELETE_COLUMN: return Object.class;
198 default: return Object.class;
199 }
200 }
201
202 public Object getValueAt(int row, int column){
203 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
204 (URL)Gate.getKnownPlugins().get(row));
205 switch (column){
206 case NAME_COLUMN: return new File(dInfo.getUrl().getFile()).getName();
207 case ICON_COLUMN: return
208 dInfo.isValid() ? (
209 dInfo.getUrl().getProtocol().equalsIgnoreCase("file") ?
210 localIcon : remoteIcon) :
211 invalidIcon;
212 case URL_COLUMN: return dInfo.getUrl().toString();
213 case LOAD_NOW_COLUMN: return getLoadNow(dInfo.getUrl());
214 case LOAD_ALWAYS_COLUMN: return getLoadAlways(dInfo.getUrl());
215 case DELETE_COLUMN: return null;
216 default: return null;
217 }
218 }
219
220 public boolean isCellEditable(int rowIndex, int columnIndex){
221 return columnIndex == LOAD_NOW_COLUMN ||
222 columnIndex == LOAD_ALWAYS_COLUMN ||
223 columnIndex == DELETE_COLUMN;
224 }
225
226 public void setValueAt(Object aValue, int rowIndex, int columnIndex){
227 Boolean valueBoolean = (Boolean)aValue;
228 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
229 (URL)Gate.getKnownPlugins().get(rowIndex));
230 switch(columnIndex){
231 case LOAD_NOW_COLUMN:
232 loadNowByURL.put(dInfo.getUrl(), valueBoolean);
233 break;
234 case LOAD_ALWAYS_COLUMN:
235 loadAlwaysByURL.put(dInfo.getUrl(), valueBoolean);
236 break;
237 }
238 }
239
240 protected Icon localIcon;
241 protected Icon remoteIcon;
242 protected Icon invalidIcon;
243 }
244
245 protected class ResourcesListModel extends AbstractListModel{
246 public Object getElementAt(int index){
247 int row = mainTable.getSelectedRow();
248 if(row == -1) return null;
249 row = mainTable.rowViewToModel(row);
250 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
251 (URL)Gate.getKnownPlugins().get(row));
252 return (Gate.ResourceInfo)dInfo.getResourceInfoList().get(index);
253 }
254
255 public int getSize(){
256
257 int row = mainTable.getSelectedRow();
258 if(row == -1) return 0;
259 row = mainTable.rowViewToModel(row);
260 Gate.DirectoryInfo dInfo = Gate.getDirectoryInfo(
261 (URL)Gate.getKnownPlugins().get(row));
262 return dInfo.getResourceInfoList().size();
263 }
264
265 public void dataChanged(){
266 fireContentsChanged(this, 0, getSize() - 1);
269 }
270 }
271
272
276 protected class DeleteColumnCellRendererEditor extends AbstractCellEditor
277 implements TableCellRenderer, TableCellEditor{
278
279 public DeleteColumnCellRendererEditor(){
280 label = new JLabel();
281 rendererDeleteButton = new JButton(MainFrame.getIcon("delete.gif"));
282 rendererDeleteButton.setMaximumSize(rendererDeleteButton.getPreferredSize());
283 editorDeleteButton = new JButton(MainFrame.getIcon("delete.gif"));
284 editorDeleteButton.addActionListener(new ActionListener(){
285 public void actionPerformed(ActionEvent evt){
286 int row = mainTable.getEditingRow();
287 row = mainTable.rowViewToModel(row);
288 URL toDelete = (URL)Gate.getKnownPlugins().get(row);
289 Gate.removeKnownPlugin(toDelete);
290 loadAlwaysByURL.remove(toDelete);
291 loadNowByURL.remove(toDelete);
292 mainTableModel.fireTableDataChanged();
293 resourcesListModel.dataChanged();
294 }
295 });
296 }
297
298 public Component getTableCellRendererComponent(JTable table,
299 Object value,
300 boolean isSelected,
301 boolean hasFocus,
302 int row,
303 int column){
304 switch(column){
306 case DELETE_COLUMN:
307 return rendererDeleteButton;
308 default: return null;
309 }
310 }
311
312 public Component getTableCellEditorComponent(JTable table,
313 Object value,
314 boolean isSelected,
315 int row,
316 int column){
317 switch(column){
318 case DELETE_COLUMN:
319 return editorDeleteButton;
320 default: return null;
321 }
322 }
323
324 public Object getCellEditorValue(){
325 return null;
326 }
327
328 JButton editorDeleteButton;
329 JButton rendererDeleteButton;
330 JLabel label;
331 }
332
333 protected class ResourcesListCellRenderer extends DefaultListCellRenderer{
334 public Component getListCellRendererComponent(JList list,
335 Object value,
336 int index,
337 boolean isSelected,
338 boolean cellHasFocus){
339 Gate.ResourceInfo rInfo = (Gate.ResourceInfo)value;
340 super.getListCellRendererComponent(list,
342 rInfo.getResourceName(), index, isSelected, cellHasFocus);
343 setToolTipText(rInfo.getResourceComment());
345 return this;
346 }
347 }
348
349
350 protected class OkAction extends AbstractAction {
351 public OkAction(){
352 super("OK");
353 }
354 public void actionPerformed(ActionEvent evt){
355 setVisible(false);
356 Iterator pluginIter = loadNowByURL.keySet().iterator();
358 while(pluginIter.hasNext()){
359 URL aPluginURL = (URL)pluginIter.next();
360 boolean load = ((Boolean)loadNowByURL.get(aPluginURL)).booleanValue();
361 boolean loaded = Gate.getCreoleRegister().
362 getDirectories().contains(aPluginURL);
363 if(load && !loaded){
364 try{
366 Gate.getCreoleRegister().registerDirectories(aPluginURL);
367 }catch(GateException ge){
368 throw new GateRuntimeException(ge);
369 }
370 }
371 if(!load && loaded){
372 Gate.getCreoleRegister().removeDirectory(aPluginURL);
374 }
375 }
376
377
378 pluginIter = loadAlwaysByURL.keySet().iterator();
379 while(pluginIter.hasNext()){
380 URL aPluginURL = (URL)pluginIter.next();
381 boolean load = ((Boolean)loadAlwaysByURL.get(aPluginURL)).booleanValue();
382 boolean loaded = Gate.getAutoloadPlugins().contains(aPluginURL);
383 if(load && !loaded){
384 Gate.addAutoloadPlugin(aPluginURL);
386 }
387 if(!load && loaded){
388 Gate.removeAutoloadPlugin(aPluginURL);
390 }
391 }
392 loadNowByURL.clear();
393 loadAlwaysByURL.clear();
394 }
395 }
396
397
400 public void setVisible(boolean visible){
401 if(visible){
402 loadNowByURL.clear();
403 loadAlwaysByURL.clear();
404 mainTableModel.fireTableDataChanged();
405 }
406 super.setVisible(visible);
407 }
408 protected class CancelAction extends AbstractAction {
409 public CancelAction(){
410 super("Cancel");
411 }
412
413 public void actionPerformed(ActionEvent evt){
414 setVisible(false);
415 loadNowByURL.clear();
416 loadAlwaysByURL.clear();
417 }
418 }
419
420 protected class AddCreoleRepositoryAction extends AbstractAction {
421 public AddCreoleRepositoryAction(){
422 super("Add a new CREOLE repository");
423 putValue(SHORT_DESCRIPTION,"Load a new CREOLE repository");
424 }
425
426 public void actionPerformed(ActionEvent e) {
427 Box messageBox = Box.createHorizontalBox();
428 Box leftBox = Box.createVerticalBox();
429 JTextField urlTextField = new JTextField(20);
430 leftBox.add(new JLabel("Type an URL"));
431 leftBox.add(urlTextField);
432 messageBox.add(leftBox);
433
434 messageBox.add(Box.createHorizontalStrut(10));
435 messageBox.add(new JLabel("or"));
436 messageBox.add(Box.createHorizontalStrut(10));
437
438 class URLfromFileAction extends AbstractAction{
439 URLfromFileAction(JTextField textField){
440 super(null, MainFrame.getIcon("loadFile.gif"));
441 putValue(SHORT_DESCRIPTION,"Click to select a directory");
442 this.textField = textField;
443 }
444
445 public void actionPerformed(ActionEvent e){
446 JFileChooser fileChooser = MainFrame.getFileChooser();
447 fileChooser.setMultiSelectionEnabled(false);
448 fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
449 fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());
450 int result = fileChooser.showOpenDialog(PluginManagerUI.this);
451 if(result == JFileChooser.APPROVE_OPTION){
452 try{
453 textField.setText(fileChooser.getSelectedFile().
454 toURL().toExternalForm());
455 }catch(MalformedURLException mue){
456 throw new GateRuntimeException(mue.toString());
457 }
458 }
459 }
460 JTextField textField;
461 };
463 Box rightBox = Box.createVerticalBox();
464 rightBox.add(new JLabel("Select a directory"));
465 JButton fileBtn = new JButton(new URLfromFileAction(urlTextField));
466 rightBox.add(fileBtn);
467 messageBox.add(rightBox);
468
469 int res = JOptionPane.showOptionDialog(
470 PluginManagerUI.this, messageBox,
471 "Enter an URL to the directory containing the " +
472 "\"creole.xml\" file", JOptionPane.OK_CANCEL_OPTION,
473 JOptionPane.QUESTION_MESSAGE, null, null, null);
474 if(res == JOptionPane.OK_OPTION){
475 try{
476 URL creoleURL = new URL(urlTextField.getText());
477 Gate.addKnownPlugin(creoleURL);
478 mainTableModel.fireTableDataChanged();
479 }catch(Exception ex){
480 JOptionPane.showMessageDialog(
481 PluginManagerUI.this,
482 "There was a problem with your selection:\n" +
483 ex.toString() ,
484 "GATE", JOptionPane.ERROR_MESSAGE);
485 ex.printStackTrace(Err.getPrintWriter());
486 }
487 }
488 }
489 }
491 protected XJTable mainTable;
492 protected JSplitPane mainSplit;
493 protected MainTableModel mainTableModel;
494 protected ResourcesListModel resourcesListModel;
495 protected JList resourcesList;
496
497
500 protected Map loadNowByURL;
501
505 protected Map loadAlwaysByURL;
506
507 protected static final int ICON_COLUMN = 0;
508 protected static final int NAME_COLUMN = 1;
509 protected static final int URL_COLUMN = 2;
510 protected static final int LOAD_NOW_COLUMN = 3;
511 protected static final int LOAD_ALWAYS_COLUMN = 4;
512 protected static final int DELETE_COLUMN = 5;
513
514 }
515