1
15
16 package gate.gui;
17
18 import java.awt.Component;
19 import java.awt.event.ActionEvent;
20 import java.awt.event.ActionListener;
21 import java.lang.reflect.Constructor;
22 import java.util.*;
23
24 import javax.swing.*;
25 import javax.swing.table.AbstractTableModel;
26 import javax.swing.table.TableCellEditor;
27
28 import gate.*;
29 import gate.creole.*;
30 import gate.util.GateException;
31 import gate.util.LuckyException;
32
33
36 public class SchemaAnnotationEditor extends AbstractVisualResource
37 implements AnnotationVisualResource,
38 ResizableVisualResource{
39
40
41 public SchemaAnnotationEditor(){}
42
43
45
50 public void setTarget(Object target){
51 currentAnnotSet = (AnnotationSet) target;
52 }
54
59 public void setAnnotation(Annotation ann){
60 if (ann == null) return;
62
63 currentAnnot = ann;
64 currentStartOffset = currentAnnot.getStartNode().getOffset();
65 currentEndOffset = currentAnnot.getEndNode().getOffset();
66 currentAnnotFeaturesMap = Factory.newFeatureMap();
67 currentAnnotFeaturesMap.putAll(currentAnnot.getFeatures());
68 currentAnnotSchema = null;
69 CreoleRegister creoleReg = Gate.getCreoleRegister();
70 List currentAnnotationSchemaList =
71 creoleReg.getLrInstances("gate.creole.AnnotationSchema");
72 if (currentAnnotationSchemaList.isEmpty()) return;
74 name2annotSchemaMap = new TreeMap();
75 Iterator annotSchemaIter = currentAnnotationSchemaList.iterator();
76 currentAnnotSchema = (AnnotationSchema) currentAnnotationSchemaList.get(0);
78
79 AnnotationSchema annotSch;
80 String annotSchName;
81 while (annotSchemaIter.hasNext()){
82 annotSch = (AnnotationSchema)annotSchemaIter.next();
83 annotSchName = annotSch.getAnnotationName();
84 if(annotSch != null && annotSchName != null)
85 name2annotSchemaMap.put(annotSchName, annotSch);
86 if (currentAnnot.getType().equals(annotSchName))
87 currentAnnotSchema = annotSch;
88 }
90 initLocalData();
91 buildGuiComponents();
92 initListeners();
93 }
95
102 public void setSpan(Long startOffset, Long endOffset, String annotType){
103 if (startOffset == null || endOffset == null) return;
105 currentStartOffset = startOffset;
106 currentEndOffset = endOffset;
107 currentAnnot = null;
108 currentAnnotFeaturesMap = null;
109 currentAnnotSchema = null;
110 CreoleRegister creoleReg = Gate.getCreoleRegister();
111 List currentAnnotationSchemaList = null;
112 try{
113 currentAnnotationSchemaList =
114 creoleReg.getAllInstances("gate.creole.AnnotationSchema");
115 } catch (GateException e){
116 throw new LuckyException("gate.creole.AnnotationSchema or a class that"+
119 " extends it, is not registered in the creole.xml register.Edit your"+
120 " creole.xml and try again.");
121 } if (currentAnnotationSchemaList.isEmpty()) return;
124 name2annotSchemaMap = new TreeMap();
125 Iterator annotSchemaIter = currentAnnotationSchemaList.iterator();
126 currentAnnotSchema = (AnnotationSchema) currentAnnotationSchemaList.get(0);
128
129 AnnotationSchema annotSch;
130 String annotSchName;
131 while (annotSchemaIter.hasNext()){
132 annotSch = (AnnotationSchema)annotSchemaIter.next();
133 annotSchName = annotSch.getAnnotationName();
134 if(annotSch != null && annotSchName != null)
135 name2annotSchemaMap.put(annotSchName, annotSch);
136 }
138 initLocalData();
139 buildGuiComponents();
140 initListeners();
141 }
143
147 public void okAction() throws GateException{
148 Iterator iter = tableModel.data.iterator();
150 while (iter.hasNext()){
151 RowData rd = (RowData) iter.next();
152 responseMap.put(rd.getFeatureSchema().getFeatureName(), rd.getValue());
153 } if (currentAnnot == null){
155 currentAnnotSet.add( currentStartOffset,
156 currentEndOffset,
157 currentAnnotSchema.getAnnotationName(),
158 responseMap);
159 }else{
160 if (currentAnnot.getType().equals(currentAnnotSchema.getAnnotationName())){
161 currentAnnot.setFeatures(responseMap);
162 }else{
163 currentAnnotSet.add( currentStartOffset,
164 currentEndOffset,
165 currentAnnotSchema.getAnnotationName(),
166 responseMap);
167 currentAnnotSet.remove(currentAnnot);
168 } } }
172 public void cancelAction() throws GateException {
173 return;
177 }
178
179
186 public boolean canDisplayAnnotationType(String annotationType){
187 if (annotationType == null) return false;
190 CreoleRegister creoleReg = Gate.getCreoleRegister();
191 List currentAnnotationSchemaList =
192 creoleReg.getLrInstances("gate.creole.AnnotationSchema");
193 if (currentAnnotationSchemaList.isEmpty()) return false;
194 Iterator iter = currentAnnotationSchemaList.iterator();
195 while (iter.hasNext()){
196 AnnotationSchema annotSchema = (AnnotationSchema) iter.next();
197 if (annotationType.equals(annotSchema.getAnnotationName())) return true;
198 } return false;
200 }
202
204
206 List currentAnnotationSchemaList = null;
207
208 AnnotationSet currentAnnotSet = null;
209
210 Annotation currentAnnot = null;
211
212 Long currentStartOffset = null;
213
214 Long currentEndOffset = null;
215
216 AnnotationSchema currentAnnotSchema = null;
217
218 FeatureMap currentAnnotFeaturesMap = null;
219
220 FeatureMap responseMap = null;
221
222 FeaturesTableModel tableModel = null;
223
224 Map name2featureSchemaMap = null;
225
226 Map name2annotSchemaMap = null;
227
228 DefaultListModel listModel = null;
229
230
232 JTable featuresTable = null;
233
234 JScrollPane featuresTableScroll = null;
235
238 JList featureSchemaList = null;
239
240 JScrollPane featuresListScroll = null;
241
242 JButton removeFeatButton = null;
243
244 JButton addFeatButton = null;
245
246 JComboBox annotSchemaComboBox = null;
247
248 InnerFeaturesEditor featuresEditor = null;
249
250
251 protected void initLocalData(){
252 responseMap = Factory.newFeatureMap();
254
255 if (currentAnnotFeaturesMap == null)
256 currentAnnotFeaturesMap = Factory.newFeatureMap();
257
258 name2featureSchemaMap = new HashMap();
259 Map fSNames2FSMap = new HashMap();
261
262 listModel = new DefaultListModel();
263 Set featuresSch = currentAnnotSchema.getFeatureSchemaSet();
266 if (featuresSch != null){
267 Iterator iter = featuresSch.iterator();
268 while (iter.hasNext()){
269 FeatureSchema fs = (FeatureSchema) iter.next();
270 if (fs != null){
274 fSNames2FSMap.put(fs.getFeatureName(),fs);
275 if( !currentAnnotFeaturesMap.containsKey(fs.getFeatureName())){
276 name2featureSchemaMap.put(fs.getFeatureName(),fs);
277 listModel.addElement(fs.getFeatureName());
278 } } } }
283 Set tableData = new HashSet();
285 Iterator iterator = currentAnnotFeaturesMap.keySet().iterator();
286 while (iterator.hasNext()){
287 String key = (String) iterator.next();
288 if (fSNames2FSMap.keySet().contains(key)){
293 Object value = currentAnnotFeaturesMap.get(key);
295 tableData.add(new RowData(value,(FeatureSchema)fSNames2FSMap.get(key)));
296 } else
297 responseMap.put(key,currentAnnotFeaturesMap.get(key));
301 } tableModel = new FeaturesTableModel(tableData);
303 }
305
306 protected void buildGuiComponents(){
307 this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
308
310 JPanel annotSchBox = new JPanel();
311 annotSchBox.setLayout(new BoxLayout(annotSchBox, BoxLayout.Y_AXIS));
312 annotSchBox.setAlignmentX(Component.LEFT_ALIGNMENT);
313 annotSchBox.add(Box.createVerticalStrut(5));
314 annotSchemaComboBox = new JComboBox(name2annotSchemaMap.keySet().toArray());
315 annotSchemaComboBox.setEditable(false);
316 annotSchemaComboBox.setAlignmentX(Component.LEFT_ALIGNMENT);
317 annotSchemaComboBox.setSelectedItem(currentAnnotSchema.getAnnotationName());
318 JLabel annotSchemaLabel = new JLabel("Select annotation type");
319 annotSchemaLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
320 annotSchBox.add(annotSchemaLabel);
321 annotSchBox.add(annotSchemaComboBox);
322
323
324 JPanel componentsBox = new JPanel();
326 componentsBox.setLayout(new BoxLayout(componentsBox, BoxLayout.X_AXIS));
327 componentsBox.setAlignmentX(Component.LEFT_ALIGNMENT);
328
329 featuresTable = new JTable();
331 featuresTable.setSelectionMode(
332 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
333 featuresTable.setModel(new FeaturesTableModel(new HashSet()));
334 featuresEditor = new InnerFeaturesEditor();
336 featuresTable.setDefaultEditor(java.lang.Object.class, featuresEditor);
337 featuresTableScroll = new JScrollPane(featuresTable);
338
339 Box box = Box.createVerticalBox();
340 JLabel currentFeat = new JLabel("Current features");
341 currentFeat.setAlignmentX(Component.LEFT_ALIGNMENT);
342 box.add(currentFeat);
343 box.add(Box.createVerticalStrut(10));
344 box.add(featuresTableScroll);
345 featuresTableScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
346
347 componentsBox.add(box);
348 componentsBox.add(Box.createHorizontalStrut(10));
349
350 Box buttBox = Box.createVerticalBox();
352 removeFeatButton = new JButton(">>");
353 addFeatButton = new JButton("<<");
354
355 buttBox.add(addFeatButton);
356 buttBox.add(Box.createVerticalStrut(10));
357 buttBox.add(removeFeatButton);
358
359 componentsBox.add(buttBox);
360
361 componentsBox.add(Box.createHorizontalStrut(10));
362
363 featureSchemaList = new JList();
365 featureSchemaList.setSelectionMode(
366 ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
367 Set featuresSch = currentAnnotSchema.getFeatureSchemaSet();
368 if(featuresSch != null){
369 featureSchemaList.setVisibleRowCount(featuresSch.size());
370 }
371 featuresListScroll = new JScrollPane(featureSchemaList);
372
373 box = Box.createVerticalBox();
374 JLabel possibFeaturesLabel = new JLabel("Possible features");
375 possibFeaturesLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
376 box.add(possibFeaturesLabel);
377 box.add(Box.createVerticalStrut(10));
378 featuresListScroll.setAlignmentX(Component.LEFT_ALIGNMENT);
379 box.add(featuresListScroll);
380
381 componentsBox.add(box);
382 componentsBox.add(Box.createHorizontalStrut(5));
383
384 box = Box.createVerticalBox();
385 box.add(annotSchBox);
386 box.add(componentsBox);
387 this.add(box);
388 this.initGuiComponents();
389 }
391
392 protected void initGuiComponents(){
393 featuresTable.setModel(tableModel);
394 featureSchemaList.setModel(listModel);
395 }
397
398 protected void initListeners(){
399
400 annotSchemaComboBox.addActionListener(new ActionListener() {
401 public void actionPerformed(ActionEvent e) {
402 currentAnnotSchema = (AnnotationSchema) name2annotSchemaMap.get(
403 (String)annotSchemaComboBox.getSelectedItem());
404 initLocalData();
405 initGuiComponents();
406 } });
409 removeFeatButton.addActionListener(new ActionListener() {
411 public void actionPerformed(ActionEvent e) {
412 doRemoveFeatures();
413 } });
416 addFeatButton.addActionListener(new ActionListener() {
418 public void actionPerformed(ActionEvent e) {
419 doAddFeatures();
420 } }); }
424
425 private void doRemoveFeatures(){
426 int[] selectedRows = featuresTable.getSelectedRows();
427
428 if (selectedRows.length <= 0) return;
429
430 for (int i = (selectedRows.length - 1); i > -1 ; i--)
431 doRemoveFeature(selectedRows[i]);
432
433 tableModel.fireTableDataChanged();
434 }
436
437 private void doRemoveFeature(int rowIndex){
438 RowData rd = (RowData) tableModel.data.get(rowIndex);
439
440 name2featureSchemaMap.put(rd.getFeatureSchema().getFeatureName(),
441 rd.getFeatureSchema());
442
443 listModel.addElement(rd.getFeatureSchema().getFeatureName());
444 tableModel.data.remove(rowIndex);
445 }
447
448 private void doAddFeatures(){
449 Object[] selectedFeaturesName = featureSchemaList.getSelectedValues();
450 for (int i = 0 ; i < selectedFeaturesName.length; i ++){
451 doAddFeature((String) selectedFeaturesName[i]);
452 } tableModel.fireTableDataChanged();
454 }
456
457 private void doAddFeature(String aFeatureName){
458 FeatureSchema fs=(FeatureSchema) name2featureSchemaMap.get(aFeatureName);
459
460 name2featureSchemaMap.remove(aFeatureName);
462 listModel.removeElement(aFeatureName);
463
464 Object value = null;
465 if (fs.isDefault() || fs.isFixed())
466 value = fs.getFeatureValue();
467 if (value == null && fs.isEnumeration()){
468 Iterator iter = fs.getPermissibleValues().iterator();
469 if (iter.hasNext()) value = iter.next();
470 }
471 tableModel.data.add(new RowData(value,fs));
472 }
474
476 protected class FeaturesTableModel extends AbstractTableModel{
478
479 ArrayList data = null;
480
481 public FeaturesTableModel(Set aData){
482 data = new ArrayList(aData);
483 }
485 public void fireTableDataChanged(){
486 super.fireTableDataChanged();
487 }
489 public int getColumnCount(){return 3;}
490
491 public Class getColumnClass(int columnIndex){
492 switch(columnIndex){
493 case 0: return String.class;
494 case 1: return Object.class;
495 case 2: return String.class;
496 default: return Object.class;
497 }
498 }
500 public String getColumnName(int columnIndex){
501 switch(columnIndex){
502 case 0: return "Name";
503 case 1: return "Value";
504 case 2: return "Type";
505 default: return "?";
506 }
507 }
509 public boolean isCellEditable( int rowIndex,
510 int columnIndex){
511
512
513 if(columnIndex == 1){
514 RowData rd = (RowData) data.get(rowIndex);
515 FeatureSchema fs = rd.getFeatureSchema();
516 if (fs.isFixed() || fs.isProhibited()) return false;
517 else return true;
518 } if(columnIndex == 0 || columnIndex == 2) return false;
520 return false;
521 }
523 public int getRowCount(){
524 return data.size();
525 }
527
528 public Object getValueAt( int rowIndex,
529 int columnIndex){
530
531 RowData rd = (RowData) data.get(rowIndex);
532
533 switch(columnIndex){
534 case 0: return rd.getFeatureSchema().getFeatureName();
535 case 1: return (rd.getValue() == null)? new String(""): rd.getValue();
536 case 2: {
537 String type = rd.getFeatureSchema().getValueClassName();
540 if(type == null)
541 return new String("");
542 else{
543 int start = type.lastIndexOf(".");
544 if ((start > -1) && (start < type.length()))
545 return type.substring(start+1,type.length());
546 else return type;
547 } }
549
550 default: return "?";
551 } }
554
555 public void setValueAt( Object aValue,
556 int rowIndex,
557 int columnIndex){
558
559 if (data == null || data.isEmpty()) return;
560 RowData rd = (RowData) data.get(rowIndex);
561 switch(columnIndex){
562 case 0:{break;}
563 case 1:{
564 String className = null;
566 String aValueClassName = null;
567 if (aValue == null){
570 rd.setValue("?");
571 return;
572 } className = rd.getFeatureSchema().getValueClassName();
575 aValueClassName = aValue.getClass().toString();
577 if (className == null){
580 rd.setValue(aValue);
581 return;
582 }
584 if (className.equals(aValueClassName)){
587 rd.setValue(aValue);
588 return;
589 } if (!"class java.lang.String".equals(aValueClassName)){
593 rd.setValue(aValue);
594 return;
595 }
597 Class classObj = null;
600 try{
601 classObj = Gate.getClassLoader().loadClass(className);
603 }catch (ClassNotFoundException cnfex){
604 try{
605 classObj = Class.forName(className);
607 }catch (ClassNotFoundException cnfe){
608 rd.setValue(aValue);
609 return;
610 }
611 } Constructor[] constrArray = classObj.getConstructors();
614 if (constrArray == null){
615 rd.setValue(aValue);
616 return;
617 }
619 boolean found = false;
621 Constructor constructor = null;
622 for (int i=0; i<constrArray.length; i++){
623 constructor = constrArray[i];
624 if ( constructor.getParameterTypes().length == 1 &&
625 "class java.lang.String".equals(
626 constructor.getParameterTypes()[0].toString())
627 ){
628 found = true;
629 break;
630 } }
633 if (!found){
634 rd.setValue(aValue);
635 return;
636 } try{
638 Object[] paramsArray = new Object[1];
640 paramsArray[0] = aValue;
641 Object newValueObject = constructor.newInstance(paramsArray);
642
643 rd.setValue(newValueObject);
644
645 } catch (Exception e){
646 rd.setValue("");
647 }
649 break;
651 } case 2:{break;}
653 case 3:{break;}
654 default:{}
655 } }
658 }
660
661 class RowData {
662 private Object value = null;
663 private FeatureSchema featSchema = null;
664
665
666 RowData(Object aValue, FeatureSchema aFeatureSchema){
667 value = aValue;
668 featSchema = aFeatureSchema;
669 }
671 public void setValue(Object aValue){
672 value = aValue;
673 }
675 public Object getValue(){
676 return value;
677 }
679 public void setFeatureSchema(FeatureSchema aFeatureSchema){
680 featSchema = aFeatureSchema;
681 }
683 public FeatureSchema getFeatureSchema(){
684 return featSchema;
685 }
687 }
689
693 class InnerFeaturesEditor extends AbstractCellEditor implements TableCellEditor{
694 JComboBox cb = null;
696 JTextField tf = null;
697 int thisRow = 0;
698 int thisColumn = 0;
699
700 public InnerFeaturesEditor(){}
701
702 public Component getTableCellEditorComponent( JTable table,
703 Object value,
704 boolean isSelected,
705 int row,
706 int column){
707 thisRow = row;
708 thisColumn = column;
709 RowData rd = (RowData) tableModel.data.get(row);
710 if (rd.getFeatureSchema().isEnumeration()){
711 cb = new JComboBox(rd.getFeatureSchema().
712 getPermissibleValues().toArray());
713 cb.setSelectedItem(value);
714 cb.addActionListener(new ActionListener(){
715 public void actionPerformed(ActionEvent e){
716 tableModel.setValueAt(cb.getSelectedItem(),thisRow,thisColumn);
717 } }); tf = null;
720 return cb;
721 } if ( rd.getFeatureSchema().isDefault() ||
723 rd.getFeatureSchema().isOptional() ||
724 rd.getFeatureSchema().isRequired() ){
725
726 tf = new JTextField(value.toString());
727 cb = null;
728 return tf;
729 } return new JLabel(value.toString());
731 }
733 public Object getCellEditorValue(){
734 if (cb != null ) return cb.getSelectedItem();
735 if (tf != null ) return tf.getText();
736 return new String("");
737 } }}