| NameBearerHandle |

    1   /*
    2    *  Copyright (c) 1998-2001, The University of Sheffield.
    3    *
    4    *  This file is part of GATE (see http://gate.ac.uk/), and is free
    5    *  software, licenced under the GNU Library General Public License,
    6    *  Version 2, June 1991 (in the distribution as file licence.html,
    7    *  and also available at http://gate.ac.uk/gate/licence.html).
    8    *
    9    *  Valentin Tablan 23/01/2001
    10   *
    11   *  $Id: NameBearerHandle.java,v 1.39 2001/12/03 09:33:22 valyt Exp $
    12   *
    13   */
    14
    15  package gate.gui;
    16
    17  import javax.swing.*;
    18  import java.util.*;
    19  import java.net.*;
    20  import java.awt.Component;
    21  import java.awt.Window;
    22  import java.awt.event.*;
    23  import java.text.NumberFormat;
    24  import java.io.*;
    25  import javax.swing.filechooser.FileFilter;
    26
    27  import gate.*;
    28  import gate.util.*;
    29  import gate.swing.*;
    30  import gate.creole.*;
    31  import gate.persist.*;
    32  import gate.event.*;
    33  import gate.security.*;
    34  import gate.security.SecurityException;
    35
    36  /**
    37   * Class used to store the GUI information about an open entity (resource,
    38   * controller, datastore).
    39   * Such information will include icon to be used for tree components,
    40   * popup menu for right click events, large and small views, etc.
    41   */
    42  public class NameBearerHandle implements Handle,
    43                                           StatusListener,
    44                                           ProgressListener, CreoleListener {
    45
    46    public NameBearerHandle(NameBearer target, Window window) {
    47      this.target = target;
    48      this.window = window;
    49      sListenerProxy = new ProxyStatusListener();
    50      String iconName = null;
    51      if(target instanceof Resource){
    52        rData = (ResourceData)Gate.getCreoleRegister().
    53                                                get(target.getClass().getName());
    54        if(rData != null){
    55          iconName = rData.getIcon();
    56          if(iconName == null){
    57            if(target instanceof LanguageResource) iconName = "lr.gif";
    58            else if(target instanceof ProcessingResource) iconName = "pr.gif";
    59            else if(target instanceof Controller) iconName = "controller.gif";
    60          }
    61          tooltipText = "<HTML> <b>" + rData.getComment() + "</b><br>(<i>" +
    62                        rData.getClassName() + "</i>)</HTML>";
    63        } else {
    64          this.icon = MainFrame.getIcon("lr.gif");
    65        }
    66      }else if(target instanceof DataStore){
    67        iconName = ((DataStore)target).getIconName();
    68        tooltipText = ((DataStore)target).getComment();
    69      }
    70
    71      popup = null;
    72      title = (String)target.getName();
    73      this.icon = MainFrame.getIcon(iconName);
    74
    75      Gate.getCreoleRegister().addCreoleListener(this);
    76      buildViews();
    77      // Add the CTRL +F4 key & action combination to the resource
    78      JComponent largeView = this.getLargeView();
    79      if (largeView != null){
    80        largeView.getActionMap().put("Close resource",
    81                          new CloseAction());
    82        if (target instanceof gate.corpora.DocumentImpl){
    83          largeView.getActionMap().put("Save As XML", new SaveAsXmlAction());
    84        }// End if
    85      }// End if
    86    }//public DefaultResourceHandle(FeatureBearer res)
    87
    88    public Icon getIcon(){
    89      return icon;
    90    }
    91
    92    public void setIcon(Icon icon){
    93      this.icon = icon;
    94    }
    95
    96    public String getTitle(){
    97      return title;
    98    }
    99
    100   public void setTitle(String newTitle){
    101     this.title = newTitle;
    102   }
    103
    104   /**
    105    * Returns a GUI component to be used as a small viewer/editor, e.g. below
    106    * the main tree in the Gate GUI for the selected resource
    107    */
    108   public JComponent getSmallView() {
    109     return smallView;
    110   }
    111
    112   /**
    113    * Returns the large view for this resource. This view will go into the main
    114    * display area.
    115    */
    116   public JComponent getLargeView() {
    117     return largeView;
    118   }
    119
    120   public JPopupMenu getPopup() {
    121     return popup;
    122   }
    123
    124   public void setPopup(JPopupMenu popup) {
    125     this.popup = popup;
    126   }
    127
    128   public String getTooltipText() {
    129     return tooltipText;
    130   }
    131
    132   public void setTooltipText(String text) {
    133     this.tooltipText = text;
    134   }
    135
    136   public Object getTarget() {
    137     return target;
    138   }
    139
    140   public Action getCloseAction(){
    141     return new CloseAction();
    142   }
    143   protected void buildViews() {
    144     //build the popup
    145     popup = new JPopupMenu();
    146     XJMenuItem closeItem = new XJMenuItem(new CloseAction(), sListenerProxy);
    147     closeItem.setAccelerator(KeyStroke.getKeyStroke(
    148                                 KeyEvent.VK_F4, ActionEvent.CTRL_MASK));
    149     popup.add(closeItem);
    150
    151     if(target instanceof ProcessingResource){
    152       popup.addSeparator();
    153       popup.add(new XJMenuItem(new ReloadAction(), sListenerProxy));
    154     }else if(target instanceof LanguageResource) {
    155       //Language Resources
    156       popup.addSeparator();
    157 //      popup.add(new XJMenuItem(new RenameAction(), sListenerProxy));
    158       popup.add(new XJMenuItem(new SaveAction(), sListenerProxy));
    159       popup.add(new XJMenuItem(new SaveToAction(), sListenerProxy));
    160       if(target instanceof gate.corpora.DocumentImpl){
    161         XJMenuItem saveAsXmlItem =
    162                          new XJMenuItem(new SaveAsXmlAction(), sListenerProxy);
    163         saveAsXmlItem.setAccelerator(KeyStroke.getKeyStroke(
    164                                         KeyEvent.VK_X, ActionEvent.CTRL_MASK));
    165
    166         popup.add(saveAsXmlItem);
    167       }else if(target instanceof Corpus){
    168         popup.addSeparator();
    169         corpusFiller = new CorpusFillerComponent();
    170         popup.add(new XJMenuItem(new PopulateCorpusAction(), sListenerProxy));
    171         popup.addSeparator();
    172         popup.add(new XJMenuItem(new SaveCorpusAsXmlAction(), sListenerProxy));
    173       }
    174     }else if(target instanceof Controller){
    175       //Applications
    176       popup.addSeparator();
    177       popup.add(new XJMenuItem(new DumpToFileAction(), sListenerProxy));
    178     }
    179 //    if(target instanceof Resource){
    180 //      popup.addSeparator();
    181 //      popup.add(new XJMenuItem(new ReloadClassAction(), sListenerProxy));
    182 //    }
    183
    184
    185     fireStatusChanged("Building views...");
    186
    187     //build the large views
    188     List largeViewNames = Gate.getCreoleRegister().
    189                           getLargeVRsForResource(target.getClass().getName());
    190     if(largeViewNames != null && !largeViewNames.isEmpty()){
    191       largeView = new JTabbedPane(JTabbedPane.BOTTOM);
    192       Iterator classNameIter = largeViewNames.iterator();
    193       while(classNameIter.hasNext()){
    194         try{
    195           String className = (String)classNameIter.next();
    196           ResourceData rData = (ResourceData)Gate.getCreoleRegister().
    197                                                   get(className);
    198           FeatureMap params = Factory.newFeatureMap();
    199           FeatureMap features = Factory.newFeatureMap();
    200           Gate.setHiddenAttribute(features, true);
    201           VisualResource view = (VisualResource)
    202                                 Factory.createResource(className,
    203                                                        params,
    204                                                        features);
    205           view.setTarget(target);
    206           view.setHandle(this);
    207           ((JTabbedPane)largeView).add((Component)view, rData.getName());
    208         }catch(ResourceInstantiationException rie){
    209           rie.printStackTrace(Err.getPrintWriter());
    210         }
    211       }
    212       if(largeViewNames.size() == 1){
    213         largeView = (JComponent)((JTabbedPane)largeView).getComponentAt(0);
    214       }else{
    215         ((JTabbedPane)largeView).setSelectedIndex(0);
    216       }
    217     }
    218
    219     //build the small views
    220     List smallViewNames = Gate.getCreoleRegister().
    221                           getSmallVRsForResource(target.getClass().getName());
    222     if(smallViewNames != null && !smallViewNames.isEmpty()){
    223       smallView = new JTabbedPane(JTabbedPane.BOTTOM);
    224       Iterator classNameIter = smallViewNames.iterator();
    225       while(classNameIter.hasNext()){
    226         try{
    227           String className = (String)classNameIter.next();
    228           ResourceData rData = (ResourceData)Gate.getCreoleRegister().
    229                                                   get(className);
    230           FeatureMap params = Factory.newFeatureMap();
    231           FeatureMap features = Factory.newFeatureMap();
    232           Gate.setHiddenAttribute(features, true);
    233           VisualResource view = (VisualResource)
    234                                 Factory.createResource(className,
    235                                                        params,
    236                                                        features);
    237           view.setTarget(target);
    238           view.setHandle(this);
    239           ((JTabbedPane)smallView).add((Component)view, rData.getName());
    240         }catch(ResourceInstantiationException rie){
    241           rie.printStackTrace(Err.getPrintWriter());
    242         }
    243       }
    244       if(smallViewNames.size() == 1){
    245         smallView = (JComponent)((JTabbedPane)smallView).getComponentAt(0);
    246       }else{
    247         ((JTabbedPane)smallView).setSelectedIndex(0);
    248       }
    249     }
    250     fireStatusChanged("Views built!");
    251   }//protected void buildViews
    252
    253   public String toString(){ return title;}
    254
    255   public synchronized void removeProgressListener(ProgressListener l) {
    256     if (progressListeners != null && progressListeners.contains(l)) {
    257       Vector v = (Vector) progressListeners.clone();
    258       v.removeElement(l);
    259       progressListeners = v;
    260     }
    261   }//public synchronized void removeProgressListener(ProgressListener l)
    262
    263   public synchronized void addProgressListener(ProgressListener l) {
    264     Vector v = progressListeners == null ? new Vector(2) : (Vector) progressListeners.clone();
    265     if (!v.contains(l)) {
    266       v.addElement(l);
    267       progressListeners = v;
    268     }
    269   }//public synchronized void addProgressListener(ProgressListener l)
    270
    271   JPopupMenu popup;
    272   String title;
    273   String tooltipText;
    274   NameBearer target;
    275   /**
    276    * The top level GUI component this hadle belongs to.
    277    */
    278   Window window;
    279   ResourceData rData;
    280   Icon icon;
    281   JComponent smallView;
    282   JComponent largeView;
    283
    284   /**
    285    * Component used to select the options for corpus populating
    286    */
    287   CorpusFillerComponent corpusFiller;
    288
    289   StatusListener sListenerProxy;
    290
    291 //  File currentDir = null;
    292   private transient Vector progressListeners;
    293   private transient Vector statusListeners;
    294
    295   class CloseAction extends AbstractAction {
    296     public CloseAction() {
    297       super("Close");
    298       putValue(SHORT_DESCRIPTION, "Removes this resource from the system");
    299     }
    300
    301     public void actionPerformed(ActionEvent e){
    302       if(target instanceof Resource){
    303         Factory.deleteResource((Resource)target);
    304       }else if(target instanceof DataStore){
    305         try{
    306           ((DataStore)target).close();
    307         } catch(PersistenceException pe){
    308           JOptionPane.showMessageDialog(largeView != null ?
    309                                                      largeView : smallView,
    310                                         "Error!\n" + pe.toString(),
    311                                         "Gate", JOptionPane.ERROR_MESSAGE);
    312         }
    313         statusListeners.clear();
    314         progressListeners.clear();
    315         //delete the viewers
    316         if(largeView instanceof VisualResource){
    317           Factory.deleteResource((VisualResource)largeView);
    318         }else if(largeView instanceof JTabbedPane){
    319           Component[] comps = ((JTabbedPane)largeView).getComponents();
    320           for(int i = 0; i < comps.length; i++){
    321             if(comps[i] instanceof VisualResource)
    322               Factory.deleteResource((VisualResource)comps[i]);
    323           }
    324         }
    325         if(smallView instanceof VisualResource){
    326           Factory.deleteResource((VisualResource)smallView);
    327         }else if(smallView instanceof JTabbedPane){
    328           Component[] comps = ((JTabbedPane)smallView).getComponents();
    329           for(int i = 0; i < comps.length; i++){
    330             if(comps[i] instanceof VisualResource)
    331               Factory.deleteResource((VisualResource)comps[i]);
    332           }
    333         }
    334       }
    335     }//public void actionPerformed(ActionEvent e)
    336   }//class CloseAction
    337
    338   /**
    339    * Used to save a document as XML
    340    */
    341   class SaveAsXmlAction extends AbstractAction {
    342     public SaveAsXmlAction(){
    343       super("Save As Xml...");
    344       putValue(SHORT_DESCRIPTION, "Saves this resource in XML");
    345     }// SaveAsXmlAction()
    346
    347     public void actionPerformed(ActionEvent e) {
    348       Runnable runableAction = new Runnable(){
    349         public void run(){
    350           JFileChooser fileChooser = MainFrame.getFileChooser();
    351           File selectedFile = null;
    352
    353           List filters = Arrays.asList(fileChooser.getChoosableFileFilters());
    354           Iterator filtersIter = filters.iterator();
    355           FileFilter filter = null;
    356           if(filtersIter.hasNext()){
    357             filter = (FileFilter)filtersIter.next();
    358             while(filtersIter.hasNext() &&
    359                   filter.getDescription().indexOf("XML") == -1){
    360               filter = (FileFilter)filtersIter.next();
    361             }
    362           }
    363           if(filter == null || filter.getDescription().indexOf("XML") == -1){
    364             //no suitable filter found, create a new one
    365             ExtensionFileFilter xmlFilter = new ExtensionFileFilter();
    366             xmlFilter.setDescription("XML files");
    367             xmlFilter.addExtension("xml");
    368             xmlFilter.addExtension("gml");
    369             fileChooser.addChoosableFileFilter(xmlFilter);
    370             filter = xmlFilter;
    371           }
    372           fileChooser.setFileFilter(filter);
    373
    374           fileChooser.setMultiSelectionEnabled(false);
    375           fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    376           fileChooser.setDialogTitle("Select document to save ...");
    377           fileChooser.setSelectedFiles(null);
    378
    379           int res = (getLargeView() != null) ?
    380                                   fileChooser.showDialog(getLargeView(), "Save"):
    381                     (getSmallView() != null) ?
    382                                   fileChooser.showDialog(getSmallView(), "Save") :
    383                                               fileChooser.showDialog(null, "Save");
    384           if(res == JFileChooser.APPROVE_OPTION){
    385             selectedFile = fileChooser.getSelectedFile();
    386             File currentDir = fileChooser.getCurrentDirectory();
    387             if(selectedFile == null) return;
    388             NameBearerHandle.this.statusChanged("Saving as XML to " +
    389              selectedFile.toString() + "...");
    390             try{
    391               // Prepare to write into the xmlFile using UTF-8 encoding
    392               OutputStreamWriter writer = new OutputStreamWriter(
    393                               new FileOutputStream(selectedFile),"UTF-8");
    394
    395               // Write (test the toXml() method)
    396               // This Action is added only when a gate.Document is created.
    397               // So, is for sure that the resource is a gate.Document
    398               writer.write(((gate.Document)target).toXml());
    399               writer.flush();
    400               writer.close();
    401             } catch (Exception ex){
    402               ex.printStackTrace(Out.getPrintWriter());
    403             }// End try
    404             NameBearerHandle.this.statusChanged("Finished saving as xml into "+
    405              " the file : "+ selectedFile.toString());
    406           }// End if
    407         }// End run()
    408       };// End Runnable
    409       Thread thread = new Thread(runableAction, "");
    410       thread.setPriority(Thread.MIN_PRIORITY);
    411       thread.start();
    412     }// actionPerformed()
    413   }// SaveAsXmlAction
    414
    415   /**
    416    * Saves a corpus as a set of xml files in a directory.
    417    */
    418   class SaveCorpusAsXmlAction extends AbstractAction {
    419     public SaveCorpusAsXmlAction(){
    420       super("Save As Xml...");
    421       putValue(SHORT_DESCRIPTION, "Saves this corpus in XML");
    422     }// SaveAsXmlAction()
    423
    424     public void actionPerformed(ActionEvent e) {
    425       Runnable runnable = new Runnable(){
    426         public void run(){
    427           //we need a directory
    428           JFileChooser filer = MainFrame.getFileChooser();
    429           filer.setDialogTitle(
    430               "Select the directory that will contain the corpus");
    431           filer.setFileSelectionMode(filer.DIRECTORIES_ONLY);
    432
    433           if (filer.showDialog(getLargeView() != null ?
    434                                    getLargeView() :
    435                                    getSmallView(),
    436                                    "Select") == filer.APPROVE_OPTION){
    437
    438             File dir = filer.getSelectedFile();
    439             //create the top directory if needed
    440             if(!dir.exists()){
    441               if(!dir.mkdirs()){
    442                 JOptionPane.showMessageDialog(
    443                   largeView != null ?largeView : smallView,
    444                   "Could not create top directory!",
    445                   "Gate", JOptionPane.ERROR_MESSAGE);
    446                 return;
    447               }
    448             }
    449             //iterate through all the docs and save each of them as xml
    450             Corpus corpus = (Corpus)target;
    451             Iterator docIter = corpus.iterator();
    452             boolean overwriteAll = false;
    453             int docCnt = corpus.size();
    454             int currentDocIndex = 0;
    455             while(docIter.hasNext()){
    456               Document currentDoc = (Document)docIter.next();
    457               URL sourceURL = currentDoc.getSourceUrl();
    458               String fileName = null;
    459               if(sourceURL != null){
    460                 fileName = sourceURL.getFile();
    461                 fileName = Files.getLastPathComponent(fileName);
    462               }
    463               if(fileName == null || fileName.length() == 0){
    464                 fileName = currentDoc.getName();
    465               }
    466               if(!fileName.toLowerCase().endsWith(".xml")) fileName += ".xml";
    467               File docFile = null;
    468               boolean nameOK = false;
    469               do{
    470                 docFile = new File(dir, fileName);
    471                 if(docFile.exists() && !overwriteAll){
    472                   //ask the user if we can ovewrite the file
    473                   Object[] options = new Object[] {"Yes", "All",
    474                                                    "No", "Cancel"};
    475                   int answer = JOptionPane.showOptionDialog(
    476                     largeView != null ? largeView : smallView,
    477                     "File " + docFile.getName() + " already exists!\n" +
    478                     "Overwrite?" ,
    479                     "Gate", JOptionPane.DEFAULT_OPTION,
    480                     JOptionPane.WARNING_MESSAGE, null, options, options[2]);
    481                   switch(answer){
    482                     case 0: {
    483                       nameOK = true;
    484                       break;
    485                     }
    486                     case 1: {
    487                       nameOK = true;
    488                       overwriteAll = true;
    489                       break;
    490                     }
    491                     case 2: {
    492                       //user said NO, allow them to provide an alternative name;
    493                       fileName = (String)JOptionPane.showInputDialog(
    494                           largeView != null ? largeView : smallView,
    495                           "Please provide an alternative file name",
    496                           "Gate", JOptionPane.QUESTION_MESSAGE,
    497                           null, null, fileName);
    498                       if(fileName == null) return;
    499                       break;
    500                     }
    501                     case 3: {
    502                       //user gave up; return
    503                       return;
    504                     }
    505                   }
    506
    507                 }else{
    508                   nameOK = true;
    509                 }
    510               }while(!nameOK);
    511               //save the file
    512               try{
    513                 OutputStreamWriter writer = new OutputStreamWriter(
    514                               new FileOutputStream(docFile),"UTF-8");
    515                 writer.write(currentDoc.toXml());
    516                 writer.flush();
    517                 writer.close();
    518               }catch(IOException ioe){
    519                 JOptionPane.showMessageDialog(
    520                   largeView != null ? largeView : smallView,
    521                   "Could not create write file:" +
    522                   ioe.toString(),
    523                   "Gate", JOptionPane.ERROR_MESSAGE);
    524                 ioe.printStackTrace(Err.getPrintWriter());
    525                 return;
    526               }
    527
    528               fireStatusChanged(currentDoc.getName() + " saved");
    529               fireProgressChanged(100 * currentDocIndex++ / docCnt);
    530             }//while(docIter.hasNext())
    531             fireStatusChanged("Corpus saved");
    532             fireProcessFinished();
    533           }//select directory
    534         }//public void run(){
    535       };//Runnable runnable = new Runnable()
    536       Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
    537                                  runnable, "Corpus XML dumper");
    538       thread.setPriority(Thread.MIN_PRIORITY);
    539       thread.start();
    540
    541     }//public void actionPerformed(ActionEvent e)
    542   }//class SaveCorpusAsXmlAction extends AbstractAction
    543
    544   /**
    545    * Saves a corpus as a set of xml files in a directory.
    546    */
    547   class ReloadClassAction extends AbstractAction {
    548     public ReloadClassAction(){
    549       super("Reload resource class");
    550       putValue(SHORT_DESCRIPTION, "Reloads the java class for this resource");
    551     }// SaveAsXmlAction()
    552
    553     public void actionPerformed(ActionEvent e) {
    554       int answer = JOptionPane.showOptionDialog(
    555                 largeView != null ? largeView : smallView,
    556                 "This is an advanced option!\n" +
    557                 "You should not use this unless your name is Hamish.\n" +
    558                 "Are you sure you want to do this?" ,
    559                 "Gate", JOptionPane.YES_NO_OPTION,
    560                 JOptionPane.WARNING_MESSAGE, null, null, null);
    561       if(answer == JOptionPane.OK_OPTION){
    562         try{
    563           String className = target.getClass().getName();
    564           Gate.getClassLoader().reloadClass(className);
    565           fireStatusChanged("Class " + className + " reloaded!");
    566         }catch(Exception ex){
    567           JOptionPane.showMessageDialog(largeView != null ?
    568                                         largeView : smallView,
    569                                         "Look what you've done: \n" +
    570                                         ex.toString() +
    571                                         "\nI told you not to do it...",
    572                                         "Gate", JOptionPane.ERROR_MESSAGE);
    573           ex.printStackTrace(Err.getPrintWriter());
    574         }
    575       }
    576     }
    577   }
    578
    579   class RenameAction extends AbstractAction {
    580     public RenameAction(){
    581       super("Rename");
    582       putValue(SHORT_DESCRIPTION, "Rename this language resource");
    583     }
    584     public void actionPerformed(ActionEvent e){
    585       LanguageResource lr = (LanguageResource)target;
    586
    587       String newName = JOptionPane.showInputDialog(
    588                                      getLargeView(),
    589                                     "Please enter the LR's new name");
    590
    591       //don't change if nothing selected
    592       if (newName == null || newName.equals(""))
    593         return;
    594       lr.setName(newName);
    595
    596     }//public void actionPerformed(ActionEvent e)
    597   }//class RenameAction
    598
    599
    600
    601   class SaveAction extends AbstractAction {
    602     public SaveAction(){
    603       super("Save");
    604       putValue(SHORT_DESCRIPTION, "Save back to the datastore");
    605     }
    606     public void actionPerformed(ActionEvent e){
    607       DataStore ds = ((LanguageResource)target).getDataStore();
    608       if(ds != null){
    609         try {
    610           StatusListener sListener = (StatusListener)
    611                                      gate.gui.MainFrame.getListeners().
    612                                      get("gate.event.StatusListener");
    613           if(sListener != null) sListener.statusChanged(
    614             "Saving: " + ((LanguageResource)target).getName());
    615           double timeBefore = System.currentTimeMillis();
    616           ((LanguageResource)
    617                     target).getDataStore().sync((LanguageResource)target);
    618           double timeAfter = System.currentTimeMillis();
    619           if(sListener != null) sListener.statusChanged(
    620             ((LanguageResource)target).getName() + " saved in " +
    621             NumberFormat.getInstance().format((timeAfter-timeBefore)/1000)
    622             + " seconds");
    623         } catch(PersistenceException pe) {
    624           JOptionPane.showMessageDialog(getLargeView(),
    625                                         "Save failed!\n " +
    626                                         pe.toString(),
    627                                         "Gate", JOptionPane.ERROR_MESSAGE);
    628         } catch(SecurityException se) {
    629           JOptionPane.showMessageDialog(getLargeView(),
    630                                         "Save failed!\n " +
    631                                         se.toString(),
    632                                         "Gate", JOptionPane.ERROR_MESSAGE);
    633         }
    634       } else {
    635         JOptionPane.showMessageDialog(getLargeView(),
    636                         "This resource has not been loaded from a datastore.\n"+
    637                          "Please use the \"Save to\" option!\n",
    638                          "Gate", JOptionPane.ERROR_MESSAGE);
    639
    640       }
    641     }//public void actionPerformed(ActionEvent e)
    642   }//class SaveAction
    643
    644   class DumpToFileAction extends AbstractAction {
    645     public DumpToFileAction(){
    646       super("Save application state");
    647       putValue(SHORT_DESCRIPTION,
    648                "Saves the data needed to recreate this application");
    649     }
    650
    651     public void actionPerformed(ActionEvent ae){
    652       JFileChooser fileChooser = MainFrame.getFileChooser();
    653
    654       fileChooser.setDialogTitle("Select a file for this resource");
    655       fileChooser.setFileSelectionMode(fileChooser.FILES_AND_DIRECTORIES);
    656       if (fileChooser.showSaveDialog(largeView) ==
    657                                             fileChooser.APPROVE_OPTION){
    658         final File file = fileChooser.getSelectedFile();
    659           Runnable runnable = new Runnable(){
    660             public void run(){
    661               try{
    662                 gate.util.persistence.PersistenceManager.
    663                                       saveObjectToFile((Resource)target, file);
    664               }catch(Exception e){
    665                 JOptionPane.showMessageDialog(getLargeView(),
    666                                 "Error!\n"+
    667                                  e.toString(),
    668                                  "Gate", JOptionPane.ERROR_MESSAGE);
    669                 e.printStackTrace(Err.getPrintWriter());
    670               }
    671             }
    672           };
    673           Thread thread = new Thread(runnable);
    674           thread.setPriority(Thread.MIN_PRIORITY);
    675           thread.start();
    676       }
    677     }
    678
    679   }
    680
    681   class SaveToAction extends AbstractAction {
    682     public SaveToAction(){
    683       super("Save to...");
    684       putValue(SHORT_DESCRIPTION, "Save this resource to a datastore");
    685     }
    686
    687     public void actionPerformed(ActionEvent e) {
    688       try {
    689         DataStoreRegister dsReg = Gate.getDataStoreRegister();
    690         Map dsByName =new HashMap();
    691         Iterator dsIter = dsReg.iterator();
    692         while(dsIter.hasNext()){
    693           DataStore oneDS = (DataStore)dsIter.next();
    694           String name;
    695           if((name = (String)oneDS.getName()) != null){
    696           } else {
    697             name  = oneDS.getStorageUrl();
    698             try {
    699               URL tempURL = new URL(name);
    700               name = tempURL.getFile();
    701             } catch (java.net.MalformedURLException ex) {
    702               throw new GateRuntimeException(
    703                         );
    704             }
    705           }
    706           dsByName.put(name, oneDS);
    707         }
    708         List dsNames = new ArrayList(dsByName.keySet());
    709         if(dsNames.isEmpty()){
    710           JOptionPane.showMessageDialog(getLargeView(),
    711                                         "There are no open datastores!\n " +
    712                                         "Please open a datastore first!",
    713                                         "Gate", JOptionPane.ERROR_MESSAGE);
    714
    715         } else {
    716           Object answer = JOptionPane.showInputDialog(
    717                               getLargeView(),
    718                               "Select the datastore",
    719                               "Gate", JOptionPane.QUESTION_MESSAGE,
    720                               null, dsNames.toArray(),
    721                               dsNames.get(0));
    722           if(answer == null) return;
    723           DataStore ds = (DataStore)dsByName.get(answer);
    724           if (ds == null){
    725             Err.prln("The datastore does not exists. Saving procedure" +
    726                               " has FAILED! This should never happen again!");
    727             return;
    728           }// End if
    729           DataStore ownDS = ((LanguageResource)target).getDataStore();
    730           if(ds == ownDS){
    731             StatusListener sListener = (StatusListener)
    732                                        gate.gui.MainFrame.getListeners().
    733                                        get("gate.event.StatusListener");
    734             if(sListener != null) sListener.statusChanged(
    735               "Saving: " + ((LanguageResource)target).getName());
    736             double timeBefore = System.currentTimeMillis();
    737             ds.sync((LanguageResource)target);
    738             double timeAfter = System.currentTimeMillis();
    739             if(sListener != null) sListener.statusChanged(
    740               ((LanguageResource)target).getName() + " saved in " +
    741               NumberFormat.getInstance().format((timeAfter-timeBefore)/1000)
    742               + " seconds");
    743           }else{
    744             FeatureMap securityData = (FeatureMap)
    745                          Gate.getDataStoreRegister().getSecurityData(ds);
    746             SecurityInfo si = null;
    747             //check whether the datastore supports security data
    748             //serial ones do not for example
    749             if (securityData != null) {
    750               //first get the type of access from the user
    751               if(!AccessRightsDialog.showDialog(window))
    752                 return;
    753               int accessType = AccessRightsDialog.getSelectedMode();
    754               if(accessType < 0)
    755                 return;
    756               si = new SecurityInfo(accessType,
    757                                     (User) securityData.get("user"),
    758                                     (Group) securityData.get("group"));
    759             }//if security info
    760             StatusListener sListener = (StatusListener)
    761                                        gate.gui.MainFrame.getListeners().
    762                                        get("gate.event.StatusListener");
    763             if(sListener != null) sListener.statusChanged(
    764               "Saving: " + ((LanguageResource)target).getName());
    765             double timeBefore = System.currentTimeMillis();
    766             LanguageResource lr = ds.adopt((LanguageResource)target,si);
    767             ds.sync(lr);
    768             double timeAfter = System.currentTimeMillis();
    769             if(sListener != null) sListener.statusChanged(
    770               ((LanguageResource)target).getName() + " saved in " +
    771               NumberFormat.getInstance().format((timeAfter-timeBefore)/1000)
    772               + " seconds");
    773
    774             //check whether the new LR is different from the transient one and
    775             //if so, unload the transient LR, so the user realises
    776             //it is no longer valid. Don't do this in the adopt() code itself
    777             //because the batch code might wish to keep the transient
    778             //resource for some purpose.
    779             if (lr != target) {
    780               Factory.deleteResource((LanguageResource)target);
    781             }
    782           }
    783         }
    784       } catch(PersistenceException pe) {
    785         JOptionPane.showMessageDialog(getLargeView(),
    786                                       "Save failed!\n " +
    787                                       pe.toString(),
    788                                       "Gate", JOptionPane.ERROR_MESSAGE);
    789       }catch(gate.security.SecurityException se) {
    790         JOptionPane.showMessageDialog(getLargeView(),
    791                                       "Save failed!\n " +
    792                                       se.toString(),
    793                                       "Gate", JOptionPane.ERROR_MESSAGE);
    794       }
    795     }
    796   }//class SaveToAction extends AbstractAction
    797
    798   class ReloadAction extends AbstractAction {
    799     ReloadAction() {
    800       super("Reinitialise");
    801       putValue(SHORT_DESCRIPTION, "Reloads this resource");
    802     }
    803
    804     public void actionPerformed(ActionEvent e) {
    805       Runnable runnable = new Runnable(){
    806         public void run(){
    807           if(!(target instanceof ProcessingResource)) return;
    808           try{
    809             long startTime = System.currentTimeMillis();
    810             fireStatusChanged("Reinitialising " +
    811                                target.getName());
    812             Map listeners = new HashMap();
    813             StatusListener sListener = new StatusListener(){
    814                                         public void statusChanged(String text){
    815                                           fireStatusChanged(text);
    816                                         }
    817                                        };
    818             listeners.put("gate.event.StatusListener", sListener);
    819
    820             ProgressListener pListener =
    821                 new ProgressListener(){
    822                   public void progressChanged(int value){
    823                     fireProgressChanged(value);
    824                   }
    825                   public void processFinished(){
    826                     fireProcessFinished();
    827                   }
    828                 };
    829             listeners.put("gate.event.ProgressListener", pListener);
    830
    831             ProcessingResource res = (ProcessingResource)target;
    832             try{
    833               AbstractResource.setResourceListeners(res, listeners);
    834             }catch (Exception e){
    835               e.printStackTrace(Err.getPrintWriter());
    836             }
    837             //show the progress indicator
    838             fireProgressChanged(0);
    839             //the actual reinitialisation
    840             res.reInit();
    841             try{
    842               AbstractResource.removeResourceListeners(res, listeners);
    843             }catch (Exception e){
    844               e.printStackTrace(Err.getPrintWriter());
    845             }
    846             long endTime = System.currentTimeMillis();
    847             fireStatusChanged(target.getName() +
    848                               " reinitialised in " +
    849                               NumberFormat.getInstance().format(
    850                               (double)(endTime - startTime) / 1000) + " seconds");
    851             fireProcessFinished();
    852           }catch(ResourceInstantiationException rie){
    853             fireStatusChanged("reinitialisation failed");
    854             rie.printStackTrace(Err.getPrintWriter());
    855             JOptionPane.showMessageDialog(getLargeView(),
    856                                           "Reload failed!\n " +
    857                                           "See \"Messages\" tab for details!",
    858                                           "Gate", JOptionPane.ERROR_MESSAGE);
    859             fireProcessFinished();
    860           }
    861         }//public void run()
    862       };
    863       Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
    864                                  runnable,
    865                                  "DefaultResourceHandle1");
    866       thread.setPriority(Thread.MIN_PRIORITY);
    867       thread.start();
    868     }//public void actionPerformed(ActionEvent e)
    869
    870   }//class ReloadAction
    871
    872   class PopulateCorpusAction extends AbstractAction {
    873     PopulateCorpusAction() {
    874       super("Populate");
    875       putValue(SHORT_DESCRIPTION,
    876                "Fills this corpus with documents from a directory");
    877     }
    878
    879     public void actionPerformed(ActionEvent e) {
    880       Runnable runnable = new Runnable(){
    881         public void run(){
    882           corpusFiller.setExtensions(new ArrayList());
    883           corpusFiller.setEncoding("");
    884           boolean answer = OkCancelDialog.showDialog(
    885                                   getLargeView(),
    886                                   corpusFiller,
    887                                   "Select a directory and allowed extensions");
    888           if(answer){
    889             URL url = null;
    890             try{
    891               url = new URL(corpusFiller.getUrlString());
    892               java.util.List extensions = corpusFiller.getExtensions();
    893               ExtensionFileFilter filter = null;
    894               if(extensions == null || extensions.isEmpty()) filter = null;
    895               else{
    896                 filter = new ExtensionFileFilter();
    897                 Iterator extIter = corpusFiller.getExtensions().iterator();
    898                 while(extIter.hasNext()){
    899                   filter.addExtension((String)extIter.next());
    900                 }
    901               }
    902               ((Corpus)target).populate(url, filter,
    903                                         corpusFiller.getEncoding(),
    904                                         corpusFiller.isRecurseDirectories());
    905               fireStatusChanged("Corpus populated!");
    906
    907             }catch(MalformedURLException mue){
    908               JOptionPane.showMessageDialog(getLargeView(),
    909                                             "Invalid URL!\n " +
    910                                             "See \"Messages\" tab for details!",
    911                                             "Gate", JOptionPane.ERROR_MESSAGE);
    912               mue.printStackTrace(Err.getPrintWriter());
    913             }catch(IOException ioe){
    914               JOptionPane.showMessageDialog(getLargeView(),
    915                                             "I/O error!\n " +
    916                                             "See \"Messages\" tab for details!",
    917                                             "Gate", JOptionPane.ERROR_MESSAGE);
    918               ioe.printStackTrace(Err.getPrintWriter());
    919             }catch(ResourceInstantiationException rie){
    920               JOptionPane.showMessageDialog(getLargeView(),
    921                                             "Could not create document!\n " +
    922                                             "See \"Messages\" tab for details!",
    923                                             "Gate", JOptionPane.ERROR_MESSAGE);
    924               rie.printStackTrace(Err.getPrintWriter());
    925             }
    926           }
    927         }
    928       };
    929       Thread thread = new Thread(Thread.currentThread().getThreadGroup(),
    930                                  runnable);
    931       thread.setPriority(Thread.MIN_PRIORITY);
    932       thread.start();
    933     }
    934   }
    935
    936   /**
    937    * Releases the memory, removes the listeners, cleans up.
    938    * Will get called when the target resource is unloaded from the system
    939    */
    940   protected void cleanup(){
    941     //delete all the VRs that were created
    942     if(largeView != null){
    943       if(largeView instanceof VisualResource){
    944         //we only had a view so no tabbed pane was used
    945         ((VisualResource)largeView).setTarget(null);
    946         ((VisualResource)largeView).setHandle(null);
    947         Factory.deleteResource((VisualResource)largeView);
    948       }else{
    949         Component vrs[] = ((JTabbedPane)largeView).getComponents();
    950         for(int i = 0; i < vrs.length; i++){
    951           if(vrs[i] instanceof VisualResource){
    952             Factory.deleteResource((VisualResource)vrs[i]);
    953           }
    954         }
    955       }
    956     }
    957
    958     if(smallView != null){
    959       if(smallView instanceof VisualResource){
    960         //we only had a view so no tabbed pane was used
    961         Factory.deleteResource((VisualResource)smallView);
    962       }else{
    963         Component vrs[] = ((JTabbedPane)smallView).getComponents();
    964         for(int i = 0; i < vrs.length; i++){
    965           if(vrs[i] instanceof VisualResource){
    966             ((VisualResource)vrs[i]).setTarget(null);
    967             ((VisualResource)vrs[i]).setHandle(null);
    968             Factory.deleteResource((VisualResource)vrs[i]);
    969           }
    970         }
    971       }
    972     }
    973
    974     Gate.getCreoleRegister().removeCreoleListener(this);
    975     target = null;
    976   }
    977
    978   class ProxyStatusListener implements StatusListener{
    979     public void statusChanged(String text){
    980       fireStatusChanged(text);
    981     }
    982   }
    983
    984   protected void fireProgressChanged(int e) {
    985     if (progressListeners != null) {
    986       Vector listeners = progressListeners;
    987       int count = listeners.size();
    988       for (int i = 0; i < count; i++) {
    989         ((ProgressListener) listeners.elementAt(i)).progressChanged(e);
    990       }
    991     }
    992   }//protected void fireProgressChanged(int e)
    993
    994   protected void fireProcessFinished() {
    995     if (progressListeners != null) {
    996       Vector listeners = progressListeners;
    997       int count = listeners.size();
    998       for (int i = 0; i < count; i++) {
    999         ((ProgressListener) listeners.elementAt(i)).processFinished();
    1000      }
    1001    }
    1002  }//protected void fireProcessFinished()
    1003
    1004  public synchronized void removeStatusListener(StatusListener l) {
    1005    if (statusListeners != null && statusListeners.contains(l)) {
    1006      Vector v = (Vector) statusListeners.clone();
    1007      v.removeElement(l);
    1008      statusListeners = v;
    1009    }
    1010  }//public synchronized void removeStatusListener(StatusListener l)
    1011
    1012  public synchronized void addStatusListener(StatusListener l) {
    1013    Vector v = statusListeners == null ? new Vector(2) : (Vector) statusListeners.clone();
    1014    if (!v.contains(l)) {
    1015      v.addElement(l);
    1016      statusListeners = v;
    1017    }
    1018  }//public synchronized void addStatusListener(StatusListener l)
    1019
    1020  protected void fireStatusChanged(String e) {
    1021    if (statusListeners != null) {
    1022      Vector listeners = statusListeners;
    1023      int count = listeners.size();
    1024      for (int i = 0; i < count; i++) {
    1025        ((StatusListener) listeners.elementAt(i)).statusChanged(e);
    1026      }
    1027    }
    1028  }
    1029
    1030  public void statusChanged(String e) {
    1031    fireStatusChanged(e);
    1032  }
    1033  public void progressChanged(int e) {
    1034    fireProgressChanged(e);
    1035  }
    1036  public void processFinished() {
    1037    fireProcessFinished();
    1038  }
    1039  public Window getWindow() {
    1040    return window;
    1041  }
    1042
    1043  public void resourceLoaded(CreoleEvent e) {
    1044  }
    1045
    1046  public void resourceUnloaded(CreoleEvent e) {
    1047    if(getTarget() == e.getResource()) cleanup();
    1048  }
    1049
    1050  public void datastoreOpened(CreoleEvent e) {
    1051  }
    1052
    1053  public void datastoreCreated(CreoleEvent e) {
    1054  }
    1055
    1056  public void datastoreClosed(CreoleEvent e) {
    1057    if(getTarget() == e.getDatastore()) cleanup();
    1058  }
    1059}//class DefaultResourceHandle
    1060

| NameBearerHandle |