package com.quantum.sql; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import com.quantum.model.Bookmark; import com.quantum.model.Entity; /** * @author Tom Schneider * @author BC Holmes */ public abstract class SQLResultSetResults extends SQLResults { class ColumnArrayComparator implements Comparator { public int compare(Object arg0, Object arg1) { return compare((Column[]) arg0, (Column[]) arg1); } public int compare(Column[] columns0, Column[] columns1) { if (columns0 == null && columns1 == null) { return 0; } else if (columns0 == null) { return -1; } else if (columns1 == null) { return 1; } else if (columns0.length < columns1.length) { return -1; } else if (columns0.length > columns1.length) { return 1; } else { int result = 0; for (int i = 0, length = columns1 == null ? 0 : columns1.length; result == 0 && i < length; i++) { result = compare(columns0[i], columns1[i]); } return result; } } /** * @param columns0 * @param columns1 * @param result * @param i * @return */ private int compare(Column column0, Column column1) { if (column0 == null && column1 == null) { return 0; } else if (column0 == null) { return -1; } else if (column1 == null) { return 1; } else if (column0.getName() == null) { return -1; } else if (column1.getName() == null) { return 1; } else if (column0.getName() != null && column1.getName() != null && column0.getName().compareTo(column1.getName()) != 0) { return column0.getName().compareTo(column1.getName()); } else if (column0.getType() == null) { return -1; } else if (column1.getType() == null) { return 1; } else if (column0.getType() != null && column1.getType() != null && column0.getType().compareTo(column1.getType()) != 0) { return column0.getType().compareTo(column1.getType()); } else { return column0.getSize() - column1.getSize(); } } } public class Row { private final List elements; Row(List elements) { this.elements = elements; } public Object get(int columnNumber) { return (columnNumber > this.elements.size() || columnNumber <= 0) ? null : this.elements.get(columnNumber - 1); } public SQLResultSetResults getResultSet() { return SQLResultSetResults.this; } } public class Column { private final String name; private final String type; private final int size; Column(String name, String type, int size) { this.name = name; this.type = type; this.size = size; } public String getName() { return this.name; } public int getSize() { return this.size; } public String getType() { return this.type; } } private List rows = Collections.synchronizedList(new ArrayList()); private List columns = Collections.synchronizedList(new ArrayList()); private String query; private Bookmark bookmark; private final Entity entity; private String encoding = ""; private FilterSort filterSort = null; /** * @param entity * @param query2 */ public SQLResultSetResults(String query, Bookmark bookmark, Entity entity) { this.query = query; this.bookmark = bookmark; this.entity = entity; } public String getColumnName(int columnNumber) { Column column = getColumn(columnNumber); return column == null ? "" : column.getName(); } /** * @param columnNumber * @return */ protected Column getColumn(int columnNumber) { return columnNumber <= this.columns.size() ? (Column) this.columns.get(columnNumber-1) : null; } public Column[] getColumns() { return (Column[]) this.columns.toArray(new Column[this.columns.size()]); } protected void setColumns(Column[] columns) { Column[] original = getColumns(); if (new ColumnArrayComparator().compare(original, columns) != 0) { this.columns.clear(); this.columns.addAll(Arrays.asList(columns)); this.propertyChangeSupport.firePropertyChange("columns", original, columns); } } public Object getElement(int column, int row) { return ((Row) rows.get(row - 1)).get(column); } public int getColumnCount() { if (columns.size() > 0) { return columns.size(); } return 0; } public int getRowCount() { return rows.size(); } public String[] getColumnNames() { List names = new ArrayList(); for (Iterator i = this.columns.iterator(); i.hasNext();) { Column column = (Column) i.next(); names.add(column.getName()); } return (String[]) names.toArray(new String[names.size()]); } /** * Returns the resultSet. * @return boolean */ public boolean isResultSet() { return true; } public Row[] getRows() { return (Row[]) rows.toArray(new Row[this.rows.size()]); } /** * Returns the query. * @return String */ public String getQuery() { return this.query; } public String getFilteredQuery() { if (this.filterSort == null) { return this.query; } else { return this.query + this.filterSort.toString(); } } public Bookmark getBookmark() { return this.bookmark; } public Entity getEntity() { return this.entity; } /** * Returns the resultSet. * @return boolean */ public boolean isMetaData() { return false; } private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); public void addPropertyChangeListener(PropertyChangeListener listener) { this.propertyChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { this.propertyChangeSupport.removePropertyChangeListener(listener); } protected abstract void parseResultSet(ResultSet set) throws SQLException; public void refresh(Connection connection) throws SQLException { Statement statement = connection.createStatement(); try { ResultSet resultSet = statement.executeQuery(getFilteredQuery()); try { parseResultSet(resultSet); } finally { resultSet.close(); } } finally { statement.close(); } } protected void setRows(Row[] rows) { Row[] original = getRows(); this.rows.clear(); if (rows != null) { this.rows.addAll(Arrays.asList(rows)); } this.propertyChangeSupport.firePropertyChange("rows", original, getRows()); } public String getEncoding() { return this.encoding; } public void setEncoding(String encoding) { this.encoding = encoding; } public FilterSort getFilterSort() { return this.filterSort; } public void setFilterSort(FilterSort filterSort) { this.filterSort = filterSort; } }