1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 package org.apache.openoffice.comp.sdbc.dbtools.util;
23 
24 import java.util.ArrayList;
25 
26 import org.apache.openoffice.comp.sdbc.dbtools.comphelper.PropertySet;
27 
28 import com.sun.star.beans.XPropertySet;
29 import com.sun.star.container.XNameAccess;
30 import com.sun.star.io.XInputStream;
31 import com.sun.star.lang.IllegalArgumentException;
32 import com.sun.star.sdbc.SQLException;
33 import com.sun.star.sdbc.XArray;
34 import com.sun.star.sdbc.XBlob;
35 import com.sun.star.sdbc.XClob;
36 import com.sun.star.sdbc.XCloseable;
37 import com.sun.star.sdbc.XColumnLocate;
38 import com.sun.star.sdbc.XRef;
39 import com.sun.star.sdbc.XResultSet;
40 import com.sun.star.sdbc.XResultSetMetaData;
41 import com.sun.star.sdbc.XResultSetMetaDataSupplier;
42 import com.sun.star.sdbc.XRow;
43 import com.sun.star.sdbcx.CompareBookmark;
44 import com.sun.star.sdbcx.XRowLocate;
45 import com.sun.star.uno.AnyConverter;
46 import com.sun.star.util.Date;
47 import com.sun.star.util.DateTime;
48 import com.sun.star.util.Time;
49 
50 public class CustomResultSet extends PropertySet
51         implements XResultSet, XCloseable, XRowLocate, XPropertySet, XColumnLocate, XRow, XResultSetMetaDataSupplier {
52 
53     private XResultSetMetaData resultSetMetaData;
54     private ArrayList<ORowSetValue[]> rows;
55     /// 0-based:
56     private int currentRow = -1;
57     /// 1-based:
58     private int currentColumn;
59 
CustomResultSet(XResultSetMetaData resultSetMetaData, ArrayList<ORowSetValue[]> rows)60     public CustomResultSet(XResultSetMetaData resultSetMetaData, ArrayList<ORowSetValue[]> rows) {
61         this.resultSetMetaData = resultSetMetaData;
62         this.rows = rows;
63     }
64 
65     // XComponent:
66     @Override
postDisposing()67     protected void postDisposing() {
68     }
69 
70     // XCloseable:
71 
close()72     public void close() throws SQLException {
73         dispose();
74     }
75 
76     // XResultSet:
77 
getField(int columnIndex)78     private ORowSetValue getField(int columnIndex) throws SQLException {
79         if (isBeforeFirst() || isAfterLast()) {
80             throw new SQLException("Row out of range");
81         }
82         ORowSetValue[] fields = rows.get(currentRow);
83         if (columnIndex < 1 || fields.length < columnIndex) {
84             throw new SQLException("Column out of range");
85         }
86         currentColumn = columnIndex;
87         return fields[columnIndex - 1];
88     }
89 
absolute(int position)90     public synchronized boolean absolute(int position) throws SQLException {
91         checkDisposed();
92         if (position >= 0) {
93             currentRow = position;
94         } else {
95             currentRow = rows.size() + position;
96         }
97         if (currentRow <= -1) {
98             currentRow = -1;
99             return false;
100         }
101         if (currentRow >= rows.size()) {
102             currentRow = rows.size();
103             return false;
104         }
105         return true;
106     }
107 
afterLast()108     public synchronized void afterLast() throws SQLException {
109         checkDisposed();
110         currentRow = rows.size();
111     }
112 
beforeFirst()113     public synchronized void beforeFirst() throws SQLException {
114         checkDisposed();
115         currentRow = -1;
116     }
117 
first()118     public synchronized boolean first() throws SQLException {
119         checkDisposed();
120         currentRow = 0;
121         return true;
122     }
123 
getRow()124     public synchronized int getRow() throws SQLException {
125         checkDisposed();
126         return currentRow + 1;
127     }
128 
getStatement()129     public synchronized Object getStatement() throws SQLException {
130         checkDisposed();
131         return null;
132     }
133 
isAfterLast()134     public synchronized boolean isAfterLast() throws SQLException {
135         checkDisposed();
136         return currentRow == rows.size();
137     }
138 
isBeforeFirst()139     public synchronized boolean isBeforeFirst() throws SQLException {
140         checkDisposed();
141         return currentRow == -1;
142     }
143 
isFirst()144     public synchronized boolean isFirst() throws SQLException {
145         checkDisposed();
146         return currentRow == 0;
147     }
148 
isLast()149     public synchronized boolean isLast() throws SQLException {
150         checkDisposed();
151         return currentRow == (rows.size() - 1);
152     }
153 
last()154     public synchronized boolean last() throws SQLException {
155         checkDisposed();
156         currentRow = rows.size() - 1;
157         return true;
158     }
159 
next()160     public synchronized boolean next() throws SQLException {
161         checkDisposed();
162         if (currentRow < rows.size()) {
163             ++currentRow;
164         }
165         return currentRow < rows.size();
166     }
167 
previous()168     public synchronized boolean previous() throws SQLException {
169         checkDisposed();
170         if (currentRow > -1) {
171             --currentRow;
172         }
173         return currentRow > -1;
174     }
175 
refreshRow()176     public synchronized void refreshRow() throws SQLException {
177         checkDisposed();
178     }
179 
relative(int offset)180     public synchronized boolean relative(int offset) throws SQLException {
181         checkDisposed();
182         currentRow += offset;
183         if (currentRow <= -1) {
184             currentRow = -1;
185             return false;
186         }
187         if (currentRow >= rows.size()) {
188             currentRow = rows.size();
189             return false;
190         }
191         return true;
192     }
193 
rowDeleted()194     public synchronized boolean rowDeleted() throws SQLException {
195         checkDisposed();
196         return false;
197     }
198 
rowInserted()199     public synchronized boolean rowInserted() throws SQLException {
200         checkDisposed();
201         return false;
202     }
203 
rowUpdated()204     public synchronized boolean rowUpdated() throws SQLException {
205         checkDisposed();
206         return false;
207     }
208 
209     // XResultSetMetaDataSupplier:
210 
getMetaData()211     public synchronized XResultSetMetaData getMetaData() throws SQLException {
212         checkDisposed();
213         return resultSetMetaData;
214     }
215 
216     // XRow:
217 
getArray(int columnIndex)218     public synchronized XArray getArray(int columnIndex) throws SQLException {
219         checkDisposed();
220         return null;
221     }
222 
getBinaryStream(int columnIndex)223     public synchronized XInputStream getBinaryStream(int columnIndex) throws SQLException {
224         checkDisposed();
225         return null;
226     }
227 
getBlob(int columnIndex)228     public synchronized XBlob getBlob(int columnIndex) throws SQLException {
229         checkDisposed();
230         return null;
231     }
232 
getBoolean(int columnIndex)233     public synchronized boolean getBoolean(int columnIndex) throws SQLException {
234         checkDisposed();
235         ORowSetValue field = getField(columnIndex);
236         return field.getBoolean();
237     }
238 
getByte(int columnIndex)239     public synchronized byte getByte(int columnIndex) throws SQLException {
240         checkDisposed();
241         ORowSetValue field = getField(columnIndex);
242         return field.getInt8();
243     }
244 
getBytes(int columnIndex)245     public synchronized byte[] getBytes(int columnIndex) throws SQLException {
246         checkDisposed();
247         ORowSetValue field = getField(columnIndex);
248         return field.getSequence();
249     }
250 
getCharacterStream(int columnIndex)251     public synchronized XInputStream getCharacterStream(int columnIndex) throws SQLException {
252         checkDisposed();
253         return null;
254     }
255 
getClob(int columnIndex)256     public synchronized XClob getClob(int columnIndex) throws SQLException {
257         checkDisposed();
258         return null;
259     }
260 
getDate(int columnIndex)261     public synchronized Date getDate(int columnIndex) throws SQLException {
262         checkDisposed();
263         ORowSetValue field = getField(columnIndex);
264         return field.getDate();
265     }
266 
getDouble(int columnIndex)267     public synchronized double getDouble(int columnIndex) throws SQLException {
268         checkDisposed();
269         ORowSetValue field = getField(columnIndex);
270         return field.getDouble();
271     }
272 
getFloat(int columnIndex)273     public synchronized float getFloat(int columnIndex) throws SQLException {
274         checkDisposed();
275         ORowSetValue field = getField(columnIndex);
276         return field.getFloat();
277     }
278 
getInt(int columnIndex)279     public synchronized int getInt(int columnIndex) throws SQLException {
280         checkDisposed();
281         ORowSetValue field = getField(columnIndex);
282         return field.getInt32();
283     }
284 
getLong(int columnIndex)285     public synchronized long getLong(int columnIndex) throws SQLException {
286         checkDisposed();
287         ORowSetValue field = getField(columnIndex);
288         return field.getLong();
289     }
290 
getObject(int columnIndex, XNameAccess arg1)291     public synchronized Object getObject(int columnIndex, XNameAccess arg1) throws SQLException {
292         checkDisposed();
293         ORowSetValue field = getField(columnIndex);
294         return field.makeAny();
295     }
296 
getRef(int columnIndex)297     public synchronized XRef getRef(int columnIndex) throws SQLException {
298         checkDisposed();
299         return null;
300     }
301 
getShort(int columnIndex)302     public synchronized short getShort(int columnIndex) throws SQLException {
303         checkDisposed();
304         ORowSetValue field = getField(columnIndex);
305         return field.getInt16();
306     }
307 
getString(int columnIndex)308     public synchronized String getString(int columnIndex) throws SQLException {
309         checkDisposed();
310         ORowSetValue field = getField(columnIndex);
311         return field.getString();
312     }
313 
getTime(int columnIndex)314     public synchronized Time getTime(int columnIndex) throws SQLException {
315         checkDisposed();
316         ORowSetValue field = getField(columnIndex);
317         return field.getTime();
318     }
319 
getTimestamp(int columnIndex)320     public synchronized DateTime getTimestamp(int columnIndex) throws SQLException {
321         checkDisposed();
322         ORowSetValue field = getField(columnIndex);
323         return field.getDateTime();
324     }
325 
wasNull()326     public synchronized boolean wasNull() throws SQLException {
327         checkDisposed();
328         ORowSetValue field = getField(currentColumn);
329         return field.isNull();
330     }
331 
332     // XColumnLocate:
333 
findColumn(String name)334     public synchronized int findColumn(String name) throws SQLException {
335         checkDisposed();
336         for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
337             boolean isCaseSensitive = resultSetMetaData.isCaseSensitive(i);
338             String columnName = resultSetMetaData.getColumnName(i);
339             boolean matched;
340             if (isCaseSensitive) {
341                 matched = columnName.equals(name);
342             } else {
343                 matched = columnName.equalsIgnoreCase(name);
344             }
345             if (matched) {
346                 return i;
347             }
348         }
349         String error = SharedResources.getInstance().getResourceStringWithSubstitution(
350                 Resources.STR_UNKNOWN_COLUMN_NAME, "$columnname$", name);
351         throw new SQLException(error, this, StandardSQLState.SQL_COLUMN_NOT_FOUND.text(), 0, null);
352     }
353 
354     // XRowLocate:
355 
compareBookmarks(Object arg0, Object arg1)356     public synchronized int compareBookmarks(Object arg0, Object arg1) throws SQLException {
357         checkDisposed();
358 
359         int bookmark1, bookmark2;
360         try {
361             bookmark1 = AnyConverter.toInt(arg0);
362             bookmark2 = AnyConverter.toInt(arg1);
363         } catch (IllegalArgumentException illegalArgumentException) {
364             return CompareBookmark.NOT_COMPARABLE;
365         }
366 
367         if (bookmark1 < bookmark2) {
368             return CompareBookmark.LESS;
369         } else if (bookmark1 > bookmark2) {
370             return CompareBookmark.GREATER;
371         } else {
372             return CompareBookmark.EQUAL;
373         }
374     }
375 
getBookmark()376     public synchronized Object getBookmark() throws SQLException {
377         checkDisposed();
378         return currentRow;
379     }
380 
hasOrderedBookmarks()381     public synchronized boolean hasOrderedBookmarks() throws SQLException {
382         checkDisposed();
383         return true;
384     }
385 
hashBookmark(Object arg0)386     public synchronized int hashBookmark(Object arg0) throws SQLException {
387         checkDisposed();
388         int bookmark;
389         try {
390             bookmark = AnyConverter.toInt(arg0);
391         } catch (IllegalArgumentException illegalArgumentException) {
392             throw new SQLException("Bad bookmark", this, StandardSQLState.SQL_INVALID_BOOKMARK_VALUE.text(), 0, null);
393         }
394         return bookmark;
395     }
396 
moveRelativeToBookmark(Object arg0, int arg1)397     public synchronized boolean moveRelativeToBookmark(Object arg0, int arg1) throws SQLException {
398         checkDisposed();
399         int bookmark;
400         boolean moved = false;
401         try {
402             bookmark = AnyConverter.toInt(arg0);
403             moved = absolute(bookmark);
404             if (moved) {
405                 moved = relative(arg1);
406             }
407         } catch (IllegalArgumentException illegalArgumentException) {
408         }
409         if (!moved) {
410             afterLast();
411         }
412         return moved;
413     }
414 
moveToBookmark(Object arg0)415     public synchronized boolean moveToBookmark(Object arg0) throws SQLException {
416         checkDisposed();
417         int bookmark;
418         boolean moved = false;
419         try {
420             bookmark = AnyConverter.toInt(arg0);
421             moved = absolute(bookmark);
422         } catch (IllegalArgumentException illegalArgumentException) {
423         }
424         if (!moved) {
425             afterLast();
426         }
427         return moved;
428     }
429 }
430