/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.bio.seq.io; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import org.biojava.bio.Annotation; import org.biojava.bio.BioError; import org.biojava.bio.seq.Feature; import org.biojava.bio.seq.FeatureHolder; import org.biojava.bio.seq.Sequence; import org.biojava.bio.symbol.IllegalAlphabetException; import org.biojava.bio.symbol.Symbol; /** * SeqIOEventEmitter is a utility class which scans a * Sequence object and sends events describing its * constituent data to a SeqIOListener. The listener * should be able to reconstruct the Sequence from these * events. * * @author Keith James * @since 1.2 * @deprecated Use org.biojavax.bio.seq.io framework instead */ public class SeqIOEventEmitter { private static Symbol [] symProto = new Symbol [0]; private Comparator seqPropComparator; private Comparator refPropComparator; private Comparator featureComparator; public SeqIOEventEmitter(Comparator seqPropComparator, Comparator featureComparator) { this.seqPropComparator = seqPropComparator; this.featureComparator = featureComparator; } /** * getSeqIOEvents scans a Sequence * object and sends events describing its data to the * SeqIOListener. * * @param seq a Sequence. * @param listener a SeqIOListener. */ public void getSeqIOEvents(Sequence seq, SeqIOListener listener) { try { // Inform listener of sequence start listener.startSequence(); // Pass name to listener listener.setName(seq.getName()); // Pass URN to listener listener.setURI(seq.getURN()); // Pass sequence properties to listener Annotation a = seq.getAnnotation(); List sKeys = new ArrayList(a.keys()); Collections.sort(sKeys, seqPropComparator); for (Iterator ki = sKeys.iterator(); ki.hasNext();) { Object key = ki.next(); if ( key.equals(ReferenceAnnotation.class)) { ArrayList references = null; if (a.getProperty(key) instanceof ArrayList) { references = ((ArrayList)a.getProperty(key)); } else if (a.getProperty(key) instanceof ReferenceAnnotation){ //mark_s: if only one ReferenceAnnotation references = new ArrayList(); references.add(a.getProperty(key)); } if (references != null) { for ( int i = 0; i < references.size(); i++ ) { ReferenceAnnotation refAnnot = (ReferenceAnnotation)references.get(i); Map referenceLines = refAnnot.getProperties(); List refKeys = new ArrayList(referenceLines.keySet()); refPropComparator = EmblReferenceComparator.INSTANCE; Collections.sort(refKeys, refPropComparator); for (Iterator kit = refKeys.iterator(); kit.hasNext();) { Object refKey = kit.next(); //adds all the R* tags and final XX tag listener.addSequenceProperty(refKey, refAnnot.getProperty(refKey)); } } } } else { if (!(key.equals(EmblLikeFormat.SEPARATOR_TAG))) { //lorna: ignore XX listener.addSequenceProperty(key, a.getProperty(key)); } } } // Recurse through sub feature tree, flattening it for // EMBL List subs = getSubFeatures(seq); Collections.sort(subs, featureComparator); // Put the source features first for EMBL for (Iterator fi = subs.iterator(); fi.hasNext();) { // The template is required to call startFeature Feature.Template t = ((Feature) fi.next()).makeTemplate(); // Inform listener of feature start listener.startFeature(t); // Pass feature properties (i.e. qualifiers to // listener) // FIXME: this will drop all non-comparable keys List fKeys = comparableList(t.annotation.keys()); Collections.sort(fKeys); for (Iterator ki = fKeys.iterator(); ki.hasNext();) { Object key = ki.next(); listener.addFeatureProperty(key, t.annotation.getProperty(key)); } // Inform listener of feature end listener.endFeature(); } // Add symbols listener.addSymbols(seq.getAlphabet(), (Symbol []) seq.toList().toArray(symProto), 0, seq.length()); // Inform listener of sequence end listener.endSequence(); } catch (IllegalAlphabetException iae) { // This should never happen as the alphabet is being used // by this Sequence instance throw new BioError("An internal error occurred processing symbols",iae); } catch (ParseException pe) { throw new BioError("An internal error occurred creating SeqIO events",pe); } } /** * getSubFeatures is a recursive method which returns * a list of all Features within a * FeatureHolder. * * @param fh a FeatureHolder. * * @return a List. */ private static List getSubFeatures(FeatureHolder fh) { List subfeat = new ArrayList(); for (Iterator fi = fh.features(); fi.hasNext();) { FeatureHolder sfh = (FeatureHolder) fi.next(); subfeat.addAll((Collection) getSubFeatures(sfh)); subfeat.add(sfh); } return subfeat; } private List comparableList(Collection coll) { ArrayList res = new ArrayList(); for(Iterator i = coll.iterator(); i.hasNext(); ) { Object o = i.next(); if(o instanceof Comparable) { res.add(o); } } return res; } }