/* $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.atomtypes;
import java.util.ArrayList;
import java.util.List;
import org.openscience.cdk.CDKConstants;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.interfaces.IAtomType;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.interfaces.IAtomType.Hybridization;
import org.openscience.cdk.tools.ILoggingTool;
import org.openscience.cdk.tools.LoggingToolFactory;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
/**
* SAX Handler for the AtomTypeReader.
*
* @see AtomTypeReader
*
* @cdk.module core
* @cdk.githash
*/
@TestClass("org.openscience.cdk.config.atomtypes.AtomTypeHandlerTest")
public class AtomTypeHandler extends DefaultHandler {
private final int SCALAR_UNSET = 0;
private final int SCALAR_MAXBONDORDER = 1;
private final int SCALAR_BONDORDERSUM = 2;
private final int SCALAR_HYBRIDIZATION = 3;
private final int SCALAR_FORMALNEIGHBOURCOUNT = 4;
private final int SCALAR_VALENCY = 5;
private final int SCALAR_DA = 6;
private final int SCALAR_SPHERICALMATCHER = 7;
private final int SCALAR_CHEMICALGROUPCONSTANT = 8;
private final int SCALAR_RINGSIZE = 9;
private final int SCALAR_ISAROMATIC = 10;
private final int SCALAR_FORMALCHARGE=11;
private final int SCALAR_VANDERWAALSRADIUS=12;
private final int SCALAR_PIBONDCOUNT=13;
private final int SCALAR_LONEPAIRCOUNT=14;
private static ILoggingTool logger =
LoggingToolFactory.createLoggingTool(AtomTypeHandler.class);
private String currentChars;
private List<IAtomType> atomTypes;
private int scalarType;
private IAtomType atomType;
private static IChemObjectBuilder builder;
/**
* Constructs a new AtomTypeHandler and will create IAtomType
* implementations using the given IChemObjectBuilder.
*
* @param build The IChemObjectBuilder used to create the IAtomType's.
*/
public AtomTypeHandler(IChemObjectBuilder build) {
builder = build;
}
/**
* Returns a List with read IAtomType's.
*
* @return The read IAtomType's.
*/
@TestMethod("testGetAtomTypes")
public List<IAtomType> getAtomTypes() {
return atomTypes;
}
// SAX Parser methods
/* public void doctypeDecl(String name, String publicId, String systemId) {
logger.info("DocType root element: " + name);
logger.info("DocType root PUBLIC: " + publicId);
logger.info("DocType root SYSTEM: " + systemId);
} */
@TestMethod("testStartDocument")
public void startDocument() {
atomTypes = new ArrayList<IAtomType>();
scalarType = SCALAR_UNSET;
atomType = null;
}
@TestMethod("testEndElement_String_String_String")
public void endElement(String uri, String local, String raw) { //NOPMD
logger.debug("END Element: ", raw);
logger.debug(" uri: ", uri);
logger.debug(" local: ", local);
logger.debug(" raw: ", raw);
logger.debug(" chars: ", currentChars.trim());
if ("atomType".equals(local)) {
atomTypes.add(atomType);
} else if ("scalar".equals(local)) {
currentChars.trim();
try {
if (scalarType == SCALAR_BONDORDERSUM) {
atomType.setBondOrderSum(Double.parseDouble(currentChars));
} else if (scalarType == SCALAR_MAXBONDORDER) {
double scalarValue = Double.parseDouble(currentChars);
if (scalarValue == 1.0) {
atomType.setMaxBondOrder(IBond.Order.SINGLE);
} else if (scalarValue == 2.0) {
atomType.setMaxBondOrder(IBond.Order.DOUBLE);
} else if (scalarValue == 3.0) {
atomType.setMaxBondOrder(IBond.Order.TRIPLE);
} else if (scalarValue == 4.0) {
atomType.setMaxBondOrder(IBond.Order.QUADRUPLE);
}
} else if (scalarType == SCALAR_FORMALNEIGHBOURCOUNT) {
atomType.setFormalNeighbourCount(Integer.parseInt(currentChars));
}else if (scalarType == SCALAR_VALENCY) {
atomType.setValency(Integer.parseInt(currentChars));
}else if (scalarType == SCALAR_FORMALCHARGE) {
atomType.setFormalCharge(Integer.parseInt(currentChars));
} else if (scalarType == SCALAR_HYBRIDIZATION) {
if ("sp1".equals(currentChars)) {
atomType.setHybridization(Hybridization.SP1);
} else if ("sp2".equals(currentChars)) {
atomType.setHybridization(Hybridization.SP2);
} else if ("sp3".equals(currentChars)) {
atomType.setHybridization(Hybridization.SP3);
} else if ("planar".equals(currentChars)) {
atomType.setHybridization(Hybridization.PLANAR3);
}else {
logger.warn("Unrecognized hybridization in config file: ", currentChars);
}
} else if (scalarType == SCALAR_DA){
if ("A".equals(currentChars)) {
atomType.setFlag(CDKConstants.IS_HYDROGENBOND_ACCEPTOR, true);
} else if ("D".equals(currentChars)){
atomType.setFlag(CDKConstants.IS_HYDROGENBOND_DONOR, true);
} else {
logger.warn("Unrecognized H-bond donor/acceptor pattern in config file: ", currentChars);
}
} else if (scalarType == SCALAR_SPHERICALMATCHER){
atomType.setProperty(CDKConstants.SPHERICAL_MATCHER, currentChars);
} else if (scalarType == SCALAR_RINGSIZE){
atomType.setProperty(CDKConstants.PART_OF_RING_OF_SIZE, Integer.valueOf(currentChars));
} else if (scalarType == SCALAR_CHEMICALGROUPCONSTANT){
atomType.setProperty(CDKConstants.CHEMICAL_GROUP_CONSTANT, Integer.valueOf(currentChars));
} else if (scalarType == SCALAR_ISAROMATIC){
atomType.setFlag(CDKConstants.ISAROMATIC, true);
} else if (scalarType == SCALAR_PIBONDCOUNT){
atomType.setProperty(CDKConstants.PI_BOND_COUNT, Integer.valueOf(currentChars));
} else if (scalarType == SCALAR_LONEPAIRCOUNT){
atomType.setProperty(CDKConstants.LONE_PAIR_COUNT, Integer.valueOf(currentChars));
}
} catch (Exception exception) {
logger.error("Value (", currentChars, ") is not off the expected type: ", exception.getMessage());
logger.debug(exception);
}
scalarType = SCALAR_UNSET;
}
currentChars = "";
}
@TestMethod("testStartElement_String_String_String_Attributes")
public void startElement(String uri, String local, //NOPMD
String raw, Attributes atts) {
currentChars = "";
logger.debug("START Element: ", raw);
logger.debug(" uri: ", uri);
logger.debug(" local: ", local);
logger.debug(" raw: ", raw);
if ("atomType".equals(local)) {
atomType = builder.newAtomType("R");
for (int i = 0; i < atts.getLength(); i++) {
if ("id".equals(atts.getQName(i))) {
atomType.setAtomTypeName(atts.getValue(i));
}
}
} else if ("atom".equals(local)) {
for (int i = 0; i < atts.getLength(); i++) {
if ("elementType".equals(atts.getQName(i))) {
atomType.setSymbol(atts.getValue(i));
} else if ("formalCharge".equals(atts.getQName(i))) {
try {
atomType.setFormalCharge(Integer.parseInt(atts.getValue(i)));
} catch (NumberFormatException exception) {
logger.error("Value of <atom> @", atts.getQName(i), " is not an integer: ", atts.getValue(i));
logger.debug(exception);
}
}
}
} else if ("label".equals(local)) {
// assume xpath atomType/label
for (int i = 0; i < atts.getLength(); i++) {
if ("value".equals(atts.getQName(i))) {
if (atomType.getAtomTypeName() != null) {
atomType.setID(atomType.getAtomTypeName());
}
atomType.setAtomTypeName(atts.getValue(i));
}
}
} else if ("scalar".equals(local)) {
for (int i = 0; i < atts.getLength(); i++) {
if ("dictRef".equals(atts.getQName(i))) {
if ("cdk:maxBondOrder".equals(atts.getValue(i))) {
scalarType = SCALAR_MAXBONDORDER;
} else if ("cdk:bondOrderSum".equals(atts.getValue(i))) {
scalarType = SCALAR_BONDORDERSUM;
} else if ("cdk:hybridization".equals(atts.getValue(i))) {
scalarType = SCALAR_HYBRIDIZATION;
} else if ("cdk:formalNeighbourCount".equals(atts.getValue(i))) {
scalarType = SCALAR_FORMALNEIGHBOURCOUNT;
} else if ("cdk:valency".equals(atts.getValue(i))) {
scalarType = SCALAR_VALENCY;
} else if ("cdk:formalCharge".equals(atts.getValue(i))) {
scalarType = SCALAR_FORMALCHARGE;
} else if ("cdk:DA".equals(atts.getValue(i))) {
scalarType = SCALAR_DA;
} else if ("cdk:sphericalMatcher".equals(atts.getValue(i))) {
scalarType = SCALAR_SPHERICALMATCHER;
} else if ("cdk:ringSize".equals(atts.getValue(i))) {
scalarType = SCALAR_RINGSIZE;
} else if ("cdk:ringConstant".equals(atts.getValue(i))) {
scalarType = SCALAR_CHEMICALGROUPCONSTANT;
} else if ("cdk:aromaticAtom".equals(atts.getValue(i))) {
scalarType = SCALAR_ISAROMATIC;
} else if ("emboss:vdwrad".equals(atts.getValue(i))) {
scalarType = SCALAR_VANDERWAALSRADIUS;
} else if ("cdk:piBondCount".equals(atts.getValue(i))) {
scalarType = SCALAR_PIBONDCOUNT;
} else if ("cdk:lonePairCount".equals(atts.getValue(i))) {
scalarType = SCALAR_LONEPAIRCOUNT;
}
}
}
}
}
@TestMethod("testCharacters_arraychar_int_int")
public void characters(char chars[], int start, int length) {
logger.debug("character data");
currentChars += new String(chars, start, length);
}
}