/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * 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 Lesser General Public License * for more details. * * Last commit: $Rev: 1210 $ by $Author: glycoslave $ on $Date:: 2009-06-12 #$ */ package org.eurocarbdb.application.glycanbuilder; import java.io.*; import java.util.*; import org.w3c.dom.*; import org.xml.sax.SAXException; import javax.xml.transform.sax.TransformerHandler; import org.xml.sax.helpers.AttributesImpl; /** This class holds an ordered set of fragment entries. @author Alessio Ceroni (a.ceroni@imperial.ac.uk) */ public class FragmentCollection implements SAXUtils.SAXWriter { // ----- private Vector<FragmentEntry> fragments; /** Empty constructor. */ public FragmentCollection() { fragments = new Vector<FragmentEntry>(); } /** Create a complete copy of this object. All the fragment entries are copied. */ public FragmentCollection clone() { FragmentCollection ret = new FragmentCollection(); for( Iterator<FragmentEntry> i=fragments.iterator(); i.hasNext(); ) ret.fragments.add(i.next().clone()); return ret; } /** Return the underlying collection of fragment entries. */ public Collection<FragmentEntry> getFragments() { return fragments; } /** Return an iterator over the underlying collection of fragment entries. */ public Iterator<FragmentEntry> iterator() { return fragments.iterator(); } /** Return the entry at the specified position. */ public FragmentEntry elementAt(int ind) { return fragments.elementAt(ind); } /** Return the number of entries in the collection. */ public int size() { return fragments.size(); } /** Add a new fragment entry to the collection. The entry is generated from the supplied information. Duplicated entries are discarded. @return <code>true</code> if the operation was successful */ public boolean addFragment(Glycan _fragment, String _name) { if( _fragment==null ) return false; if( _fragment.getRoot()==null ) return false; Double _mass = _fragment.computeMass(); Double _mz = _fragment.computeMZ(); String _structure = _fragment.toString(); return addFragment(new FragmentEntry(_fragment,_name,_mass,_mz,_structure)); } /** Add a fragment entry to the collection. Duplicated entries are discarded. @return <code>true</code> if the operation was successful */ public boolean addFragment(FragmentEntry toadd) { // sorted insertion for( int i=0; i<fragments.size(); i++ ) { FragmentEntry fe = fragments.elementAt(i); int comp = toadd.compareTo(fe); if( comp==0 ) return false; if( comp<0 ) { fragments.insertElementAt(toadd,i); return true; } /*if( fe.mass.equals(toadd.mass) && fe.structure.equalsStructure(toadd.structure) ) { if( fe.name.length()>toadd.name.length() ) { fragments.setElementAt(toadd,i); return true; } return false; } if( fe.mass>toadd.mass ) { fragments.insertElementAt(toadd,i); return true; }*/ } fragments.add(toadd); return true; } /** Remove the specified fragments from the collection. @return <code>true</code> if the operation was successful */ public boolean removeFragments(Collection<FragmentEntry> fec) { if( fec==null ) return false; return fragments.removeAll(fec); } /** Remove the fragment entry from the collection. @return <code>true</code> if the operation was successful */ public boolean removeFragment(FragmentEntry _fe) { if( _fe==null ) return false; for( int i=0; i<fragments.size(); i++ ) { if( fragments.elementAt(i).equals(_fe) ) { fragments.removeElementAt(i); return true; } } return false; } /** Merge two fragment collections. */ public boolean addFragments(FragmentCollection _fc) { if( _fc==null ) return false; return addFragments(_fc.getFragments()); } /** Add all the specified fragments to the collection. */ public boolean addFragments(Collection<FragmentEntry> _fragments) { if( fragments==null ) return false; boolean added = false; for( FragmentEntry fe : _fragments) added |= addFragment(fe.clone()); return added; } /*public void updateMasses(MassOptions mass_opt) { FragmentCollection updated = new FragmentCollection(); for( Iterator<FragmentEntry> i=fragments.iterator(); i.hasNext(); ) { FragmentEntry e = i.next(); updated.addFragment(e.fragment,e.name,mass_opt); } fragments = updated.fragments; } */ //--------------- // serialization /** Create a new object from its XML representation as part of a DOM tree. */ static public FragmentCollection fromXML(Node root_node) throws Exception { FragmentCollection ret = new FragmentCollection(); // read fragments Vector<Node> fe_nodes = XMLUtils.findAllChildren(root_node, "FragmentEntry"); for( Node fe_node : fe_nodes) ret.addFragment(FragmentEntry.fromXML(fe_node)); return ret; } /** Create an XML representation of this object to be part of a DOM tree. */ public Element toXML(Document document) { if( document==null ) return null; // create root node Element root_node = document.createElement("FragmentCollection"); if( root_node==null ) return null; // add fragments for(FragmentEntry fe : fragments ) root_node.appendChild(fe.toXML(document)); return root_node; } /** Default SAX handler to read a representation of this object from an XML stream. */ public static class SAXHandler extends SAXUtils.ObjectTreeHandler { public boolean isElement(String namespaceURI, String localName, String qName) { return qName.equals(getNodeElementName()); } public static String getNodeElementName() { return "FragmentCollection"; } protected SAXUtils.ObjectTreeHandler getHandler(String namespaceURI, String localName, String qName) throws SAXException { if( qName.equals(FragmentEntry.SAXHandler.getNodeElementName()) ) return new FragmentEntry.SAXHandler(); return null; } protected Object finalizeContent(String namespaceURI, String localName, String qName) throws SAXException { FragmentCollection ret = new FragmentCollection(); for( Object o : getSubObjects(FragmentEntry.SAXHandler.getNodeElementName()) ) ret.addFragment((FragmentEntry)o); return (object = ret); } } /** Write a representation of this object into an XML stream using a SAX handler. */ public void write(TransformerHandler th) throws SAXException { th.startElement("","","FragmentCollection",new AttributesImpl()); for(FragmentEntry fe : fragments ) fe.write(th); th.endElement("","","FragmentCollection"); } }