/* $RCSfile$ * $Author$ * $Date$ * $Revision$ * * Copyright (C) 2003-2007 Egon Willighagen <egonw@users.sf.net> * * Contact: cdk-devel@lists.sf.net * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package org.openscience.cdk.config.isotopes; import java.util.ArrayList; import java.util.List; import org.openscience.cdk.annotations.TestClass; import org.openscience.cdk.annotations.TestMethod; import org.openscience.cdk.interfaces.IChemObjectBuilder; import org.openscience.cdk.interfaces.IIsotope; import org.openscience.cdk.tools.ILoggingTool; import org.openscience.cdk.tools.LoggingToolFactory; import org.xml.sax.Attributes; import org.xml.sax.helpers.DefaultHandler; /** * Reads an isotope list in CML2 format. An example definition is: * <pre> * <isotopeList id="H"> * <isotope id="H1" isotopeNumber="1" elementTyp="H"> * <abundance dictRef="cdk:relativeAbundance">100.0</abundance> * <scalar dictRef="cdk:exactMass">1.00782504</scalar> * <scalar dictRef="cdk:atomicNumber">1</scalar> * </isotope> * <isotope id="H2" isotopeNumber="2" elementTyp="H"> * <abundance dictRef="cdk:relativeAbundance">0.015</abundance> * <scalar dictRef="cdk:exactMass">2.01410179</scalar> * <scalar dictRef="cdk:atomicNumber">1</scalar> * </isotope> * </isotopeList> * </pre> * * @cdk.module core * @cdk.githash */ @TestClass("org.openscience.cdk.config.isotopes.IsotopeHandlerTest") public class IsotopeHandler extends DefaultHandler { private static ILoggingTool logger = LoggingToolFactory.createLoggingTool(IsotopeHandler.class); private String currentChars; private List<IIsotope> isotopes; private IIsotope workingIsotope; private String currentElement; private String dictRef; private IChemObjectBuilder builder; /** * Constructs an IsotopeHandler used by the IsotopeReader. * * @param builder The IChemObjectBuilder used to create new IIsotope's. */ public IsotopeHandler(IChemObjectBuilder builder) { this.builder = builder; } /** * Returns the isotopes read from the XML file. * * @return A List object with all isotopes */ @TestMethod("testGetIsotopes") public List<IIsotope> getIsotopes() { return isotopes; } // SAX Parser methods @TestMethod("testStartDocument") public void startDocument() { isotopes = new ArrayList<IIsotope>(); } @TestMethod("testEndElement_String_String_String") public void endElement(String uri, String local, String raw) { logger.debug("end element: ", raw); if ("isotope".equals(local)) { if (workingIsotope != null) isotopes.add(workingIsotope); workingIsotope = null; } else if ("isotopeList".equals(local)) { currentElement = null; } else if ("scalar".equals(local)) { try { if ("bo:exactMass".equals(dictRef)) { workingIsotope.setExactMass(Double.parseDouble(currentChars)); } else if ("bo:atomicNumber".equals(dictRef)) { workingIsotope.setAtomicNumber(Integer.parseInt(currentChars)); } else if ("bo:relativeAbundance".equals(dictRef)) { workingIsotope.setNaturalAbundance(Double.parseDouble(currentChars)); } } catch (NumberFormatException exception) { logger.error("The ", dictRef, " value is incorrect: ", currentChars); logger.debug(exception); } } } @TestMethod("testEndElement_String_String_String") public void startElement(String uri, String local, String raw, Attributes atts) { currentChars = ""; dictRef = ""; logger.debug("startElement: ", raw); logger.debug("uri: ", uri); logger.debug("local: ", local); logger.debug("raw: ", raw); if ("isotope".equals(local)) { workingIsotope = createIsotopeOfElement(currentElement, atts); } else if ("isotopeList".equals(local)) { currentElement = getElementSymbol(atts); } else if ("scalar".equals(local)) { for (int i = 0; i < atts.getLength(); i++) { if ("dictRef".equals(atts.getQName(i))) { dictRef = atts.getValue(i); } } } } @TestMethod("testCharacters_arraychar_int_int") public void characters(char chars[], int start, int length) { currentChars += new String(chars, start, length); } private IIsotope createIsotopeOfElement(String currentElement, Attributes atts) { IIsotope isotope = builder.newIsotope(currentElement); for (int i = 0; i < atts.getLength(); i++) { try { if ("id".equals(atts.getQName(i))) { isotope.setID(atts.getValue(i)); } else if ("number".equals(atts.getQName(i))) { isotope.setMassNumber(Integer.parseInt(atts.getValue(i))); } else if ("elementType".equals(atts.getQName(i))) { isotope.setSymbol(atts.getValue(i)); } } catch (NumberFormatException exception) { logger.error("Value of isotope@", atts.getQName(i), " is not as expected."); logger.debug(exception); } } // we set the natural abundance to 0, since the default is -1, but // some isotope entries have no entry for this field, so the values // stays at -1 isotope.setNaturalAbundance(0.0); return isotope; } private String getElementSymbol(Attributes atts) { for (int i = 0; i < atts.getLength(); i++) { if ("id".equals(atts.getQName(i))) { return atts.getValue(i); } } return ""; } }