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 */
021
022package org.biojava.bio.seq.io;
023
024import java.util.Iterator;
025import java.util.Set;
026
027import org.biojava.bio.Annotation;
028import org.biojava.bio.BioException;
029import org.biojava.bio.seq.DNATools;
030import org.biojava.bio.seq.Sequence;
031import org.biojava.bio.seq.db.IllegalIDException;
032import org.biojava.bio.seq.db.SequenceDB;
033import org.biojava.bio.seq.db.biosql.BioSQLSequenceDB;
034import org.biojava.bio.seq.impl.DummySequence;
035import org.biojava.bio.symbol.Alphabet;
036import org.biojava.bio.symbol.Symbol;
037import org.biojava.utils.ChangeVetoException;
038
039/**
040 * This SequenceBuilder has a variety of modes of operation.
041 * It can take a sequence from an existing SequenceDB and
042 * apply annotations to it.
043 * <p>
044 * If the SequenceDB has persistence, then it can also create
045 * a sequence in the sequenceDB and apply the annotation to that.
046 * However, performance under those circumstances can vary depending
047 * on how well the persistent SequenceDB handles this.
048 *
049 * <p>Following the introduction of biojavax persistence is handled by
050 * Hibernate refer to 
051 * {@link org.biojavax.bio.db.biosql.BioSQLRichObjectBuilder BioSQLRichObjectBuilder}</p>
052 *
053 * @author David Huen
054 */
055public class SequenceDBSequenceBuilder extends SequenceBuilderBase
056{
057    public static final int ANNOTATE_EXISTING = 1;
058    public static final int CREATE_DUMMYSEQ = 2;
059    public static final int CREATE_REALSEQ = 3;
060
061    // class variables
062    // the DB on which I will be working
063    private SequenceDB db;
064    int mode;
065
066    /**
067     * constructor
068     */
069    public SequenceDBSequenceBuilder(
070        SequenceDB db,
071        int mode)
072    {
073        super();
074
075        this.db = db;
076        this.mode = mode;
077    }
078
079    /**
080     * does nothing for now.
081     */
082    public void addSymbols(Alphabet alpha, Symbol[] syms, int pos, int len)
083    {
084    }
085
086    /**
087     * create the sequence
088     */
089    public Sequence makeSequence()
090        throws BioException
091    {
092        if (name == null) {
093            System.err.println("sequence doesn't have a name!!!!  Abandoning task.");
094            System.exit(1);
095        }
096
097        // check if the sequence exists in the DB
098//        Sequence seq = null;
099        try {
100            seq = db.getSequence(name);
101        }
102        catch (BioException be) {
103        }
104
105        if ((mode == ANNOTATE_EXISTING) && (seq == null)) { 
106            System.err.println("no existing sequence to annotate for " + name);
107            return null;
108        }
109
110        if ((mode == CREATE_DUMMYSEQ) || (mode == CREATE_REALSEQ)) {
111
112            // make sure the sequence isn't there already!
113            if (seq != null) {
114                System.err.println("sequence " + name + " already exists.");
115                return null;
116            }
117
118            if (mode == CREATE_DUMMYSEQ) {
119                int length = Integer.MAX_VALUE;
120//                String id = null;
121
122                // recover sequence length from sequence properties
123                if (annotation.containsProperty("length")) {
124                    length = Integer.parseInt((String) annotation.getProperty("length"));
125                }
126
127                // sequence MUST have a name!!
128//                if (annotation.containsProperty("id")) {
129//                    id = (String) annotation.getProperty("id");
130//                }
131//                else return null;
132
133                // make the dummy sequence
134                try {
135                    if (db instanceof BioSQLSequenceDB) {
136                        ((BioSQLSequenceDB) db).createDummySequence(name, DNATools.getDNA(), length);
137                        seq = db.getSequence(name);
138                    }
139                    else {
140                        seq = new DummySequence(uri, name);
141                    }
142                }
143                catch (ChangeVetoException cve) {
144                    System.err.println("BioSQLSequenceDB was immutable");
145                    return null;
146                }
147                catch (IllegalIDException iie) {
148                    System.err.println("name " + name + " is illegal.");
149                    return null;
150                }
151                catch (BioException be) {
152                    System.err.println("Caught BioException");
153                    return null;
154                }
155
156                // I must have a sequence to go on!!!
157                if (seq == null) return null;
158            }
159            else if (mode == CREATE_REALSEQ) {
160                // implement this some other time.
161            }
162        }
163
164        // I will have a sequence by this point.
165
166        // transfer over annotations to the sequence
167        Set keys = annotation.keys();
168        System.out.println("sequence is " + seq);
169        System.out.println("sequence name is " + seq.getName());
170        Annotation seqAnnotation = seq.getAnnotation();
171
172        if (keys != null) {
173            Iterator keyI = keys.iterator();
174            while (keyI.hasNext()) {
175                Object thisKey = keyI.next();
176
177                // transfer over contents
178                try {
179                    seqAnnotation.setProperty(thisKey, annotation.getProperty(thisKey));
180                }
181                catch (ChangeVetoException cve) {
182                    System.err.println("BioSQLSequenceDB was immutable");
183                    return null;
184                }
185            }
186        }
187
188        // go to overloaded method
189        return super.makeSequence();
190    }
191}