in progress...
[jalview.git] / forester / java / src / org / forester / phylogeny / data / Property.java
1 // $Id:
2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
4 //
5 // Copyright (C) 2008-2009 Christian M. Zmasek
6 // Copyright (C) 2008-2009 Burnham Institute for Medical Research
7 // Copyright (C) 2000-2001 Washington University School of Medicine
8 // and Howard Hughes Medical Institute
9 // All rights reserved
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Lesser General Public
13 // License as published by the Free Software Foundation; either
14 // version 2.1 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 // Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License along with this library; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 //
25 // Contact: phylosoft @ gmail . com
26 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
27
28 package org.forester.phylogeny.data;
29
30 import java.io.IOException;
31 import java.io.Writer;
32 import java.util.StringTokenizer;
33
34 import org.forester.io.parsers.phyloxml.PhyloXmlMapping;
35 import org.forester.util.ForesterUtil;
36
37 public class Property implements PhylogenyData {
38
39     private String          _value;
40     private final String    _ref;
41     private final String    _unit;
42     private final String    _datatype;
43     private final AppliesTo _applies_to;
44     private final String    _id_ref;
45
46     public Property( final String ref,
47                      final String value,
48                      final String unit,
49                      final String datatype,
50                      final AppliesTo applies_to ) {
51         this( ref, value, unit, datatype, applies_to, "" );
52     }
53
54     // Only used by method createFromNhxString.
55     private Property( final String ref,
56                       final String value,
57                       final String unit,
58                       final String datatype,
59                       final AppliesTo applies_to,
60                       final boolean dummy ) {
61         _ref = ref;
62         _unit = unit;
63         _datatype = datatype;
64         _applies_to = applies_to;
65         _id_ref = "";
66         setValue( value );
67     }
68
69     public Property( final String ref,
70                      final String value,
71                      final String unit,
72                      final String datatype,
73                      final AppliesTo applies_to,
74                      final String id_ref ) {
75         if ( !ForesterUtil.isEmpty( ref ) && ( ref.indexOf( ":" ) < 1 ) ) {
76             throw new IllegalArgumentException( "property reference [" + ref
77                                                 + "] is not in the expected format (missing a \":\")" );
78         }
79         if ( !ForesterUtil.isEmpty( unit ) && ( unit.indexOf( ":" ) < 1 ) ) {
80             throw new IllegalArgumentException( "property unit [" + unit
81                                                 + "] is not in the expected format (missing a \":\")" );
82         }
83         if ( !ForesterUtil.isEmpty( datatype ) && ( datatype.indexOf( ":" ) < 1 ) ) {
84             throw new IllegalArgumentException( "property datatype [" + unit
85                                                 + "] is not in the expected format (missing a \":\")" );
86         }
87         _ref = ref;
88         _unit = unit;
89         _datatype = datatype;
90         _applies_to = applies_to;
91         _id_ref = id_ref;
92         setValue( value );
93     }
94
95     @Override
96     public StringBuffer asSimpleText() {
97         return new StringBuffer( getValue() );
98     }
99
100     @Override
101     public StringBuffer asText() {
102         final StringBuffer sb = new StringBuffer();
103         sb.append( getRef() );
104         sb.append( ": " );
105         sb.append( getValue() );
106         if ( !ForesterUtil.isEmpty( getUnit() ) ) {
107             sb.append( " " );
108             sb.append( getUnit() );
109         }
110         return sb;
111     }
112
113     @Override
114     public PhylogenyData copy() {
115         return new Property( getRef(), getValue(), getUnit(), getDataType(), getAppliesTo(), getIdRef() );
116     }
117
118     public AppliesTo getAppliesTo() {
119         return _applies_to;
120     }
121
122     public String getDataType() {
123         return _datatype;
124     }
125
126     public String getIdRef() {
127         return _id_ref;
128     }
129
130     public String getRef() {
131         return _ref;
132     }
133
134     public String getUnit() {
135         return _unit;
136     }
137
138     public String getValue() {
139         return _value;
140     }
141
142     @Override
143     public boolean isEqual( final PhylogenyData data ) {
144         if ( data == null ) {
145             return false;
146         }
147         return ( ( Property ) data ).getValue().equals( getValue() )
148                 && ( ( Property ) data ).getUnit().equals( getUnit() )
149                 && ( ( Property ) data ).getRef().equals( getRef() );
150     }
151
152     public void setValue( final String value ) {
153         _value = value;
154     }
155
156     @Override
157     public StringBuffer toNHX() {
158         throw new UnsupportedOperationException();
159     }
160
161     @Override
162     public void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {
163         PhylogenyDataUtil.appendElement( writer,
164                                          PhyloXmlMapping.PROPERTY,
165                                          getValue(),
166                                          PhyloXmlMapping.PROPERTY_REF,
167                                          getRef(),
168                                          PhyloXmlMapping.PROPERTY_UNIT,
169                                          getUnit(),
170                                          PhyloXmlMapping.PROPERTY_DATATYPE,
171                                          getDataType(),
172                                          PhyloXmlMapping.PROPERTY_APPLIES_TO,
173                                          getAppliesTo().toString(),
174                                          PhyloXmlMapping.ID_REF,
175                                          getIdRef(),
176                                          indentation );
177     }
178
179     @Override
180     public String toString() {
181         return asText().toString();
182     }
183
184     public static Property createFromNhxString( final String nhx ) throws IllegalArgumentException {
185         final StringTokenizer st = new StringTokenizer( nhx, "=" );
186         final int tokens = st.countTokens();
187         final String error = "error in NHX property tag format: "
188                 + "expected: X[N|B|C|S|T|P|O]=<datatype>=<ref>=<value>[=<unit>], got: \"" + nhx + "\" instead";
189         if ( ( tokens != 4 ) && ( tokens != 5 ) ) {
190             throw new IllegalArgumentException( error );
191         }
192         final String first = st.nextToken();
193         AppliesTo applies_to = null;
194         if ( first.equals( "XN" ) ) {
195             applies_to = AppliesTo.NODE;
196         }
197         else if ( first.equals( "XB" ) ) {
198             applies_to = AppliesTo.PARENT_BRANCH;
199         }
200         else if ( first.equals( "XC" ) ) {
201             applies_to = AppliesTo.CLADE;
202         }
203         else if ( first.equals( "XS" ) ) {
204             applies_to = AppliesTo.ANNOTATION;
205         }
206         else if ( first.equals( "XT" ) ) {
207             applies_to = AppliesTo.OTHER;
208         }
209         else if ( first.equals( "XP" ) ) {
210             applies_to = AppliesTo.PHYLOGENY;
211         }
212         else if ( first.equals( "XO" ) ) {
213             applies_to = AppliesTo.OTHER;
214         }
215         else {
216             throw new IllegalArgumentException( error );
217         }
218         String datatype = st.nextToken();
219         if ( datatype.equals( "S" ) ) {
220             datatype = "xsd:string";
221         }
222         else if ( datatype.equals( "L" ) ) {
223             datatype = "xsd:long";
224         }
225         else if ( datatype.equals( "D" ) ) {
226             datatype = "xsd:decimal";
227         }
228         else if ( datatype.equals( "B" ) ) {
229             datatype = "xsd:boolean";
230         }
231         else if ( datatype.equals( "U" ) ) {
232             datatype = "xsd:anyURI";
233         }
234         final String ref = st.nextToken();
235         final String value = st.nextToken();
236         String unit = "";
237         if ( tokens == 5 ) {
238             unit = st.nextToken();
239         }
240         return new Property( ref, value, unit, datatype, applies_to, true );
241     }
242
243     public static enum AppliesTo {
244         PHYLOGENY {
245
246             @Override
247             public String toString() {
248                 return "phylogeny";
249             }
250         },
251         CLADE {
252
253             @Override
254             public String toString() {
255                 return "clade";
256             }
257         },
258         NODE {
259
260             @Override
261             public String toString() {
262                 return "node";
263             }
264         },
265         ANNOTATION {
266
267             @Override
268             public String toString() {
269                 return "annotation";
270             }
271         },
272         PARENT_BRANCH {
273
274             @Override
275             public String toString() {
276                 return "parent_branch";
277             }
278         },
279         OTHER {
280
281             @Override
282             public String toString() {
283                 return "other";
284             }
285         }
286     }
287 }