/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.nbio.protmod.io; import org.biojava.nbio.protmod.ProteinModification; import org.biojava.nbio.protmod.ProteinModificationRegistry; import org.biojava.nbio.protmod.structure.*; import org.biojava.nbio.core.util.PrettyXMLWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import java.io.IOException; import java.io.PrintWriter; import java.io.StringReader; import java.io.StringWriter; import java.util.*; public class ModifiedCompoundXMLConverter { private static final Logger logger = LoggerFactory.getLogger(ModifiedCompoundXMLConverter.class); public static String toXML(ModifiedCompound mc) throws IOException{ if ( mc == null) { logger.warn("ModifiedCompound == null! "); return "<modifiedCompound/>"; } StringWriter out = new StringWriter(); PrettyXMLWriter xml = new PrettyXMLWriter(new PrintWriter(out)); ProteinModification protMod = mc.getModification(); String modificationId = protMod==null?null:protMod.getId(); xml.openTag("modifiedCompound"); if ( modificationId != null) { // ProteinModificationXMLConverter.toXML(modification, xml); xml.openTag("proteinModification"); xml.attribute("id", modificationId); xml.closeTag("proteinModification"); } Set<StructureAtomLinkage > linkages = mc.getAtomLinkages(); if ( linkages.size() > 0 ) { int pos = -1; for ( StructureAtomLinkage link: linkages){ pos ++; xml.openTag("linkage"); xml.attribute("pos", String.valueOf(pos)); xml.attribute("total", String.valueOf(linkages.size())); StructureAtom atom1 = link.getAtom1(); StructureAtom atom2 = link.getAtom2(); double distance = link.getDistance(); xml.attribute("distance", String.valueOf(distance)); xml.openTag("atom1"); StructureAtomXMLConverter.toXML(atom1,xml); xml.closeTag("atom1"); xml.openTag("atom2"); StructureAtomXMLConverter.toXML(atom2,xml); xml.closeTag("atom2"); xml.closeTag("linkage"); } } else { // no linkages, need to serialize the residues... xml.openTag("linkage"); xml.closeTag("linkage"); Set<StructureGroup> groups = mc.getGroups(); for (StructureGroup group : groups) { StructureGroupXMLConverter.toXML(group, xml); } } xml.closeTag("modifiedCompound"); return out.toString(); } public static ModifiedCompound fromXML(String xml){ ProteinModification modification = null; //Collection<StructureAtomLinkage> linkages = new ArrayList<StructureAtomLinkage>(); StructureAtomLinkage[] linkages = null; List<StructureGroup> structureGroups = new ArrayList<StructureGroup>(); try { //Convert string to XML document DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder db = factory.newDocumentBuilder(); InputSource inStream = new InputSource(); inStream.setCharacterStream(new StringReader(xml)); Document doc = db.parse(inStream); // normalize text representation doc.getDocumentElement().normalize(); NodeList listOfmodifications = doc.getElementsByTagName("modifiedCompound"); //int numArrays = listOfArrays.getLength(); // go over the blocks for(int modPos=0; modPos<listOfmodifications.getLength() ; modPos++) { Node modificationElement = listOfmodifications.item(modPos); NodeList children = modificationElement.getChildNodes(); int numChildren = children.getLength(); for ( int e =0; e< numChildren ; e++){ Node listOfConditions = children.item(e); if(!listOfConditions.hasAttributes()) continue; if ( listOfConditions.getNodeName().equals("proteinModification")) { //modification = ProteinModificationXMLConverter.fromXML(listOfConditions); String modId = getAttribute(listOfConditions, "id"); modification = ProteinModificationRegistry.getById(modId); if (modification==null) { logger.warn("Error: no modification information."); } } else if ( listOfConditions.getNodeName().equals("linkage")) { double dist = Double.parseDouble(getAttribute(listOfConditions, "distance")); int pos = Integer.parseInt(getAttribute(listOfConditions,"pos")); int total = Integer.parseInt(getAttribute(listOfConditions,"total")); if ( linkages == null) linkages = new StructureAtomLinkage[total]; StructureAtom atom1 = getAtom("atom1", listOfConditions); StructureAtom atom2 = getAtom("atom2",listOfConditions); StructureAtomLinkage linkage = new StructureAtomLinkage(atom1, atom2, dist); //linkages.add(linkage); linkages[pos] = linkage; } else if (listOfConditions.getNodeName().equals("structureGroup")) { StructureGroup group = StructureGroupXMLConverter.fromXML(listOfConditions); structureGroups.add(group); // logger.info("structureGroups size:" + structureGroups.size()); } } } } catch (SAXParseException err) { logger.error("** Parsing error, line: {}, uri: {}", err.getLineNumber (), err.getSystemId (), err); } catch (SAXException e) { logger.error("Exception: ", e); } catch (Throwable t) { logger.error("Exception: ", t); } if ( linkages != null) { Collection<StructureAtomLinkage> links = Arrays.asList(linkages); return new ModifiedCompoundImpl(modification, links); } else if ( structureGroups.size() == 1) { return new ModifiedCompoundImpl(modification, structureGroups.get(0)); } return null; } private static StructureAtom getAtom(String elementName, Node n) { NodeList children = n.getChildNodes(); int numChildren = children.getLength(); StructureAtom atom = null; for ( int e =0; e< numChildren ; e++){ Node atoms = children.item(e); if ( atoms.getNodeName().equals(elementName)) { NodeList child2 = atoms.getChildNodes(); int numAtoms = child2.getLength(); //logger.info("got " + numAtoms + " atoms"); for ( int a=0;a< numAtoms; a++){ Node atomNode = child2.item(a); if(!atomNode.hasAttributes()) continue; atom = StructureAtomXMLConverter.fromXML(atomNode); return atom; } } } return atom; } private static String getAttribute(Node node, String attr){ if( ! node.hasAttributes()) return null; NamedNodeMap atts = node.getAttributes(); if ( atts == null) return null; Node att = atts.getNamedItem(attr); if ( att == null) return null; String value = att.getTextContent(); return value; } }