001 /** 002 * Copyright (c) 2003 Daffodil Software Ltd all rights reserved, 003 * Modifications Copyright (c) 2008 Regiscope Digital Imaging Co, LLC, All rights reserved. 004 * This program is free software; you can redistribute it and/or modify 005 * it under the terms of version 2 of the GNU General Public License as 006 * published by the Free Software Foundation. 007 * There are special exceptions to the terms and conditions of the GPL 008 * as it is applied to this software. See the GNU General Public License for more details. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU General Public License for more details. 014 * 015 * You should have received a copy of the GNU General Public License 016 * along with this program; if not, write to the Free Software 017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018 */ 019 020 package org.dbreplicator.replication.xml; 021 022 import java.io.*; 023 import java.sql.*; 024 import java.util.*; 025 026 import org.dbreplicator.replication.*; 027 import org.dbreplicator.replication.DBHandler.*; 028 import org.dbreplicator.replication.column.*; 029 030 /** 031 * This class is basically useful for writing data in to the XML file, 032 * it implements _XMLWriter interface which forces it to implement the 033 * method write. This method identifies the column datatype and then corresponding 034 * columnObject. SO different column data are written in differnt manner. Here 035 * special cases of Blob & Clob are also handled. 036 */ 037 038 public class XMLWriter implements _XMLWriter { 039 040 HashMap columnObjects = new HashMap(); 041 042 // OutputStreamWriter os; 043 Writer bw; 044 AbstractDataBaseHandler dbDatatypeHandler; 045 BlobOutPutStream bops; 046 ClobOutPutStream cops; 047 int noOfPrimaryCols; 048 Connection pub_sub_connection = null; 049 public XMLWriter(BufferedWriter bw0, AbstractDataBaseHandler dbDatatypeHandler0, Connection pub_sub_connection0) { 050 bw = bw0; 051 dbDatatypeHandler = dbDatatypeHandler0; 052 pub_sub_connection = pub_sub_connection0; 053 bops = new BlobOutPutStream(PathHandler.getBLobFilePathForClient()); 054 cops = new ClobOutPutStream(PathHandler.getCLobFilePathForClient()); 055 } 056 057 public void write(ResultSet rows, int index, ArrayList encodedCols, 058 String col) throws SQLException, IOException, RepException { 059 ResultSetMetaData rsmt = rows.getMetaData(); 060 int columnType = rsmt.getColumnType(index); 061 // int columnPrecision=rsmt.getPrecision(index); 062 TypeInfo typeInfo = new TypeInfo(rsmt.getColumnTypeName(index), columnType); 063 // typeInfo.setColumnSize(columnPrecision); 064 dbDatatypeHandler.setColumnPrecisionInTypeInfo(typeInfo, rsmt, index); 065 dbDatatypeHandler.setTypeInfo(typeInfo, rows); 066 AbstractColumnObject columnObject = getColumnObject(typeInfo); 067 columnObject.setBlobHandlerObject(bops); 068 columnObject.setClobHandlerObject(cops); 069 columnObject.write(bw, rows, index, encodedCols, col); 070 071 } 072 073 private AbstractColumnObject getColumnObject(TypeInfo typeInfo) throws RepException { 074 Integer key = new Integer(typeInfo.hashCode()); 075 AbstractColumnObject columnObject = (AbstractColumnObject) columnObjects.get(key); 076 if (columnObject == null) { 077 columnObject = dbDatatypeHandler.getColumnObject(typeInfo); 078 columnObjects.put(key, columnObject); 079 } 080 return columnObject; 081 } 082 083 private void write(Writer os, Object value) throws IOException { 084 os.write("<![CDATA[" + value.toString() + "]]>"); 085 } 086 087 /* public void writeRowElement(int noOfColumns, ResultSet rows_I, 088 ResultSetMetaData rsmt) throws SQLException, 089 IOException, RepException { 090 os.write("<row>"); 091 for (int c = 5; c <= noOfColumns - 1 - noOfPrimaryCols; c++) { // -1 for serverName and -noOfPrimaryCols for excluding old_Primary columns form shadow table 092 String columnName = rsmt.getColumnName(c); 093 os.write("<columnName name=\"" + columnName + "\">"); 094 write(rows_I, c); 095 os.write("</columnName>\r\n"); 096 } 097 os.write("</row>"); 098 } */ 099 100 public void writeRowElement(int noOfColumns, ResultSet rows_I, 101 ResultSetMetaData rsmt, 102 String[] primaryColumnNames, 103 Object[] primaryColValues, String tableName, 104 ArrayList encodedCols) throws SQLException, 105 IOException, RepException { 106 int columnIndex=1; 107 bw.write("<row>"); 108 for (int c = 5; c <= noOfColumns - 2 - noOfPrimaryCols; c++) { // -1 for serverName and -noOfPrimaryCols for excluding old_Primary columns form shadow table 109 String columnName = rsmt.getColumnName(c); 110 //System.out.println("columnName::" + columnName); 111 /* bjt - test to see if column data is encoded here. 112 * if it is, add column to encodedCols or set flag to follow record */ 113 /* getObject(rows_I, columnIndex).toString().matches([^\p{Print}]) ? encodedCols = Y : encodedCols = N */ 114 if (!encodedCols.contains(columnName.toUpperCase())) { 115 bw.write("<col name=\"" + "c"+columnIndex+ "\">"); 116 } 117 else { 118 bw.write("<col name=\"" + "c"+columnIndex+ "\" Encode=\"Y\">"); 119 } 120 columnIndex++; 121 if (checkClobBLOB(rows_I, c)) { 122 ResultSet rsClobBlob = getResultSetClobBlob(rows_I, primaryColumnNames,primaryColValues, tableName, c); 123 write(rsClobBlob, 1, encodedCols, columnName); 124 rsClobBlob.close(); 125 } 126 else { 127 write(rows_I, c, encodedCols, columnName); 128 } 129 bw.write("</col>\r\n"); 130 } 131 bw.write("</row>"); 132 } 133 134 public void writePrimaryKeyElement(String[] primaryColumnNames, 135 Object[] primaryColValues, 136 ArrayList encodedCols) throws IOException { 137 bw.write("<primary>"); 138 for (int c = 0; c < primaryColumnNames.length; c++) { 139 bw.write("<pk name=\"" + primaryColumnNames[c] + "\">"); 140 write(bw, primaryColValues[c]); 141 bw.write("</pk>\r\n"); 142 } 143 bw.write("</primary>"); 144 } 145 146 public void writeRowElementForUpdate(int noOfColumns, ResultSet rows, 147 ResultSetMetaData rsmt, 148 ResultSet oldResultSet, 149 String[] primaryColumnNames, 150 Object[] primaryColValues, 151 String tableName, ArrayList encodedCols) throws 152 RepException, SQLException, IOException { 153 HashMap updatedColumns = new HashMap(); 154 155 bw.write("<row>"); 156 157 AbstractColumnObject columnObject; 158 int columnType, colPrecision = -1,columnIndex=1; 159 String columnName; 160 161 for (int c = 5; c <= noOfColumns - 2 - noOfPrimaryCols; c++) { // -1 for serverName and -noOfPrimaryCols for excluding old_Primary columns form shadow table 162 columnName = rsmt.getColumnName(c); 163 if (!encodedCols.contains(columnName.toUpperCase())) { 164 bw.write("<col name=\"" +"c"+columnIndex+ "\">"); 165 } 166 else { 167 bw.write("<col name=\"" + "c"+columnIndex+ "\" Encode=\"Y\">"); 168 } 169 columnIndex++; 170 // bw.write("<columnName name=\"" + columnName + "\">"); 171 172 columnType = rsmt.getColumnType(c); 173 // colPrecision=rsmt.getPrecision(c); 174 TypeInfo typeInfo = new TypeInfo(rsmt.getColumnTypeName(c), columnType); 175 dbDatatypeHandler.setTypeInfo(typeInfo, rows); 176 dbDatatypeHandler.setColumnPrecisionInTypeInfo(typeInfo, rsmt, c); 177 // typeInfo.setColumnSize(colPrecision); 178 columnObject = getColumnObject(typeInfo); 179 columnObject.setBlobHandlerObject(bops); 180 columnObject.setClobHandlerObject(cops); 181 if (checkClobBLOB(rows, c)) { 182 ResultSet rsClobBlob = getResultSetClobBlob(rows, primaryColumnNames,primaryColValues, tableName, c); 183 columnObject.writeUpdate(bw, rsClobBlob, oldResultSet, 1,updatedColumns, columnName, encodedCols); 184 rsClobBlob.close(); 185 } 186 else { 187 columnObject.writeUpdate(bw, rows, oldResultSet, c, updatedColumns,columnName, encodedCols); 188 } 189 bw.write("</col>\r\n"); 190 } 191 bw.write("</row>"); 192 193 Iterator iterator = updatedColumns.keySet().iterator(); 194 bw.write("<ChangedCol>"); 195 if (!iterator.hasNext()) { 196 bw.write("NO_OPERATION"); 197 bw.write("</ChangedCol>"); 198 return; 199 } 200 do { 201 Object changesColumnName = iterator.next(); 202 /* bjt */ 203 bw.write("<changesCol name=\"" + changesColumnName.toString() +"\">"); 204 //bw.write("<![CDATA["); 205 //Object ob = updatedColumns.get(changesColumnName); 206 //if (ob instanceof byte[]) { 207 // bw.write(new String( (byte[]) ob)); 208 //} 209 //else { 210 // bw.write(ob.toString()); 211 //} 212 //bw.write("]]></changesCol>"); 213 bw.write("</changesCol>"); 214 } 215 while (iterator.hasNext()); 216 bw.write("</ChangedCol>"); 217 218 } 219 220 public void setNoOFPrimaryColumnNumber(int number) { 221 noOfPrimaryCols = number; 222 } 223 224 private ResultSet getResultSetClobBlob(ResultSet rs, String[] primaryColNames, Object[] primaryColValues, 225 String tableName, int index) throws SQLException { 226 227 ResultSetMetaData rsmd = rs.getMetaData(); 228 String columnName = rsmd.getColumnName(index); 229 StringBuffer query = new StringBuffer(); 230 query.append("Select "); 231 query.append(columnName); 232 query.append(" from "); 233 query.append(tableName); 234 query.append(" where "); 235 for (int i = 0; i < primaryColNames.length; i++) { 236 if (i != 0) { 237 query.append(" and "); 238 } 239 query.append(primaryColNames[i]); 240 query.append("= ?"); 241 } 242 243 PreparedStatement ps = pub_sub_connection.prepareStatement(query.toString()); 244 245 ResultSet rss = null; 246 for (int i = 0; i < primaryColValues.length; i++) { 247 ps.setObject(i + 1, primaryColValues[i]); 248 } 249 rss = ps.executeQuery(); 250 251 rss.next(); 252 return rss; 253 } 254 255 private boolean checkClobBLOB(ResultSet rs, int index) throws SQLException { 256 ResultSetMetaData rsmd = rs.getMetaData(); 257 int columnType = rsmd.getColumnType(index); 258 boolean flag = false; 259 if (columnType == 2004 || columnType == 2005 || columnType == -4 || 260 columnType == -1 || columnType == -2 || columnType == -3 || 261 columnType == 1111) { 262 flag = true; 263 } 264 return flag; 265 266 } 267 268 /* public void writeEncoderDecoder(ResultSet rows, int index) throws SQLException, IOException, RepException 269 { 270 ResultSetMetaData rsmt = rows.getMetaData(); 271 int columnType = rsmt.getColumnType(index); 272 // int columnPrecision=rsmt.getPrecision(index); 273 TypeInfo typeInfo = new TypeInfo(rsmt.getColumnTypeName(index), columnType); 274 // typeInfo.setColumnSize(columnPrecision); 275 dbDatatypeHandler.setColumnPrecisionInTypeInfo(typeInfo, rsmt, index); 276 dbDatatypeHandler.setTypeInfo(typeInfo, rows); 277 AbstractColumnObject columnObject = getColumnObject(typeInfo); 278 columnObject.setBlobHandlerObject(bops); 279 columnObject.setClobHandlerObject(cops); 280 columnObject.writeEncodedRecords(bw, rows, index); 281 282 }*/ 283 284 public void writePrimaryKeyElement(String[] primaryColumnNames, 285 ResultSet rs, ArrayList encodedCols) throws 286 IOException, SQLException { 287 bw.write("<primary>"); 288 for (int c = 0; c < primaryColumnNames.length; c++) { 289 bw.write("<pk name=\"" + primaryColumnNames[c] + "\">"); 290 write(bw, rs.getObject(primaryColumnNames[c])); 291 bw.write("</pk>\r\n"); 292 } 293 bw.write("</primary>"); 294 } 295 296 }

