/* * Copyright (C) 2004 Anthony Smith * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * ---------------------------------------------------------------------------- * TITLE $Id$ * --------------------------------------------------------------------------- * * --------------------------------------------------------------------------*/ package opendbcopy.plugin.statistics; import opendbcopy.config.APM; import opendbcopy.config.XMLTags; import opendbcopy.connection.DBConnection; import opendbcopy.connection.exception.DriverNotFoundException; import opendbcopy.connection.exception.OpenConnectionException; import opendbcopy.controller.MainController; import opendbcopy.plugin.model.DynamicPluginThread; import opendbcopy.plugin.model.Model; import opendbcopy.plugin.model.exception.MissingAttributeException; import opendbcopy.plugin.model.exception.MissingElementException; import opendbcopy.plugin.model.exception.PluginException; import opendbcopy.plugin.model.exception.UnsupportedAttributeValueException; import opendbcopy.sql.Helper; import opendbcopy.util.InputOutputHelper; import org.jdom.Element; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.Date; import java.util.Iterator; import java.util.List; /** * class description * * @author Anthony Smith * @version $Revision$ */ public class WriteStatisticsToFilePlugin extends DynamicPluginThread { private StatisticsModel model; /** * Creates a new WriteStatisticsToFilePlugin object. * * @param controller DOCUMENT ME! * @param baseModel DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ public WriteStatisticsToFilePlugin(MainController controller, Model baseModel) throws PluginException { super(controller, baseModel); model = (StatisticsModel) baseModel; } /** * DOCUMENT ME! * * @throws PluginException DOCUMENT ME! */ public final void execute() throws PluginException { try { // source db if (!isInterrupted()) { readStatisticsForDb(model.getSourceDb(), model.getSourceStatistics()); } // destination db if ((model.getDbMode() == model.DUAL_MODE) && !isInterrupted()) { readStatisticsForDb(model.getDestinationDb(), model.getDestinationStatistics()); } if (!isInterrupted()) { writeStatisticsToFile(); } } catch (UnsupportedAttributeValueException e) { throw new PluginException(e); } catch (MissingAttributeException e) { throw new PluginException(e); } catch (MissingElementException e) { throw new PluginException(e); } catch (DriverNotFoundException e) { throw new PluginException(e); } catch (SQLException e) { throw new PluginException(e); } catch (IOException e) { throw new PluginException(e); } } /** * Creates a new writeStatisticsToFile object. * * @throws IllegalArgumentException DOCUMENT ME! * @throws UnsupportedAttributeValueException DOCUMENT ME! * @throws MissingAttributeException DOCUMENT ME! * @throws MissingElementException DOCUMENT ME! * @throws IOException DOCUMENT ME! */ private void writeStatisticsToFile() throws IllegalArgumentException, UnsupportedAttributeValueException, MissingAttributeException, MissingElementException, IOException, PluginException { StringBuffer buffer = new StringBuffer(); int difference = 0; int sourceRecords = 0; int destinationRecords = 0; int totalSourceRecords = 0; int totalDestinationRecords = 0; // get parameters for plugin Element conf = model.getConf(); String pathFilename = conf.getChild(XMLTags.FILE).getAttributeValue(XMLTags.VALUE); if (pathFilename == null) { throw new PluginException("Missing path / filename to store statistics"); } String fileType = conf.getChild(XMLTags.FILE_TYPE).getAttributeValue(XMLTags.VALUE); if (fileType == null) { throw new PluginException("Missing file type"); } int indexFileExtension = pathFilename.indexOf(fileType); // file does not yet contain extension if (indexFileExtension != pathFilename.length() - fileType.length()) { pathFilename = pathFilename + "." + fileType; } String delimiter = ";"; // init the string buffer to show table headings buffer.append("Created by openDBcopy Statistics Plugin on " + model.getSourceStatistics().getAttributeValue(XMLTags.CAPTURE_DATE) + APM.LINE_SEP); buffer.append(APM.LINE_SEP); buffer.append("SOURCE" + delimiter); buffer.append("RECORDS" + delimiter); if (model.getDbMode() == model.DUAL_MODE) { buffer.append("DESTINATION" + delimiter); buffer.append("RECORDS" + delimiter); buffer.append("+ / -" + delimiter); } buffer.append(APM.LINE_SEP); if (model.getDbMode() == model.DUAL_MODE) { // go through the tables which are mapped Iterator itMappingTables = model.getMappingTables().iterator(); while (itMappingTables.hasNext() && !isInterrupted()) { Element mappingTable = (Element) itMappingTables.next(); Element statisticsSourceTable = model.getSourceStatisticsTable(mappingTable.getAttributeValue(XMLTags.SOURCE_DB)); Element statisticsDestinationTable = model.getDestinationStatisticsTable(mappingTable.getAttributeValue(XMLTags.DESTINATION_DB)); if ((statisticsSourceTable != null) && (statisticsDestinationTable != null)) { sourceRecords = Integer.parseInt(statisticsSourceTable.getAttributeValue(XMLTags.RECORDS)); destinationRecords = Integer.parseInt(statisticsDestinationTable.getAttributeValue(XMLTags.RECORDS)); difference = sourceRecords - destinationRecords; buffer.append(statisticsSourceTable.getAttributeValue(XMLTags.NAME) + delimiter); buffer.append(statisticsSourceTable.getAttributeValue(XMLTags.RECORDS) + delimiter); buffer.append(statisticsDestinationTable.getAttributeValue(XMLTags.NAME) + delimiter); buffer.append(statisticsDestinationTable.getAttributeValue(XMLTags.RECORDS) + delimiter); buffer.append(difference + delimiter); buffer.append(APM.LINE_SEP); } totalSourceRecords += sourceRecords; totalDestinationRecords += destinationRecords; } // add total records of mapped tables to buffer buffer.append("TOTAL" + delimiter); buffer.append(totalSourceRecords + delimiter); buffer.append("TOTAL" + delimiter); buffer.append(totalDestinationRecords + delimiter); buffer.append(totalSourceRecords - totalDestinationRecords); buffer.append(APM.LINE_SEP); // add empty line buffer.append(APM.LINE_SEP); // go through unmapped source tables List unmappedSourceTables = model.getUnmappedSourceTables(); Iterator itUnmappedSourceTables = unmappedSourceTables.iterator(); while (itUnmappedSourceTables.hasNext() && !isInterrupted()) { Element table = model.getSourceStatisticsTable(((Element) itUnmappedSourceTables.next()).getAttributeValue(XMLTags.NAME)); buffer.append(table.getAttributeValue(XMLTags.NAME) + delimiter); buffer.append(table.getAttributeValue(XMLTags.RECORDS) + delimiter); buffer.append("UNMAPPED" + delimiter); buffer.append(delimiter); buffer.append(delimiter); buffer.append(APM.LINE_SEP); } // go through unmapped destination tables List unmappedDestinationTables = model.getUnmappedDestinationTables(); Iterator itUnmappedDestinationTables = unmappedDestinationTables.iterator(); while (itUnmappedDestinationTables.hasNext() && !isInterrupted()) { Element table = model.getDestinationStatisticsTable(((Element) itUnmappedDestinationTables.next()).getAttributeValue(XMLTags.NAME)); buffer.append("UNMAPPED" + delimiter); buffer.append(delimiter); buffer.append(table.getAttributeValue(XMLTags.NAME) + delimiter); buffer.append(table.getAttributeValue(XMLTags.RECORDS) + delimiter); buffer.append(delimiter); buffer.append(APM.LINE_SEP); } } // single_db mode else { // go through source tables List sourceTables = model.getSourceTables(); Iterator itSourceTables = sourceTables.iterator(); while (itSourceTables.hasNext() && !isInterrupted()) { Element table = model.getSourceStatisticsTable(((Element) itSourceTables.next()).getAttributeValue(XMLTags.NAME)); buffer.append(table.getAttributeValue(XMLTags.NAME) + delimiter); buffer.append(table.getAttributeValue(XMLTags.RECORDS) + delimiter); buffer.append(APM.LINE_SEP); sourceRecords = Integer.parseInt(table.getAttributeValue(XMLTags.RECORDS)); totalSourceRecords += sourceRecords; } buffer.append("TOTAL" + delimiter + totalSourceRecords + delimiter); } if (!isInterrupted()) { File outputFile = new File(pathFilename); FileWriter fileWriter = new FileWriter(outputFile); fileWriter.write(buffer.toString()); fileWriter.close(); // append output file to plugin model.appendToOutput(InputOutputHelper.createFileElement(outputFile)); logger.info("statistics written to " + pathFilename); } } /** * DOCUMENT ME! * * @param db_element DOCUMENT ME! * @param statistics DOCUMENT ME! * * @throws IllegalArgumentException DOCUMENT ME! * @throws MissingAttributeException DOCUMENT ME! * @throws MissingElementException DOCUMENT ME! * @throws OpenConnectionException DOCUMENT ME! * @throws DriverNotFoundException DOCUMENT ME! * @throws SQLException DOCUMENT ME! */ private void readStatisticsForDb(Element db_element, Element statistics) throws IllegalArgumentException, MissingAttributeException, MissingElementException, OpenConnectionException, DriverNotFoundException, SQLException { if ((db_element == null) || (statistics == null)) { throw new IllegalArgumentException("Missing arguments values: db_element=" + db_element + " statistics=" + statistics); } // remove former statistics if existing if (statistics.getChildren().size() > 0) { statistics.removeChildren(XMLTags.TABLE); } // set the capture data statistics.setAttribute(XMLTags.CAPTURE_DATE, new Date().toString()); // get connection Connection conn = DBConnection.getConnection(db_element.getChild(XMLTags.CONNECTION)); // extract the tables to read Iterator itTables = db_element.getChild(XMLTags.MODEL).getChildren(XMLTags.TABLE).iterator(); Statement stmSource = conn.createStatement(); int nbrTables = db_element.getChild(XMLTags.MODEL).getChildren(XMLTags.TABLE).size(); int nbrRecords = 0; int tableCounter = 0; int totalNbrRecords = 0; String qualifiedTableName = ""; model.setLengthProgressTable(nbrTables); model.setCurrentProgressTable(tableCounter); logger.info("Counting records of " + db_element.getChild(XMLTags.CONNECTION).getAttributeValue(XMLTags.URL)); while (itTables.hasNext() && !isInterrupted()) { Element table = (Element) itTables.next(); String tableName = table.getAttributeValue(XMLTags.NAME); if (db_element.getName().compareTo(XMLTags.SOURCE_DB) == 0) { qualifiedTableName = model.getQualifiedSourceTableName(tableName); nbrRecords = Helper.getNumberOfRecords(stmSource, model, XMLTags.SOURCE_DB, tableName); } else { qualifiedTableName = model.getQualifiedDestinationTableName(tableName); nbrRecords = Helper.getNumberOfRecords(stmSource, model, XMLTags.DESTINATION_DB, tableName); } model.setProgressMessage(qualifiedTableName); logger.info(qualifiedTableName + " (" + nbrRecords + ")"); Element tableStatistics = new Element(XMLTags.TABLE); tableStatistics.setAttribute(XMLTags.NAME, table.getAttributeValue(XMLTags.NAME)); tableStatistics.setAttribute(XMLTags.RECORDS, Integer.toString(nbrRecords)); statistics.addContent(tableStatistics); model.setCurrentProgressTable(++tableCounter); totalNbrRecords += nbrRecords; } logger.info(db_element.getChild(XMLTags.CONNECTION).getAttributeValue(XMLTags.URL) + ": TOTAL records = " + totalNbrRecords); } }