ad0c5c1ee84b877db073f1d493546ba040209d1f
[jalview.git] / src2 / fr / orsay / lri / varna / models / rna / ModeleBaseNucleotide.java
1 /*
2  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.
3  Copyright (C) 2008  Kevin Darty, Alain Denise and Yann Ponty.
4  electronic mail : Yann.Ponty@lri.fr
5  paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
6
7  This file is part of VARNA version 3.1.
8  VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9  as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
10
11  VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  See the GNU General Public License for more details.
14
15  You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16  If not, see http://www.gnu.org/licenses.
17  */
18 package fr.orsay.lri.varna.models.rna;
19
20 import java.awt.geom.Point2D;
21 import java.util.HashMap;
22
23 import javax.xml.transform.sax.TransformerHandler;
24
25 import org.xml.sax.SAXException;
26 import org.xml.sax.helpers.AttributesImpl;
27
28 import fr.orsay.lri.varna.utils.XMLUtils;
29
30
31 /**
32  * The rna base model with the first character of the nitrogenous base and it
33  * display
34  * 
35  * @author darty
36  * 
37  */
38 public class ModeleBaseNucleotide extends ModeleBase {
39
40         /**
41          * 
42          */
43         private static final long serialVersionUID = -5493938366569588113L;
44         private String _c;
45         private int _index;
46         
47
48         
49         public static String XML_ELEMENT_NAME = "nt";
50         public static String XML_VAR_CONTENT_NAME = "base";
51         
52         
53         public void toXML(TransformerHandler hd) throws SAXException
54         {
55                 AttributesImpl atts = new AttributesImpl();
56                 atts.addAttribute("","",XML_VAR_INDEX_NAME,"CDATA",""+_index);
57                 atts.addAttribute("","",XML_VAR_NUMBER_NAME,"CDATA",""+_realIndex);
58                 atts.addAttribute("","",XML_VAR_CUSTOM_DRAWN_NAME,"CDATA",""+_colorie);
59                 atts.addAttribute("","",XML_VAR_VALUE_NAME,"CDATA",""+_value);
60                 atts.addAttribute("","",XML_VAR_LABEL_NAME,"CDATA",""+_label);
61                 hd.startElement("","",XML_ELEMENT_NAME,atts);
62                 atts.clear();
63                 hd.startElement("","",XML_VAR_CONTENT_NAME,atts);
64                 XMLUtils.exportCDATAString(hd, _c);
65                 hd.endElement("","",XML_VAR_CONTENT_NAME);
66
67                 _coords.toXML(hd,XML_VAR_POSITION_NAME);
68                 _center.toXML(hd,XML_VAR_CENTER_NAME);
69                 if (_colorie)
70                 { _styleBase.toXML(hd); }
71                 hd.endElement("","",XML_ELEMENT_NAME);
72         }
73
74         /**
75          * Creates a new rna base with the default display style and a space as
76          * nitrogenous base
77          * @param index The index of this base
78          */
79         public ModeleBaseNucleotide(int index) {
80                 this(" ", index);
81         }
82
83         /**
84          * Creates a new rna base with the nitrogenous base
85          * 
86          * @param s
87          *            The code of this base
88          * @param index The index of this base
89          */
90         public ModeleBaseNucleotide(String s, int index) {
91                 this(s, new ModelBaseStyle(), index);
92         }
93
94
95         /**
96          * Creates a new rna base with the nitrogenous base
97          * 
98          * @param s
99          *            The full label, potentially requiring further decoding
100          * @param index The index of this base
101          * @param baseNumber The number of this base, which may differ from the index (e.g. discontinuous numbering)
102          */
103         public ModeleBaseNucleotide(String s, int index, int baseNumber) {
104                 this(s, new ModelBaseStyle(), index);
105                 _realIndex = baseNumber;
106         }
107
108         /**
109          * Creates a new rna base with the nitrogenous base and the display style
110          * 
111          * @param s
112          *            The full label, potentially requiring further decoding
113          * @param msb
114          *            The display style
115          * @param index The index of this base
116          */
117         public ModeleBaseNucleotide(String s, ModelBaseStyle msb, int index) {
118                 this(new Point2D.Double(), new Point2D.Double(), true, s, msb, -1,
119                                 index);
120         }
121
122         /**
123          * Creates a new rna base with a display style
124          * 
125          * @param msb
126          *            The display style
127          */
128         public ModeleBaseNucleotide(ModelBaseStyle msb, int index, int baseNumber) {
129                 this("", msb, index);
130                 _realIndex = baseNumber;
131         }
132
133         /**
134          * Creates a new rna base with a space as the nitrogenous base and the
135          * display style
136          * 
137          * @param coord
138          * @param index
139          */
140         public ModeleBaseNucleotide(Point2D.Double coord, int index) {
141                 this(new Point2D.Double(coord.getX(), coord.getY()),
142                                 new Point2D.Double(), true, "", new ModelBaseStyle(), -1,
143                                 index);
144         }
145
146         /**
147          * Creates a new rna base from another one with the same attributes
148          * 
149          * @param mb
150          *            The base to copy
151          */
152         public ModeleBaseNucleotide(ModeleBaseNucleotide mb, int index) {
153                 this(
154                                 new Point2D.Double(mb.getCoords().getX(), mb.getCoords()
155                                                 .getY()), new Point2D.Double(mb.getCenter().getX(), mb
156                                                 .getCenter().getY()), true, mb.getBase(), mb
157                                                 .getStyleBase(), mb.getElementStructure(), index);
158         }
159
160         public ModeleBaseNucleotide(Point2D.Double coords, Point2D.Double center,
161                         boolean colorie, String label, ModelBaseStyle mb, int elementStruct,
162                         int index) {
163                 _colorie = colorie;
164                 _c = label;
165                 _styleBase = mb;
166                 _coords = new VARNAPoint(coords);
167                 _center = new VARNAPoint(center);
168                 _index = index;
169                 _realIndex = index + 1;
170                 _value = 0.0;
171         }
172
173         
174         public ModelBaseStyle getStyleBase() {
175                 if (_colorie)
176                         return _styleBase;
177                 return new ModelBaseStyle();
178         }
179
180         public String getBase() {
181                 return decode(_c);
182         }
183
184         public void setBase(String _s) {
185                 this._c = _s;
186         }
187
188
189
190         public String getContent() {
191                 return getBase();
192         }
193
194         public void setContent(String s) {
195                 setBase(s);
196         }
197
198         public int getIndex() {
199                 return _index;
200         }
201         
202         public String toString()
203         {
204                 return ""+this._realIndex+" ("+_index+") (x,y):"+this._coords +" C:"+_center;
205         }
206
207         
208         private enum STATE_SPECIAL_CHARS_STATES{ NORMAL,SUBSCRIPT, SUPERSCRIPT, COMMAND};
209
210         private static HashMap<Character,Character> _subscripts = new HashMap<Character,Character>();
211         private static HashMap<Character,Character> _superscripts = new HashMap<Character,Character>();
212         private static HashMap<String,Character> _commands = new HashMap<String,Character>();
213         {
214                 _subscripts.put('0', '\u2080');
215                 _subscripts.put('1', '\u2081');
216                 _subscripts.put('2', '\u2082');
217                 _subscripts.put('3', '\u2083');
218                 _subscripts.put('4', '\u2084');
219                 _subscripts.put('5', '\u2085');
220                 _subscripts.put('6', '\u2086');
221                 _subscripts.put('7', '\u2087');
222                 _subscripts.put('8', '\u2088');
223                 _subscripts.put('9', '\u2089');
224                 _subscripts.put('+', '\u208A');
225                 _subscripts.put('-', '\u208B');
226                 _subscripts.put('a', '\u2090');
227                 _subscripts.put('e', '\u2091');
228                 _subscripts.put('o', '\u2092');
229                 _subscripts.put('i', '\u1D62');
230                 _subscripts.put('r', '\u1D63');
231                 _subscripts.put('u', '\u1D64');
232                 _subscripts.put('v', '\u1D65');
233                 _subscripts.put('x', '\u2093');
234                 _superscripts.put('0', '\u2070');
235                 _superscripts.put('1', '\u00B9');
236                 _superscripts.put('2', '\u00B2');
237                 _superscripts.put('3', '\u00B3');
238                 _superscripts.put('4', '\u2074');
239                 _superscripts.put('5', '\u2075');
240                 _superscripts.put('6', '\u2076');
241                 _superscripts.put('7', '\u2077');
242                 _superscripts.put('8', '\u2078');
243                 _superscripts.put('9', '\u2079');
244                 _superscripts.put('+', '\u207A');
245                 _superscripts.put('-', '\u207B');
246                 _superscripts.put('i', '\u2071');
247                 _superscripts.put('n', '\u207F');
248                 _commands.put("alpha",  '\u03B1');
249                 _commands.put("beta",   '\u03B2');
250                 _commands.put("gamma",  '\u03B3');
251                 _commands.put("delta",  '\u03B4');
252                 _commands.put("epsilon",'\u03B5');
253                 _commands.put("zeta",   '\u03B6');
254                 _commands.put("eta",    '\u03B7');
255                 _commands.put("theta",  '\u03B8');
256                 _commands.put("iota",   '\u03B9');
257                 _commands.put("kappa",  '\u03BA');
258                 _commands.put("lambda", '\u03BB');
259                 _commands.put("mu",     '\u03BC');
260                 _commands.put("nu",     '\u03BD');
261                 _commands.put("xi",     '\u03BE');
262                 _commands.put("omicron",'\u03BF');
263                 _commands.put("pi",     '\u03C1');
264                 _commands.put("rho",    '\u03C2');
265                 _commands.put("sigma",  '\u03C3');
266                 _commands.put("tau",    '\u03C4');
267                 _commands.put("upsilon",'\u03C5');
268                 _commands.put("phi",    '\u03C6');
269                 _commands.put("chi",    '\u03C7');
270                 _commands.put("psi",    '\u03C8');
271                 _commands.put("omega",  '\u03C9');
272                 _commands.put("Psi",    '\u03A8');
273                 _commands.put("Phi",    '\u03A6');
274                 _commands.put("Sigma",  '\u03A3');
275                 _commands.put("Pi",     '\u03A0');
276                 _commands.put("Theta",  '\u0398');
277                 _commands.put("Omega",  '\u03A9');
278                 _commands.put("Gamma",  '\u0393');
279                 _commands.put("Delta",  '\u0394');
280                 _commands.put("Lambda", '\u039B');
281         }
282
283         
284         
285         private static String decode(String s)
286         {
287                 if (s.length()<=1)
288                 {
289                         return s;
290                 }
291                 STATE_SPECIAL_CHARS_STATES state = STATE_SPECIAL_CHARS_STATES.NORMAL;
292                 
293                 String result = "";
294                 String buffer = ""; 
295                 for(int i=0;i<s.length();i++)
296                 {
297                         char c = s.charAt(i);
298                         switch (state)
299                         {
300                                 case NORMAL:
301                                 {
302                                         switch(c)
303                                         {
304                                                 case '_':
305                                                         state = STATE_SPECIAL_CHARS_STATES.SUBSCRIPT;
306                                                 break;
307                                                 case '^':
308                                                         state = STATE_SPECIAL_CHARS_STATES.SUPERSCRIPT;
309                                                 break;
310                                                 case '\\':
311                                                         buffer = "";
312                                                         state = STATE_SPECIAL_CHARS_STATES.COMMAND;
313                                                 break;
314                                                 default:
315                                                         result += c;
316                                                         state = STATE_SPECIAL_CHARS_STATES.NORMAL;
317                                                 break;
318                                         }
319                                 }
320                                 break;
321                                 case SUBSCRIPT:
322                                 case SUPERSCRIPT:
323                                 {
324                                         switch(c)
325                                         {
326                                                 case '_':
327                                                         state = STATE_SPECIAL_CHARS_STATES.SUBSCRIPT;
328                                                 break;
329                                                 case '^':
330                                                         state = STATE_SPECIAL_CHARS_STATES.SUPERSCRIPT;
331                                                 break;
332                                                 case '\\':
333                                                         buffer = "";
334                                                         state = STATE_SPECIAL_CHARS_STATES.COMMAND;
335                                                 break;
336                                                 default:
337                                                         if ((state==STATE_SPECIAL_CHARS_STATES.SUBSCRIPT) && _subscripts.containsKey(c))
338                                                                 result += _subscripts.get(c); 
339                                                         else if ((state==STATE_SPECIAL_CHARS_STATES.SUPERSCRIPT) && _superscripts.containsKey(c))
340                                                                 result += _superscripts.get(c); 
341                                                         else
342                                                                 result += c;
343                                                         state = STATE_SPECIAL_CHARS_STATES.NORMAL;
344                                                 break;
345                                         }
346                                 }
347                                 break;
348                                 case COMMAND:
349                                 {
350                                         switch(c)
351                                         {
352                                                 case '_':
353                                                         if (_commands.containsKey(buffer))
354                                                         { result += _commands.get(buffer); }
355                                                         else
356                                                         { result += buffer; }
357                                                         buffer = "";
358                                                         state = STATE_SPECIAL_CHARS_STATES.SUBSCRIPT;
359                                                 break;
360                                                 case '^':
361                                                         if (_commands.containsKey(buffer))
362                                                         { result += _commands.get(buffer); }
363                                                         else
364                                                         { result += buffer; }
365                                                         buffer = "";
366                                                         state = STATE_SPECIAL_CHARS_STATES.SUPERSCRIPT;
367                                                 break;
368                                                 case '\\':
369                                                         if (_commands.containsKey(buffer))
370                                                         { result += _commands.get(buffer); }
371                                                         else
372                                                         { result += buffer; }
373                                                         buffer = "";
374                                                         state = STATE_SPECIAL_CHARS_STATES.COMMAND;
375                                                 break;
376                                                 case ' ':
377                                                         state = STATE_SPECIAL_CHARS_STATES.NORMAL;
378                                                         if (_commands.containsKey(buffer))
379                                                         { 
380                                                                 result += _commands.get(buffer);
381                                                         }
382                                                         else
383                                                         {
384                                                                 result += buffer;
385                                                         }
386                                                         buffer = "";
387                                                 break;
388                                                 default:
389                                                         buffer += c;
390                                                 break;
391                                         }
392                                 }
393                                 break;
394                         }
395                 }
396                 if (_commands.containsKey(buffer))
397                 { 
398                         result += _commands.get(buffer);
399                 }
400                 else
401                 {
402                         result += buffer;
403                 }
404                 return result;
405         }
406         
407         
408 }