/******************************************************************************* | |
* Copyright (c) 1998, 2013 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 ADEScriptGenerator { | |
private static final String ADE_SCRIPT_FILE_NAME = "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 ADEScriptGenerator().execute(args); | |
} | |
public ADEScriptGenerator() 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 root directory of the ADE tree; | |
* which is typically the user's home directory on Linux | |
*/ | |
private File buildADEScriptFile() { | |
File root = this.adeDirectory; | |
while (root.getParentFile() != null) { | |
root = root.getParentFile(); | |
} | |
return new File(root, ADE_SCRIPT_FILE_NAME); | |
} | |
/** | |
* 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); | |
} | |
} |