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 
23 package com.sun.star.report;
24 
25 import com.sun.star.beans.UnknownPropertyException;
26 import com.sun.star.beans.XPropertySet;
27 import com.sun.star.container.XIndexAccess;
28 import com.sun.star.container.XNameAccess;
29 import com.sun.star.lang.IndexOutOfBoundsException;
30 import com.sun.star.lang.WrappedTargetException;
31 import com.sun.star.sdb.XParametersSupplier;
32 import com.sun.star.sdbc.DataType;
33 import com.sun.star.sdbc.SQLException;
34 import com.sun.star.sdbc.XResultSetMetaData;
35 import com.sun.star.sdbc.XResultSetMetaDataSupplier;
36 import com.sun.star.sdbc.XRow;
37 import com.sun.star.sdbc.XRowSet;
38 import com.sun.star.sdbcx.XColumnsSupplier;
39 import com.sun.star.uno.Any;
40 import com.sun.star.uno.UnoRuntime;
41 import com.sun.star.util.DateTime;
42 import com.sun.star.util.Time;
43 
44 import java.sql.Timestamp;
45 
46 public class SDBCReportData implements DataSource
47 {
48 
49     private final XRowSet rowSet;
50     private final XRow row;
51     private int rowCount;
52     private XIndexAccess parameters;
53     private int firstParameterIndex = -1;
54     private int columnCount;
55     private final String[] columnNames;
56     private final int[] columnTypes;
57 
SDBCReportData(final XRowSet rowSet)58     public SDBCReportData(final XRowSet rowSet) throws SQLException
59     {
60         row = (XRow) UnoRuntime.queryInterface(XRow.class, rowSet);
61         this.rowSet = rowSet;
62 
63         if (rowSet == null)
64         {
65             rowCount = 0;
66             columnCount = 0;
67             columnTypes = new int[1];
68             columnNames = new String[1];
69         }
70         else
71         {
72             final XParametersSupplier xSuppParams = (XParametersSupplier) UnoRuntime.queryInterface(
73                     XParametersSupplier.class, rowSet);
74             if (xSuppParams != null)
75             {
76                 parameters = xSuppParams.getParameters();
77             }
78 
79             final XColumnsSupplier columnsSup = (XColumnsSupplier) UnoRuntime.queryInterface(XColumnsSupplier.class, rowSet);
80             final XNameAccess columns = columnsSup.getColumns();
81             final String[] columnNamesList = columns.getElementNames();
82             final XResultSetMetaDataSupplier sup = (XResultSetMetaDataSupplier) UnoRuntime.queryInterface(XResultSetMetaDataSupplier.class, rowSet);
83             final XResultSetMetaData resultSetMetaData = sup.getMetaData();
84 
85             columnCount = resultSetMetaData.getColumnCount();
86             firstParameterIndex = columnCount + 1;
87             if (parameters != null)
88             {
89                 columnCount += parameters.getCount();
90             }
91 
92             columnTypes = new int[columnCount];
93             columnNames = new String[columnCount];
94 
95             for (int i = 1; i <= columnCount; ++i)
96             {
97                 if (i < firstParameterIndex)
98                 {
99                     columnNames[i - 1] = columnNamesList[i - 1];// resultSetMetaData.getColumnName(i);
100                     columnTypes[i - 1] = resultSetMetaData.getColumnType(i);
101                 }
102                 else
103                 {
104                     try
105                     {
106                         final XPropertySet paramColumn = (XPropertySet) UnoRuntime.queryInterface(
107                                 XPropertySet.class, parameters.getByIndex(i - firstParameterIndex));
108                         columnNames[i - 1] = (String) paramColumn.getPropertyValue("Name");
109                         columnTypes[i - 1] = (Integer) paramColumn.getPropertyValue("Type");
110                     }
111                     catch (Exception e)
112                     {
113                         columnNames[i - 1] = "Error";
114                         columnTypes[i - 1] = DataType.CHAR;
115                     }
116                 }
117             }
118 
119             if (rowSet.last())
120             {
121                 rowCount = rowSet.getRow();
122                 rowSet.beforeFirst();
123             }
124             else
125             {
126                 rowCount = 0;
127             }
128         }
129     }
130 
getColumnCount()131     public int getColumnCount() throws DataSourceException
132     {
133         return columnCount;
134     }
135 
getRowCount()136     public int getRowCount()
137     {
138         return rowCount;
139     }
140 
getColumnName(final int column)141     public String getColumnName(final int column) throws DataSourceException
142     {
143         return columnNames[column - 1];
144     }
145 
absolute(final int row)146     public boolean absolute(final int row) throws DataSourceException
147     {
148         if (rowSet == null)
149         {
150             return false;
151         }
152         try
153         {
154             if (row == 0)
155             {
156                 rowSet.beforeFirst();
157                 return true;
158             }
159             return rowSet.absolute(row);
160         }
161         catch (SQLException e)
162         {
163             throw new DataSourceException(e.getMessage(), e);
164         }
165     }
166 
next()167     public boolean next() throws DataSourceException
168     {
169         if (rowSet == null)
170         {
171             return false;
172         }
173         try
174         {
175             return rowSet.next();
176         }
177         catch (SQLException e)
178         {
179             throw new DataSourceException(e.getMessage(), e);
180         }
181     }
182 
close()183     public void close() throws DataSourceException
184     {
185     }
186 
187 //  public int getCurrentRow() throws DataSourceException
188 //  {
189 //    try
190 //    {
191 //      return rowSet.getRow();
192 //    }
193 //    catch (SQLException e)
194 //    {
195 //      throw new DataSourceException(e.getMessage(), e);
196 //    }
197 //  }
getDate(final Object obj)198     static private java.sql.Date getDate(final Object obj)
199     {
200         final java.sql.Date date;
201         if (obj instanceof com.sun.star.util.Date)
202         {
203             final com.sun.star.util.Date unodate = (com.sun.star.util.Date) obj;
204             date = java.sql.Date.valueOf(getDateString(unodate.Year, unodate.Month, unodate.Day).toString());
205         }
206         else
207         {
208             date = null;
209         }
210         return date;
211     }
212 
getTimeString(final int hours, final int minutes, final int seconds)213     private static StringBuffer getTimeString(final int hours, final int minutes, final int seconds)
214     {
215         final StringBuffer timeString = new StringBuffer();
216         if (hours < 10)
217         {
218             timeString.append('0');
219         }
220         timeString.append(hours);
221         timeString.append(':');
222         if (minutes < 10)
223         {
224             timeString.append('0');
225         }
226         timeString.append(minutes);
227         timeString.append(':');
228         if (seconds < 10)
229         {
230             timeString.append('0');
231         }
232         timeString.append(seconds);
233         return timeString;
234     }
235 
getDateString(final int years, final int months, final int days)236     static private StringBuffer getDateString(final int years, final int months, final int days)
237     {
238         final StringBuffer str = new StringBuffer();
239         str.append(years);
240         final StringBuffer str2 = new StringBuffer("0000");
241         str2.delete(0, str.length());
242         str.insert(0, str2);
243         str.append('-');
244         if (months < 10)
245         {
246             str.append('0');
247         }
248         str.append(months);
249         str.append('-');
250         if (days < 10)
251         {
252             str.append('0');
253         }
254         str.append(days);
255         return str;
256     }
257 
getTime(final Object obj)258     static private java.sql.Time getTime(final Object obj)
259     {
260         final java.sql.Time time;
261         if (obj instanceof Time)
262         {
263             final Time unoTime = (Time) obj;
264             time = java.sql.Time.valueOf(getTimeString(unoTime.Hours, unoTime.Minutes, unoTime.Seconds).toString());
265         }
266         else
267         {
268             time = null;
269         }
270         return time;
271     }
272 
getTimestamp(final Object obj)273     static private Timestamp getTimestamp(final Object obj)
274     {
275         final Timestamp ts;
276         if (obj instanceof DateTime)
277         {
278             final DateTime unoTs = (DateTime) obj;
279             final StringBuffer str = getDateString(unoTs.Year, unoTs.Month, unoTs.Day);
280             str.append(' ');
281             str.append(getTimeString(unoTs.Hours, unoTs.Minutes, unoTs.Seconds));
282             str.append('.');
283             str.append(unoTs.HundredthSeconds);
284             ts = java.sql.Timestamp.valueOf(str.toString());
285         }
286         else
287         {
288             ts = null;
289         }
290         return ts;
291     }
292 
getObject(final int column)293     public Object getObject(final int column) throws DataSourceException
294     {
295         if (rowSet == null)
296         {
297             return null;
298         }
299         try
300         {
301             final boolean isParameterValue = (parameters != null) && (column >= firstParameterIndex);
302             Object obj;
303             final boolean wasNull;
304             if (isParameterValue)
305             {
306                 final XPropertySet paramCol = (XPropertySet) UnoRuntime.queryInterface(
307                         XPropertySet.class, parameters.getByIndex(column - firstParameterIndex));
308                 obj = paramCol.getPropertyValue("Value");
309                 wasNull = obj == null;
310             }
311             else
312             {
313                 obj = row.getObject(column, null);
314                 wasNull = row.wasNull();
315             }
316 
317             if (wasNull)
318             {
319                 obj = null;
320             }
321             else
322             {
323                 obj = convertObject(columnTypes[column - 1], obj);
324             }
325             return obj;
326         }
327         catch (SQLException ex)
328         {
329             throw new DataSourceException(ex.getMessage(), ex);
330         }
331         catch (UnknownPropertyException ex)
332         {
333             throw new DataSourceException(ex.getMessage(), ex);
334         }
335         catch (IndexOutOfBoundsException ex)
336         {
337             throw new DataSourceException(ex.getMessage(), ex);
338         }
339         catch (WrappedTargetException ex)
340         {
341             throw new DataSourceException(ex.getMessage(), ex);
342         }
343     }
344 
convertObject(final int type, final Object obj)345     private Object convertObject(final int type, final Object obj)
346     {
347         Object ret;
348         switch (type)
349         {
350             case DataType.DATE:
351                 ret = getDate(obj);
352                 break;
353             case DataType.TIME:
354                 ret = getTime(obj);
355                 break;
356             case DataType.TIMESTAMP:
357                 ret = getTimestamp(obj);
358                 break;
359             case DataType.DECIMAL:
360             case DataType.NUMERIC:
361                 if (!(obj instanceof Any))
362                 {
363                     try
364                     {
365                         ret = new java.math.BigDecimal(String.valueOf(obj));
366                     }
367                     catch (NumberFormatException ex)
368                     {
369                         ret = obj;
370                     }
371                 }
372                 else
373                 {
374                     ret = obj;
375                 }
376                 break;
377             default:
378                 ret = obj;
379                 break;
380         }
381         return ret;
382     }
383 }
384