001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.nbio.structure.align.gui;
022
023import org.biojava.nbio.structure.Atom;
024import org.biojava.nbio.structure.align.model.AFPChain;
025import org.biojava.nbio.structure.align.multiple.MultipleAlignment;
026import org.biojava.nbio.structure.align.multiple.util.MultipleAlignmentWriter;
027import org.biojava.nbio.structure.align.util.AtomCache;
028import org.biojava.nbio.structure.align.util.UserConfiguration;
029import org.biojava.nbio.structure.align.webstart.WebStartMain;
030import org.biojava.nbio.structure.align.xml.AFPChainXMLConverter;
031
032import javax.swing.*;
033
034import java.awt.event.ActionEvent;
035import java.awt.event.ActionListener;
036import java.io.BufferedWriter;
037import java.io.File;
038import java.io.FileWriter;
039
040/**
041 * Save an alignment to a specified File by the user. The alignment to be
042 * saved depends on the constructor used to instantiate this class, so that
043 * AFPChains and MultipleAlignments can be saved.
044 * <p>
045 * The format to save the alignment depends on the Frame that generated the
046 * Action: from a sequence alignment a FatCat or FASTA formats are saved,
047 * and from a Jmol view an XML format is saved.
048 *
049 * @author Aleix Lafita
050 * @version 2.0 - adapted for MultipleAligments
051 *
052 */
053public class MySaveFileListener implements ActionListener {
054
055        private AFPChain afpChain;
056        private MultipleAlignment msa;
057        private boolean printText;
058
059        public MySaveFileListener (AFPChain afpChain){
060                this.afpChain = afpChain;
061                this.msa = null;
062                printText = false;
063        }
064
065        public MySaveFileListener (MultipleAlignment msa){
066                this.afpChain = null;
067                this.msa = msa;
068                printText = false;
069        }
070
071        /**
072         * Constructor to avoid checking which of the two is null before
073         * instantiating this class. One of the two, or both, have to be null.
074         * If both are different than null the MultipleAlignment will be saved
075         * only.
076         *
077         * @param afpChain
078         * @param msa
079         */
080        public MySaveFileListener (AFPChain afpChain, MultipleAlignment msa){
081                this.afpChain = afpChain;
082                this.msa = msa;
083                printText = false;
084        }
085
086        @Override
087        public void actionPerformed(ActionEvent evt) {
088
089                //Return if nothing to save
090                if (afpChain == null && msa == null) {
091                        JOptionPane.showMessageDialog(null,
092                                        "Could not save alignment, no alignment being displayed.");
093                        return;
094                }
095
096                //Choose the file path from the user input
097                JFileChooser fc = new JFileChooser();
098                int returnVal = fc.showSaveDialog(null);
099
100                if (returnVal != JFileChooser.APPROVE_OPTION) {
101                        System.err.println("User canceled file save.");
102                        return;
103                }
104                File selFile = fc.getSelectedFile();
105                if (selFile == null) return;
106
107                System.out.println("Saving alignment to file: " + selFile.getName());
108
109                //XML serialization of the alignment
110                try {
111
112                        String output = "";
113
114                        if (msa!=null){
115                                if (!printText) {
116                                        output = MultipleAlignmentWriter.toXML(msa.getEnsemble());
117                                } else {
118                                        output = MultipleAlignmentWriter.toFASTA(msa);
119                                }
120                        }
121                        else if (afpChain!=null){
122                                UserConfiguration config = WebStartMain.getWebStartConfig();
123                                AtomCache cache = new AtomCache(config);
124
125                                //TODO use the right ca atoms, fails for a custom file!
126                                //This is a bad solution, solved for MultipleAlignments
127                                Atom[] ca1 =cache.getAtoms(afpChain.getName1());
128                                Atom[] ca2 =cache.getAtoms(afpChain.getName2());
129
130                                if (!printText) {
131                                        output = AFPChainXMLConverter.toXML(afpChain,ca1,ca2);
132                                } else {
133                                        output = afpChain.toFatcat(ca1,ca2);
134                                }
135                        }
136
137                        //Write to the file
138                        BufferedWriter out = new BufferedWriter(new FileWriter(selFile));
139                        out.write(output);
140                        out.close();
141
142                } catch (Exception e){
143                        e.printStackTrace();
144                        JOptionPane.showMessageDialog(null,
145                                        "Could not save file. Exception: " + e.getMessage());
146                }
147        }
148
149        /**
150         * If true, the alignment format saved will be a text output (FASTA for
151         * MultipleAlignments and FatCat for pairwise alignments)
152         *
153         * @param text if true the output will be text format
154         */
155        public void setTextOutput(boolean text) {
156                printText = text;
157        }
158
159}