/* * 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.MolecularFramework.io.iupac; import java.util.ArrayList; import java.util.Iterator; import org.eurocarbdb.MolecularFramework.io.SugarImporterException; import org.eurocarbdb.MolecularFramework.io.SugarImporterText; import org.eurocarbdb.MolecularFramework.sugar.GlycoEdge; import org.eurocarbdb.MolecularFramework.sugar.GlycoconjugateException; import org.eurocarbdb.MolecularFramework.sugar.Linkage; import org.eurocarbdb.MolecularFramework.sugar.UnvalidatedGlycoNode; /** * condensed form one line * * Gal(b1-4)[Fuc(a1-3)]GlcNAc(b1-2)Man(a1- * * start ::= residue "(" anomer linkageposition "-" { linkageposition ")" { subbranch } residue "(" anomer linkageposition "-" } * anomer ::= a | b | ? | o * linkageposition ::= number | "?" * resiude ::= symbol { symbol } * subbranch ::= "[" fullresidue { [ subbranch { subbranch } ] fullresidue } "]" * fullresidue ::= residue "(" anomer linkageposition "-" linkageposition ")" * symbol ::= character | "?" | "-" | number */ public class SugarImporterIupacCondenced extends SugarImporterText { /** * residue "(" anomer linkageposition { "-" linkageposition ")" { subbranch } residue "(" anomer linkageposition } */ protected void start() throws SugarImporterException { try { this.clear(); UnvalidatedGlycoNode t_objResiduumChild = new UnvalidatedGlycoNode(); UnvalidatedGlycoNode t_objResiduumParent = new UnvalidatedGlycoNode(); GlycoEdge t_objEdge = new GlycoEdge(); Linkage t_objLinkage = new Linkage(); int t_iStartPosition = this.m_iPosition; // residue this.residue(); String t_strResidueName = this.m_strText.substring( t_iStartPosition , this.m_iPosition ); if ( this.m_cToken != '(' ) { throw new SugarImporterException("IUPAC000", this.m_iPosition); } this.nextToken(); t_objResiduumChild.setName( this.anomer() + t_strResidueName ); this.m_objSugar.addNode(t_objResiduumChild); // residue "(" anomer linkageposition t_objLinkage.addChildLinkage(this.linkageposition()); if ( this.m_cToken == '-' ) { this.nextToken(); } else if ( this.m_cToken == '$' ) {} else { throw new SugarImporterException("IUPAC005", this.m_iPosition); } while ( this.m_cToken != '$' ) { t_objLinkage.addParentLinkage(this.linkageposition()); t_objEdge.addGlycosidicLinkage(t_objLinkage); if ( this.m_cToken != ')' ) { throw new SugarImporterException("IUPAC001", this.m_iPosition); } this.nextToken(); ArrayList<IupacSubTree> t_aIupacSubtree = new ArrayList<IupacSubTree>(); while ( this.m_cToken == '[' ) { t_aIupacSubtree.add(this.subbranch()); } t_iStartPosition = this.m_iPosition; this.residue(); t_strResidueName = this.m_strText.substring( t_iStartPosition , this.m_iPosition ); if ( this.m_cToken != '(' ) { throw new SugarImporterException("IUPAC000", this.m_iPosition); } this.nextToken(); t_objResiduumParent.setName( this.anomer() + t_strResidueName ); this.m_objSugar.addNode(t_objResiduumParent); this.m_objSugar.addEdge(t_objResiduumParent, t_objResiduumChild, t_objEdge); // add subtrees for (Iterator<IupacSubTree> t_iterSubtree = t_aIupacSubtree.iterator(); t_iterSubtree.hasNext();) { IupacSubTree t_objTree = t_iterSubtree.next(); this.m_objSugar.addEdge(t_objResiduumParent, t_objTree.getGlycoNode(), t_objTree.getGlycoEdge()); } t_objResiduumChild = t_objResiduumParent; t_objResiduumParent = new UnvalidatedGlycoNode(); t_objEdge = new GlycoEdge(); t_objLinkage = new Linkage(); t_objLinkage.addChildLinkage(this.linkageposition()); if ( this.m_cToken == '-' ) { this.nextToken(); } else if ( this.m_cToken == '$' ) {} else { throw new SugarImporterException("IUPAC005", this.m_iPosition); } } if ( ! this.finished() ) { throw new SugarImporterException("IUPAC002", this.m_iPosition); } } catch (GlycoconjugateException e) { throw new SugarImporterException("COMMON013", this.m_iPosition); } } /** * subbranch ::= "[" fullresidue { { subbranch } fullresidue } "]" * @throws SugarImporterException * @throws GlycoconjugateException */ private IupacSubTree subbranch() throws SugarImporterException, GlycoconjugateException { IupacSubTree t_objTreeChild; IupacSubTree t_objTreeParent; if ( this.m_cToken != '[' ) { throw new SugarImporterException("IUPAC004", this.m_iPosition); } this.nextToken(); t_objTreeChild = this.fullresidue(); this.m_objSugar.addNode(t_objTreeChild.getGlycoNode()); while ( this.m_cToken != ']' ) { ArrayList<IupacSubTree> t_aIupacSubtree = new ArrayList<IupacSubTree>(); while ( this.m_cToken == '[' ) { t_aIupacSubtree.add(this.subbranch()); } t_objTreeParent = this.fullresidue(); this.m_objSugar.addNode(t_objTreeChild.getGlycoNode()); this.m_objSugar.addEdge(t_objTreeParent.getGlycoNode(), t_objTreeChild.getGlycoNode(), t_objTreeChild.getGlycoEdge()); // add subtrees for (Iterator<IupacSubTree> t_iterSubtree = t_aIupacSubtree.iterator(); t_iterSubtree.hasNext();) { IupacSubTree t_objTree = t_iterSubtree.next(); this.m_objSugar.addEdge(t_objTreeParent.getGlycoNode(), t_objTree.getGlycoNode(), t_objTree.getGlycoEdge()); } t_objTreeChild = t_objTreeParent; } this.nextToken(); return t_objTreeChild; } /** * fullresidue ::= residue "(" anomer linkageposition "-" linkageposition ")" * @throws SugarImporterException * @throws GlycoconjugateException */ private IupacSubTree fullresidue() throws SugarImporterException, GlycoconjugateException { IupacSubTree t_objTree = new IupacSubTree(); UnvalidatedGlycoNode t_objNode = new UnvalidatedGlycoNode(); GlycoEdge t_objEdge = new GlycoEdge(); Linkage t_objLinkage = new Linkage(); int t_iStartPosition = this.m_iPosition; // residue this.residue(); String t_strResidueName = this.m_strText.substring( t_iStartPosition , this.m_iPosition ); if ( this.m_cToken != '(' ) { throw new SugarImporterException("IUPAC000", this.m_iPosition); } this.nextToken(); t_objNode.setName( this.anomer() + t_strResidueName ); this.m_objSugar.addNode(t_objNode); // residue "(" anomer linkageposition t_objLinkage.addChildLinkage(this.linkageposition()); if ( this.m_cToken != '-' ) { throw new SugarImporterException("IUPAC005", this.m_iPosition); } this.nextToken(); t_objLinkage.addParentLinkage(this.linkageposition()); if ( this.m_cToken != ')' ) { throw new SugarImporterException("IUPAC001", this.m_iPosition); } this.nextToken(); t_objEdge.addGlycosidicLinkage(t_objLinkage); t_objTree.setGlycoEdge(t_objEdge); t_objTree.setGlycoNode(t_objNode); return t_objTree; } /** * linkageposition ::= number | "?" * @throws SugarImporterException */ private int linkageposition() throws SugarImporterException { if ( this.m_cToken == '?' ) { this.nextToken(); return Linkage.UNKNOWN_POSITION; } else { return this.number(); } } /** * anomer ::= a | b | ? | o * @throws SugarImporterException */ private String anomer() throws SugarImporterException { if ( this.m_cToken == 'a' ) { this.nextToken(); return "a"; } else if ( this.m_cToken == 'b' ) { this.nextToken(); return "b"; } else if ( this.m_cToken == '?' ) { this.nextToken(); return "?"; } else if ( this.m_cToken == 'o' ) { this.nextToken(); return "o"; } else { throw new SugarImporterException("IUPAC0003", this.m_iPosition); } } /** * resiude ::= symbol { symbol } * @throws SugarImporterException */ private void residue() throws SugarImporterException { this.symbol(); while ( this.m_cToken != '(' ) { this.symbol(); } } /** * symbol ::= character | "?" | "-" | number * @throws SugarImporterException */ private void symbol() throws SugarImporterException { if ( this.m_cToken == '?' || this.m_cToken == '-' ) { this.nextToken(); } else { int t_iDigit = (int) this.m_cToken;; if ( t_iDigit > 47 && t_iDigit < 58 ) { this.number(); } else { this.character(); } } } private void clear() {} }