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 029 //import test.*; 030 031 /** 032 * Handles the Character Large Object data type. 033 */ 034 public class ClobObject extends AbstractColumnObject 035 { 036 037 int sqlType; 038 AbstractDataBaseHandler abstractDBHandler; 039 /** 040 * sets the SQL type fro clob datatype 041 * @param sqlType0 042 */ 043 044 public ClobObject(int sqlType0,AbstractDataBaseHandler abstractDBHandler0) 045 { 046 sqlType = sqlType0; 047 abstractDBHandler=abstractDBHandler0; 048 } 049 050 /** 051 * set the value for the corresponding datatype i.e BLob 052 * @param pst 053 * @param element 054 * @param index 055 * @throws SQLException 056 */ 057 public void setColumnObject(PreparedStatement pst, XMLElement element, 058 int index) throws SQLException 059 { 060 XMLElement[] elements = (XMLElement[]) element.getChildElements().toArray(new 061 XMLElement[2]); 062 int start = 0; 063 int length = 0; 064 try 065 { 066 start = Integer.parseInt(elements[0].elementValue); 067 length = Integer.parseInt(elements[1].elementValue); 068 // System.out.println(" start = "+start+" length ="+length); 069 } 070 catch (NullPointerException ex) 071 { 072 String value = element.elementValue; 073 int lenghtIndex = value.indexOf("length"); 074 int startIndex = value.indexOf("start"); 075 //System.out.println(" lenghtIndex ="+lenghtIndex+" startIndex = "+startIndex); 076 if (lenghtIndex == -1 && startIndex == -1) 077 { 078 pst.setObject(index, value); 079 return; 080 } 081 else if (lenghtIndex != -1) 082 { 083 start = Integer.parseInt(value.substring(5, lenghtIndex)); 084 length = Integer.parseInt(value.substring(lenghtIndex + 6)); 085 //System.out.println(" start = "+start+" length = "+length); 086 } 087 } 088 if (length == -1) 089 { 090 pst.setNull(index, Types.CLOB); 091 } 092 else 093 { 094 pst.setClob(index, new RClob(start, length)); 095 } 096 } 097 098 public void setColumnObject(PreparedStatement pst, String value, int index) throws SQLException 099 { 100 int start = -1, length = -1; 101 int lenghtIndex = value.indexOf("length"); 102 int startIndex = value.indexOf("start"); 103 if (lenghtIndex == -1 && startIndex == -1) 104 { 105 pst.setObject(index, value); 106 return; 107 } 108 else if (lenghtIndex != -1) 109 { 110 start = Integer.parseInt(value.substring(5, lenghtIndex)); 111 length = Integer.parseInt(value.substring(lenghtIndex + 6)); 112 } 113 if (length == -1) 114 { 115 pst.setNull(index, Types.CLOB); 116 } 117 else 118 { 119 pst.setClob(index, new RClob(start, length)); 120 } 121 } 122 123 /** 124 * writes a clob values in XML file 125 * @param os 126 * @param rs 127 * @param index 128 * @throws IOException 129 * @throws SQLException 130 */ 131 132 public void write(Writer os, ResultSet rs, int index,ArrayList encodedCols,String col) throws 133 SQLException, IOException 134 { 135 Object objrowValue = getObject(rs, index); 136 InputStream rowValue; 137 if (objrowValue == null) 138 { 139 rowValue = null; 140 } 141 else 142 { 143 rowValue = (InputStream) objrowValue; 144 // new ByteArrayInputStream((objrowValue.toString()).getBytes()); 145 146 // System.out.println("<--------------------PRINT------------------------------->"); 147 // int len = rowValue.available(); 148 // System.out.println(" Length of data in Client ="+len); 149 // byte[] bClient=new byte[len]; 150 // int noOfByteRead1=rowValue.read(bClient); 151 // System.out.println("noOfByteRead1 "+noOfByteRead1+" clobObject = "+new String(bClient)); 152 // System.out.println("<--------------------PRINT------------------------------->"); 153 } 154 os.write("<start>"); 155 os.write("" + clobst.getStreamStart()); 156 os.write("</start>"); 157 //RepPrinter.print(" Bfter Writing the Clob to file " + clobst); 158 os.write("<length>"); 159 if (rowValue != null) 160 { 161 os.write("" + clobst.write(rowValue)); 162 } 163 else 164 { 165 os.write("-1"); 166 } 167 //RepPrinter.print(" After Writing the Clob to file " +clobst); 168 os.write("</length>"); 169 } 170 171 /** 172 * puts the value for the column against the column Name 173 * @param os 174 * @param rows 175 * @param oldResultSet 176 * @param index 177 * @param modifiedColumns 178 * @param columnName 179 * @throws SQLException 180 * @throws IOException 181 */ 182 183 public void writeUpdate(Writer os, ResultSet rows, 184 ResultSet oldResultSet 185 , int index, HashMap modifiedColumns, 186 String columnName,ArrayList encodedCols) throws SQLException, IOException 187 { 188 InputStream obj1 = null; 189 190 try 191 { 192 //System.out.println("Object = "+rows.getObject(index)+" CLASS rows.getObject(index) ="+rows.getObject(index).getClass()); 193 Object clobObject =rows.getObject(index); 194 if(clobObject instanceof Clob) { 195 Clob clob = (Clob) clobObject; 196 obj1 = clob.getAsciiStream(); 197 } else { 198 obj1 = new ByteArrayInputStream( ( (String) (clobObject)).getBytes()); 199 } 200 // obj1 = (InputStream)rows.getObject(index); 201 if (obj1 == null) 202 { 203 write(os, null,encodedCols,columnName); 204 } 205 else 206 { 207 String data = getClobNotNullData(obj1); 208 write(os, data,encodedCols,columnName); 209 modifiedColumns.put(columnName, data); 210 } 211 } 212 catch (Exception ex) 213 { 214 RepConstants.writeERROR_FILE(ex); 215 } 216 217 } 218 219 public void writeUpdateBKUP_11_17_04(OutputStreamWriter os, ResultSet rows, 220 ResultSet oldResultSet 221 , int index, HashMap modifiedColumns, 222 String columnName) throws SQLException, IOException 223 { 224 Clob newObject = null; 225 Clob oldObject = null; 226 try 227 { 228 newObject = (Clob) rows.getObject(index); 229 oldObject = (Clob) oldResultSet.getObject(index); 230 231 // InputStream newObject = obj1.getBinaryStream();// new ByteArrayInputStream(newValue.getBytes()); 232 // InputStream oldObject = obj2.getBinaryStream();//new ByteArrayInputStream((obj2.toString()).getBytes()); 233 234 if (newObject == null) 235 { 236 // write(os, null); 237 if (oldObject != null) 238 { 239 modifiedColumns.put(columnName, "NULL"); 240 } 241 } 242 else 243 { 244 String data = getClobNotNullData(newObject.getAsciiStream()); 245 246 int legthOfStream = newObject.getAsciiStream().available(); 247 byte[] buf = new byte[legthOfStream]; 248 int noOfBytesRead = newObject.getAsciiStream().read(buf); 249 String InputString = new String(buf); 250 // write(os, data); 251 if (oldObject != null) 252 { 253 if (!checkInputStreamEquality(oldObject.getAsciiStream(), 254 newObject.getAsciiStream())) 255 { 256 modifiedColumns.put(columnName, data); 257 } 258 } 259 else 260 { 261 modifiedColumns.put(columnName, data); 262 } 263 264 } 265 } 266 catch (Exception ex) 267 { 268 RepConstants.writeERROR_FILE(ex); 269 } 270 271 } 272 273 /* This method was previously written and running fine */ 274 public void writeUpdate1(OutputStreamWriter os, ResultSet rows, 275 ResultSet oldResultSet 276 , int index, HashMap modifiedColumns, 277 String columnName) throws SQLException, IOException 278 { 279 Clob newObject = rows.getClob(index); 280 //RepPrinter.print(" Inside ClobObject newObject =" + newObject); 281 Clob oldObject = oldResultSet.getClob(index); 282 //RepPrinter.print(" Inside ClobObject oldObject =" + oldObject); 283 if (newObject == null) 284 { 285 // write(os, "NULL"); 286 if (oldObject != null) 287 { 288 modifiedColumns.put(columnName, "NULL"); 289 } 290 } 291 else 292 { 293 String data = getClobNotNullData(newObject); 294 // write(os, data); 295 if (oldObject != null) 296 { 297 if (!checkBlobEquality(oldObject, newObject)) 298 { 299 modifiedColumns.put(columnName, data); 300 } 301 } 302 else 303 { 304 modifiedColumns.put(columnName, data); 305 } 306 307 } 308 } 309 310 /*public void writeUpdate1(OutputStreamWriter os, ResultSet rows, ResultSet oldResultSet 311 , int index, HashMap modifiedColumns, String columnName) throws SQLException, IOException{ 312 Clob newObject = rows.getClob(index); 313 Clob oldObject = oldResultSet.getClob(index); 314 315 if( newObject == null ){ 316 String data = getBlobNullData(); 317 write(os,data); 318 if( oldObject != null ) 319 modifiedColumns.put( columnName ,data); 320 } 321 else { 322 String data = getBlobNotNullData(newObject); 323 write(os, data); 324 try { 325 if (oldObject != null) { 326 if (!checkBlobEquality(oldObject,newObject)) { 327 modifiedColumns.put(columnName, data); 328 } 329 } 330 else { 331 modifiedColumns.put(columnName, data); 332 } 333 } 334 catch (Exception ex) { 335 RepConstants.writeERROR_FILE(ex); 336 } 337 } 338 }*/ 339 340 public Object getObject(String value) 341 { 342 //RepPrinter.print("ClobObject.getObject(value)" + value); 343 int start = 0, length = 0; 344 try 345 { 346 int lenghtIndex = value.indexOf("length"); 347 start = Integer.parseInt(value.substring(5, lenghtIndex)); 348 length = Integer.parseInt(value.substring(lenghtIndex + 6)); 349 } 350 catch (Exception ex) 351 { 352 RepConstants.writeERROR_FILE(ex); 353 } 354 return new RClob(start, length); 355 } 356 357 /** 358 * returns the Object corresponding to the index passed from the resultSet 359 * @param row 360 * @param index 361 * @return 362 * @throws SQLException 363 */ 364 private Object getObject(ResultSet row, int index) throws SQLException 365 { 366 Object object = row.getObject(index); 367 //System.out.println("Clob object CLASS ="+object.getClass()); 368 if (object == null) 369 { 370 return null; 371 } 372 if(object instanceof Clob ) { 373 Clob clob = (Clob) object; 374 return clob.getAsciiStream(); 375 } else { 376 InputStream objInputStream = new ByteArrayInputStream((object.toString()).getBytes()); 377 return objInputStream; 378 } 379 // return row.getBinaryStream(index); 380 } 381 382 /** 383 * writes a Clob values in XML file 384 * @param os 385 * @param rs 386 * @param index 387 * @throws IOException 388 * @throws SQLException 389 */ 390 private void write(Writer os, Object rowValue,ArrayList encodedCols,String col) throws 391 SQLException, IOException 392 { 393 try 394 { 395 os.write("<![CDATA[" + rowValue.toString() + "]]>"); 396 } 397 catch (NullPointerException ex) 398 { 399 os.write("<start>"); 400 os.write("" + clobst.getStreamStart()); 401 os.write("</start><length>-1</length>"); 402 } 403 } 404 405 /*private void write(OutputStreamWriter os, String rowValue) throws SQLException, IOException { 406 os.write(rowValue); 407 } 408 409 private String getClobDataToWriteInXMLFile1(Object rowValue) { 410 return rowValue != null ? getClobNotNullData1(rowValue) 411 : getClobNullData1(); 412 } 413 414 private String getClobNullData1() { 415 StringBuffer sb = new StringBuffer(); 416 sb.append("<start>").append(clobst.getStreamStart()).append("</start>") 417 .append("<length>").append("-1").append("</length>"); 418 return sb.toString(); 419 } 420 421 private String getClobNotNullData1(Object rowValue) { 422 StringBuffer sb = new StringBuffer(); 423 InputStream objInputStrea; 424 if(rowValue==null) 425 objInputStrea=null; 426 else 427 objInputStrea= new ByteArrayInputStream((rowValue.toString()).getBytes()); 428 sb.append("<start>").append(clobst.getStreamStart()).append("</start>") 429 .append("<length>").append(clobst.write((InputStream)rowValue)) 430 .append("</length>"); 431 return sb.toString(); 432 } 433 */ 434 private String getClobNotNullData(Object rowValue) 435 { 436 StringBuffer sb = new StringBuffer(); 437 try 438 { 439 //InputStream inputStram =new ByteArrayInputStream((rowValue.toString()).getBytes()); 440 sb.append("start").append(clobst.getStreamStart()) 441 .append("length").append(clobst.write( (InputStream) rowValue)); 442 //(InputStream)rowValue) 443 } 444 catch (Exception ex) 445 { 446 RepConstants.writeERROR_FILE(ex); 447 } 448 return sb.toString(); 449 } 450 451 private boolean checkBlobEquality(Clob clob1, Clob clob2) 452 { 453 try 454 { 455 return checkInputStreamEquality(clob1.getAsciiStream(), 456 clob2.getAsciiStream()); 457 } 458 catch (SQLException ex) 459 { 460 return false; 461 } 462 } 463 464 private boolean checkInputStreamEquality(InputStream stream1, 465 InputStream stream2) 466 { 467 try 468 { 469 long len1 = stream1.available(); 470 long len2 = stream2.available(); 471 if (len1 != len2) 472 { 473 return false; 474 } 475 long read = 0; 476 do 477 { 478 byte[] buf1 = new byte[1024]; 479 byte[] buf2 = new byte[1024]; 480 int byte1 = stream1.read(buf1); 481 int byte2 = stream2.read(buf2); 482 if (byte1 != byte2) 483 { 484 return false; 485 } 486 for (int i = 0; i < buf1.length; i++) 487 { 488 if (buf1[i] != buf2[i]) 489 { 490 return false; 491 } 492 } 493 read += buf1.length; 494 } 495 while (read < len1); 496 } 497 catch (IOException ex) 498 { 499 return false; 500 } 501 return true; 502 } 503 504 }

