/* * Created on 8/04/2003 * */ package com.quantum.util; import java.util.Vector; /** * @author jparrai * Generic class to hold a Matrix of Strings, that is a Vector of Vectors of Strings. * The first Vector "line" is supposed to have headers to the values of the rest. * Those headers will always be case insensitive */ public class StringMatrix { private final int DEFAULT_COLUMNS = 10; private final int DEFAULT_ROWS = 10; private final int DEFAULT_INCREMENT = 10; private Vector header = new Vector(DEFAULT_COLUMNS,DEFAULT_INCREMENT); private Vector matrix = new Vector(DEFAULT_ROWS,DEFAULT_INCREMENT); /** * Adds a String to the end of the header keys * @param header : The string to be added */ public void addHeader(String header) { this.header.add(header); } /** * Adds a whole vector to the header * @param header */ private void addVectorHeader(Vector header){ this.header.addAll(header); for (int i = 0; i < this.header.size(); i++) { String element = (String) this.header.get(i); this.header.setElementAt(element, i); } } /** * Adds a whole matrix to the header * @param header */ public void addMatrixHeader(String header[]){ for (int i = 0; i < header.length; i++) { String element = header[i]; this.header.add(element); } } /** * Adds a String to the end of the row indicated * @param value : The string to be added * @param row : The row to */ public void add(String value, int row) { grow(row); Vector rowVector = (Vector) matrix.get(row); rowVector.add(value); } /** * Adds a StringMatrix to the end of the row indicated * @param value : The string to be added * @param row : The row to */ public void add(StringMatrix value) { int row = matrix.size(); for (int i = 0; i < value.size(); i++){ grow(row); for (int j = 0; j < value.getNumColumns(); j++){ String header = value.getHeaderColumn(j); addAt(header, value.get(header,i), row); } row++; } Vector rowVector = (Vector) matrix.get(row); rowVector.add(value); } /** * Converts the StringMatrix into a copy of the given * @param origin - The StringMatrix to be copied */ public void copy(StringMatrix origin) { clear(); add(origin); } /** * Clears (emtpies) the StringMatrix */ public void clear(){ header.clear(); matrix.clear(); } /** * Adds a String to the row indicated, to the column that matches the key * @param value : The string to be added * @param row : The row to */ public void addAt(String key, String value, int row) { grow(row); Vector rowVector = (Vector) matrix.get(row); int ind = header.indexOf(key); if (ind < 0) return; if (rowVector.size() < ind+1) rowVector.setSize(ind); rowVector.add(ind, value); } /** * Adds a whole vector to the end of the row indicated * @param value : The vector to be added * @param row : The row to */ private void addVector(Vector value, int row){ grow(row); Vector rowVector = (Vector) matrix.get(row); rowVector.addAll(value); } /** * Tells if you have that particular key in your StringMatrix * @param key * @return */ public boolean contains(String key){ return (findKey(key) >= 0); } /** * Gets a String value from the row indicated, from the column that matches the key * @param key * @param row * @return */ public String get(String key, int row){ if (matrix.size() <= row) return null; int col = findKey(key); if (col < 0) return null; Vector rowVector = (Vector) matrix.get(row); if (rowVector == null) return null; return (String) rowVector.get(col); } /** * Finds the key in the header * @param key * @return */ private int findKey(String key) { for (int i = 0; i < header.size(); i++) { String element = (String) header.get(i); if (element.equalsIgnoreCase(key)) return i; } return -1; } /** * @param key: selects the column * @return a Vector with all the values in the selected column; null if empty */ public Vector getColumn(String key){ if (size() < 1 ) return null; Vector result = new Vector(size(),1); for (int i = 0; i < size(); i++){ result.add(get(key, i)); } return result; } /** * @param key: selects the column * @return a Vector with all the values in the selected column, dropping duplicates; null if empty */ public Vector getUniqueColumn(String key){ if (size() < 1 ) return null; Vector result = new Vector(size(),1); for (int i = 0; i < size(); i++){ if (!result.contains(get(key, i))) result.add(get(key, i)); } return result; } /** * @param key: selects the column * @return a Vector of Integers with all the indexes of the rows * matching the selected column, dropping duplicates; null if empty */ public Vector getIndexes(String key, String value){ Vector result = new Vector(); for (int i = 0; i < size(); i++){ if (get(key, i).equals(value)) result.add(new Integer(i)); } return result; } /** * Deletes all the rows that matches the value for the key * @param key: selects the column */ public void dropMatching(String key, String value){ for (int i = 0; i < size(); i++){ if (get(key, i).equals(value)) deleteRow(i); } } /** * Returns a StringMatrix with all the complete rows that match the key - value pair * @param key The column key * @param value The value to match * @return a StringMatrix with only the rows where the key equals the value */ public StringMatrix select(String key, String value){ StringMatrix result = new StringMatrix(); result.addVectorHeader(header); int j = 0; for (int i = 0; i < size(); i++){ if (get(key, i).equals(value)) { result.addVector((Vector)matrix.get(i), j); j++; } } return result; } // Private functions /** * Grows the StringMatrix till it's able to hold "row" rows. * @param row : The number of rows that must hold */ private void grow(int row) { if (matrix.size() <= row) for (int i = matrix.size(); i <= row; i++) { matrix.add(new Vector(header.size(), 1)); } } /** * Gets a String value from the row indicated , from the column number * @param col : 0-index column * @param row : 0-index column * @return */ private String get(int col, int row){ if (col < 0 || row < 0) return null; Vector rowVector = (Vector) matrix.get(row); if (rowVector == null) return null; return (String) rowVector.get(col); } // Generic interfaces /** * @param i * @return : a StringMatrix with only one row, the selected by i */ public StringMatrix rowMatrix(int i){ StringMatrix result = new StringMatrix(); result.addVectorHeader(header); result.addVector((Vector)matrix.get(i),0); return result; } /** * Resturns a String[] with the selected row * @param i The index of the row * @return */ public String[] getRow(int i) { if (i < matrix.size()) { String[] result = new String[header.size()]; Vector resVector = (Vector)matrix.get(i); resVector.toArray(result); return result; } return null; } /** * @return the number of rows */ public int size() { return matrix.size(); } public int getNumColumns() { return header.size(); } public String getHeaderColumn(int i){ return (String) header.get(i); } public void deleteRow(int i){ matrix.remove(i); } // Common Object interface /* (non-Javadoc) * @see java.lang.Object#clone() */ public Object clone() { // Deep clone StringMatrix matrix = new StringMatrix(); matrix.copy(this); return matrix; } /* (non-Javadoc) * @see java.lang.Object#toString() */ public String toString() { String result = ""; for (int j = 0; j < header.size(); j++){ result += (String) header.get(j); result += "\t"; } result += "\n"; // Write the lines for (int i = 0; i < matrix.size(); i++){ for (int j = 0; j < header.size(); j++){ result += get(j,i); result += "\t"; } result += "\n"; } return result; } /* (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ public boolean equals(Object obj) { if (!(obj instanceof StringMatrix)) return false; StringMatrix sm = (StringMatrix) obj; if (!header.equals(sm.header)) return false; if (matrix.size() != sm.matrix.size()) return false; for (int i = 0; i < matrix.size(); i++){ Vector row = (Vector) matrix.get(i); Vector smRow = (Vector) sm.matrix.get(i); if (!(row.equals(smRow))) return false; } return true; } /** * @return */ public Vector getMatrix() { return matrix; } /** * @return */ public String[] getHeader() { String[] result = new String[header.size()]; header.toArray(result); return result; } }