/* VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases. Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty. electronic mail : Yann.Ponty@lri.fr paper mail : LRI, bat 490 Universit� Paris-Sud 91405 Orsay Cedex France This file is part of VARNA version 3.1. VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. VARNA version 3.1 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 General Public License for more details. You should have received a copy of the GNU General Public License along with VARNA version 3.1. If not, see http://www.gnu.org/licenses. */ package fr.orsay.lri.varna.utils; import java.awt.Color; import java.awt.Font; import java.awt.Point; import java.awt.geom.Point2D; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.URL; import java.net.URLConnection; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.List; import java.util.Stack; import java.util.TreeSet; import java.util.Vector; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import fr.orsay.lri.varna.VARNAPanel; import fr.orsay.lri.varna.models.VARNAConfig; import fr.orsay.lri.varna.models.annotations.ChemProbAnnotation; import fr.orsay.lri.varna.models.annotations.ChemProbAnnotation.ChemProbAnnotationType; import fr.orsay.lri.varna.models.annotations.HighlightRegionAnnotation; import fr.orsay.lri.varna.models.annotations.TextAnnotation; import fr.orsay.lri.varna.models.annotations.TextAnnotation.AnchorType; import fr.orsay.lri.varna.models.rna.ModeleBP; import fr.orsay.lri.varna.models.rna.ModeleBP.Edge; import fr.orsay.lri.varna.models.rna.ModeleBP.Stericity; import fr.orsay.lri.varna.models.rna.ModeleBPStyle; import fr.orsay.lri.varna.models.rna.ModeleBackbone; import fr.orsay.lri.varna.models.rna.ModeleBackboneElement; import fr.orsay.lri.varna.models.rna.ModeleBase; import fr.orsay.lri.varna.models.rna.ModeleBaseNucleotide; import fr.orsay.lri.varna.models.rna.ModeleBasesComparison; import fr.orsay.lri.varna.models.rna.ModelBaseStyle; import fr.orsay.lri.varna.models.rna.RNA; import fr.orsay.lri.varna.models.rna.VARNAPoint; public class VARNASessionParser extends DefaultHandler { StringBuffer _buffer = null; ModeleBaseNucleotide mbn = null; ModeleBasesComparison mbc = null; ModeleBP mbp = null; ModeleBPStyle mbps = null; ModelBaseStyle msb = null; TextAnnotation ta = null; ModeleBackbone backbone = null; HighlightRegionAnnotation hra = null; RNA rna = null; Font f = null; VARNAConfig config = null; public VARNASessionParser() { super(); } public InputSource createSourceFromURL(String path) { URL url = null; try { url = new URL(path); URLConnection connexion = url.openConnection(); connexion.setUseCaches(false); InputStream r = connexion.getInputStream(); InputStreamReader inr = new InputStreamReader(r); return new InputSource(inr); } catch(Exception e) { e.printStackTrace(); } return new InputSource(new StringReader("")); } public InputSource resolveEntity(String publicId, String systemId) { return new InputSource(new StringReader("")); } private TreeSet _context = new TreeSet(); private void addToContext(String s) { _context.add(s); } private void removeFromContext(String s) { _context.remove(s); } private boolean contextContains(String s) { return _context.contains(s); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equals(VARNAPanel.XML_ELEMENT_NAME)) { } else if (qName.equals(VARNAConfig.XML_ELEMENT_NAME)){ config = new VARNAConfig(); config.loadFromXMLAttributes(attributes); } else if (qName.equals(RNA.XML_ELEMENT_NAME)){ rna = new RNA(); int mode = Integer.parseInt(attributes.getValue(RNA.XML_VAR_DRAWN_MODE_NAME)); rna.setDrawMode(mode); } else if (qName.equals(ModeleBackbone.XML_ELEMENT_NAME)){ backbone = new ModeleBackbone(); rna.setBackbone(backbone); } else if (qName.equals(ModeleBackboneElement.XML_ELEMENT_NAME)){ if (backbone!=null){ int index = Integer.parseInt(attributes.getValue(ModeleBackboneElement.XML_VAR_INDEX_NAME)); ModeleBackboneElement.BackboneType type = ModeleBackboneElement.BackboneType.getType( (attributes.getValue(ModeleBackboneElement.XML_VAR_TYPE_NAME))); Color c = null; if (type == ModeleBackboneElement.BackboneType.CUSTOM_COLOR) { c = Color.decode(attributes.getValue(TextAnnotation.XML_VAR_COLOR_NAME)); backbone.addElement(new ModeleBackboneElement(index, c)); } else { backbone.addElement(new ModeleBackboneElement(index, type)); } } } else if (qName.equals(ModeleBackbone.XML_ELEMENT_NAME)){ backbone = new ModeleBackbone(); } else if (qName.equals(ModeleBaseNucleotide.XML_ELEMENT_NAME)){ if (rna!=null){ mbn = new ModeleBaseNucleotide(rna.getSize()); if (mbn.getIndex()!=Integer.parseInt(attributes.getValue(ModeleBase.XML_VAR_INDEX_NAME))) throw new SAXException("Index mismatch for Base"); mbn.setBaseNumber(Integer.parseInt(attributes.getValue(ModeleBase.XML_VAR_NUMBER_NAME))); mbn.setLabel(attributes.getValue(ModeleBase.XML_VAR_LABEL_NAME)); mbn.setColorie(Boolean.parseBoolean(attributes.getValue(ModeleBase.XML_VAR_CUSTOM_DRAWN_NAME))); mbn.setValue(Double.parseDouble(attributes.getValue(ModeleBase.XML_VAR_VALUE_NAME))); rna.addBase(mbn); } } else if (qName.equals(XMLUtils.XML_FONT_ELEMENT_NAME)){ f = XMLUtils.getFont(qName,attributes); if (contextContains(TextAnnotation.XML_ELEMENT_NAME)) { ta.setFont(f); f=null; } else if (contextContains(VARNAConfig.XML_ELEMENT_NAME)) { String role = attributes.getValue(XMLUtils.XML_ROLE_NAME); if (role.equals(VARNAConfig.XML_VAR_TITLE_FONT)) { config._titleFont = XMLUtils.getFont(qName, attributes); } else if (role.equals(VARNAConfig.XML_VAR_NUMBERS_FONT)) { config._numbersFont = XMLUtils.getFont(qName, attributes); } else if (role.equals(VARNAConfig.XML_VAR_FONT_BASES)) { config._fontBasesGeneral = XMLUtils.getFont(qName, attributes); } } } else if (qName.equals(ModeleBaseNucleotide.XML_VAR_CONTENT_NAME)){ _buffer = new StringBuffer(); } else if (qName.equals(ModeleBasesComparison.XML_VAR_FIRST_CONTENT_NAME)){ _buffer = new StringBuffer(); } else if (qName.equals(ModeleBasesComparison.XML_VAR_SECOND_CONTENT_NAME)){ _buffer = new StringBuffer(); } else if (qName.equals(ModeleBasesComparison.XML_ELEMENT_NAME)){ if (rna!=null){ mbc = new ModeleBasesComparison(rna.getSize()); if (mbc.getIndex()!=Integer.parseInt(attributes.getValue(ModeleBase.XML_VAR_INDEX_NAME))) throw new SAXException("Index mismatch for Base"); mbc.setBaseNumber(Integer.parseInt(attributes.getValue(ModeleBase.XML_VAR_NUMBER_NAME))); mbc.setLabel(attributes.getValue(ModeleBase.XML_VAR_LABEL_NAME)); mbc.set_appartenance(Integer.parseInt(attributes.getValue(ModeleBasesComparison.XML_VAR_MEMBERSHIP_NAME))); mbc.setColorie(Boolean.parseBoolean(attributes.getValue(ModeleBase.XML_VAR_CUSTOM_DRAWN_NAME))); mbc.setValue(Double.parseDouble(attributes.getValue(ModeleBase.XML_VAR_VALUE_NAME))); rna.addBase(mbc); } } else if (qName.equals(RNA.XML_VAR_NAME_NAME)) { if (rna!=null){ _buffer = new StringBuffer(); } } else if (qName.equals(ModeleBP.XML_ELEMENT_NAME)) { Edge e5 = Edge.valueOf(attributes.getValue(ModeleBP.XML_VAR_EDGE5_NAME)); Edge e3 = Edge.valueOf(attributes.getValue(ModeleBP.XML_VAR_EDGE3_NAME)); Stericity s = Stericity.valueOf(attributes.getValue(ModeleBP.XML_VAR_STERICITY_NAME)); int i5 = Integer.parseInt(attributes.getValue(ModeleBP.XML_VAR_PARTNER5_NAME)); int i3 = Integer.parseInt(attributes.getValue(ModeleBP.XML_VAR_PARTNER3_NAME)); boolean inSecStr = Boolean.parseBoolean(attributes.getValue(ModeleBP.XML_VAR_SEC_STR_NAME)); mbp = new ModeleBP(rna.getBaseAt(i5),rna.getBaseAt(i3),e5,e3,s); if (inSecStr) rna.addBP(i5,i3,mbp); else rna.addBPAux(i5,i3,mbp); } else if (qName.equals(ChemProbAnnotation.XML_ELEMENT_NAME)) { int i5 = Integer.parseInt(attributes.getValue(ChemProbAnnotation.XML_VAR_INDEX5_NAME)); int i3 = Integer.parseInt(attributes.getValue(ChemProbAnnotation.XML_VAR_INDEX3_NAME)); ChemProbAnnotation cpa = new ChemProbAnnotation(rna.getBaseAt(i5),rna.getBaseAt(i3)); cpa.setColor(Color.decode(attributes.getValue(ChemProbAnnotation.XML_VAR_COLOR_NAME))); cpa.setIntensity(Double.parseDouble(attributes.getValue(ChemProbAnnotation.XML_VAR_INTENSITY_NAME))); cpa.setType(ChemProbAnnotationType.valueOf(attributes.getValue(ChemProbAnnotation.XML_VAR_TYPE_NAME))); cpa.setOut(Boolean.parseBoolean(attributes.getValue(ChemProbAnnotation.XML_VAR_OUTWARD_NAME))); rna.addChemProbAnnotation(cpa); } else if (qName.equals(TextAnnotation.XML_VAR_TEXT_NAME)){ _buffer = new StringBuffer(); } else if (qName.equals(VARNAConfig.XML_VAR_TITLE)){ _buffer = new StringBuffer(); } else if (qName.equals(VARNAConfig.XML_VAR_CM_CAPTION)){ _buffer = new StringBuffer(); } else if (qName.equals(TextAnnotation.XML_ELEMENT_NAME)) { AnchorType t = AnchorType.valueOf(attributes.getValue(TextAnnotation.XML_VAR_TYPE_NAME)); ta = new TextAnnotation(""); ta.setColor(Color.decode(attributes.getValue(TextAnnotation.XML_VAR_COLOR_NAME))); ta.setAngleInDegres(Double.parseDouble(attributes.getValue(TextAnnotation.XML_VAR_ANGLE_NAME))); ta.setType(t); } else if (qName.equals(HighlightRegionAnnotation.XML_ELEMENT_NAME)) { hra = new HighlightRegionAnnotation(); rna.addHighlightRegion(hra); hra.setOutlineColor(Color.decode(attributes.getValue(HighlightRegionAnnotation.XML_VAR_OUTLINE_NAME))); hra.setFillColor(Color.decode(attributes.getValue(HighlightRegionAnnotation.XML_VAR_FILL_NAME))); hra.setRadius(Double.parseDouble(attributes.getValue(HighlightRegionAnnotation.XML_VAR_RADIUS_NAME))); } else if (qName.equals(XMLUtils.XML_BASELIST_ELEMENT_NAME)) { _buffer = new StringBuffer(); } else if (qName.equals(VARNAPoint.XML_ELEMENT_NAME)) { Point2D.Double vp = new Point2D.Double(); vp.x = Double.parseDouble(attributes.getValue(VARNAPoint.XML_VAR_X_NAME)); vp.y = Double.parseDouble(attributes.getValue(VARNAPoint.XML_VAR_Y_NAME)); String role = attributes.getValue(VARNAPoint.XML_VAR_ROLE_NAME); if (contextContains(ModeleBaseNucleotide.XML_ELEMENT_NAME)) { if (role != null) { if (role.equals(ModeleBase.XML_VAR_POSITION_NAME)) { if (mbn!=null) { mbn.setCoords(vp); } else throw new SAXException("No Base model for this position Point"); } else if (role.equals(ModeleBase.XML_VAR_CENTER_NAME)) { if (mbn!=null) { mbn.setCenter(vp); } else throw new SAXException("No Base model for this center Point"); } } } if (contextContains(ModeleBasesComparison.XML_ELEMENT_NAME)) { if (role != null) { if (role.equals(ModeleBase.XML_VAR_POSITION_NAME)) { if (mbc!=null) { mbc.setCoords(vp); } else throw new SAXException("No Base model for this position Point"); } else if (role.equals(ModeleBase.XML_VAR_CENTER_NAME)) { if (mbc!=null) { mbc.setCenter(vp); } else throw new SAXException("No Base model for this center Point"); } } } if (contextContains(TextAnnotation.XML_ELEMENT_NAME)) { if (ta!=null) ta.setAncrage(vp.x,vp.y); else throw new SAXException("No TextAnnotation model for this Point"); } } else if (qName.equals(ModelBaseStyle.XML_ELEMENT_NAME)) { msb = new ModelBaseStyle(); msb.setBaseOutlineColor(Color.decode(attributes.getValue(ModelBaseStyle.XML_VAR_OUTLINE_NAME))); msb.setBaseInnerColor(Color.decode(attributes.getValue(ModelBaseStyle.XML_VAR_INNER_NAME))); msb.setBaseNameColor(Color.decode(attributes.getValue(ModelBaseStyle.XML_VAR_NAME_NAME))); msb.setBaseNumberColor(Color.decode(attributes.getValue(ModelBaseStyle.XML_VAR_NUMBER_NAME))); if (mbn!=null) { mbn.setStyleBase(msb); } else if (mbc!=null) { mbc.setStyleBase(msb); } msb = null; } else if (qName.equals(ModeleBPStyle.XML_ELEMENT_NAME)) { mbps = new ModeleBPStyle(); boolean customColor = Boolean.parseBoolean(attributes.getValue(ModeleBPStyle.XML_VAR_CUSTOM_STYLED_NAME)); if (customColor) mbps.setCustomColor(Color.decode(attributes.getValue(ModeleBPStyle.XML_VAR_COLOR_NAME))); mbps.setThickness(Double.parseDouble(attributes.getValue(ModeleBPStyle.XML_VAR_THICKNESS_NAME))); mbps.setBent(Double.parseDouble(attributes.getValue(ModeleBPStyle.XML_VAR_BENT_NAME))); if (mbp!=null) { mbp.setStyle(mbps); } mbps = null; } addToContext(qName); } public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equals(ModeleBaseNucleotide.XML_VAR_CONTENT_NAME)){ if (_buffer==null){ throw new SAXException("Invalid location for tag "+ModeleBaseNucleotide.XML_VAR_CONTENT_NAME); } if (mbn==null){ throw new SAXException("Invalid location for tag "+ModeleBaseNucleotide.XML_VAR_CONTENT_NAME); } String val = _buffer.toString(); mbn.setContent(val); } else if (qName.equals(ModeleBasesComparison.XML_VAR_FIRST_CONTENT_NAME)){ if (_buffer==null){ throw new SAXException("Invalid location for tag "+ModeleBaseNucleotide.XML_VAR_CONTENT_NAME); } if (mbc==null){ throw new SAXException("Invalid location for tag "+ModeleBaseNucleotide.XML_VAR_CONTENT_NAME); } String val = _buffer.toString(); mbc.setBase1(val.trim().charAt(0)); } else if (qName.equals(ModeleBasesComparison.XML_VAR_SECOND_CONTENT_NAME)){ if (_buffer==null){ throw new SAXException("Invalid location for tag "+ModeleBaseNucleotide.XML_VAR_CONTENT_NAME); } if (mbc==null){ throw new SAXException("Invalid location for tag "+ModeleBaseNucleotide.XML_VAR_CONTENT_NAME); } String val = _buffer.toString(); mbc.setBase2(val.trim().charAt(0)); } else if (qName.equals(ModeleBaseNucleotide.XML_ELEMENT_NAME)){ mbn = null; } else if (qName.equals(ModeleBP.XML_ELEMENT_NAME)) { mbp = null; } else if (qName.equals(HighlightRegionAnnotation.XML_ELEMENT_NAME)) { hra = null; } else if (qName.equals(TextAnnotation.XML_VAR_TEXT_NAME)) { String text = _buffer.toString(); ta.setText(text); _buffer = null; } else if (qName.equals(RNA.XML_VAR_NAME_NAME)) { if (rna!=null){ rna.setName(_buffer.toString()); _buffer = null; } } else if (qName.equals(VARNAConfig.XML_VAR_CM_CAPTION)){ config._colorMapCaption = _buffer.toString(); _buffer = null; } else if (qName.equals(TextAnnotation.XML_ELEMENT_NAME)) { rna.addAnnotation(ta); ta = null; } else if (qName.equals(XMLUtils.XML_BASELIST_ELEMENT_NAME)) { String result = _buffer.toString(); ArrayList al = XMLUtils.toModeleBaseArray(result, rna); if (contextContains(TextAnnotation.XML_ELEMENT_NAME)) { switch(ta.getType()) { case POSITION: break; case BASE: ta.setAncrage(al.get(0)); break; case HELIX: case LOOP: try { ta.setAncrage(al, ta.getType()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } break; default: } } if (contextContains(HighlightRegionAnnotation.XML_ELEMENT_NAME)) { hra.setBases(al); } _buffer = null; } removeFromContext(qName); } public void characters(char[] ch, int start, int length) throws SAXException { String lecture = new String(ch, start, length); if (_buffer != null) _buffer.append(lecture); } public void startDocument() throws SAXException { } public void endDocument() throws SAXException { } public RNA getRNA() { return rna; } public VARNAConfig getVARNAConfig() { return config; } }