/******************************************************************************* * Copyright (c) 1998, 2015 Oracle and/or its affiliates. All rights reserved. * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0 * which accompanies this distribution. * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Oracle - initial API and implementation from Oracle TopLink ******************************************************************************/ package org.eclipse.persistence.tools.workbench.test; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.Writer; import java.text.DateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.List; /** * This class will take a Beyond Compare "Comparison Report" and generate * two scripts: * * 1. A Unix/Linux shell script that contains the appropriate ADE commands * for removing, checking out, and adding the appropriate files necessary * to synchronize the ADE source tree with the tree it was compared to. * This shell script is written to the root directory of the ADE source tree. * * 2. A Windows command script that contains the appropriate file copy * commands to copy the files over to the ADE source tree once the * files have been checked out and created by the script described * above. This command script is written to the same directory that * holder the Beyond Compare "Comparison Report". * * The file name of the Beyond Compare "Comparison Report" can be specified * via a command-line parm. The default value is C:\temp\bc.txt. * * We expect the Beyond Compare "Comparison Report" to have the ADE * source tree on the "Left Side". */ public class ADEScriptGenerator2 { private static final String ADE_SCRIPT_FILE_NAME = "check_out.sh"; private static final String DEFAULT_ADE_SCRIPT_FILE_LOCATION = "C:/temp/check_out.sh"; private static final String UPLOAD_SCRIPT_FILE_NAME = "upload.cmd"; private static final String UPLOAD_LOG_FILE_NAME = "upload.log"; private static final String TODAY = DateFormat.getDateInstance().format(new Date()); private static final String ADE_COMMENT = "Raleigh " + TODAY; private File beyondCompareReportFile; private static final String DEFAULT_BEYOND_COMPARE_REPORT_FILE_NAME = "C:/temp/bc.txt"; private File adeDirectory; private File localDirectory; private String[] matchingFileNames; private String[] leftSideNewerFileNames; private String[] rightSideNewerFileNames; private String[] leftSideOrphanFileNames; private String[] rightSideOrphanFileNames; private String[] contentsDifferFileNames; private final static String CR = System.getProperty("line.separator"); public static void main(String[] args) throws Exception { new ADEScriptGenerator2().execute(args); } public ADEScriptGenerator2() throws Exception { super(); } public void execute(String[] args) throws Exception { this.beyondCompareReportFile = this.buildBeyondCompareReportFile(args); this.readBeyondCompareReport(new BufferedReader(new FileReader(this.beyondCompareReportFile))); this.generateADEScript(new FileWriter(this.buildADEScriptFile())); this.generateUploadScript(new FileWriter(this.buildUploadScriptFile())); this.printStatistics(); System.out.println("*** EOJ ***"); System.exit(0); } private File buildBeyondCompareReportFile(String[] args) { return new File(this.buildBeyondCompareReportFileName(args)); } /** * allow the user to specify a Beyond Compare report file on the command-line */ private String buildBeyondCompareReportFileName(String[] args) { if ((args == null) || (args.length == 0)) { return DEFAULT_BEYOND_COMPARE_REPORT_FILE_NAME; } else { return args[0]; } } /** * put the ADE script in the ADE root */ private File buildADEScriptFile() { // File root = adeDirectory; // while (root.getParentFile() != null) { // root = root.getParentFile(); // } return new File(DEFAULT_ADE_SCRIPT_FILE_LOCATION); } /** * put the upload script in the same directory as the Beyond Compare report */ private File buildUploadScriptFile() { return new File(this.beyondCompareReportFile.getParentFile(), UPLOAD_SCRIPT_FILE_NAME); } private void readBeyondCompareReport(BufferedReader bcReportReader) throws Exception { this.extractDirectoryNames(bcReportReader); this.extractFileNames(bcReportReader); // skip remainder of heading this.matchingFileNames = this.extractFileNames(bcReportReader); this.leftSideNewerFileNames = this.extractFileNames(bcReportReader); this.rightSideNewerFileNames = this.extractFileNames(bcReportReader); this.leftSideOrphanFileNames = this.extractFileNames(bcReportReader); this.rightSideOrphanFileNames = this.extractFileNames(bcReportReader); this.contentsDifferFileNames = this.extractFileNames(bcReportReader); } private void extractDirectoryNames(BufferedReader bcReportReader) throws Exception { String firstLine = bcReportReader.readLine(); String start = "Folder Comparison of "; if ( ! firstLine.startsWith(start)) { throw new IllegalStateException("invalid first line: " + firstLine); } int end = firstLine.indexOf(' ', start.length()); this.adeDirectory = new File(firstLine.substring(start.length(), end)); String secondHalf = firstLine.substring(end); String conjunction = " and "; if ( ! secondHalf.startsWith(conjunction)) { throw new IllegalStateException("invalid first line: " + firstLine); } this.localDirectory = new File(secondHalf.substring(conjunction.length()).trim()); } private String[] extractFileNames(BufferedReader bcReportReader) throws Exception { List fileNames = new ArrayList(); for (String line = bcReportReader.readLine(); this.lineIsNotATerminator(line); line = bcReportReader.readLine()) { line = line.replace('\\', '/'); // convert to unix-style file names if (line.indexOf('/') == -1) { continue; // skip report headings and filler lines } if ( ! this.lineIsMW(line)) { continue; // skip non-MW lines } if (this.lineIsMWJlib(line)) { continue; // skip MW jlib lines } if (this.lineIsMWDevDocs(line)) { continue; //skip MW dev-docs lines } fileNames.add(line); } return (String[]) fileNames.toArray(new String[fileNames.size()]); } private boolean lineIsMW(String line) { // return whether the line is for an MW file return line.startsWith("mwdev/") || line.startsWith("mwtest/"); } private boolean lineIsMWJlib(String line) { // return whether the line is for an MW jlib file return line.startsWith("mwdev/jlib/") || line.startsWith("mwtest/jlib/"); } private boolean lineIsMWDevDocs(String line) { //return whether the line is for an MW dev-doc file return line.startsWith("mwdev/dev-docs/"); } private boolean lineIsNotATerminator(String line) { if (line == null) { // EOF return false; } if (line.equals("--------------------------")) { // next section of report return false; } return true; } private void generateADEScript(Writer writer) throws Exception { // writer.write("cd ~"); // start in the user's home directory writer.write("\n"); // use unix-style LF in the ADE script // writer.write("cd "); // writer.write(this.buildRelativeADEViewDirectoryName()); // writer.write("\n"); // writer.write("\n"); this.writeADECheckOutCommandsOn(this.rightSideNewerFileNames, writer); this.writeADECheckOutCommandsOn(this.leftSideNewerFileNames, writer); this.writeADECommandsOn("rm", this.leftSideOrphanFileNames, writer); writer.write("\n"); this.writeADEMakeElementCommandsOn(this.rightSideOrphanFileNames, writer); writer.close(); } private String buildRelativeADEViewDirectoryName() { if (this.adeDirectory.getParentFile() == null) { return "~"; // the ADE directory is the root - unlikely... } // gather up all the directory names, dropping the Windows root File temp = this.adeDirectory; List dirNames = new ArrayList(); while (temp.getParentFile() != null) { dirNames.add(temp.getName()); temp = temp.getParentFile(); } StringBuffer sb = new StringBuffer(); for (int i = dirNames.size(); i-- > 0; ) { sb.append(dirNames.get(i)); if (i != 0) { sb.append('/'); // convert to unix-style file name } } return sb.toString(); } private void writeADECheckOutCommandsOn(String[] fileNames, Writer writer) throws Exception { this.writeADECommandsOn("co -c \"" + ADE_COMMENT + "\"", fileNames, writer); writer.write("\n"); } private void writeADEMakeElementCommandsOn(String[] fileNames, Writer writer) throws Exception { this.checkDirs(fileNames, writer); // check for new directories first writer.write("\n"); this.writeADECommandsOn("mkelem -c \"" + ADE_COMMENT + "\"", fileNames, writer); } private void checkDirs(String[] fileNames, Writer writer) throws Exception { Collection alreadyAddedDirs = new HashSet(); for (int i = 0; i < fileNames.length; i++) { this.checkDir(fileNames[i], alreadyAddedDirs, writer); } } private void checkDir(String fileName, Collection alreadyAddedDirs, Writer writer) throws Exception { File file = new File(this.adeDirectory, fileName); File dir = file.getParentFile(); if (( ! dir.exists()) && ( ! alreadyAddedDirs.contains(dir))) { alreadyAddedDirs.add(dir); String relativeDirName = new File(fileName).getParent(); relativeDirName = relativeDirName.replace('\\', '/'); // convert back to unix-style file names this.writeADECommandOn("mkdir -p", relativeDirName, writer); } } private void writeADECommandsOn(String command, String[] fileNames, Writer writer) throws Exception { for (int i = 0; i < fileNames.length; i++) { this.writeADECommandOn(command, fileNames[i], writer); } } private void writeADECommandOn(String command, String fileName, Writer writer) throws Exception { writer.write("ade "); writer.write(command); writer.write(" "); writer.write(fileName); writer.write("\n"); // use unix-style LF } private void generateUploadScript(Writer writer) throws Exception { File logFile = this.buildUploadLogFile(); writer.write("del "); writer.write(logFile.getPath()); writer.write(CR); writer.write(CR); this.writeCopyCommandsOn(this.leftSideNewerFileNames, logFile, writer); writer.write(CR); this.writeCopyCommandsOn(this.rightSideNewerFileNames, logFile, writer); writer.write(CR); this.writeCopyCommandsOn(this.rightSideOrphanFileNames, logFile, writer); writer.write(CR); writer.write("notepad "); writer.write(logFile.getPath()); writer.write(CR); writer.close(); } /** * put the upload log in the same directory as the Beyond Compare report */ private File buildUploadLogFile() { return new File(this.beyondCompareReportFile.getParentFile(), UPLOAD_LOG_FILE_NAME); } private void writeCopyCommandsOn(String[] fileNames, File logFile, Writer writer) throws Exception { for (int i = 0; i < fileNames.length; i++) { this.writeCopyCommandOn(fileNames[i], logFile, writer); } } private void writeCopyCommandOn(String fileName, File logFile, Writer writer) throws Exception { File source = new File(this.localDirectory, fileName); File destination = new File(this.adeDirectory, fileName); writer.write("copy "); writer.write("\""); //double quote the path writer.write(source.getPath()); writer.write("\""); //double quote the path writer.write(" "); writer.write(destination.getPath()); writer.write(" >> "); writer.write(logFile.getPath()); writer.write(CR); } private void printStatistics() { System.out.println("Inputs"); System.out.println(" Beyond Compare Comparison Report: " + this.beyondCompareReportFile.getPath()); System.out.println("Outputs"); System.out.println(" ADE script: " + this.buildADEScriptFile().getPath()); System.out.println(" Upload script: " + this.buildUploadScriptFile().getPath()); System.out.println("Statistics"); System.out.println(" matching: " + this.matchingFileNames.length); System.out.println(" ADE file newer: " + this.leftSideNewerFileNames.length + " (check these files)"); System.out.println(" local file newer: " + this.rightSideNewerFileNames.length); System.out.println(" removed: " + this.leftSideOrphanFileNames.length); System.out.println(" added: " + this.rightSideOrphanFileNames.length); System.out.println(" contents differ: " + this.contentsDifferFileNames.length); } }