in progress....
[jalview.git] / forester / java / src / org / forester / util / BasicTable.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 // All rights reserved
8 //
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.
13 //
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.
18 //
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
22 //
23 // Contact: phylosoft @ gmail . com
24 // WWW: www.phylosoft.org
25
26 package org.forester.util;
27
28 import java.io.IOException;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.SortedMap;
32 import java.util.TreeMap;
33
34 public class BasicTable<E> {
35
36     private int                         _max_col;
37     private int                         _max_row;
38     private Map<String, Map<String, E>> _rows;
39
40     public BasicTable() {
41         init();
42     }
43
44     // Returns -1 if not found, IllegalArgumentException if not unique.
45     public int findRow( final String first_col_value ) throws IllegalArgumentException {
46         int result = -1;
47         for( int i = 0; i < this.getNumberOfRows(); ++i ) {
48             if ( getValueAsString( 0, i ).equals( first_col_value ) ) {
49                 if ( result >= 0 ) {
50                     throw new IllegalArgumentException( "\"" + first_col_value + "\" is not unique" );
51                 }
52                 result = i;
53             }
54         }
55         return result;
56     }
57
58     public SortedMap<String, E> getColumnsAsMap( final int key_col, final int value_col ) throws IllegalArgumentException {
59         final SortedMap<String, E> map = new TreeMap<String, E>();
60         for( int row = 0; row < getNumberOfRows(); ++row ) {
61             final String key = ( String ) getValue( key_col, row );
62             final E value = getValue( value_col, row );
63             if ( ( key != null ) && ( value != null ) ) {
64                 if ( map.containsKey( key ) ) {
65                     throw new IllegalArgumentException( "attempt to use non-unique table value as key [" + key + "]" );
66                 }
67                 map.put( key, value );
68             }
69         }
70         return map;
71     }
72
73     public Map<String, Double> getColumnsAsMapDouble( final int key_col, final int value_col )
74             throws IllegalArgumentException, IOException {
75         final Map<String, Double> map = new HashMap<String, Double>();
76         for( int row = 0; row < getNumberOfRows(); ++row ) {
77             final String key = ( String ) getValue( key_col, row );
78             double value = 0;
79             try {
80                 value = Double.parseDouble( getValueAsString( value_col, row ) );
81             }
82             catch ( final NumberFormatException e ) {
83                 throw new IOException( e );
84             }
85             if ( key != null ) {
86                 if ( map.containsKey( key ) ) {
87                     throw new IllegalArgumentException( "attempt to use non-unique table value as key [" + key + "]" );
88                 }
89                 map.put( key, value );
90             }
91         }
92         return map;
93     }
94
95     public int getNumberOfColumns() {
96         return _max_col + 1;
97     }
98
99     public int getNumberOfRows() {
100         return _max_row + 1;
101     }
102
103     public final String getRowAsString( final int row, final String separator ) {
104         final StringBuilder sb = new StringBuilder();
105         for( int col = 0; col < getNumberOfColumns(); ++col ) {
106             sb.append( getValue( col, row ).toString() );
107             if ( col < ( getNumberOfColumns() - 1 ) ) {
108                 sb.append( separator );
109             }
110         }
111         return sb.toString();
112     }
113
114     public E getValue( final int col, final int row ) throws IllegalArgumentException {
115         if ( ( row > ( getNumberOfRows() - 1 ) ) || ( row < 0 ) ) {
116             throw new IllegalArgumentException( "value for row (" + row + ") is out of range [number of rows: "
117                     + getNumberOfRows() + "]" );
118         }
119         else if ( ( col >= getNumberOfColumns() ) || ( row < 0 ) ) {
120             throw new IllegalArgumentException( "value for column (" + col + ") is out of range [number of columns: "
121                     + getNumberOfColumns() + "]" );
122         }
123         final Map<String, E> row_map = getRow( row );
124         if ( ( row_map == null ) || ( row_map.size() < 1 ) ) {
125             return null;
126         }
127         return row_map.get( "" + col );
128     }
129
130     public String getValueAsString( final int col, final int row ) throws IllegalArgumentException {
131         if ( getValue( col, row ) != null ) {
132             return getValue( col, row ).toString();
133         }
134         return null;
135     }
136
137     public boolean isEmpty() {
138         return getNumberOfRows() <= 0;
139     }
140
141     public void setValue( final int col, final int row, final E value ) {
142         if ( ( row < 0 ) || ( col < 0 ) ) {
143             throw new IllegalArgumentException( "attempt to use negative values for row or column" );
144         }
145         if ( row > ( getNumberOfRows() - 1 ) ) {
146             setMaxRow( row );
147         }
148         if ( col > ( getNumberOfColumns() - 1 ) ) {
149             setMaxCol( col );
150         }
151         final String row_key = "" + row;
152         Map<String, E> row_map = null;
153         if ( getRows().containsKey( row_key ) ) {
154             row_map = getRows().get( row_key );
155         }
156         else {
157             row_map = new HashMap<String, E>();
158             getRows().put( row_key, row_map );
159         }
160         row_map.put( "" + col, value );
161     }
162
163     @Override
164     public String toString() {
165         final StringBuilder sb = new StringBuilder();
166         for( int row = 0; row < getNumberOfRows(); ++row ) {
167             for( int col = 0; col < getNumberOfColumns(); ++col ) {
168                 sb.append( getValue( col, row ) );
169                 if ( col < ( getNumberOfColumns() - 1 ) ) {
170                     sb.append( " " );
171                 }
172             }
173             if ( row < ( getNumberOfRows() - 1 ) ) {
174                 sb.append( ForesterUtil.LINE_SEPARATOR );
175             }
176         }
177         return sb.toString();
178     }
179
180     private Map<String, E> getRow( final int row ) {
181         return getRows().get( "" + row );
182     }
183
184     private Map<String, Map<String, E>> getRows() {
185         return _rows;
186     }
187
188     private void init() {
189         _rows = new HashMap<String, Map<String, E>>();
190         setMaxCol( -1 );
191         setMaxRow( -1 );
192     }
193
194     private void setMaxCol( final int max_col ) {
195         _max_col = max_col;
196     }
197
198     private void setMaxRow( final int max_row ) {
199         _max_row = max_row;
200     }
201 }