001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.protmod.io; 022 023import org.biojava.nbio.protmod.ProteinModification; 024import org.biojava.nbio.protmod.ProteinModificationRegistry; 025import org.biojava.nbio.protmod.structure.*; 026import org.biojava.nbio.core.util.PrettyXMLWriter; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029import org.w3c.dom.Document; 030import org.w3c.dom.NamedNodeMap; 031import org.w3c.dom.Node; 032import org.w3c.dom.NodeList; 033import org.xml.sax.InputSource; 034import org.xml.sax.SAXException; 035import org.xml.sax.SAXParseException; 036 037import javax.xml.parsers.DocumentBuilder; 038import javax.xml.parsers.DocumentBuilderFactory; 039import java.io.IOException; 040import java.io.PrintWriter; 041import java.io.StringReader; 042import java.io.StringWriter; 043import java.util.*; 044 045public class ModifiedCompoundXMLConverter { 046 047 private static final Logger logger = LoggerFactory.getLogger(ModifiedCompoundXMLConverter.class); 048 049 public static String toXML(ModifiedCompound mc) throws IOException{ 050 051 if ( mc == null) { 052 logger.warn("ModifiedCompound == null! "); 053 return "<modifiedCompound/>"; 054 } 055 StringWriter out = new StringWriter(); 056 057 PrettyXMLWriter xml = new PrettyXMLWriter(new PrintWriter(out)); 058 059 ProteinModification protMod = mc.getModification(); 060 String modificationId = protMod==null?null:protMod.getId(); 061 062 xml.openTag("modifiedCompound"); 063 if ( modificationId != null) { 064// ProteinModificationXMLConverter.toXML(modification, xml); 065 xml.openTag("proteinModification"); 066 xml.attribute("id", modificationId); 067 xml.closeTag("proteinModification"); 068 } 069 070 071 Set<StructureAtomLinkage > linkages = mc.getAtomLinkages(); 072 if ( linkages.size() > 0 ) { 073 int pos = -1; 074 for ( StructureAtomLinkage link: linkages){ 075 pos ++; 076 xml.openTag("linkage"); 077 xml.attribute("pos", String.valueOf(pos)); 078 xml.attribute("total", String.valueOf(linkages.size())); 079 StructureAtom atom1 = link.getAtom1(); 080 StructureAtom atom2 = link.getAtom2(); 081 double distance = link.getDistance(); 082 083 xml.attribute("distance", String.valueOf(distance)); 084 xml.openTag("atom1"); 085 StructureAtomXMLConverter.toXML(atom1,xml); 086 xml.closeTag("atom1"); 087 xml.openTag("atom2"); 088 StructureAtomXMLConverter.toXML(atom2,xml); 089 xml.closeTag("atom2"); 090 xml.closeTag("linkage"); 091 } 092 } else { 093 // no linkages, need to serialize the residues... 094 xml.openTag("linkage"); 095 xml.closeTag("linkage"); 096 Set<StructureGroup> groups = mc.getGroups(); 097 for (StructureGroup group : groups) { 098 StructureGroupXMLConverter.toXML(group, xml); 099 } 100 } 101 102 103 104 105 xml.closeTag("modifiedCompound"); 106 return out.toString(); 107 } 108 109 public static ModifiedCompound fromXML(String xml){ 110 ProteinModification modification = null; 111 //Collection<StructureAtomLinkage> linkages = new ArrayList<StructureAtomLinkage>(); 112 StructureAtomLinkage[] linkages = null; 113 List<StructureGroup> structureGroups = new ArrayList<StructureGroup>(); 114 try 115 { 116 //Convert string to XML document 117 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 118 DocumentBuilder db = factory.newDocumentBuilder(); 119 InputSource inStream = new InputSource(); 120 inStream.setCharacterStream(new StringReader(xml)); 121 Document doc = db.parse(inStream); 122 123 // normalize text representation 124 doc.getDocumentElement().normalize(); 125 126 NodeList listOfmodifications = doc.getElementsByTagName("modifiedCompound"); 127 //int numArrays = listOfArrays.getLength(); 128 // go over the blocks 129 for(int modPos=0; modPos<listOfmodifications.getLength() ; modPos++) 130 { 131 132 Node modificationElement = listOfmodifications.item(modPos); 133 134 NodeList children = modificationElement.getChildNodes(); 135 136 int numChildren = children.getLength(); 137 138 139 for ( int e =0; e< numChildren ; e++){ 140 Node listOfConditions = children.item(e); 141 142 if(!listOfConditions.hasAttributes()) continue; 143 144 145 if ( listOfConditions.getNodeName().equals("proteinModification")) { 146 //modification = ProteinModificationXMLConverter.fromXML(listOfConditions); 147 String modId = getAttribute(listOfConditions, "id"); 148 modification = ProteinModificationRegistry.getById(modId); 149 if (modification==null) { 150 logger.warn("Error: no modification information."); 151 } 152 } else if ( listOfConditions.getNodeName().equals("linkage")) { 153 double dist = Double.parseDouble(getAttribute(listOfConditions, "distance")); 154 int pos = Integer.parseInt(getAttribute(listOfConditions,"pos")); 155 int total = Integer.parseInt(getAttribute(listOfConditions,"total")); 156 if ( linkages == null) 157 linkages = new StructureAtomLinkage[total]; 158 159 StructureAtom atom1 = getAtom("atom1", listOfConditions); 160 StructureAtom atom2 = getAtom("atom2",listOfConditions); 161 StructureAtomLinkage linkage = new StructureAtomLinkage(atom1, atom2, dist); 162 //linkages.add(linkage); 163 linkages[pos] = linkage; 164 } else if (listOfConditions.getNodeName().equals("structureGroup")) { 165 StructureGroup group = StructureGroupXMLConverter.fromXML(listOfConditions); 166 structureGroups.add(group); 167// logger.info("structureGroups size:" + structureGroups.size()); 168 } 169 } 170 } 171 } catch (SAXParseException err) { 172 logger.error("** Parsing error, line: {}, uri: {}", err.getLineNumber (), err.getSystemId (), err); 173 } 174 catch (SAXException e) { 175 logger.error("Exception: ", e); 176 } 177 catch (Throwable t) { 178 logger.error("Exception: ", t); 179 } 180 181 182 if ( linkages != null) { 183 Collection<StructureAtomLinkage> links = Arrays.asList(linkages); 184 return new ModifiedCompoundImpl(modification, links); 185 } else if ( structureGroups.size() == 1) { 186 return new ModifiedCompoundImpl(modification, structureGroups.get(0)); 187 } 188 return null; 189 190 } 191 192 193 194 private static StructureAtom getAtom(String elementName, Node n) { 195 196 NodeList children = n.getChildNodes(); 197 198 int numChildren = children.getLength(); 199 200 StructureAtom atom = null; 201 for ( int e =0; e< numChildren ; e++){ 202 Node atoms = children.item(e); 203 204 if ( atoms.getNodeName().equals(elementName)) { 205 NodeList child2 = atoms.getChildNodes(); 206 int numAtoms = child2.getLength(); 207 //logger.info("got " + numAtoms + " atoms"); 208 for ( int a=0;a< numAtoms; a++){ 209 Node atomNode = child2.item(a); 210 if(!atomNode.hasAttributes()) continue; 211 atom = StructureAtomXMLConverter.fromXML(atomNode); 212 return atom; 213 } 214 215 } 216 } 217 return atom; 218 } 219 220 private static String getAttribute(Node node, String attr){ 221 if( ! node.hasAttributes()) 222 return null; 223 224 NamedNodeMap atts = node.getAttributes(); 225 226 if ( atts == null) 227 return null; 228 229 Node att = atts.getNamedItem(attr); 230 if ( att == null) 231 return null; 232 233 String value = att.getTextContent(); 234 235 return value; 236 237 } 238 239}