1 28 29 33 package net.sf.jasperreports.engine; 34 35 import java.awt.Image ; 36 import java.io.BufferedReader ; 37 import java.io.ByteArrayInputStream ; 38 import java.io.ByteArrayOutputStream ; 39 import java.io.CharArrayReader ; 40 import java.io.CharArrayWriter ; 41 import java.io.IOException ; 42 import java.io.InputStream ; 43 import java.io.Reader ; 44 import java.sql.Blob ; 45 import java.sql.Clob ; 46 import java.sql.ResultSet ; 47 import java.sql.ResultSetMetaData ; 48 import java.sql.SQLException ; 49 import java.sql.Types ; 50 import java.util.HashMap ; 51 import java.util.Map ; 52 53 import net.sf.jasperreports.engine.util.JRImageLoader; 54 55 56 61 public class JRResultSetDataSource implements JRDataSource 62 { 63 64 65 private static final String INDEXED_COLUMN_PREFIX = "COLUMN_"; 66 private static final int INDEXED_COLUMN_PREFIX_LENGTH = INDEXED_COLUMN_PREFIX.length(); 67 68 71 private ResultSet resultSet = null; 72 private Map columnIndexMap = new HashMap (); 73 74 75 78 public JRResultSetDataSource(ResultSet rs) 79 { 80 resultSet = rs; 81 } 82 83 84 87 public boolean next() throws JRException 88 { 89 boolean hasNext = false; 90 91 if (resultSet != null) 92 { 93 try 94 { 95 hasNext = resultSet.next(); 96 } 97 catch (SQLException e) 98 { 99 throw new JRException("Unable to get next record.", e); 100 } 101 } 102 103 return hasNext; 104 } 105 106 107 110 public Object getFieldValue(JRField field) throws JRException 111 { 112 Object objValue = null; 113 114 if (field != null && resultSet != null) 115 { 116 Integer columnIndex = getColumnIndex(field.getName()); 117 Class clazz = field.getValueClass(); 118 119 try 120 { 121 if (clazz.equals(java.lang.Boolean .class)) 122 { 123 objValue = resultSet.getBoolean(columnIndex.intValue()) ? Boolean.TRUE : Boolean.FALSE; 124 } 125 else if (clazz.equals(java.lang.Byte .class)) 126 { 127 objValue = new Byte (resultSet.getByte(columnIndex.intValue())); 128 if(resultSet.wasNull()) 129 { 130 objValue = null; 131 } 132 } 133 else if (clazz.equals(java.util.Date .class)) 134 { 135 objValue = resultSet.getDate(columnIndex.intValue()); 136 if(resultSet.wasNull()) 137 { 138 objValue = null; 139 } 140 } 141 else if (clazz.equals(java.sql.Timestamp .class)) 142 { 143 objValue = resultSet.getTimestamp(columnIndex.intValue()); 144 if(resultSet.wasNull()) 145 { 146 objValue = null; 147 } 148 } 149 else if (clazz.equals(java.sql.Time .class)) 150 { 151 objValue = resultSet.getTime(columnIndex.intValue()); 152 if(resultSet.wasNull()) 153 { 154 objValue = null; 155 } 156 } 157 else if (clazz.equals(java.lang.Double .class)) 158 { 159 objValue = new Double (resultSet.getDouble(columnIndex.intValue())); 160 if(resultSet.wasNull()) 161 { 162 objValue = null; 163 } 164 } 165 else if (clazz.equals(java.lang.Float .class)) 166 { 167 objValue = new Float (resultSet.getFloat(columnIndex.intValue())); 168 if(resultSet.wasNull()) 169 { 170 objValue = null; 171 } 172 } 173 else if (clazz.equals(java.lang.Integer .class)) 174 { 175 objValue = new Integer (resultSet.getInt(columnIndex.intValue())); 176 if(resultSet.wasNull()) 177 { 178 objValue = null; 179 } 180 } 181 else if (clazz.equals(java.io.InputStream .class)) 182 { 183 byte[] bytes = readBytes(columnIndex); 184 185 if(bytes == null) 186 { 187 objValue = null; 188 } 189 else 190 { 191 objValue = new ByteArrayInputStream (bytes); 192 } 193 } 194 else if (clazz.equals(java.lang.Long .class)) 195 { 196 objValue = new Long (resultSet.getLong(columnIndex.intValue())); 197 if(resultSet.wasNull()) 198 { 199 objValue = null; 200 } 201 } 202 else if (clazz.equals(java.lang.Short .class)) 203 { 204 objValue = new Short (resultSet.getShort(columnIndex.intValue())); 205 if(resultSet.wasNull()) 206 { 207 objValue = null; 208 } 209 } 210 else if (clazz.equals(java.math.BigDecimal .class)) 211 { 212 objValue = resultSet.getBigDecimal(columnIndex.intValue()); 213 if(resultSet.wasNull()) 214 { 215 objValue = null; 216 } 217 } 218 else if (clazz.equals(java.lang.String .class)) 219 { 220 int columnType = resultSet.getMetaData().getColumnType(columnIndex.intValue()); 221 switch (columnType) 222 { 223 case Types.CLOB: 224 Clob clob = resultSet.getClob(columnIndex.intValue()); 225 if (resultSet.wasNull()) 226 { 227 objValue = null; 228 } 229 else 230 { 231 objValue = clobToString(clob); 232 } 233 break; 234 235 default: 236 objValue = resultSet.getString(columnIndex.intValue()); 237 if(resultSet.wasNull()) 238 { 239 objValue = null; 240 } 241 break; 242 } 243 } 244 else if (clazz.equals(Clob .class)) 245 { 246 objValue = resultSet.getClob(columnIndex.intValue()); 247 if(resultSet.wasNull()) 248 { 249 objValue = null; 250 } 251 } 252 else if (clazz.equals(Reader .class)) 253 { 254 Reader reader = null; 255 long size = -1; 256 257 int columnType = resultSet.getMetaData().getColumnType(columnIndex.intValue()); 258 switch (columnType) 259 { 260 case Types.CLOB: 261 Clob clob = resultSet.getClob(columnIndex.intValue()); 262 if (!resultSet.wasNull()) 263 { 264 reader = clob.getCharacterStream(); 265 size = clob.length(); 266 } 267 break; 268 269 default: 270 reader = resultSet.getCharacterStream(columnIndex.intValue()); 271 if (resultSet.wasNull()) 272 { 273 reader = null; 274 } 275 } 276 277 if (reader == null) 278 { 279 objValue = null; 280 } 281 else 282 { 283 objValue = getArrayReader(reader, size); 284 } 285 } 286 else if (clazz.equals(Blob .class)) 287 { 288 objValue = resultSet.getBlob(columnIndex.intValue()); 289 if(resultSet.wasNull()) 290 { 291 objValue = null; 292 } 293 } 294 else if (clazz.equals(Image .class)) 295 { 296 byte[] bytes = readBytes(columnIndex); 297 298 if(bytes == null) 299 { 300 objValue = null; 301 } 302 else 303 { 304 objValue = JRImageLoader.loadImage(bytes); 305 } 306 } 307 else 308 { 309 objValue = resultSet.getObject(columnIndex.intValue()); 310 } 311 } 312 catch (Exception e) 313 { 314 throw new JRException("Unable to get value for field '" + field.getName() + "' of class '" + clazz.getName() + "'", e); 315 } 316 } 317 318 return objValue; 319 } 320 321 322 323 324 325 328 private Integer getColumnIndex(String fieldName) throws JRException 329 { 330 Integer columnIndex = (Integer )columnIndexMap.get(fieldName); 331 if (columnIndex == null) 332 { 333 try 334 { 335 columnIndex = searchColumnByName(fieldName); 336 337 if (columnIndex == null) 338 { 339 columnIndex = searchColumnByLabel(fieldName); 340 } 341 342 if (columnIndex == null && fieldName.startsWith(INDEXED_COLUMN_PREFIX)) 343 { 344 columnIndex = new Integer (fieldName.substring(INDEXED_COLUMN_PREFIX_LENGTH)); 345 if ( 346 columnIndex.intValue() <= 0 347 || columnIndex.intValue() > resultSet.getMetaData().getColumnCount() 348 ) 349 { 350 throw new JRException("Column index out of range : " + columnIndex); 351 } 352 } 353 354 if (columnIndex == null) 355 { 356 throw new JRException("Unknown column name : " + fieldName); 357 } 358 } 359 catch (SQLException e) 360 { 361 throw new JRException("Unable to retrieve result set metadata.", e); 362 } 363 364 columnIndexMap.put(fieldName, columnIndex); 365 } 366 367 return columnIndex; 368 } 369 370 371 protected Integer searchColumnByName(String fieldName) throws SQLException 372 { 373 Integer columnIndex = null; 374 ResultSetMetaData metadata = resultSet.getMetaData(); 375 for(int i = 1; i <= metadata.getColumnCount(); i++) 376 { 377 String columnName = metadata.getColumnName(i); 378 if (fieldName.equalsIgnoreCase(columnName)) 379 { 380 columnIndex = new Integer (i); 381 break; 382 } 383 } 384 return columnIndex; 385 } 386 387 388 protected Integer searchColumnByLabel(String fieldName) throws SQLException 389 { 390 Integer columnIndex = null; 391 ResultSetMetaData metadata = resultSet.getMetaData(); 392 for(int i = 1; i <= metadata.getColumnCount(); i++) 393 { 394 String columnLabel = metadata.getColumnLabel(i); 395 if (columnLabel != null && fieldName.equalsIgnoreCase(columnLabel)) 396 { 397 columnIndex = new Integer (i); 398 break; 399 } 400 } 401 return columnIndex; 402 } 403 404 405 protected String clobToString(Clob clob) throws JRException 406 { 407 try 408 { 409 int bufSize = 8192; 410 char[] buf = new char[bufSize]; 411 412 Reader reader = new BufferedReader (clob.getCharacterStream(), bufSize); 413 StringBuffer str = new StringBuffer ((int) clob.length()); 414 415 for (int read = reader.read(buf); read > 0; read = reader.read(buf)) 416 { 417 str.append(buf, 0, read); 418 } 419 420 return str.toString(); 421 } 422 catch (SQLException e) 423 { 424 throw new JRException("Unable to read clob value", e); 425 } 426 catch (IOException e) 427 { 428 throw new JRException("Unable to read clob value", e); 429 } 430 } 431 432 protected CharArrayReader getArrayReader(Reader reader, long size) throws IOException 433 { 434 char[] buf = new char[8192]; 435 CharArrayWriter bufWriter = new CharArrayWriter ((size > 0) ? (int) size : 8192); 436 437 BufferedReader bufReader = new BufferedReader (reader, 8192); 438 for (int read = bufReader.read(buf); read > 0; read = bufReader.read(buf)) 439 { 440 bufWriter.write(buf, 0, read); 441 } 442 bufWriter.flush(); 443 444 return new CharArrayReader (bufWriter.toCharArray()); 445 } 446 447 protected byte[] readBytes(Integer columnIndex) throws SQLException , IOException 448 { 449 InputStream is = null; 450 long size = -1; 451 452 int columnType = resultSet.getMetaData().getColumnType(columnIndex.intValue()); 453 switch (columnType) 454 { 455 case Types.BLOB: 456 Blob blob = resultSet.getBlob(columnIndex.intValue()); 457 if (!resultSet.wasNull()) 458 { 459 is = blob.getBinaryStream(); 460 size = blob.length(); 461 } 462 break; 463 464 default: 465 is = resultSet.getBinaryStream(columnIndex.intValue()); 466 if (resultSet.wasNull()) 467 { 468 is = null; 469 } 470 } 471 472 byte[] bytes = null; 473 if (is != null) 474 { 475 bytes = readBytes(is, size); 476 } 477 478 return bytes; 479 } 480 481 protected byte[] readBytes(InputStream is, long size) throws IOException 482 { 483 ByteArrayOutputStream baos = new ByteArrayOutputStream (size > 0 ? (int) size : 1000); 484 byte[] bytes = new byte[1000]; 485 int ln = 0; 486 try 487 { 488 while ((ln = is.read(bytes)) > 0) 489 { 490 baos.write(bytes, 0, ln); 491 } 492 baos.flush(); 493 } 494 finally 495 { 496 try 497 { 498 baos.close(); 499 } 500 catch(IOException e) 501 { 502 } 503 } 504 return baos.toByteArray(); 505 } 506 } 507 | Popular Tags |