2 // FORESTER -- software libraries and applications
3 // for evolutionary biology research and applications.
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
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.
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.
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
25 // Contact: phylosoft @ gmail . com
26 // WWW: https://sites.google.com/site/cmzmasek/home/software/forester
28 package org.forester.phylogeny.data;
30 import java.io.IOException;
31 import java.io.Writer;
32 import java.util.StringTokenizer;
34 import org.forester.io.parsers.phyloxml.PhyloXmlMapping;
35 import org.forester.util.ForesterUtil;
37 public class Property implements PhylogenyData {
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;
46 public Property( final String ref,
49 final String datatype,
50 final AppliesTo applies_to ) {
51 this( ref, value, unit, datatype, applies_to, "" );
54 // Only used by method createFromNhxString.
55 private Property( final String ref,
58 final String datatype,
59 final AppliesTo applies_to,
60 final boolean dummy ) {
64 _applies_to = applies_to;
69 public Property( final String ref,
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 \":\")" );
79 if ( !ForesterUtil.isEmpty( unit ) && ( unit.indexOf( ":" ) < 1 ) ) {
80 throw new IllegalArgumentException( "property unit [" + unit
81 + "] is not in the expected format (missing a \":\")" );
83 if ( !ForesterUtil.isEmpty( datatype ) && ( datatype.indexOf( ":" ) < 1 ) ) {
84 throw new IllegalArgumentException( "property datatype [" + unit
85 + "] is not in the expected format (missing a \":\")" );
90 _applies_to = applies_to;
96 public StringBuffer asSimpleText() {
97 return new StringBuffer( getValue() );
101 public StringBuffer asText() {
102 final StringBuffer sb = new StringBuffer();
103 sb.append( getRef() );
105 sb.append( getValue() );
106 if ( !ForesterUtil.isEmpty( getUnit() ) ) {
108 sb.append( getUnit() );
114 public PhylogenyData copy() {
115 return new Property( getRef(), getValue(), getUnit(), getDataType(), getAppliesTo(), getIdRef() );
118 public AppliesTo getAppliesTo() {
122 public String getDataType() {
126 public String getIdRef() {
130 public String getRef() {
134 public String getUnit() {
138 public String getValue() {
143 public boolean isEqual( final PhylogenyData data ) {
144 if ( data == null ) {
147 return ( ( Property ) data ).getValue().equals( getValue() )
148 && ( ( Property ) data ).getUnit().equals( getUnit() )
149 && ( ( Property ) data ).getRef().equals( getRef() );
152 public void setValue( final String value ) {
157 public StringBuffer toNHX() {
158 throw new UnsupportedOperationException();
162 public void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {
163 PhylogenyDataUtil.appendElement( writer,
164 PhyloXmlMapping.PROPERTY,
166 PhyloXmlMapping.PROPERTY_REF,
168 PhyloXmlMapping.PROPERTY_UNIT,
170 PhyloXmlMapping.PROPERTY_DATATYPE,
172 PhyloXmlMapping.PROPERTY_APPLIES_TO,
173 getAppliesTo().toString(),
174 PhyloXmlMapping.ID_REF,
180 public String toString() {
181 return asText().toString();
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 );
192 final String first = st.nextToken();
193 AppliesTo applies_to = null;
194 if ( first.equals( "XN" ) ) {
195 applies_to = AppliesTo.NODE;
197 else if ( first.equals( "XB" ) ) {
198 applies_to = AppliesTo.PARENT_BRANCH;
200 else if ( first.equals( "XC" ) ) {
201 applies_to = AppliesTo.CLADE;
203 else if ( first.equals( "XS" ) ) {
204 applies_to = AppliesTo.ANNOTATION;
206 else if ( first.equals( "XT" ) ) {
207 applies_to = AppliesTo.OTHER;
209 else if ( first.equals( "XP" ) ) {
210 applies_to = AppliesTo.PHYLOGENY;
212 else if ( first.equals( "XO" ) ) {
213 applies_to = AppliesTo.OTHER;
216 throw new IllegalArgumentException( error );
218 String datatype = st.nextToken();
219 if ( datatype.equals( "S" ) ) {
220 datatype = "xsd:string";
222 else if ( datatype.equals( "L" ) ) {
223 datatype = "xsd:long";
225 else if ( datatype.equals( "D" ) ) {
226 datatype = "xsd:decimal";
228 else if ( datatype.equals( "B" ) ) {
229 datatype = "xsd:boolean";
231 else if ( datatype.equals( "U" ) ) {
232 datatype = "xsd:anyURI";
234 final String ref = st.nextToken();
235 final String value = st.nextToken();
238 unit = st.nextToken();
240 return new Property( ref, value, unit, datatype, applies_to, true );
243 public static enum AppliesTo {
247 public String toString() {
254 public String toString() {
261 public String toString() {
268 public String toString() {
275 public String toString() {
276 return "parent_branch";
282 public String toString() {