--- /dev/null
+/*
+ * 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 = (String) 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;
+ }
+
+}