001 /** 002 * Copyright (c) 2008 Regiscope Digital Imaging Co, LLC, All rights reserved. 003 * This program is free software; you can redistribute it and/or modify 004 * it under the terms of version 2 of the GNU General Public License as 005 * published by the Free Software Foundation. 006 * There are special exceptions to the terms and conditions of the GPL 007 * as it is applied to this software. See the GNU General Public License for more details. 008 * 009 * This program is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU General Public License for more details. 013 * 014 * You should have received a copy of the GNU General Public License 015 * along with this program; if not, write to the Free Software 016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 017 */ 018 019 package org.dbreplicator.replication.column; 020 021 import java.io.*; 022 import java.sql.*; 023 import java.util.*; 024 025 import org.dbreplicator.replication.*; 026 import org.dbreplicator.replication.xml.*; 027 import org.dbreplicator.replication.DBHandler.AbstractDataBaseHandler; 028 import org.dbreplicator.replication.DBHandler.SQLServerHandler; 029 import org.dbreplicator.replication.DBHandler.PostgreSQLHandler; 030 031 /** 032 * Class for handling Binary Large Objects 033 */ 034 public class BlobObject extends AbstractColumnObject 035 { 036 037 int sqlType; 038 AbstractDataBaseHandler abstractDBHandler; 039 /** 040 * sets the SQL type for Blob datatype 041 * @param sqlType0 042 */ 043 public BlobObject(int sqlType0,AbstractDataBaseHandler abstractDBHandler0) 044 { 045 sqlType = sqlType0; 046 abstractDBHandler =abstractDBHandler0; 047 } 048 049 /** 050 * set the value for the corresponding datatype i.e BLob 051 * @param pst 052 * @param element 053 * @param index 054 * @throws SQLException 055 */ 056 public void setColumnObject(PreparedStatement pst, XMLElement element, 057 int index) throws SQLException 058 { 059 XMLElement[] elements = (XMLElement[]) element.getChildElements().toArray(new 060 XMLElement[2]); 061 int start = 0; 062 int length = 0; 063 try 064 { 065 start = Integer.parseInt(elements[0].elementValue); 066 length = Integer.parseInt(elements[1].elementValue); 067 //System.out.println(" start :: "+start+" length : "+length); 068 } 069 catch (NullPointerException ex) 070 { 071 String value = element.elementValue; 072 int lenghtIndex = value.indexOf("length"); 073 int startIndex = value.indexOf("start"); 074 if (lenghtIndex == -1 && startIndex == -1) 075 { 076 if (value.equalsIgnoreCase("NULL")) 077 { 078 pst.setNull(index, Types.BLOB); 079 return; 080 } 081 else 082 { 083 pst.setObject(index, value); 084 return; 085 } 086 } 087 start = Integer.parseInt(value.substring(5, lenghtIndex)); 088 length = Integer.parseInt(value.substring(lenghtIndex + 6)); 089 } 090 091 if (length == -1) 092 { 093 //System.out.println(" length : "+length+" So set the null "); 094 if(abstractDBHandler instanceof SQLServerHandler) { 095 RBlob rblob = new RBlob(start, length); 096 InputStream is = rblob.getBinaryStream(); 097 try { 098 pst.setBinaryStream(index, is, is.available()); 099 } 100 catch (IOException ex1) { 101 RepConstants.writeERROR_FILE(ex1); 102 } 103 } else if( abstractDBHandler instanceof PostgreSQLHandler) { 104 pst.setBlob(index, new RBlob(start, length)); 105 } 106 else { 107 pst.setNull(index, Types.BLOB); 108 } 109 } 110 else 111 { 112 113 RBlob rblob = new RBlob(start,length); 114 InputStream is = rblob.getBinaryStream() ; 115 try { 116 pst.setBinaryStream(index, is, is.available()); 117 } 118 catch (IOException ex1) { 119 RepConstants.writeERROR_FILE(ex1); 120 } 121 // Set blob does not work in oracle database 122 // pst.setBlob(index, new RBlob(start, length)); 123 } 124 } 125 126 public void setColumnObject(PreparedStatement pst, String value, int index) throws SQLException 127 { 128 int start = 0; 129 int length = 0; 130 int lenghtIndex = value.indexOf("length"); 131 int startIndex = value.indexOf("start"); 132 if (lenghtIndex == -1 && startIndex == -1) 133 { 134 if (value.equalsIgnoreCase("NULL")) 135 { 136 pst.setNull(index, Types.BLOB); 137 return; 138 } 139 else 140 { 141 pst.setObject(index, value); 142 return; 143 } 144 } 145 start = Integer.parseInt(value.substring(5, lenghtIndex)); 146 length = Integer.parseInt(value.substring(lenghtIndex + 6)); 147 //System.out.println("start : "+start+" length : "+length); 148 if (length == -1) 149 { 150 pst.setNull(index, Types.BLOB); 151 } 152 else 153 { 154 RBlob rblob = new RBlob(start,length); 155 InputStream is = rblob.getBinaryStream() ; 156 try { 157 pst.setBinaryStream(index, is, is.available()); 158 } 159 catch (IOException ex1) { 160 RepConstants.writeERROR_FILE(ex1); 161 } 162 // pst.setBlob(index, new RBlob(start, length)); 163 } 164 } 165 166 /** 167 * writes a blob values in XML file 168 * @param bw Writer 169 * @param rs ResultSet 170 * @param index int 171 * @param encodedCols ArrayList 172 * @param col String 173 * @throws IOException 174 * @throws SQLException 175 */ 176 177 public void write(Writer bw, ResultSet rs, int index,ArrayList encodedCols,String col) throws 178 SQLException, IOException 179 { 180 Object objrowValue = getObject(rs, index); 181 InputStream rowValue; 182 if (objrowValue == null) 183 { 184 rowValue = null; 185 } 186 else 187 { 188 rowValue = (InputStream) objrowValue; 189 /* 190 System.out.println("<--------------------PRINT------------------------------->"); 191 192 int len = rowValue.available(); 193 System.out.println(" Length of data in Client ="+len); 194 byte[] bClient=new byte[len]; 195 int noOfByteRead1=rowValue.read(bClient); 196 System.out.println("noOfByteRead1 "+noOfByteRead1+" BlobObject = "+new String(bClient)); 197 System.out.println("<--------------------PRINT------------------------------->"); 198 */ 199 // new ByteArrayInputStream((objrowValue.toString()).getBytes()); 200 } 201 bw.write("<start>"); 202 bw.write("" + blobst.getStreamStart()); 203 bw.write("</start>"); 204 //RepPrinter.print(" Bfter Writing the Blob to file " + blobst); 205 bw.write("<length>"); 206 if (rowValue != null) 207 { 208 bw.write("" + blobst.write(rowValue)); 209 } 210 else 211 { 212 bw.write("-1"); 213 } 214 //RepPrinter.print(" After Writing the Blob to file " + blobst); 215 bw.write("</length>"); 216 } 217 218 /** 219 * puts the value for the column aginst the column Name 220 * @param bw Writer 221 * @param rows ResultSet 222 * @param oldResultSet ResultSet 223 * @param index int 224 * @param modifiedColumns HashMap 225 * @param columnName String 226 * @param encodedCols ArrayList of columns that need character encoding 227 * @throws SQLException 228 * @throws IOException 229 */ 230 231 public void writeUpdate(Writer bw, ResultSet rows, 232 ResultSet oldResultSet 233 , int index, HashMap modifiedColumns, 234 String columnName,ArrayList encodedCols) throws SQLException, IOException 235 { 236 InputStream obj1 = null; 237 238 try 239 { 240 obj1 = rows.getBinaryStream(index); 241 if (obj1 == null) 242 { 243 write(bw, null,encodedCols,columnName); 244 } 245 else 246 { 247 String data = getBlobNotNullData(obj1); 248 write(bw, data,encodedCols,columnName); 249 modifiedColumns.put(columnName, data); 250 } 251 } 252 catch (Exception ex) 253 { 254 //System.out.println(" ******************PROBLEM OCCURE OCCURE IN BLOBOBJECT**************"); 255 // ex.printStackTrace(); 256 //System.out.println(" ******************PROBLEM OCCURE OCCURE IN BLOBOBJECT**************"); 257 RepConstants.writeERROR_FILE(ex); 258 } 259 260 } 261 262 public void writeUpdateBKUP_11_17_04(OutputStreamWriter os, ResultSet rows, 263 ResultSet oldResultSet 264 , int index, HashMap modifiedColumns, 265 String columnName) throws SQLException, IOException 266 { 267 Blob obj1 = null; 268 Blob obj2 = null; 269 try 270 { 271 obj1 = (Blob) rows.getObject(index); 272 obj2 = (Blob) oldResultSet.getObject(index); 273 274 // InputStream newObject = obj1.getBinaryStream();// new ByteArrayInputStream(newValue.getBytes()); 275 // InputStream oldObject = obj2.getBinaryStream();//new ByteArrayInputStream((obj2.toString()).getBytes()); 276 277 if (obj1 == null) 278 { 279 // write(os, null); 280 if (obj2 != null) 281 { 282 modifiedColumns.put(columnName, "NULL"); 283 } 284 } 285 else 286 { 287 String data = getBlobNotNullData(obj1.getBinaryStream()); 288 // write(os, data); 289 if (obj2 != null) 290 { 291 if (!checkInputStreamEquality(obj2.getBinaryStream(), 292 obj1.getBinaryStream())) 293 { 294 modifiedColumns.put(columnName, data); 295 } 296 } 297 else 298 { 299 modifiedColumns.put(columnName, data); 300 } 301 302 } 303 } 304 catch (Exception ex) 305 { 306 RepConstants.writeERROR_FILE(ex); 307 } 308 309 } 310 311 /* This method was previously written and running fine */ 312 public void writeUpdate1(OutputStreamWriter os, ResultSet rows, 313 ResultSet oldResultSet 314 , int index, HashMap modifiedColumns, 315 String columnName) throws SQLException, IOException 316 { 317 Blob newObject = rows.getBlob(index); 318 //RepPrinter.print(" Inside BlobObject newObject =" + newObject); 319 Blob oldObject = oldResultSet.getBlob(index); 320 //RepPrinter.print(" Inside BlobObject oldObject =" + oldObject); 321 if (newObject == null) 322 { 323 // write(os, "NULL"); 324 if (oldObject != null) 325 { 326 modifiedColumns.put(columnName, "NULL"); 327 } 328 } 329 else 330 { 331 String data = getBlobNotNullData(newObject); 332 // write(os, data); 333 if (oldObject != null) 334 { 335 if (!checkBlobEquality(oldObject, newObject)) 336 { 337 modifiedColumns.put(columnName, data); 338 } 339 } 340 else 341 { 342 modifiedColumns.put(columnName, data); 343 } 344 345 } 346 } 347 348 /*public void writeUpdate1(OutputStreamWriter os, ResultSet rows, ResultSet oldResultSet 349 , int index, HashMap modifiedColumns, String columnName) throws SQLException, IOException{ 350 Blob newObject = rows.getBlob(index); 351 Blob oldObject = oldResultSet.getBlob(index); 352 353 if( newObject == null ){ 354 String data = getBlobNullData(); 355 write(os,data); 356 if( oldObject != null ) 357 modifiedColumns.put( columnName ,data); 358 } 359 else { 360 String data = getBlobNotNullData(newObject); 361 write(os, data); 362 try { 363 if (oldObject != null) { 364 if (!checkBlobEquality(oldObject,newObject)) { 365 modifiedColumns.put(columnName, data); 366 } 367 } 368 else { 369 modifiedColumns.put(columnName, data); 370 } 371 } 372 catch (Exception ex) { 373 RepConstants.writeERROR_FILE(ex); 374 } 375 } 376 }*/ 377 378 public Object getObject(String value) 379 { 380 //RepPrinter.print("BlobObject.getObject(value)" + value); 381 int start = 0, length = 0; 382 try 383 { 384 int lenghtIndex = value.indexOf("length"); 385 start = Integer.parseInt(value.substring(5, lenghtIndex)); 386 length = Integer.parseInt(value.substring(lenghtIndex + 6)); 387 } 388 catch (Exception ex) 389 { 390 RepConstants.writeERROR_FILE(ex); 391 } 392 return new RBlob(start, length); 393 } 394 395 /** 396 * returns the Object corresponding to the index passed from the resultSet 397 * @param row 398 * @param index 399 * @return 400 * @throws SQLException 401 */ 402 private Object getObject(ResultSet row, int index) throws SQLException 403 { 404 // Object object = row.getObject(index); 405 //RepPrinter.print("$$$$$$$$$$$$$$Inside BlobObject object is ="+object); 406 // if (object == null) { 407 // return null; 408 // } 409 // InputStream objInputStream = new ByteArrayInputStream( (object.toString()). 410 // getBytes()); 411 // return objInputStream; 412 return row.getBinaryStream(index); 413 } 414 415 /** 416 * writes a blob values in XML file 417 * @param os 418 * @param rs 419 * @param index 420 * @throws IOException 421 * @throws SQLException 422 */ 423 private void write(Writer os, Object rowValue,ArrayList encodedCols,String col) throws 424 SQLException, IOException 425 { 426 try 427 { 428 if(!encodedCols.contains(col.toUpperCase())) { 429 os.write("<![CDATA[" + rowValue.toString() + "]]>"); 430 } else { 431 os.write("<![CDATA[" + 432 EncoderDecoder.escapeUnicodeString1(rowValue.toString(), true) + 433 "]]>"); 434 } 435 436 } 437 catch (NullPointerException ex) 438 { 439 os.write("<start>"); 440 os.write("" + blobst.getStreamStart()); 441 os.write("</start><length>-1</length>"); 442 } 443 } 444 445 /*private void write(OutputStreamWriter os, String rowValue) throws SQLException, IOException { 446 os.write(rowValue); 447 } 448 449 private String getBlobDataToWriteInXMLFile1(Object rowValue) { 450 return rowValue != null ? getBlobNotNullData1(rowValue) 451 : getBlobNullData1(); 452 } 453 454 private String getBlobNullData1() { 455 StringBuffer sb = new StringBuffer(); 456 sb.append("<start>").append(blobst.getStreamStart()).append("</start>") 457 .append("<length>").append("-1").append("</length>"); 458 return sb.toString(); 459 } 460 461 private String getBlobNotNullData1(Object rowValue) { 462 StringBuffer sb = new StringBuffer(); 463 InputStream objInputStrea; 464 if(rowValue==null) 465 objInputStrea=null; 466 else 467 objInputStrea= new ByteArrayInputStream((rowValue.toString()).getBytes()); 468 sb.append("<start>").append(blobst.getStreamStart()).append("</start>") 469 .append("<length>").append(blobst.write((InputStream)rowValue)) 470 .append("</length>"); 471 return sb.toString(); 472 } 473 */ 474 private String getBlobNotNullData(Object rowValue) 475 { 476 StringBuffer sb = new StringBuffer(); 477 try 478 { 479 //RepPrinter.print(" GET Blob Not null data " + rowValue.toString()); 480 //InputStream inputStram =new ByteArrayInputStream((rowValue.toString()).getBytes()); 481 sb.append("start").append(blobst.getStreamStart()) 482 .append("length").append(blobst.write( (InputStream) rowValue)); 483 //(InputStream)rowValue) 484 //RepPrinter.print("Inside BLOB Object sb.toString() =" + sb.toString()); 485 } 486 catch (Exception ex) 487 { 488 RepConstants.writeERROR_FILE(ex); 489 } 490 return sb.toString(); 491 } 492 493 private boolean checkBlobEquality(Blob blob1, Blob blob2) 494 { 495 try 496 { 497 return checkInputStreamEquality(blob1.getBinaryStream(), 498 blob2.getBinaryStream()); 499 } 500 catch (SQLException ex) 501 { 502 return false; 503 } 504 } 505 506 private boolean checkInputStreamEquality(InputStream stream1, 507 InputStream stream2) 508 { 509 try 510 { 511 long len1 = stream1.available(); 512 long len2 = stream2.available(); 513 if (len1 != len2) 514 { 515 return false; 516 } 517 long read = 0; 518 do 519 { 520 byte[] buf1 = new byte[1024]; 521 byte[] buf2 = new byte[1024]; 522 int byte1 = stream1.read(buf1); 523 int byte2 = stream2.read(buf2); 524 if (byte1 != byte2) 525 { 526 return false; 527 } 528 for (int i = 0; i < buf1.length; i++) 529 { 530 if (buf1[i] != buf2[i]) 531 { 532 return false; 533 } 534 } 535 read += buf1.length; 536 } 537 while (read < len1); 538 } 539 catch (IOException ex) 540 { 541 return false; 542 } 543 return true; 544 } 545 546 }

