fix bug #675.
[phpeclipse.git] / archive / net.sourceforge.phpeclipse.quantum.sql / src / com / quantum / util / StringMatrix.java
1 /*
2  * Created on 8/04/2003
3  *
4  */
5 package com.quantum.util;
6
7 import java.util.Vector;
8
9 /**
10  * @author jparrai
11  * Generic class to hold a Matrix of Strings, that is a Vector of Vectors of Strings.
12  * The first StringMatrix "line" is supposed to have headers to the values of the rest.
13  * Those headers will always be case insensitive
14  * Rows start at 0
15  */
16 public class StringMatrix {
17         private final int DEFAULT_COLUMNS = 10;
18         private final int DEFAULT_ROWS = 10;
19         private final int DEFAULT_INCREMENT = 10;
20         
21         private Vector header = new Vector(DEFAULT_COLUMNS,DEFAULT_INCREMENT);
22         private Vector matrix = new Vector(DEFAULT_ROWS,DEFAULT_INCREMENT);
23         
24         /**
25          * Adds a String to the end of the header keys
26          * @param header : The string to be added
27          */
28         public void addHeader(String header) {
29                         this.header.add(header);
30         }
31         /**
32          * Adds a whole vector to the header
33          * @param header
34          */
35         private void addVectorHeader(Vector header){
36                         this.header.addAll(header);
37                         for (int i = 0; i < this.header.size(); i++) {
38                                 String element = (String) this.header.get(i);
39                                 this.header.setElementAt(element, i);                   
40                         }
41         }
42         /**
43          * Adds a whole matrix to the header
44          * @param header
45          */
46         public void addMatrixHeader(String header[]){
47                         for (int i = 0; i < header.length; i++) {       
48                                 String element = header[i];
49                                 this.header.add(element);                       
50                         }
51         }
52         /**
53          * Adds a String to the end of the row indicated
54          * @param value : The string to be added
55          * @param row : The row to 
56          */
57         public void add(String value, int row) {
58                 grow(row);
59                 Vector rowVector = (Vector) matrix.get(row);
60                 rowVector.add(value);
61         }
62         /**
63          * Adds a StringMatrix to the end of the row indicated
64          * @param value : The string to be added
65          * @param row : The row to 
66          */
67         public void add(StringMatrix value) {
68                 int row = matrix.size();
69                 for (int i = 0; i < value.size(); i++){
70                         grow(row);
71                         for (int j = 0; j < value.getNumColumns(); j++){
72                                 String header = value.getHeaderColumn(j); 
73                                 addAt(header, value.get(header,i), row);
74                         }
75                         row++;
76                 }
77                 Vector rowVector = (Vector) matrix.get(row);
78                 rowVector.add(value);
79         }
80         
81         /**
82          * Converts the StringMatrix into a copy of the given
83          * @param origin - The StringMatrix to be copied
84          */
85         public void copy(StringMatrix origin) {
86                 clear();
87                 add(origin);
88         }
89         
90         /**
91          * Clears (emtpies) the StringMatrix
92          */
93         public void clear(){
94                 header.clear();
95                 matrix.clear();
96         }
97         /**
98         * Adds a String to the row indicated, to the column that matches the key
99         * The matrix will grow to acomodate the indexes, so be careful 
100         * @param value : The string to be added
101         * @param row : The row to update 
102         */
103         public void addAt(String key, String value, int row) {
104                 grow(row);
105                 Vector rowVector = (Vector) matrix.get(row);
106                 int ind = header.indexOf(key);
107                 if (ind < 0) return;
108                 if (rowVector.size() <= ind) rowVector.setSize(ind);
109                 rowVector.add(ind, value);
110         }
111         /**
112          * Adds a String in the location specified.
113          * The matrix will grow to acomodate the indexes, so be careful 
114          * @param column        Column selected
115          * @param row           row selected
116          * @param value         value to add
117          */
118         public void addAt(int column, int row, String value) {
119                 grow(row);
120                 Vector rowVector = (Vector) matrix.get(row);
121                 if (column >= rowVector.size()) rowVector.setSize(column);
122                 rowVector.add(column, value);
123         }
124         /**
125          * Adds a whole vector to the end of the row indicated
126          * @param value : The vector to be added
127          * @param row : The row to 
128          */
129         private void addVector(Vector value, int row){
130                 grow(row);
131                 Vector rowVector = (Vector) matrix.get(row);
132                 rowVector.addAll(value);
133         }
134         
135         /**
136          * Tells if you have that particular key in your StringMatrix
137          * @param key
138          * @return 
139          */
140         public boolean contains(String key){
141                 return (findKey(key) >= 0);
142         }
143         /**
144          * Gets a String value from the row indicated, from the column that matches the key
145          * @param key
146          * @param row
147          * @return
148          */
149         public String get(String key, int row){
150                 if (matrix.size() <= row) return null;
151                 int col = findKey(key);
152                 if (col < 0) return null; 
153                 Vector rowVector = (Vector) matrix.get(row);
154                 if (rowVector ==  null) return null;
155                 return (String) rowVector.get(col);
156         }
157         /**
158          * Finds the key in the header
159          * @param key
160          * @return
161          */
162         private int findKey(String key) {
163                 for (int i = 0; i < header.size(); i++) {
164                         String element = (String) header.get(i);
165                         if (element.equalsIgnoreCase(key)) return i;
166                 }
167                 return -1;
168         }
169         /**
170          * @param key: selects the column
171          * @return a Vector with all the values in the selected column; null if empty
172          */
173         public Vector getColumn(String key){
174                 if (size() < 1 ) return null;
175                 Vector result = new Vector(size(),1);
176                 for (int i = 0; i < size(); i++){
177                         result.add(get(key, i));
178                 }
179                 return result;
180         }
181         /**
182          * @param key: selects the column
183          * @return a Vector with all the values in the selected column, dropping duplicates; null if empty
184          */
185         public Vector getUniqueColumn(String key){
186                 if (size() < 1 ) return null;
187                 Vector result = new Vector(size(),1);
188                 for (int i = 0; i < size(); i++){
189                         if (!result.contains(get(key, i))) result.add(get(key, i));
190                 }
191                 return result;
192         }
193         /**
194          * @param key: selects the column
195          * @return a Vector of Integers with all the indexes of the rows
196          * matching the selected column, dropping duplicates; null if empty
197          */
198         public Vector getIndexes(String key, String value){
199                 Vector result = new Vector();
200                 for (int i = 0; i < size(); i++){
201                         if (get(key, i).equals(value))
202                                 result.add(new Integer(i));
203                 }
204                 return result;
205         }
206         /**
207          * Deletes all the rows that matches the value for the key
208          * @param key: selects the column
209          */
210         public void dropMatching(String key, String value){
211                 for (int i = 0; i < size(); i++){
212                         if (get(key, i).equals(value)) deleteRow(i);
213                 }
214         }
215         /**
216          * Returns a StringMatrix with all the complete rows that match the key - value pair
217          * @param key The column key
218          * @param value The value to match
219          * @return a StringMatrix with only the rows where the key equals the value
220          */
221         public StringMatrix select(String key, String value){
222                 StringMatrix result = new StringMatrix();
223                 result.addVectorHeader(header);
224                 int j = 0;
225                 for (int i = 0; i < size(); i++){
226                         if (get(key, i).equals(value)) {
227                                 result.addVector((Vector)matrix.get(i), j);
228                                 j++;
229                         } 
230                 }
231                 return result;
232         }
233
234         // Private functions
235         /**
236          * Grows the StringMatrix till it's able to hold "row" rows.
237          * @param row : The number of rows that must hold
238          */
239         private void grow(int row) {
240                 if (matrix.size() <= row)
241                         for (int i = matrix.size(); i <= row; i++) {
242                                 matrix.add(new Vector(header.size(), 1));
243                         }
244         }
245         /**
246          * Gets a String value from the row indicated , from the column number
247          * @param col : 0-index column 
248          * @param row : 0-index column
249          * @return
250          */
251         public String get(int col, int row){
252                 if (col < 0 || row < 0) return null; 
253                 Vector rowVector = (Vector) matrix.get(row);
254                 if (rowVector ==  null) return null;
255                 if (col < rowVector.size())
256                         return (String) rowVector.get(col);
257                 else return null;
258         }
259         
260         // Generic interfaces
261         /**
262          * @param i
263          * @return : a StringMatrix with only one row, the selected by i
264          */
265         public StringMatrix rowMatrix(int i){
266                 StringMatrix result = new StringMatrix();
267                 result.addVectorHeader(header);
268                 result.addVector((Vector)matrix.get(i),0);
269                 return result;
270         }
271         
272         /**
273          * Resturns a String[] with the selected row
274          * @param i The index of the row
275          * @return
276          */
277         public String[] getRow(int i) {
278                 if (i < matrix.size()) {
279                         String[] result = new String[header.size()];
280                         Vector resVector = (Vector)matrix.get(i);
281                         resVector.toArray(result); 
282                         return result;
283                 }
284                 return null;
285                 
286         }
287
288
289         /**
290          * @return the number of rows
291          */
292         public int size() {
293                 return matrix.size();
294         }
295         /**
296          * @return The number of columns of the StringMatrix
297          */
298         public int getNumColumns() {
299                 return header.size();
300         }
301         /**
302          * @param i
303          * @return The name of the header column in the "i" position. Null if no such position.
304          */
305         public String getHeaderColumn(int i){
306                 if (i < header.size())
307                         return (String) header.get(i);
308                 return null;
309         }
310         /**
311          * Deletes the row number i
312          * @param i
313          */
314         public void deleteRow(int i){
315                 if (i < matrix.size())
316                         matrix.remove(i);
317         }
318
319
320         // Common Object interface
321         /* (non-Javadoc)
322          * @see java.lang.Object#clone()
323          */
324         public Object clone() {
325                 // Deep clone
326                 StringMatrix matrix = new StringMatrix();
327                 matrix.copy(this);
328                 return matrix;
329         }
330
331         /* (non-Javadoc)
332          * @see java.lang.Object#toString()
333          */
334         public String toString() {
335                 String result = "";
336                 for (int j = 0; j < header.size(); j++){
337                         result += (String) header.get(j);
338                         result += "\t";
339                 }
340                 result += "\n";
341                 // Write the lines
342                 for (int i = 0; i < matrix.size(); i++){
343                         for (int j = 0; j < header.size(); j++){
344                                 result += get(j,i);
345                                 result += "\t";
346                         }
347                         result += "\n";
348                 }
349                 return result;
350         }
351
352         /* (non-Javadoc)
353          * @see java.lang.Object#equals(java.lang.Object)
354          */
355         public boolean equals(Object obj) {
356                 if (!(obj instanceof StringMatrix)) return false;
357                 StringMatrix sm = (StringMatrix) obj;
358                 if (!header.equals(sm.header)) return false;
359                 if (matrix.size() != sm.matrix.size()) return false;
360                 for (int i = 0; i < matrix.size(); i++){
361                         Vector row = (Vector) matrix.get(i);
362                         Vector smRow = (Vector) sm.matrix.get(i);
363                         if (!(row.equals(smRow))) return false;
364                 }
365                 return true;
366         }
367
368         /**
369          * @return
370          */
371         public Vector getMatrix() {
372                 return matrix;
373         }
374         /**
375          * @return
376          */
377         public String[] getHeader() {
378                 String[] result = new String[header.size()];
379                 header.toArray(result);
380                 return result;
381         }
382
383 }