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
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 // Contact: phylosoft @ gmail . com
24 // WWW: www.phylosoft.org/forester
26 package org.forester.io.parsers.tol;
28 import java.util.ArrayList;
29 import java.util.List;
31 import org.forester.io.parsers.phyloxml.XmlElement;
32 import org.forester.io.parsers.util.PhylogenyParserException;
33 import org.forester.phylogeny.Phylogeny;
34 import org.forester.phylogeny.PhylogenyNode;
35 import org.forester.phylogeny.data.Identifier;
36 import org.forester.phylogeny.data.Taxonomy;
37 import org.forester.util.FailedConditionCheckException;
38 import org.forester.util.ForesterConstants;
39 import org.forester.util.ForesterUtil;
40 import org.xml.sax.Attributes;
41 import org.xml.sax.SAXException;
42 import org.xml.sax.helpers.DefaultHandler;
44 public final class TolXmlHandler extends DefaultHandler {
46 private String _current_element_name;
47 private Phylogeny _current_phylogeny;
48 private List<Phylogeny> _phylogenies;
49 private XmlElement _current_xml_element;
50 private PhylogenyNode _current_node;
51 private final static StringBuffer _buffer = new StringBuffer();
57 private void addNode() {
58 final PhylogenyNode new_node = new PhylogenyNode();
59 getCurrentNode().addAsChild( new_node );
60 setCurrentNode( new_node );
64 public void characters( final char[] chars, final int start_index, final int end_index ) {
65 if ( ( ( getCurrentXmlElement() != null ) && ( getCurrentElementName() != null ) )
66 && !getCurrentElementName().equals( TolXmlMapping.CLADE )
67 && !getCurrentElementName().equals( TolXmlMapping.PHYLOGENY ) ) {
68 getCurrentXmlElement().setValue( new String( chars, start_index, end_index ).trim() );
73 public void endElement( final String namespace_uri, final String local_name, final String qualified_name )
75 if ( ForesterUtil.isEmpty( namespace_uri ) || namespace_uri.startsWith( ForesterConstants.PHYLO_XML_LOCATION ) ) {
76 if ( local_name.equals( TolXmlMapping.CLADE ) ) {
78 TolXmlHandler.mapElementToPhylogenyNode( getCurrentXmlElement(), getCurrentNode() );
79 if ( !getCurrentNode().isRoot() ) {
80 setCurrentNode( getCurrentNode().getParent() );
82 setCurrentXmlElement( getCurrentXmlElement().getParent() );
84 catch ( final PhylogenyParserException ex ) {
85 throw new SAXException( ex.getMessage() );
88 else if ( local_name.equals( TolXmlMapping.PHYLOGENY ) ) {
90 TolXmlHandler.mapElementToPhylogeny( getCurrentXmlElement(), getCurrentPhylogeny() );
92 catch ( final PhylogenyParserException ex ) {
93 throw new SAXException( ex.getMessage() );
98 else if ( ( getCurrentPhylogeny() != null ) && ( getCurrentXmlElement().getParent() != null ) ) {
99 setCurrentXmlElement( getCurrentXmlElement().getParent() );
101 setCurrentElementName( null );
105 private void finishPhylogeny() throws SAXException {
106 getCurrentPhylogeny().setRooted( true );
107 getCurrentPhylogeny().recalculateNumberOfExternalDescendants( false );
108 getPhylogenies().add( getCurrentPhylogeny() );
111 private String getCurrentElementName() {
112 return _current_element_name;
115 private PhylogenyNode getCurrentNode() {
116 return _current_node;
119 private Phylogeny getCurrentPhylogeny() {
120 return _current_phylogeny;
123 private XmlElement getCurrentXmlElement() {
124 return _current_xml_element;
127 List<Phylogeny> getPhylogenies() {
131 private void init() {
133 setPhylogenies( new ArrayList<Phylogeny>() );
136 private void initCurrentNode() {
137 if ( getCurrentNode() != null ) {
138 throw new FailedConditionCheckException( "attempt to create new current node when current node already exists" );
140 if ( getCurrentPhylogeny() == null ) {
141 throw new FailedConditionCheckException( "attempt to create new current node for non-existing phylogeny" );
143 final PhylogenyNode node = new PhylogenyNode();
144 getCurrentPhylogeny().setRoot( node );
145 setCurrentNode( getCurrentPhylogeny().getRoot() );
148 private void newClade() {
149 if ( getCurrentNode() == null ) {
157 private void newPhylogeny() {
158 setCurrentPhylogeny( new Phylogeny() );
161 private void reset() {
162 setCurrentPhylogeny( null );
163 setCurrentNode( null );
164 setCurrentElementName( null );
165 setCurrentXmlElement( null );
168 private void setCurrentElementName( final String element_name ) {
169 _current_element_name = element_name;
172 private void setCurrentNode( final PhylogenyNode current_node ) {
173 _current_node = current_node;
176 private void setCurrentPhylogeny( final Phylogeny phylogeny ) {
177 _current_phylogeny = phylogeny;
180 private void setCurrentXmlElement( final XmlElement element ) {
181 _current_xml_element = element;
184 private void setPhylogenies( final List<Phylogeny> phylogenies ) {
185 _phylogenies = phylogenies;
189 public void startDocument() throws SAXException {
194 public void startElement( final String namespace_uri,
195 final String local_name,
196 final String qualified_name,
197 final Attributes attributes ) throws SAXException {
198 setCurrentElementName( local_name );
199 if ( local_name.equals( TolXmlMapping.CLADE ) ) {
200 final XmlElement element = new XmlElement( namespace_uri, local_name, local_name, attributes );
201 getCurrentXmlElement().addChildElement( element );
202 setCurrentXmlElement( element );
205 else if ( local_name.equals( TolXmlMapping.PHYLOGENY ) ) {
206 setCurrentXmlElement( new XmlElement( "", "", "", null ) );
209 else if ( getCurrentPhylogeny() != null ) {
210 final XmlElement element = new XmlElement( namespace_uri, local_name, local_name, attributes );
211 getCurrentXmlElement().addChildElement( element );
212 setCurrentXmlElement( element );
216 public static boolean attributeEqualsValue( final XmlElement element,
217 final String attributeName,
218 final String attributeValue ) {
219 final String attr = element.getAttribute( attributeName );
220 return ( ( attr != null ) && attr.equals( attributeValue ) );
223 public static String getAtttributeValue( final XmlElement element, final String attributeName ) {
224 final String attr = element.getAttribute( attributeName );
225 if ( attr != null ) {
233 private static void mapElementToPhylogeny( final XmlElement xml_element, final Phylogeny phylogeny )
234 throws PhylogenyParserException {
235 // Not needed for now.
238 private static void mapElementToPhylogenyNode( final XmlElement xml_element, final PhylogenyNode node )
239 throws PhylogenyParserException {
240 if ( xml_element.isHasAttribute( TolXmlMapping.NODE_ID_ATTR ) ) {
241 final String id = xml_element.getAttribute( TolXmlMapping.NODE_ID_ATTR );
242 if ( !ForesterUtil.isEmpty( id ) ) {
243 if ( !node.getNodeData().isHasTaxonomy() ) {
244 node.getNodeData().setTaxonomy( new Taxonomy() );
246 node.getNodeData().getTaxonomy()
247 .setIdentifier( new Identifier( id, TolXmlMapping.TOL_TAXONOMY_ID_TYPE ) );
250 final boolean put_into_scientific_name = true; // Allways put into scientific name.
251 // if ( xml_element.isHasAttribute( TolXmlMapping.NODE_ITALICIZENAME_ATTR ) ) {
252 // final String ital = xml_element.getAttribute( TolXmlMapping.NODE_ITALICIZENAME_ATTR );
253 // if ( !ForesterUtil.isEmpty( ital ) && ital.equals( "1" ) ) {
254 // put_into_scientific_name = true;
257 for( int i = 0; i < xml_element.getNumberOfChildElements(); ++i ) {
258 final XmlElement element = xml_element.getChildElement( i );
259 final String qualified_name = element.getQualifiedName();
260 if ( qualified_name.equals( TolXmlMapping.TAXONOMY_NAME ) ) {
261 final String name = element.getValueAsString();
262 if ( !ForesterUtil.isEmpty( name ) ) {
263 if ( !node.getNodeData().isHasTaxonomy() ) {
264 node.getNodeData().setTaxonomy( new Taxonomy() );
266 if ( put_into_scientific_name ) {
267 node.getNodeData().getTaxonomy().setScientificName( name );
270 node.getNodeData().getTaxonomy().setCommonName( name );
274 else if ( qualified_name.equals( TolXmlMapping.AUTHORITY ) ) {
275 String auth = element.getValueAsString();
276 if ( !ForesterUtil.isEmpty( auth ) && !auth.equalsIgnoreCase( "null" ) ) {
277 if ( !node.getNodeData().isHasTaxonomy() ) {
278 node.getNodeData().setTaxonomy( new Taxonomy() );
280 auth = auth.replaceAll( "&", "&" );
281 node.getNodeData().getTaxonomy().setAuthority( auth );
284 else if ( qualified_name.equals( TolXmlMapping.AUTHDATE ) ) {
285 final String authdate = element.getValueAsString();
286 if ( !ForesterUtil.isEmpty( authdate ) && !authdate.equalsIgnoreCase( "null" ) ) {
287 if ( node.getNodeData().isHasTaxonomy()
288 && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getAuthority() ) ) {
289 _buffer.setLength( 0 );
290 _buffer.append( node.getNodeData().getTaxonomy().getAuthority() );
291 _buffer.append( " " );
292 _buffer.append( authdate );
293 node.getNodeData().getTaxonomy().setAuthority( _buffer.toString() );
297 else if ( qualified_name.equals( TolXmlMapping.OTHERNAMES ) ) {
298 for( int j = 0; j < element.getNumberOfChildElements(); ++j ) {
299 final XmlElement element_j = element.getChildElement( j );
300 if ( element_j.getQualifiedName().equals( TolXmlMapping.OTHERNAME ) ) {
301 for( int z = 0; z < element_j.getNumberOfChildElements(); ++z ) {
302 final XmlElement element_z = element_j.getChildElement( z );
303 if ( element_z.getQualifiedName().equals( TolXmlMapping.OTHERNAME_NAME ) ) {
304 final String syn = element_z.getValueAsString();
305 if ( !ForesterUtil.isEmpty( syn ) && !syn.equalsIgnoreCase( "null" ) ) {
306 if ( !node.getNodeData().isHasTaxonomy() ) {
307 node.getNodeData().setTaxonomy( new Taxonomy() );
309 node.getNodeData().getTaxonomy().getSynonyms().add( syn );