001: /*
002: * SortDefinition.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.storage;
013:
014: /**
015: * A class to store the sort definition of a result set (e.g. DataStore,
016: * DatastoreTableModel)
017: *
018: * @author support@sql-workbench.net
019: */
020: public class SortDefinition {
021: private boolean[] sortAscending;
022: private int[] sortColumns;
023:
024: public SortDefinition() {
025: }
026:
027: public SortDefinition(int column, boolean ascending) {
028: sortColumns = new int[] { column };
029: sortAscending = new boolean[] { ascending };
030: }
031:
032: public SortDefinition(int[] columns, boolean[] ascending) {
033: sortColumns = new int[columns.length];
034: sortAscending = new boolean[ascending.length];
035: System.arraycopy(columns, 0, sortColumns, 0, columns.length);
036: System.arraycopy(ascending, 0, sortAscending, 0,
037: ascending.length);
038: }
039:
040: /**
041: * Create a copy of this sort definition.
042: *
043: * @return a new SortDefinition with the same settings as <tt>this</tt>
044: */
045: public SortDefinition createCopy() {
046: SortDefinition copy = new SortDefinition();
047: if (sortColumns != null) {
048: copy.sortColumns = new int[sortColumns.length];
049: System.arraycopy(this .sortColumns, 0, copy.sortColumns, 0,
050: this .sortColumns.length);
051: copy.sortAscending = new boolean[sortAscending.length];
052: System.arraycopy(this .sortAscending, 0, copy.sortAscending,
053: 0, this .sortAscending.length);
054: }
055: return copy;
056: }
057:
058: @Override
059: public int hashCode() {
060: int hash = 7;
061: hash = 67
062: * hash
063: + (this .sortAscending != null ? this .sortAscending
064: .hashCode() : 0);
065: hash = 67
066: * hash
067: + (this .sortColumns != null ? this .sortColumns
068: .hashCode() : 0);
069: return hash;
070: }
071:
072: public boolean equals(Object other) {
073: if (other instanceof SortDefinition) {
074: SortDefinition sd = (SortDefinition) other;
075: if (sd.getColumnCount() != this .getColumnCount())
076: return false;
077: if (getColumnCount() == 0)
078: return true;
079: for (int i = 0; i < sortColumns.length; i++) {
080: if (sortColumns[i] != sd.sortColumns[i])
081: return false;
082: if (sortAscending[i] != sd.sortAscending[i])
083: return false;
084: }
085: return true;
086: }
087: return false;
088: }
089:
090: public boolean hasColumns() {
091: return getColumnCount() != 0;
092: }
093:
094: /**
095: * Returns the numer of sort columns defined.
096: * @return the count of sort columns
097: */
098: public int getColumnCount() {
099: if (this .sortColumns == null)
100: return 0;
101: return sortColumns.length;
102: }
103:
104: /**
105: * Return the column index from the result set based on the
106: * index in the column list (the primary sort column has
107: * index 0)
108: *
109: * @param definitionIndex the index in the list of columns
110: * @return the column index in the result set or -1 if no sort columns are defined
111: */
112: public int getSortColumnByIndex(int definitionIndex)
113: throws ArrayIndexOutOfBoundsException {
114: if (sortColumns == null)
115: return -1;
116: return sortColumns[definitionIndex];
117: }
118:
119: /**
120: * Return true if the data is sorted in ascending order for the given column.
121: * @param col the column index in the result set
122: * @return True if sorted in ascending order
123: */
124: public boolean isSortAscending(int col) {
125: int index = findSortColumnIndex(col);
126: if (index < 0)
127: return false;
128: return sortAscending[index];
129: }
130:
131: /**
132: * Check if the given column is the first column in the sort definition
133: * @param col the column index in the result set
134: * @return true if the column was found and if it's the first column
135: */
136: public boolean isPrimarySortColumn(int col) {
137: int index = findSortColumnIndex(col);
138: return (index == 0);
139: }
140:
141: /**
142: * Check if the table is sorted by a column
143: * @return true if the given column is a sort column
144: * @see #isSortAscending(int)
145: */
146: public boolean isSortColumn(int col) {
147: int index = findSortColumnIndex(col);
148: return (index > -1);
149: }
150:
151: /**
152: * Remove the specified sort column from this definition.
153: * If the column is not found, nothing is changed.
154: *
155: * @param column the column index in the result set
156: */
157: public void removeSortColumn(int column) {
158: int index = findSortColumnIndex(column);
159: if (index < 0)
160: return;
161:
162: if (this .sortColumns.length == 1) {
163: this .sortColumns = null;
164: this .sortAscending = null;
165: return;
166: }
167:
168: int[] newColumns = new int[sortColumns.length - 1];
169: boolean[] newDir = new boolean[sortColumns.length - 1];
170:
171: // Copy the old values before the removed column
172: System.arraycopy(sortColumns, 0, newColumns, 0, index);
173: System.arraycopy(sortAscending, 0, newDir, 0, index);
174:
175: // Copy the old values after the removed column
176: System.arraycopy(sortColumns, index + 1, newColumns, index,
177: sortColumns.length - index - 1);
178: System.arraycopy(sortAscending, 0, newDir, index,
179: sortColumns.length - index - 1);
180:
181: this .sortColumns = newColumns;
182: this .sortAscending = newDir;
183: }
184:
185: /**
186: * Add a column to the list of sort columns.
187: * If sort columns exist, the new column is added at the end, otherwise
188: * the column will be the primary sort column.
189: *
190: * @param column the column index (inside the result set) to be added
191: * @param ascending true if sorting should be ascending
192: */
193: public void addSortColumn(int column, boolean ascending) {
194: setSortColumn(column, ascending, true);
195: }
196:
197: /**
198: * Define a single column as the sort column.
199: * If sort columns exist, they are reqplaced with the given column
200: *
201: * @param column the column index (inside the result set) to be set
202: * @param ascending true if sorting should be ascending
203: */
204: public void setSortColumn(int column, boolean ascending) {
205: setSortColumn(column, ascending, false);
206: }
207:
208: private void setSortColumn(int column, boolean ascending,
209: boolean addSortColumn) {
210: if (!addSortColumn || sortColumns == null) {
211: this .sortColumns = new int[] { column };
212: this .sortAscending = new boolean[] { ascending };
213: } else {
214: int index = findSortColumnIndex(column);
215:
216: if (index < 0) {
217: // No definition for this column found, add the column to the list of columns
218: int[] newColumns = new int[sortColumns.length + 1];
219: boolean[] newDir = new boolean[sortColumns.length + 1];
220:
221: System.arraycopy(sortColumns, 0, newColumns, 0,
222: sortColumns.length);
223: System.arraycopy(sortAscending, 0, newDir, 0,
224: sortColumns.length);
225:
226: newColumns[sortColumns.length] = column;
227: newDir[sortColumns.length] = ascending;
228:
229: this .sortColumns = newColumns;
230: this .sortAscending = newDir;
231: } else {
232: // if this column already existed, simply store the new sort order
233: this .sortAscending[index] = ascending;
234: }
235: }
236: }
237:
238: /**
239: * Finds the index of a column in the internal array
240: * based on the index of the result set
241: *
242: * @param column
243: * @return -1 if the column was not found. The index in sortColumns otherwise
244: */
245: private int findSortColumnIndex(int column) {
246: if (this .sortColumns == null)
247: return -1;
248: for (int i = 0; i < this .sortColumns.length; i++) {
249: if (sortColumns[i] == column)
250: return i;
251: }
252: return -1;
253: }
254:
255: }
|