Skip to content
Snippets Groups Projects
ProjectProperty.java 25.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • tcarver's avatar
    tcarver committed
    /* ProjectProperty
    
    tcarver's avatar
    tcarver committed
     * This file is part of Artemis
     *
     * Copyright(C) 2012  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.
     *
     */
    package uk.ac.sanger.artemis.components;
    
    import java.awt.BorderLayout;
    
    tcarver's avatar
    tcarver committed
    import java.awt.Color;
    
    tcarver's avatar
    tcarver committed
    import java.awt.Cursor;
    
    tcarver's avatar
    tcarver committed
    import java.awt.Dimension;
    
    tcarver's avatar
    tcarver committed
    import java.awt.Font;
    
    tcarver's avatar
    tcarver committed
    import java.awt.GridBagConstraints;
    
    import java.awt.GridBagLayout;
    
    tcarver's avatar
    tcarver committed
    import java.awt.Toolkit;
    
    tcarver's avatar
    tcarver committed
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    tcarver's avatar
    tcarver committed
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    
    tcarver's avatar
    tcarver committed
    import java.io.BufferedWriter;
    
    tcarver's avatar
    tcarver committed
    import java.io.File;
    
    tcarver's avatar
    tcarver committed
    import java.io.FileNotFoundException;
    import java.io.FileWriter;
    
    tcarver's avatar
    tcarver committed
    import java.io.IOException;
    import java.io.InputStream;
    
    tcarver's avatar
    tcarver committed
    import java.net.URISyntaxException;
    
    tcarver's avatar
    tcarver committed
    
    
    tcarver's avatar
    tcarver committed
    import java.util.Arrays;
    
    import java.util.Comparator;
    
    tcarver's avatar
    tcarver committed
    import java.util.HashMap;
    import java.util.Properties;
    import java.util.Vector;
    import java.util.Map.Entry;
    import java.util.Set;
    
    import javax.swing.BorderFactory;
    import javax.swing.Box;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.DefaultListModel;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JButton;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JCheckBox;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JComboBox;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JFrame;
    import javax.swing.JList;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JOptionPane;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JPanel;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JScrollPane;
    
    import javax.swing.JTextField;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.JToolBar;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.ListSelectionModel;
    import javax.swing.SwingUtilities;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.UIManager;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.border.Border;
    import javax.swing.border.TitledBorder;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.event.DocumentEvent;
    
    import javax.swing.event.DocumentListener;
    
    tcarver's avatar
    tcarver committed
    import javax.swing.event.ListSelectionEvent;
    import javax.swing.event.ListSelectionListener;
    
    
    tcarver's avatar
    tcarver committed
    import uk.ac.sanger.artemis.Options;
    
    tcarver's avatar
    tcarver committed
    import uk.ac.sanger.artemis.util.Document;
    import uk.ac.sanger.artemis.util.FileDocument;
    
    tcarver's avatar
    tcarver committed
    
    
    tcarver's avatar
    tcarver committed
    /**
     * Project file management system using a properties file.
     * 
     * Example of the syntax for defining a project in the property file:
    
    tcarver's avatar
    tcarver committed
     * project.Pknowlsei.sequence = Pknowlsei:Pk_strainH_chr01
    
    tcarver's avatar
    tcarver committed
     * project.Pknowlsei.chado =  genedb-db.sanger.ac.uk:5432/snapshot?genedb_ro
     * project.Pknowlsei.title = Pknowlsei
     */
    public class ProjectProperty extends JFrame
    
    tcarver's avatar
    tcarver committed
    {
      private static final long serialVersionUID = 1L;
    
    tcarver's avatar
    tcarver committed
      private static HashMap<String, HashMap<String, String>> centralProjects;
      private static HashMap<String, HashMap<String, String>> userProjects;
      private Splash splash;
    
    tcarver's avatar
    tcarver committed
      
      private final static int REFERENCE = 1;
      private final static int ANNOTATION = 2;
      private final static int NEXT_GEN_DATA = 3;
      private final static int CHADO = 4;
    
    tcarver's avatar
    tcarver committed
      private final static int USERPLOT = 5;
    
    tcarver's avatar
    tcarver committed
      private static org.apache.log4j.Logger logger4j = 
          org.apache.log4j.Logger.getLogger(ProjectProperty.class);
      
      private final static String[] TYPES = 
    
        { "title", "sequence", "annotation", "bam", "vcf", "userplot", "chado" };
    
    tcarver's avatar
    tcarver committed
      
    
    tcarver's avatar
    tcarver committed
      public ProjectProperty()
    
    tcarver's avatar
    tcarver committed
      {
        this(null);
    
    tcarver's avatar
    tcarver committed
        
        final javax.swing.plaf.FontUIResource font_ui_resource =
            Options.getOptions().getFontUIResource();
        java.util.Enumeration<Object> keys = UIManager.getDefaults().keys();
        while(keys.hasMoreElements()) 
        {
          Object key = keys.nextElement();
          Object value = UIManager.get(key);
          if(value instanceof javax.swing.plaf.FontUIResource) 
            UIManager.put(key, font_ui_resource);
        }
    
    tcarver's avatar
    tcarver committed
      }
      
      public ProjectProperty(Splash splash)
    
    tcarver's avatar
    tcarver committed
      {
    
    tcarver's avatar
    tcarver committed
        super("Project File Manager");
    
    tcarver's avatar
    tcarver committed
        this.splash = splash;
    
    tcarver's avatar
    tcarver committed
        InputStream ins = 
    
    tcarver's avatar
    tcarver committed
            this.getClass().getClassLoader().getResourceAsStream("etc/project.properties");
    
    tcarver's avatar
    tcarver committed
        
        try
        {
          logger4j.debug("Reading properties from: "+
              this.getClass().getClassLoader().getResource("etc/project.properties").toURI());
        }
        catch (URISyntaxException e1){}
    
    
    tcarver's avatar
    tcarver committed
        final Properties projectProps = new Properties();
        try
        {
          projectProps.load(ins);
          ins.close();
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }
    
    tcarver's avatar
    tcarver committed
        centralProjects = getProjectMap(projectProps);
        projectProps.clear();
    
    tcarver's avatar
    tcarver committed
        
        final String [] propFiles = 
        {
          "project.properties",
    
    tcarver's avatar
    tcarver committed
          System.getProperty("user.home") + File.separator + ".artemis.project.properties"
    
    tcarver's avatar
    tcarver committed
        };
        
        for(int i=0; i<propFiles.length; i++)
        {
          final Document doc =
              new FileDocument(new File(propFiles[i]));
          if(doc.readable()) 
          {
            try
            {
              ins = doc.getInputStream();
              projectProps.load(ins);
            }
            catch (IOException e)
            {
              e.printStackTrace();
            }
            
            logger4j.debug("Reading properties from: "+propFiles[i]);
          }
        }
    
    
    tcarver's avatar
    tcarver committed
        userProjects = getProjectMap(projectProps);
    
    tcarver's avatar
    tcarver committed
        createProjectViewer((JPanel) getContentPane());
        pack();
        setVisible(true);
      }
      
      private void createProjectViewer(JPanel panel)
      {
    
    tcarver's avatar
    tcarver committed
        final DefaultListModel model = new DefaultListModel();
        
        final JList projectList = new JList(model);
        final JScrollPane jspList = new JScrollPane(projectList);
    
    tcarver's avatar
    tcarver committed
        Object[] items = centralProjects.keySet().toArray();
        Arrays.sort(items);
        for (int i=0; i<items.length; i++)
          model.add(i, items[i]);
        
        items = userProjects.keySet().toArray();
        Arrays.sort(items);
    
    tcarver's avatar
    tcarver committed
        for (int i=0; i<items.length; i++)
          model.add(i, items[i]);
    
        final Box yBox = Box.createVerticalBox();
    
        final JScrollPane jspProp = new JScrollPane(yBox);
    
    tcarver's avatar
    tcarver committed
        final LaunchActionListener listener = new LaunchActionListener();
        projectList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        projectList.setVisibleRowCount(-1);
        panel.add(jspList, BorderLayout.WEST);
    
        panel.add(jspProp, BorderLayout.CENTER);
    
    tcarver's avatar
    tcarver committed
    
    
    tcarver's avatar
    tcarver committed
        // Add / remove project buttons
    
    tcarver's avatar
    tcarver committed
        
    
    tcarver's avatar
    tcarver committed
        final JToolBar toolBar = new JToolBar();
        panel.add(toolBar, BorderLayout.PAGE_START);
    
    tcarver's avatar
    tcarver committed
        final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
    
    tcarver's avatar
    tcarver committed
        panel.setPreferredSize(new Dimension((int)(screen.width/2.5),screen.height/3));
    
    tcarver's avatar
    tcarver committed
        panel.setBackground(Color.WHITE);
    
    tcarver's avatar
    tcarver committed
        final JButton addProjectButton = new JButton("+");
        addProjectButton.setOpaque(false);
    
    tcarver's avatar
    tcarver committed
        Font font = addProjectButton.getFont().deriveFont(Font.BOLD).deriveFont(14.f);
    
    tcarver's avatar
    tcarver committed
        addProjectButton.setFont(font);
        addProjectButton.setToolTipText("ADD PROJECT");
        addProjectButton.setForeground(new Color(35, 149, 35));
        addProjectButton.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent arg0)
          {
            addProject(projectList);
          }
        });
        toolBar.add(addProjectButton);
        
        final JButton removeProjectButton = new JButton("-");
        removeProjectButton.setOpaque(false);
        removeProjectButton.setFont(font);
        removeProjectButton.setToolTipText("REMOVE PROJECT");
        removeProjectButton.setForeground(new Color(149, 35, 35));
        removeProjectButton.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent arg0)
          {
            removeProject(projectList, yBox);
          }
        });
        toolBar.add(removeProjectButton);
        
    
    tcarver's avatar
    tcarver committed
        
        final JButton openArt = new JButton("OPEN");
        openArt.addActionListener(listener);
    
    tcarver's avatar
    tcarver committed
        final JButton closeButton = new JButton("CLOSE");
        closeButton .addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent arg0)
          {
            dispose();
          }
        });
        
        Box xBox = Box.createHorizontalBox();
        xBox.add(openArt);
        xBox.add(closeButton);
        xBox.add(Box.createHorizontalGlue());
        
        panel.add(xBox, BorderLayout.SOUTH);
    
    tcarver's avatar
    tcarver committed
        
        final GridBagConstraints c = new GridBagConstraints();
        c.anchor = GridBagConstraints.NORTHWEST;
        c.fill = GridBagConstraints.VERTICAL;
        c.ipadx = 10;
        c.ipady = 10;
        
    
    tcarver's avatar
    tcarver committed
        
    
    tcarver's avatar
    tcarver committed
        projectList.addListSelectionListener(new ListSelectionListener()
        {
          public void valueChanged(ListSelectionEvent e)
          {
    
    tcarver's avatar
    tcarver committed
            if(e.getValueIsAdjusting() == false &&
               projectList.getSelectedIndex() > -1) 
              refreshProperties(projectList, yBox, listener);
          }
        });
      }
      
    
    tcarver's avatar
    tcarver committed
      private void addProject(final JList projectList)
      {
        DefaultListModel model = (DefaultListModel) projectList.getModel();
        
        String projName = 
            JOptionPane.showInputDialog(ProjectProperty.this,
                "Project Name", "New Project", JOptionPane.QUESTION_MESSAGE);
        if(projName == null)
          return;
        userProjects.put(projName, new HashMap<String, String>());
        model.add(model.getSize(), projName);
        projectList.repaint();
        projectList.setSelectedIndex(model.getSize()-1);
      }
      
      private void removeProject(final JList projectList, final Box yBox)
      {
        if(projectList.getSelectedValue() == null)
        {
          JOptionPane.showMessageDialog(ProjectProperty.this, 
              "Select a project from the list to be removed.", 
              "Remove", JOptionPane.INFORMATION_MESSAGE);
          return;
        }
        DefaultListModel model = (DefaultListModel) projectList.getModel();
        int status = JOptionPane.showConfirmDialog(
            ProjectProperty.this, "Remove "+projectList.getSelectedValue()+"?",
            "Remove Project", JOptionPane.YES_NO_OPTION);
        if(status != JOptionPane.YES_OPTION)
          return;
        userProjects.remove(projectList.getSelectedValue());
        model.remove(projectList.getSelectedIndex());
        projectList.repaint();
        yBox.removeAll();
        yBox.repaint();
      }
      
    
    tcarver's avatar
    tcarver committed
      /**
       * Refresh components in the properties panel.
       * @param projectList
       * @param yBox
       * @param listener
       */
      private void refreshProperties(final JList projectList, 
                                     final Box yBox, 
                                     final LaunchActionListener listener)
      {
        yBox.removeAll();
    
    tcarver's avatar
    tcarver committed
    
    
    tcarver's avatar
    tcarver committed
        final HashMap<String, String> projProps;
        if(centralProjects.containsKey(projectList.getSelectedValue()))
          projProps = centralProjects.get(projectList.getSelectedValue());
        else
          projProps = userProjects.get(projectList.getSelectedValue());
    
    
        final HashMap<Integer, Vector<JTextField>> settings = new HashMap<Integer, Vector<JTextField>>();
        // order the keys
        Object keys[] = projProps.keySet().toArray();
        Arrays.sort(keys, new TypeComparator());
    
        for(final Object key: keys)
    
    tcarver's avatar
    tcarver committed
        {
    
          final String keyStr = (String) key;
          final Vector<JTextField> vText = new Vector<JTextField>();
          
          Border lineBorder = BorderFactory.createLineBorder(Color.DARK_GRAY);
    
    tcarver's avatar
    tcarver committed
          TitledBorder title = BorderFactory.createTitledBorder(
    
              lineBorder, keyStr);
    
    tcarver's avatar
    tcarver committed
          //title.setTitlePosition(TitledBorder.LEFT);
    
    tcarver's avatar
    tcarver committed
    
    
          final JPanel propPanel = new JPanel(new GridBagLayout());
          GridBagConstraints c = new GridBagConstraints();
          c.gridy = 0;
    
    tcarver's avatar
    tcarver committed
          
    
          c.fill = GridBagConstraints.BOTH;
          propPanel.setBorder(title);
          propPanel.setBackground(Color.WHITE);
          
    
    tcarver's avatar
    tcarver committed
          //
          final Vector<JCheckBox> checkBoxes = new Vector<JCheckBox>();
          final JButton toggle = new JButton("Toggle");
          toggle.setToolTipText("toggle "+keyStr+" selection");
          toggle.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0)
            {
               for(JCheckBox cb: checkBoxes)
                 cb.setSelected(!cb.isSelected());
            }
          });
                   
    
    tcarver's avatar
    tcarver committed
          final Vector<String> anns = splitLine(projProps.get(keyStr).trim());
          for (int i=0; i<anns.size(); i++)
          {
            c.gridx = 0;
    
    tcarver's avatar
    tcarver committed
            addProperyToPanel(projectList, propPanel, vText, c, i, anns.get(i), projProps, keyStr, yBox, listener, checkBoxes);
    
    tcarver's avatar
    tcarver committed
          
    
    tcarver's avatar
    tcarver committed
          if (!keyStr.equals("title") && !keyStr.equals("chado"))
    
    tcarver's avatar
    tcarver committed
          {
    
            Box xBox = Box.createHorizontalBox();
    
    tcarver's avatar
    tcarver committed
            final JButton selectButton = new JButton(
                keyStr.startsWith("seq") ? "Select " : "Add file");
    
    tcarver's avatar
    tcarver committed
            selectButton.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent e)
              {
                StickyFileChooser fileChooser = new StickyFileChooser();
                int status = fileChooser.showOpenDialog(ProjectProperty.this);
    
    tcarver's avatar
    tcarver committed
    
    
    tcarver's avatar
    tcarver committed
                if(status == StickyFileChooser.APPROVE_OPTION)
                {
    
    tcarver's avatar
    tcarver committed
                  if(keyStr.startsWith("seq"))
                    vText.get(0).setText(fileChooser.getSelectedFile().getAbsolutePath());
                  else
                  {
                    projProps.put(keyStr, projProps.get(keyStr)+" "+
    
                                fileChooser.getSelectedFile().getAbsolutePath());
    
    tcarver's avatar
    tcarver committed
                    refreshProperties(projectList, yBox, listener);
                  }
    
    tcarver's avatar
    tcarver committed
                }
              }
            });
    
            c.gridy = c.gridy+1;
            
    
    tcarver's avatar
    tcarver committed
            c.gridx = 0;
    
            xBox.add(selectButton);
            xBox.add(Box.createHorizontalGlue());
    
    tcarver's avatar
    tcarver committed
            if(checkBoxes.size() > 1) // add toggle option
              xBox.add(toggle, c);
            
            c.gridwidth = 2;
    
            propPanel.add(xBox, c);
    
    tcarver's avatar
    tcarver committed
            c.gridwidth = 1;
    
          yBox.add(propPanel);
    
    tcarver's avatar
    tcarver committed
          
    
          if(keyStr.startsWith("seq"))
            settings.put(ProjectProperty.REFERENCE, vText);
          else if(keyStr.equals("annotation"))
            settings.put(ProjectProperty.ANNOTATION, vText);
          else if(keyStr.equals("bam") || keyStr.equals("vcf") || keyStr.equals("bcf"))
            settings.put(ProjectProperty.NEXT_GEN_DATA, vText);
          else if(keyStr.equals("chado"))
            settings.put(ProjectProperty.CHADO, vText);
          else if(keyStr.equals("userplot"))
            settings.put(ProjectProperty.USERPLOT, vText);
    
    tcarver's avatar
    tcarver committed
        }
        
        // ADD property
        Box xBox = Box.createHorizontalBox();
        final JButton addPropertyButton = new JButton("NEW PROPERTY");
        final JComboBox propertyList = new JComboBox(TYPES);
        xBox.add(addPropertyButton);
        xBox.add(propertyList);
        xBox.add(Box.createHorizontalGlue());
        yBox.add(xBox);
        addPropertyButton.addActionListener(new ActionListener(){
          public void actionPerformed(ActionEvent arg0)
          {
            String key = (String) propertyList.getSelectedItem();
            if(!projProps.containsKey(key))
            {
              projProps.put(key, "");
              refreshProperties(projectList, yBox, listener);
    
    tcarver's avatar
    tcarver committed
        //
        yBox.add(Box.createVerticalGlue());
        yBox.revalidate();
        yBox.repaint();
        
        listener.setSettings(settings);
    
    tcarver's avatar
    tcarver committed
      private Vector<String> splitLine(String line)
      {
        Vector<String> parts = new Vector<String>();
        int index = line.indexOf(" ");
        if(index < 0)
          parts.add(line);
        else
        {
          int startIndex = 0;
          line = line.replaceAll("\\s+", " ");
          while((index = line.indexOf(" ", startIndex)) > -1)
          {
            if(line.charAt(index-1) == '\\')
            {
              startIndex = index+1;
              continue;
            }
            parts.add(line.substring(0, index));
            line = line.substring(index+1);
            startIndex = 0;
          }
          parts.add(line);
        }
        
        return parts;
      }
      
    
      private void addProperyToPanel(final JList projectList,
                                     final JPanel propPanel,
                                     final Vector<JTextField> vText,
                                     final GridBagConstraints c,
                                     final int index,
                                     final String ann, 
                                     final HashMap<String, String> projProps, 
                                     final String key,
                                     final Box yBox, 
    
    tcarver's avatar
    tcarver committed
                                     final LaunchActionListener listener,
                                     final Vector<JCheckBox> cbs)
    
    tcarver's avatar
    tcarver committed
        final JTextField qta = new JTextField(67);
    
    tcarver's avatar
    tcarver committed
        if(key.equals("title"))
          qta.setText(removeSpaceEscape(ann));
        else
          qta.setText(ann);
    
        qta.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
        qta.getDocument().addDocumentListener(new DocumentListener()
        {
          private void update()
          {
    
    tcarver's avatar
    tcarver committed
            final String anns[];
            if(key.equals("title")) // only takes one value
              anns = new String[]{ escapeSpace(projProps.get(key).trim()) };
            else
              anns = projProps.get(key).trim().split("\\s{2,}");
    
            String value = "";
            for(int i=0;i<anns.length;i++)
            {
              if(i == index)
                value += " "+qta.getText();
              else
                value += " "+anns[i];
            }
            projProps.put(key, value);
          }
          
          public void changedUpdate(DocumentEvent e)
          {
            update();
          }
          public void insertUpdate(DocumentEvent e)
          {
            update();
          }
          public void removeUpdate(DocumentEvent e)
          {
            update();
          }
        });
        
        // REMOVE PROPERTY
        Box xButtons = Box.createHorizontalBox();
        final JButton removeProperty = new JButton("X");
        removeProperty.setOpaque(false);
        Font font = removeProperty.getFont().deriveFont(Font.BOLD);
        removeProperty.setFont(font);
        removeProperty.setToolTipText("REMOVE");
        removeProperty.setForeground(new Color(139, 35, 35));
        removeProperty.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
    
    tcarver's avatar
    tcarver committed
            int status = JOptionPane.showConfirmDialog(
                ProjectProperty.this, "Remove "+key+"?",
                "Remove", JOptionPane.YES_NO_OPTION);
            if(status != JOptionPane.YES_OPTION)
              return;
    
            final String anns[] = projProps.get(key).trim().split("\\s+");
            String value = "";
            for(int i=0;i<anns.length;i++)
            {
              if(i != index)
                value += " "+anns[i];
            }
            if(value.equals(""))
              projProps.remove(key);
            else
              projProps.put(key, value.trim());
            refreshProperties(projectList, yBox, listener);
          }
        });
        xButtons.add(removeProperty);
        //
        if(!key.equals("title") && !key.startsWith("seq") && !key.equals("chado"))
        {
          final JCheckBox useProperty = new JCheckBox("",true);
    
    tcarver's avatar
    tcarver committed
          useProperty.addItemListener(new ItemListener(){
            public void itemStateChanged(ItemEvent arg0)
    
            {
              qta.setEnabled(useProperty.isSelected());
            }
          });
    
    tcarver's avatar
    tcarver committed
    
    
          xButtons.add(useProperty);
    
    tcarver's avatar
    tcarver committed
          cbs.add(useProperty);
    
        }
        xButtons.add(Box.createHorizontalGlue());
        
        c.gridy = c.gridy+1;
        propPanel.add(qta, c);
    
    tcarver's avatar
    tcarver committed
        c.gridx = c.gridx+1;
    
        propPanel.add(xButtons, c);
      }
    
    tcarver's avatar
    tcarver committed
    
    
    tcarver's avatar
    tcarver committed
      /**
       * Create a project hash of the properties.
       * @param projectProps
       * @return
       */
      private HashMap<String, HashMap<String, String>> getProjectMap(final Properties projectProps)
      {
        final HashMap<String, HashMap<String, String>> projects =
            new HashMap<String, HashMap<String, String>>();
        
        for (Entry<Object, Object> propItem : projectProps.entrySet())
        {
          String key = (String) propItem.getKey();
          String value = (String) propItem.getValue();
    
          if (key.startsWith("project."))
          {
            key = key.substring(8);
            int ind = key.indexOf(".");
            if (ind > -1)
            {
              String projName = key.substring(0, ind);
              key = key.substring(ind + 1);
              final HashMap<String, String> thisProj;
              if (projects.containsKey(projName))
                thisProj = projects.get(projName);
              else
                thisProj = new HashMap<String, String>();
              thisProj.put(key, value);
    
    tcarver's avatar
    tcarver committed
              projects.put(projName, thisProj);
            }
          }
        }
        return projects;
      }
      
    
    tcarver's avatar
    tcarver committed
      /**
      * Write or re-write properties and insert/update the user.dir property
      * @param jemProp      properties file
      * @param uHome        user working directory
      */
      protected static void writeProperties()
      {
        if(userProjects == null)
          return;
    
    tcarver's avatar
    tcarver committed
        final String prop = System.getProperty("user.home") + File.separator + ".artemis.project.properties";
    
    tcarver's avatar
    tcarver committed
        File propFile = new File(prop);
        try
        {
          if(userProjects.size() > 0)
          {
    
    tcarver's avatar
    tcarver committed
            propFile.renameTo(new File(propFile.getAbsolutePath()+".bak"));
    
    tcarver's avatar
    tcarver committed
            final BufferedWriter bufferedwriter = new BufferedWriter(new FileWriter(propFile));
            for (String project: userProjects.keySet())
            {
              bufferedwriter.write("#");
              bufferedwriter.newLine();
              
              HashMap<String, String> projProps = userProjects.get(project);
              for(final String key: projProps.keySet())
              {
    
    tcarver's avatar
    tcarver committed
                final String val;
                if(key.equals("title"))
                  val = escapeSpace(projProps.get(key).trim());
                else
                  val = projProps.get(key).trim().replaceAll("\\s{2,}", " ");
    
                bufferedwriter.write("project."+project+"."+key+"="+val );
    
    tcarver's avatar
    tcarver committed
                bufferedwriter.newLine();
              }
    
    tcarver's avatar
    tcarver committed
              
              // unfortunately Properties.store() adds a timestamp as a comment
              /*myProps.clear();
              HashMap<String, String> projProps = userProjects.get(project);
              for(final String key: projProps.keySet())
                myProps.setProperty("project."+project+"."+key, 
                    projProps.get(key).trim().replaceAll("\\s+", " "));
              myProps.store(bufferedwriter, null);*/
    
    tcarver's avatar
    tcarver committed
            }
    
            bufferedwriter.close();
          }
          else
            propFile.delete();
        }
        catch (FileNotFoundException filenotfoundexception)
        {
          System.err.println(prop+" read error");
        }
        catch (IOException e)
        {
          System.err.println(prop+" i/o error");
        }
      }
      
    
    tcarver's avatar
    tcarver committed
      /**
       * Escape the spaces with a double backslash (i.e. '\\ ').
       * @param s
       * @return
       */
      private static String escapeSpace(String s)
      {
        s = removeSpaceEscape(s).replace(" ", "\\\\ ");
        return s;
      }
      
      private static String removeSpaceEscape(String s)
      {
        return s.replace("\\ ", " ");
      }
      
    
    tcarver's avatar
    tcarver committed
      class LaunchActionListener implements ActionListener
      {
    
        private HashMap<Integer, Vector<JTextField>> settings;
    
    tcarver's avatar
    tcarver committed
        
    
        private void setSettings(HashMap<Integer, Vector<JTextField>> settings)
    
    tcarver's avatar
    tcarver committed
        {
          this.settings = settings;
        }
        
        private String[] getArgs()
    
    tcarver's avatar
    tcarver committed
        {
          try
          {
            System.getProperties().remove("bam");
            System.getProperties().remove("chado");
          }
          catch(Exception e){ e.printStackTrace(); }
          
          final Set<Integer> keys = settings.keySet();
          final Vector<String> vargs = new Vector<String>();
          final Vector<String> vann = new Vector<String>();
          for(Integer key: keys)
          {
    
            final Vector<JTextField> vText = settings.get(key);
    
    tcarver's avatar
    tcarver committed
            switch(key)
            {
              case ProjectProperty.REFERENCE:
    
                vargs.add( vText.get(0).getText().trim() );
    
    tcarver's avatar
    tcarver committed
                break;
              case ProjectProperty.ANNOTATION:
    
                for(JTextField ann: vText)
                  if(ann.isEnabled())
                    vann.add( ann.getText().trim() );
    
    tcarver's avatar
    tcarver committed
                break;
              case ProjectProperty.NEXT_GEN_DATA:
    
                String bam = "";
                for(JTextField ann: vText)
                  if(ann.isEnabled())
                    bam += ","+ann.getText().trim();
                if(!bam.equals(""))
                  System.setProperty("bam", bam.replaceFirst(",", ""));
    
    tcarver's avatar
    tcarver committed
                break;
    
    tcarver's avatar
    tcarver committed
              case ProjectProperty.USERPLOT:
    
                String userplot = "";
                for(JTextField ann: vText)
                {
                  if(ann.isEnabled())
                    userplot += ","+ann.getText().trim();
                }
                if(!userplot.equals(""))
                  System.setProperty("userplot", userplot.replaceFirst(",", ""));
                    
                    
    
    tcarver's avatar
    tcarver committed
                break;
    
    tcarver's avatar
    tcarver committed
              case ProjectProperty.CHADO:
    
                System.setProperty("chado", vText.get(0).getText().trim());
    
    tcarver's avatar
    tcarver committed
          String[] args = new String[vargs.size()+(vann.size()*2)];
    
    tcarver's avatar
    tcarver committed
          for(int i=0; i<vargs.size(); i++)
            args[i] = vargs.get(i);
          for(int i=0; i<vann.size(); i++)
          {
            args[vargs.size()+(i*2)] = "+";
            args[vargs.size()+(i*2)+1] = vann.get(i);
          }
    
    tcarver's avatar
    tcarver committed
          return args;
    
    tcarver's avatar
    tcarver committed
        }
        
        public void actionPerformed(ActionEvent arg0)
        {
          SwingUtilities.invokeLater(new Runnable() 
          {
            public void run() 
            {
    
    tcarver's avatar
    tcarver committed
              setCursor(new Cursor(Cursor.WAIT_CURSOR));
              try
              {
                String[] args = getArgs();
                final ArtemisMain main_window;
                if (splash == null)
                {
                  main_window = new ArtemisMain(args);
                  main_window.setVisible(true);
                }
                else
                  main_window = (ArtemisMain) splash;
                main_window.readArgsAndOptions(args);
              } 
              finally
              {
                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
              }
    
      class TypeComparator implements Comparator<Object> 
      {
        public int compare(Object o1, Object o2)
        {
          String s1 = (String)o1;
          String s2 = (String)o2;
          if( s1.equals("title") )
            return -1;
          else if(s2.equals("title"))
            return 1;
          
          return s1.compareTo(s2);
        }
      }
      
    
    tcarver's avatar
    tcarver committed
      public static void main(String args[])
      {
        new ProjectProperty();
      }
    }