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.util.ORowSetValue;
27 import org.apache.openoffice.comp.sdbc.dbtools.util.StandardSQLState;
28 
29 import com.sun.star.beans.PropertyVetoException;
30 import com.sun.star.beans.UnknownPropertyException;
31 import com.sun.star.beans.XPropertyChangeListener;
32 import com.sun.star.beans.XPropertySet;
33 import com.sun.star.beans.XPropertySetInfo;
34 import com.sun.star.beans.XVetoableChangeListener;
35 import com.sun.star.container.XNameAccess;
36 import com.sun.star.io.XInputStream;
37 import com.sun.star.lang.IllegalArgumentException;
38 import com.sun.star.lang.WrappedTargetException;
39 import com.sun.star.lib.uno.helper.ComponentBase;
40 import com.sun.star.sdbc.SQLException;
41 import com.sun.star.sdbc.XArray;
42 import com.sun.star.sdbc.XBlob;
43 import com.sun.star.sdbc.XClob;
44 import com.sun.star.sdbc.XCloseable;
45 import com.sun.star.sdbc.XColumnLocate;
46 import com.sun.star.sdbc.XRef;
47 import com.sun.star.sdbc.XResultSet;
48 import com.sun.star.sdbc.XResultSetMetaData;
49 import com.sun.star.sdbc.XResultSetMetaDataSupplier;
50 import com.sun.star.sdbc.XRow;
51 import com.sun.star.sdbcx.CompareBookmark;
52 import com.sun.star.sdbcx.XColumnsSupplier;
53 import com.sun.star.sdbcx.XRowLocate;
54 import com.sun.star.uno.AnyConverter;
55 import com.sun.star.uno.UnoRuntime;
56 import com.sun.star.util.Date;
57 import com.sun.star.util.DateTime;
58 import com.sun.star.util.Time;
59 
60 public class DatabaseMetaDataResultSet extends ComponentBase
61         implements XResultSet, XCloseable, XColumnsSupplier, XRowLocate, XPropertySet, XColumnLocate, XRow, XResultSetMetaDataSupplier {
62 
63     private XCloseable implCloseable;
64     private XResultSetMetaDataSupplier implResultSetMetaDataSupplier;
65     private XColumnLocate implColumnLocate;
66     private XPropertySet implPropertySet;
67     private XColumnsSupplier implColumnSupplier;
68     private ArrayList<ORowSetValue[]> rows;
69     /// 0-based:
70     private int currentRow = -1;
71     /// 1-based:
72     private int currentColumn;
73 
DatabaseMetaDataResultSet(XResultSet impl, ArrayList<ORowSetValue[]> rows)74     public DatabaseMetaDataResultSet(XResultSet impl, ArrayList<ORowSetValue[]> rows) {
75         implCloseable = UnoRuntime.queryInterface(XCloseable.class, impl);
76         implPropertySet = UnoRuntime.queryInterface(XPropertySet.class, impl);
77         implColumnSupplier = UnoRuntime.queryInterface(XColumnsSupplier.class, impl);
78         implColumnLocate = UnoRuntime.queryInterface(XColumnLocate.class, impl);
79         implResultSetMetaDataSupplier = UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, impl);
80         this.rows = rows;
81     }
82 
83     // XComponent:
84     @Override
postDisposing()85     protected void postDisposing() {
86         try {
87             implCloseable.close();
88         } catch (SQLException sqlException) {
89         }
90     }
91 
92     // XCloseable:
93 
close()94     public void close() throws SQLException {
95         dispose();
96     }
97 
98     // XResultSet:
99 
getField(int columnIndex)100     private ORowSetValue getField(int columnIndex) throws SQLException {
101         if (isBeforeFirst() || isAfterLast()) {
102             throw new SQLException("Row out of range");
103         }
104         ORowSetValue[] fields = rows.get(currentRow);
105         if (columnIndex < 1 || fields.length < columnIndex) {
106             throw new SQLException("Column out of range");
107         }
108         currentColumn = columnIndex;
109         return fields[columnIndex - 1];
110     }
111 
absolute(int position)112     public synchronized boolean absolute(int position) throws SQLException {
113         checkDisposed();
114         if (position >= 0) {
115             currentRow = position;
116         } else {
117             currentRow = rows.size() + position;
118         }
119         if (currentRow <= -1) {
120             currentRow = -1;
121             return false;
122         }
123         if (currentRow >= rows.size()) {
124             currentRow = rows.size();
125             return false;
126         }
127         return true;
128     }
129 
afterLast()130     public synchronized void afterLast() throws SQLException {
131         checkDisposed();
132         currentRow = rows.size();
133     }
134 
beforeFirst()135     public synchronized void beforeFirst() throws SQLException {
136         checkDisposed();
137         currentRow = -1;
138     }
139 
first()140     public synchronized boolean first() throws SQLException {
141         checkDisposed();
142         currentRow = 0;
143         return true;
144     }
145 
getRow()146     public synchronized int getRow() throws SQLException {
147         checkDisposed();
148         return currentRow + 1;
149     }
150 
getStatement()151     public synchronized Object getStatement() throws SQLException {
152         checkDisposed();
153         return null;
154     }
155 
isAfterLast()156     public synchronized boolean isAfterLast() throws SQLException {
157         checkDisposed();
158         return currentRow == rows.size();
159     }
160 
isBeforeFirst()161     public synchronized boolean isBeforeFirst() throws SQLException {
162         checkDisposed();
163         return currentRow == -1;
164     }
165 
isFirst()166     public synchronized boolean isFirst() throws SQLException {
167         checkDisposed();
168         return currentRow == 0;
169     }
170 
isLast()171     public synchronized boolean isLast() throws SQLException {
172         checkDisposed();
173         return currentRow == (rows.size() - 1);
174     }
175 
last()176     public synchronized boolean last() throws SQLException {
177         checkDisposed();
178         currentRow = rows.size() - 1;
179         return true;
180     }
181 
next()182     public synchronized boolean next() throws SQLException {
183         checkDisposed();
184         if (currentRow < rows.size()) {
185             ++currentRow;
186         }
187         return currentRow < rows.size();
188     }
189 
previous()190     public synchronized boolean previous() throws SQLException {
191         checkDisposed();
192         if (currentRow > -1) {
193             --currentRow;
194         }
195         return currentRow > -1;
196     }
197 
refreshRow()198     public synchronized void refreshRow() throws SQLException {
199         checkDisposed();
200     }
201 
relative(int offset)202     public synchronized boolean relative(int offset) throws SQLException {
203         checkDisposed();
204         currentRow += offset;
205         if (currentRow <= -1) {
206             currentRow = -1;
207             return false;
208         }
209         if (currentRow >= rows.size()) {
210             currentRow = rows.size();
211             return false;
212         }
213         return true;
214     }
215 
rowDeleted()216     public synchronized boolean rowDeleted() throws SQLException {
217         checkDisposed();
218         return false;
219     }
220 
rowInserted()221     public synchronized boolean rowInserted() throws SQLException {
222         checkDisposed();
223         return false;
224     }
225 
rowUpdated()226     public synchronized boolean rowUpdated() throws SQLException {
227         checkDisposed();
228         return false;
229     }
230 
231     // XResultSetMetaDataSupplier:
232 
getMetaData()233     public synchronized XResultSetMetaData getMetaData() throws SQLException {
234         checkDisposed();
235         return implResultSetMetaDataSupplier.getMetaData();
236     }
237 
238     // XRow:
239 
getArray(int columnIndex)240     public synchronized XArray getArray(int columnIndex) throws SQLException {
241         checkDisposed();
242         return null;
243     }
244 
getBinaryStream(int columnIndex)245     public synchronized XInputStream getBinaryStream(int columnIndex) throws SQLException {
246         checkDisposed();
247         return null;
248     }
249 
getBlob(int columnIndex)250     public synchronized XBlob getBlob(int columnIndex) throws SQLException {
251         checkDisposed();
252         return null;
253     }
254 
getBoolean(int columnIndex)255     public synchronized boolean getBoolean(int columnIndex) throws SQLException {
256         checkDisposed();
257         ORowSetValue field = getField(columnIndex);
258         return field.getBoolean();
259     }
260 
getByte(int columnIndex)261     public synchronized byte getByte(int columnIndex) throws SQLException {
262         checkDisposed();
263         ORowSetValue field = getField(columnIndex);
264         return field.getInt8();
265     }
266 
getBytes(int columnIndex)267     public synchronized byte[] getBytes(int columnIndex) throws SQLException {
268         checkDisposed();
269         ORowSetValue field = getField(columnIndex);
270         return field.getSequence();
271     }
272 
getCharacterStream(int columnIndex)273     public synchronized XInputStream getCharacterStream(int columnIndex) throws SQLException {
274         checkDisposed();
275         return null;
276     }
277 
getClob(int columnIndex)278     public synchronized XClob getClob(int columnIndex) throws SQLException {
279         checkDisposed();
280         return null;
281     }
282 
getDate(int columnIndex)283     public synchronized Date getDate(int columnIndex) throws SQLException {
284         checkDisposed();
285         ORowSetValue field = getField(columnIndex);
286         return field.getDate();
287     }
288 
getDouble(int columnIndex)289     public synchronized double getDouble(int columnIndex) throws SQLException {
290         checkDisposed();
291         ORowSetValue field = getField(columnIndex);
292         return field.getDouble();
293     }
294 
getFloat(int columnIndex)295     public synchronized float getFloat(int columnIndex) throws SQLException {
296         checkDisposed();
297         ORowSetValue field = getField(columnIndex);
298         return field.getFloat();
299     }
300 
getInt(int columnIndex)301     public synchronized int getInt(int columnIndex) throws SQLException {
302         checkDisposed();
303         ORowSetValue field = getField(columnIndex);
304         return field.getInt32();
305     }
306 
getLong(int columnIndex)307     public synchronized long getLong(int columnIndex) throws SQLException {
308         checkDisposed();
309         ORowSetValue field = getField(columnIndex);
310         return field.getLong();
311     }
312 
getObject(int columnIndex, XNameAccess arg1)313     public synchronized Object getObject(int columnIndex, XNameAccess arg1) throws SQLException {
314         checkDisposed();
315         ORowSetValue field = getField(columnIndex);
316         return field.makeAny();
317     }
318 
getRef(int columnIndex)319     public synchronized XRef getRef(int columnIndex) throws SQLException {
320         checkDisposed();
321         return null;
322     }
323 
getShort(int columnIndex)324     public synchronized short getShort(int columnIndex) throws SQLException {
325         checkDisposed();
326         ORowSetValue field = getField(columnIndex);
327         return field.getInt16();
328     }
329 
getString(int columnIndex)330     public synchronized String getString(int columnIndex) throws SQLException {
331         checkDisposed();
332         ORowSetValue field = getField(columnIndex);
333         return field.getString();
334     }
335 
getTime(int columnIndex)336     public synchronized Time getTime(int columnIndex) throws SQLException {
337         checkDisposed();
338         ORowSetValue field = getField(columnIndex);
339         return field.getTime();
340     }
341 
getTimestamp(int columnIndex)342     public synchronized DateTime getTimestamp(int columnIndex) throws SQLException {
343         checkDisposed();
344         ORowSetValue field = getField(columnIndex);
345         return field.getDateTime();
346     }
347 
wasNull()348     public synchronized boolean wasNull() throws SQLException {
349         checkDisposed();
350         ORowSetValue field = getField(currentColumn);
351         return field.isNull();
352     }
353 
354     // XColumnLocate:
355 
findColumn(String arg0)356     public synchronized int findColumn(String arg0) throws SQLException {
357         checkDisposed();
358         return implColumnLocate.findColumn(arg0);
359     }
360 
361     // XPropertySet:
362 
addPropertyChangeListener(String arg0, XPropertyChangeListener arg1)363     public synchronized void addPropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
364         checkDisposed();
365         implPropertySet.addPropertyChangeListener(arg0, arg1);
366     }
367 
addVetoableChangeListener(String arg0, XVetoableChangeListener arg1)368     public synchronized void addVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
369         checkDisposed();
370         implPropertySet.addVetoableChangeListener(arg0, arg1);
371     }
372 
getPropertySetInfo()373     public synchronized XPropertySetInfo getPropertySetInfo() {
374         checkDisposed();
375         return implPropertySet.getPropertySetInfo();
376     }
377 
getPropertyValue(String arg0)378     public synchronized Object getPropertyValue(String arg0) throws UnknownPropertyException, WrappedTargetException {
379         checkDisposed();
380         return implPropertySet.getPropertyValue(arg0);
381     }
382 
removePropertyChangeListener(String arg0, XPropertyChangeListener arg1)383     public synchronized void removePropertyChangeListener(String arg0, XPropertyChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
384         checkDisposed();
385         implPropertySet.removePropertyChangeListener(arg0, arg1);
386     }
387 
removeVetoableChangeListener(String arg0, XVetoableChangeListener arg1)388     public synchronized void removeVetoableChangeListener(String arg0, XVetoableChangeListener arg1) throws UnknownPropertyException, WrappedTargetException {
389         checkDisposed();
390         implPropertySet.removeVetoableChangeListener(arg0, arg1);
391     }
392 
setPropertyValue(String arg0, Object arg1)393     public synchronized void setPropertyValue(String arg0, Object arg1)
394             throws UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException {
395         checkDisposed();
396         implPropertySet.setPropertyValue(arg0, arg1);
397     }
398 
399     // XRowLocate:
400 
compareBookmarks(Object arg0, Object arg1)401     public synchronized int compareBookmarks(Object arg0, Object arg1) throws SQLException {
402         checkDisposed();
403 
404         int bookmark1, bookmark2;
405         try {
406             bookmark1 = AnyConverter.toInt(arg0);
407             bookmark2 = AnyConverter.toInt(arg1);
408         } catch (IllegalArgumentException illegalArgumentException) {
409             return CompareBookmark.NOT_COMPARABLE;
410         }
411 
412         if (bookmark1 < bookmark2) {
413             return CompareBookmark.LESS;
414         } else if (bookmark1 > bookmark2) {
415             return CompareBookmark.GREATER;
416         } else {
417             return CompareBookmark.EQUAL;
418         }
419     }
420 
getBookmark()421     public synchronized Object getBookmark() throws SQLException {
422         checkDisposed();
423         return currentRow;
424     }
425 
hasOrderedBookmarks()426     public synchronized boolean hasOrderedBookmarks() throws SQLException {
427         checkDisposed();
428         return true;
429     }
430 
hashBookmark(Object arg0)431     public synchronized int hashBookmark(Object arg0) throws SQLException {
432         checkDisposed();
433         int bookmark;
434         try {
435             bookmark = AnyConverter.toInt(arg0);
436         } catch (IllegalArgumentException illegalArgumentException) {
437             throw new SQLException("Bad bookmark", this, StandardSQLState.SQL_INVALID_BOOKMARK_VALUE.text(), 0, null);
438         }
439         return bookmark;
440     }
441 
moveRelativeToBookmark(Object arg0, int arg1)442     public synchronized boolean moveRelativeToBookmark(Object arg0, int arg1) throws SQLException {
443         checkDisposed();
444         int bookmark;
445         boolean moved = false;
446         try {
447             bookmark = AnyConverter.toInt(arg0);
448             moved = absolute(bookmark);
449             if (moved) {
450                 moved = relative(arg1);
451             }
452         } catch (IllegalArgumentException illegalArgumentException) {
453         }
454         if (!moved) {
455             afterLast();
456         }
457         return moved;
458     }
459 
moveToBookmark(Object arg0)460     public synchronized boolean moveToBookmark(Object arg0) throws SQLException {
461         checkDisposed();
462         int bookmark;
463         boolean moved = false;
464         try {
465             bookmark = AnyConverter.toInt(arg0);
466             moved = absolute(bookmark);
467         } catch (IllegalArgumentException illegalArgumentException) {
468         }
469         if (!moved) {
470             afterLast();
471         }
472         return moved;
473     }
474 
475     // XColumnSupplier:
476 
getColumns()477     public synchronized XNameAccess getColumns() {
478         checkDisposed();
479         return implColumnSupplier.getColumns();
480     }
481 }
482