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