Skip to content
Snippets Groups Projects
ArtemisMain.java 19.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
    /* ArtemisMain.java
     *
     * created: Wed Feb 23 2000
     *
     * This file is part of Artemis
     *
     * Copyright(C) 2000  Genome Research Limited
     *
     * This program is free software; you can redistribute it and/or
     * modify it under the terms of the GNU General Public License
     * as published by the Free Software Foundation; either version 2
     * of the License, or(at your option) any later version.
     *
     * This program is distributed in the hope that it will be useful,
     * but WITHOUT ANY WARRANTY; without even the implied warranty of
     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     * GNU General Public License for more details.
     *
     * You should have received a copy of the GNU General Public License
     * along with this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     *
    
    tjc's avatar
    tjc committed
     * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/ArtemisMain.java,v 1.17 2005-08-17 08:43:05 tjc Exp $
    
    tjc's avatar
    tjc committed
     */
    
    package uk.ac.sanger.artemis.components;
    
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.components.filetree.FileManager;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.*;
    import uk.ac.sanger.artemis.sequence.NoSequenceException;
    import uk.ac.sanger.artemis.sequence.Bases;
    import uk.ac.sanger.artemis.util.Document;
    import uk.ac.sanger.artemis.util.DocumentFactory;
    import uk.ac.sanger.artemis.util.OutOfRangeException;
    import uk.ac.sanger.artemis.util.InputStreamProgressListener;
    import uk.ac.sanger.artemis.io.EntryInformation;
    
    import org.biojava.bio.seq.io.SequenceFormat;
    
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    
    import java.awt.Toolkit;
    
    tjc's avatar
    tjc committed
    import java.io.*;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
    /**
     *  The main window for the Artemis sequence editor.
     *
     *  @author Kim Rutherford <kmr@sanger.ac.uk>
    
    tjc's avatar
    tjc committed
     *  @version $Id: ArtemisMain.java,v 1.17 2005-08-17 08:43:05 tjc Exp $
    
    tjc's avatar
    tjc committed
     **/
    
    public class ArtemisMain extends Splash 
    {
      /** Version String use for banner messages and title bars. */
    
    tjc's avatar
    tjc committed
      public static final String version = "Release 8";
    
    tjc's avatar
    tjc committed
    
      /** A vector containing all EntryEdit object we have created. */
      private EntryEditVector entry_edit_objects = new EntryEditVector();
    
      protected static FileManager filemanager = null;
      /**
       *  The constructor creates all the components for the main Artemis 
       *  window and sets up all the menu callbacks.
       **/
      public ArtemisMain() 
      {
        super("Artemis", "Artemis", version);
    
        ActionListener menu_listener = new ActionListener()
        {
          public void actionPerformed(ActionEvent event)
          {
            if(filemanager == null)
              filemanager = new FileManager(ArtemisMain.this);
            else
              filemanager.setVisible(true);
          }
        };
        makeMenuItem(file_menu, "Open File Manager ...", menu_listener);
    
        final EntrySourceVector entry_sources = getEntrySources(this);
    
        for(int source_index=0; source_index<entry_sources.size();
                                ++source_index) 
        {
          final EntrySource this_entry_source =
            entry_sources.elementAt(source_index);
    
          String entry_source_name = this_entry_source.getSourceName();
          String menu_name = null;
    
          if(entry_source_name.equals("Filesystem")) 
            menu_name = "Open ...";
          else 
            menu_name = "Open from " + entry_source_name + " ...";
    
          menu_listener = new ActionListener() 
          {
            public void actionPerformed(ActionEvent event) 
            {
              getEntryEditFromEntrySource(this_entry_source);
            }
          };
          makeMenuItem(file_menu, menu_name, menu_listener);
        }
    
    
    tjc's avatar
    tjc committed
        menu_listener = new ActionListener()
        {
          public void actionPerformed(ActionEvent event)
          {
    
            launchDatabaseJFrame(true);
    
    tjc's avatar
    tjc committed
          }
        };
    
        final boolean sanger_options =
          Options.getOptions().getPropertyTruthValue("sanger_options");
    
        if(sanger_options)
    
    tjc's avatar
    tjc committed
          makeMenuItem(file_menu, "Database Entry ...", menu_listener);
    
          if(System.getProperty("chado") != null)
            launchDatabaseJFrame(false);
        }
    
    
    tjc's avatar
    tjc committed
        menu_listener = new ActionListener() 
        {
          public void actionPerformed(ActionEvent event)
          {
            exit();
          }
        };
        makeMenuItem(file_menu, "Quit", menu_listener);
    
    //      getCanvas().addMouseListener(new MouseAdapter() {
    //        /**
    //         *  Listen for mouse press events so that we can do popup menus and
    //         *  selection.
    //         **/
    //        public void mousePressed(MouseEvent event) {
    //          handleCanvasMousePress(event);
    //        }
    //      });
    
    //  java.util.Properties props = System.getProperties();
    //  java.util.Enumeration en = props.propertyNames();
    //  while(en.hasMoreElements())
    //  {
    //    String prop = (String)en.nextElement();
    //    System.out.println(prop+":: "+props.getProperty(prop));
    //  }
    
      }
    
    
    // XXX add pasteClipboard() one day
    
    //    /**
    //     *  Handle a mouse press event on the drawing canvas - select on click,
    //     *  select and broadcast it on double click.
    //     **/
    //    private void handleCanvasMousePress(MouseEvent event) {
    //      if(event.getID() != MouseEvent.MOUSE_PRESSED) {
    //        return;
    //      }
    
    //      if((event.getModifiers() & InputEvent.BUTTON2_MASK) != 0) {
    //        pasteClipboard();
    //      }
    //    }
    
    
      /**
      *
      * Launch database manager window
      *
      */
      private void launchDatabaseJFrame(final boolean prompt_user)
      {
        SwingWorker entryWorker = new SwingWorker()
        {
          public Object construct()
          {
            getStatusLabel().setText("Connecting ...");
            DatabaseEntrySource entry_source = new DatabaseEntrySource();
            if(!entry_source.setLocation(prompt_user))
              return null;
    
            final DatabaseJFrame frame = new DatabaseJFrame(entry_source,
                                                   ArtemisMain.this);
            frame.setVisible(true);
            getStatusLabel().setText("");
            return null;
          }
        };
        entryWorker.start();
      }
    
    
    tjc's avatar
    tjc committed
      /**
       *  Read the entries named in args and in the diana.ini file.
       **/
    
      public void readArgsAndOptions(final String [] args)
    
    tjc's avatar
    tjc committed
      {
        if(args.length == 0) 
        {
          // open the entries given in the options file(diana.ini)
          readDefaultEntries();
          return;
        }
    
        if(args[0].equals("-biojava")) 
        {
          handleBioJava(args);
          return;
        }
    
        final EntryInformation artemis_entry_information =
                              Options.getArtemisEntryInformation();
    
        EntryEdit last_entry_edit = null;
        boolean seen_plus = false;
    
        for(int i = 0 ; i<args.length ; ++i) 
        {
          String new_entry_name = args[i];
    
          if(new_entry_name.length() == 0) 
            continue;
    
          if(new_entry_name.equals("+")) 
          {
            seen_plus = true;
            continue;
          }
    
          if(new_entry_name.startsWith("+") && last_entry_edit != null ||
             seen_plus) 
          {
            // new feature file
    
            final Document entry_document;
    
            if(seen_plus) 
              entry_document = DocumentFactory.makeDocument(new_entry_name);
            else 
              entry_document =
                DocumentFactory.makeDocument(new_entry_name.substring(1));
    
            final InputStreamProgressListener progress_listener =
                                         getInputStreamProgressListener();
    
            entry_document.addInputStreamProgressListener(progress_listener);
    
            final uk.ac.sanger.artemis.io.Entry new_embl_entry =
              EntryFileDialog.getEntryFromFile(this, entry_document,
                                               artemis_entry_information,
                                               false);
    
            if(new_embl_entry == null)  // the read failed
              break;
    
            try
            {
              final Entry new_entry =
                new Entry(last_entry_edit.getEntryGroup().getBases(),
                          new_embl_entry);
    
              last_entry_edit.getEntryGroup().add(new_entry);
            } 
            catch(OutOfRangeException e) 
            {
              new MessageDialog(this, "read failed: one of the features in " +
                                 new_entry_name + " has an out of range " +
                                 "location: " + e.getMessage());
            }
          } 
          else
          {
            // new sequence file
    
            if(last_entry_edit != null) 
            {
              last_entry_edit.setVisible(true);
              last_entry_edit = null;
            }
    
            final Document entry_document =
              DocumentFactory.makeDocument(new_entry_name);
    
            entry_document.addInputStreamProgressListener(getInputStreamProgressListener());
     
            final uk.ac.sanger.artemis.io.Entry new_embl_entry =
              EntryFileDialog.getEntryFromFile(this, entry_document,
                                               artemis_entry_information,
                                               false);
    
            if(new_embl_entry == null)  // the read failed
              break;
    
            try 
            {
              final Entry entry = new Entry(new_embl_entry);
              last_entry_edit = makeEntryEdit(entry);
              addEntryEdit(last_entry_edit);
              getStatusLabel().setText("");
            }
            catch(OutOfRangeException e) 
            {
              new MessageDialog(this, "read failed: one of the features in " +
                                 new_entry_name + " has an out of range " +
                                 "location: " + e.getMessage());
              break;
            } 
            catch(NoSequenceException e) 
            {
              new MessageDialog(this, "read failed: " +
                                 new_entry_name + " contains no sequence");
              break;
            }
          }
        }
    
        for(int entry_index=0; entry_index<entry_edit_objects.size();
            ++entry_index) 
    
          entry_edit_objects.elementAt(entry_index).setVisible(true);
    
    tjc's avatar
    tjc committed
      }
    
      /**
    
    tjc's avatar
    tjc committed
       *
    
    tjc's avatar
    tjc committed
       *  Handle the -biojava option
    
    tjc's avatar
    tjc committed
       * 
       *  Command line syntax:  
       *  art -biojava org.biojava.bio.seq.io.EmblLikeFormat foo.embl
       *
       *  BioJava formats:
       *  EmblLikeFormat, FastaFormat, GAMEFormat, GenbankFormat, PhredFormat
       *
    
    tjc's avatar
    tjc committed
       **/
      private void handleBioJava(final String [] args) 
      {
        if(args.length == 3) 
        {
          final String class_name = args[1];
    
    tjc's avatar
    tjc committed
          final String location   = args[2];
    
    tjc's avatar
    tjc committed
    
          final Document location_document =
            DocumentFactory.makeDocument(location);
    
          try 
          {
            final Object biojava_object =
              Class.forName(class_name).newInstance();
    
            final EntryInformation entry_information =
              Options.getArtemisEntryInformation();
    
            final uk.ac.sanger.artemis.io.BioJavaEntry emblEntry;
    
            if(biojava_object instanceof SequenceFormat)
            {
    
    tjc's avatar
    tjc committed
              final SequenceFormat sequence_format = (SequenceFormat)biojava_object;
    
    tjc's avatar
    tjc committed
    
              emblEntry =
                new uk.ac.sanger.artemis.io.BioJavaEntry(entry_information,
    
    tjc's avatar
    tjc committed
                                                         location_document,
                                                         sequence_format);
    
    tjc's avatar
    tjc committed
    
              final Entry new_entry = new Entry(emblEntry);
              final EntryEdit new_entry_edit = makeEntryEdit(new_entry);
              new_entry_edit.setVisible(true);
            } 
            else 
              new MessageDialog(this, "not a SequenceFormat: " + class_name);
          } 
          catch(IllegalAccessException e) 
          {
            new MessageDialog(this, "cannot create class: " + class_name +
                               " - IllegalAccessException");
          }
          catch(ClassNotFoundException e)
          {
            new MessageDialog(this, "cannot find class: " + class_name);
          } 
          catch(ClassCastException e)
          {
            new MessageDialog(this, class_name + " is not a sub-class of " +
                               "SequenceFormat");
          }
          catch(IOException e) 
          {
            new MessageDialog(this, "I/O error while reading from " +
                               location + ": " + e.getMessage());
          }
          catch(NoSequenceException e) 
          {
            new MessageDialog(this, location + " contained no sequence");
          } 
          catch(InstantiationException e) 
          {
            new MessageDialog(this, "cannot instantiate " + class_name);
          } 
          catch(OutOfRangeException e) 
          {
            new MessageDialog(this, "read failed: one of the features in " +
                               location +
                               " has an out of range location: " +
                               e.getMessage());
          }
        } 
        else 
          new MessageDialog(this, "the -biojava option needs two arguments");
      }
    
      /**
       *  Read the entries given in the uk.ac.sanger.artemis.ini file.
       **/
      private void readDefaultEntries() 
      {
        final EntryInformation artemis_entry_information =
                         Options.getArtemisEntryInformation();
    
        final String default_sequence_file_name =
                         Options.getOptions().getDefaultSequenceFileName();
    
        final String default_feature_file_name =
                         Options.getOptions().getDefaultFeatureFileName();
    
        if(default_sequence_file_name != null) 
        {
          final String default_sequence_file_name_embl =
                         default_sequence_file_name + "_embl";
    
          uk.ac.sanger.artemis.io.Entry new_embl_entry = null;
    
          // try opening the default sequence file with "_embl" added to the name
          // if that fails try the plain sequence file name
    
          final Document entry_document =
            DocumentFactory.makeDocument(default_sequence_file_name_embl);
    
          final InputStreamProgressListener progress_listener =
            getInputStreamProgressListener();
    
          entry_document.addInputStreamProgressListener(progress_listener);
    
          if(entry_document.readable()) 
          {
            new_embl_entry =
              EntryFileDialog.getEntryFromFile(this,
                                                entry_document,
                                                artemis_entry_information,
                                                false);
          }
    
          if(new_embl_entry == null || new_embl_entry.getSequence() == null ||
              new_embl_entry.getSequence().length() == 0) 
          {
            final File entry_file = new File(default_sequence_file_name);
    
            if(entry_file.exists())
            {
              new_embl_entry =
                EntryFileDialog.getEntryFromFile(this,
                                                  entry_document,
                                                  artemis_entry_information,
                                                  false);
            }
            else
            {
              // read failed
              System.err.println("file does not exist: " +
                                  default_sequence_file_name +
                                  "(given in options files)");
              return;
            }
          }
    
          if(new_embl_entry == null || new_embl_entry.getSequence() == null ||
              new_embl_entry.getSequence().length() == 0) 
          {
            // read failed
            System.err.println("failed to read " + default_sequence_file_name +
                                "(given in options files)");
            return;
          }
    
          getStatusLabel().setText("");
    
          try 
          {
            final Entry entry = new Entry(new_embl_entry);
    
            final EntryEdit new_entry_edit = makeEntryEdit(entry);
    
            new_entry_edit.setVisible(true);
    
            if(default_feature_file_name != null) 
            {
              final Document feature_document =
                DocumentFactory.makeDocument(default_feature_file_name);
    
              final uk.ac.sanger.artemis.io.Entry new_embl_table_entry =
                EntryFileDialog.getEntryFromFile(this,
                                                  feature_document,
                                                  artemis_entry_information,
                                                  false);
    
              if(new_embl_table_entry == null)  // open failed
                return;
    
              final EntryGroup entry_group = new_entry_edit.getEntryGroup();
    
              final Entry new_table_entry =
                new Entry(entry.getBases(), new_embl_table_entry);
    
              entry_group.add(new_table_entry);
            }
          } catch(OutOfRangeException e) {
            new MessageDialog(this, "read failed: one of the features in " +
                               default_feature_file_name +
                               " has an out of range location: " +
                               e.getMessage());
          } catch(NoSequenceException e) {
            new MessageDialog(this, "read failed: " +
                               new_embl_entry.getName() +
                               " contains no sequence");
          }
        }
      }
    
      /**
       *  Make an EntryEdit component from the given Entry.
       **/
    
      protected EntryEdit makeEntryEdit(final Entry entry) 
    
    tjc's avatar
    tjc committed
      {
        final Bases bases = entry.getBases();
        final EntryGroup entry_group = new SimpleEntryGroup(bases);
        entry_group.add(entry);
        final EntryEdit entry_edit = new EntryEdit(entry_group);
    
        return entry_edit;
      }
    
      /**
       *  This method gets rid of an EntryEdit object and it's frame.  Each object
       *  removed with this method must have been added previously with
       *  addEntryEdit().
       *  @param entry_edit The object to get rid of.
       **/
      public void entryEditFinished(EntryEdit entry_edit) 
      {
        if(null == entry_edit) 
          throw new Error("entryEditFinished() was passed a null object");
    
        if(!entry_edit_objects.removeElement(entry_edit)) 
          throw new Error("entryEditFinished() - could not remove a " +
                           "object from an empty vector");
    
        entry_edit.setVisible(false);
        entry_edit.dispose();
      }
    
      /**
       *  Add an EntryEdit object to our list of objects.
       *  @param entry_edit The object to add.
       **/
      public synchronized void addEntryEdit(EntryEdit entry_edit) 
      {
        entry_edit_objects.addElement(entry_edit);
      }
    
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      /**
       *  Read an Entry from the given EntrySource and make a new EntryEdit
       *  component for the Entry.
       **/
      private void getEntryEditFromEntrySource(final EntrySource entry_source) 
      {
        SwingWorker entryWorker = new SwingWorker()
        { 
          EntryEdit entry_edit;
          public Object construct()
          {
            try
            {
    
              final Entry entry = entry_source.getEntry(true);
    
    tjc's avatar
    tjc committed
              if(entry == null)
                return null;
    
              final EntryGroup entry_group =
                  new SimpleEntryGroup(entry.getBases());
    
              entry_group.add(entry);
              entry_edit = new EntryEdit(entry_group);
            }
            catch(OutOfRangeException e)
            {
              new MessageDialog(ArtemisMain.this, "read failed: one of the features in " +
                         " the entry has an out of range " +
                         "location: " + e.getMessage());
            }
            catch(NoSequenceException e)
            {
              new MessageDialog(ArtemisMain.this, "read failed: entry contains no sequence");
            }
            catch(IOException e)
            {
              new MessageDialog(ArtemisMain.this, "read failed due to IO error: " + e);
            }
            return null;
          }
    
          public void finished()
          {
            if(entry_edit != null)
              entry_edit.setVisible(true);
          }
        };
        entryWorker.start();
      }
    
      /**
       *  Close the main frame and all EntryEdit frames and then this frame,
       *  then exit.
       **/
      protected void exit() 
      {
    //  for(int i=0 ; i<entry_edit_objects.size() ;++i) 
    //    entryEditFinished(entry_edit_objects.elementAt(i));
     
    //  if(filemanager != null)
    //    filemanager.setVisible(false);
    
    //  setVisible(false);
    //  dispose();
    //  System.gc();
        System.exit(0);
      }
    
      /**
       *  Main entry point for the stand-alone version of Artemis.
       **/
      public static void main(final String [] args) 
      {
        final ArtemisMain main_window = new ArtemisMain();
        main_window.setVisible(true);
    
        SwingWorker entryWorker = new SwingWorker()
        {
          public Object construct()
          {
            // read the entries given on the command line and in the diana.ini file
    
            main_window.readArgsAndOptions(args);
    
    tjc's avatar
    tjc committed
            return null;
          }
        };
        entryWorker.start();
      }
    
    }