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