/* * 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.resourcesdb.io; import java.util.ArrayList; import org.eurocarbdb.resourcesdb.*; import org.eurocarbdb.resourcesdb.monosaccharide.*; import org.eurocarbdb.resourcesdb.template.SubstituentTemplate; import org.eurocarbdb.resourcesdb.template.TemplateContainer; import org.eurocarbdb.resourcesdb.template.TrivialnameTemplate; /** * Importer class for CFG LinearCode residue names * @author Thomas Luetteke * */ public class CfgImporter extends StandardImporter implements MonosaccharideImporter { //***************************************************************************** //*** constructors: *********************************************************** //***************************************************************************** public CfgImporter() { this(null, null); } public CfgImporter(Config confObj) { this(confObj, null); } public CfgImporter(Config confObj, TemplateContainer container) { super(GlycanNamescheme.CFG, confObj, container); } //***************************************************************************** //*** parsing methods: ******************************************************** //***************************************************************************** public Monosaccharide parseMsString(String name) throws ResourcesDbException { Monosaccharide ms = new Monosaccharide(this.getConfig(), this.getTemplateContainer()); this.parseMsString(name, ms); return ms; } public Monosaccharide parseMsString(String name, Monosaccharide ms) throws ResourcesDbException { if(ms == null) { throw new NameParsingException("CfgImporter.parseMsString(String, Monosaccharide): Monosaccharide must not be null."); } this.init(); this.setInputName(name); ms.init(); ms.setCheckPositionsOnTheFly(false); String residueBaseStr = ""; boolean hasNonStdConfig = false; boolean hasNonStdRingtype = false; Anomer anomeric = null; ArrayList<Substitution> substList = null; //*** parse name: *** //*** get base name: *** while(this.hasCurrentToken() && Character.isUpperCase(name.charAt(this.getParsingPosition()))) { residueBaseStr += name.charAt(this.getParsingPosition()); this.increaseParsingPosition(); } if(residueBaseStr.length() == 0) { throw new NameParsingException("Cfg residue name must start with uppercase letter.", this.getInputName(), this.getParsingPosition()); } TrivialnameTemplate template = this.getTemplateContainer().getTrivialnameTemplateContainer().forBasetypeName(GlycanNamescheme.CFG, residueBaseStr); if(template == null) { throw new NameParsingException("unknown cfg base name: " + residueBaseStr, this.getInputName(), 0); } this.setDetectedTrivialname(template); //*** check for non standard configuration: *** if(name.length() > this.getParsingPosition()) { if(name.charAt(this.getParsingPosition()) == '\'') { hasNonStdConfig = true; this.increaseParsingPosition(); } } //*** check for non standard ring type: *** if(name.length() > this.getParsingPosition()) { if(name.charAt(this.getParsingPosition()) == '^') { hasNonStdRingtype = true; this.increaseParsingPosition(); } } //*** check for both non standard ring type and configuration: *** if(name.length() > this.getParsingPosition()) { if(name.charAt(this.getParsingPosition()) == '~') { hasNonStdRingtype = true; hasNonStdConfig = true; this.increaseParsingPosition(); } } //*** check for substitutions: *** if(name.length() > this.getParsingPosition()) { substList = this.parseSubstitutions(); } //*** get anomeric: *** if(name.length() > this.getParsingPosition()) { if(name.charAt(this.getParsingPosition()) == 'a') { anomeric = Anomer.ALPHA; this.increaseParsingPosition(); } else if(name.charAt(this.getParsingPosition()) == 'b') { anomeric = Anomer.BETA; this.increaseParsingPosition(); } else if(name.charAt(this.getParsingPosition()) == '?') { anomeric = Anomer.UNKNOWN; this.increaseParsingPosition(); } } else { anomeric = Anomer.UNKNOWN; } if(name.length() > this.getParsingPosition()) { throw new NameParsingException("unexpected token: '" + name.charAt(this.getParsingPosition()) + "'", this.getInputName(), this.getParsingPosition()); } //*** build monosaccharide: *** //*** set stereocode + anomer: *** ms.setSize(template.getSize()); String stereoStr = Stereocode.StereoN + template.getStereocode() + Stereocode.StereoN; if(template.getDefaultConfiguration().equals(StereoConfiguration.Laevus)) { stereoStr = Stereocode.changeDLinStereoString(stereoStr); } ms.setStereoStr(stereoStr); ms.setAnomer(anomeric); ms.setAnomerInStereocode(); //*** set configuration: *** if(hasNonStdConfig) { if(template.isDefaultConfigIsCompulsory()) { throw new NameParsingException("Change of configuration not allowed for " + template.getPrimaryName(this.getNamescheme()), this.getInputName(), this.getInputName().indexOf("'")); } ms.setConfiguration(StereoConfiguration.invert(template.getDefaultConfiguration())); ms.setStereoStr(Stereocode.changeDLinStereoString(ms.getStereoStr())); } else { ms.setConfiguration(template.getDefaultConfiguration()); } //*** set ring: *** int ringstart = template.getCarbonylPosition(); ms.setDefaultCarbonylPosition(ringstart); ms.setRingStart(ringstart); int ringend = template.getDefaultRingend(); if(hasNonStdRingtype) { if(ringend - ringstart == 4) { ringend --; } else { ringend ++; } } ms.setRingEnd(ringend); //*** set modifications: *** ms.getBasetype().setCoreModifications(template.getCoreModifications()); ms.setSubstitutions(template.getSubstitutionsClone()); if(substList != null) { for(Substitution subst : substList) { ms.addSeparateDisplaySubstitution(subst, GlycanNamescheme.CFG, this.getTemplateContainer().getSubstituentTemplateContainer(), false); } } return ms; } private ArrayList<Substitution> parseSubstitutions() throws ResourcesDbException { ArrayList<Substitution> outList = new ArrayList<Substitution>(); String parseStr = this.getInputName(); if(parseStr.charAt(this.getParsingPosition()) == '[') { this.increaseParsingPosition(); Substitution subst; while((subst = this.parseSingleSubstitution()) != null) { outList.add(subst); if(parseStr.charAt(this.getParsingPosition()) == ',') { this.increaseParsingPosition(); } else if(parseStr.charAt(this.getParsingPosition()) == ']') { break; } } if(parseStr.charAt(this.getParsingPosition()) != ']') { throw new NameParsingException("unexpected token '" + parseStr.charAt(this.getParsingPosition()) + "' (expected ']')", this.getInputName(), this.getParsingPosition()); } else { this.increaseParsingPosition(); } } return outList; } private Substitution parseSingleSubstitution() throws ResourcesDbException { String parseStr = this.getInputName(); Substitution subst = new Substitution(); int pos; pos = this.parseIntNumber(true); subst.addPosition1(pos); while(parseStr.charAt(this.getParsingPosition()) == '/') { this.increaseParsingPosition(); pos = this.parseIntNumber(true); subst.addPosition1(pos); } if(parseStr.charAt(this.getParsingPosition()) == ',') { this.increaseParsingPosition(); pos = this.parseIntNumber(true); subst.addPosition2(pos); while(parseStr.charAt(this.getParsingPosition()) == '/') { this.increaseParsingPosition(); pos = this.parseIntNumber(true); subst.addPosition2(pos); } } String substName = ""; while(Character.isUpperCase(parseStr.charAt(this.getParsingPosition()))) { substName += parseStr.charAt(this.getParsingPosition()); this.increaseParsingPosition(); } if(substName.length() == 0) { throw new NameParsingException("substituent identifier expected", parseStr, this.getParsingPosition()); } SubstituentTemplate substTmpl = this.getTemplateContainer().getSubstituentTemplateContainer().forResidueIncludedName(GlycanNamescheme.CFG, substName); if(substTmpl == null) { throw new NameParsingException("unknown substituent identifier", parseStr, this.getParsingPosition() - substName.length()); } subst.setTemplate(substTmpl); subst.setLinkagetype1(substTmpl.getLinkageTypeBySubstituentName(GlycanNamescheme.CFG, substName)); subst.setSubstituentPosition1(substTmpl.getDefaultLinkingPosition1()); if(subst.hasPosition2()) { //TODO: set position 2 linkage type in template alias and get it from there subst.setLinkagetype2(substTmpl.getDefaultLinkagetype2()); subst.setSubstituentPosition2(substTmpl.getDefaultLinkingPosition2()); } return subst; } }