blob: 359ef862418e50e9ee32736f0ea739f90dec6d6a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2007 Boeing.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Boeing - initial API and implementation
*******************************************************************************/
package org.eclipse.osee.framework.ui.skynet.util;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Writer;
import java.util.Map.Entry;
import java.util.logging.Level;
import org.eclipse.osee.framework.core.exception.OseeCoreException;
import org.eclipse.osee.framework.core.exception.OseeExceptions;
import org.eclipse.osee.framework.jdk.core.util.Lib;
import org.eclipse.osee.framework.logging.OseeLevel;
import org.eclipse.osee.framework.logging.OseeLog;
import org.eclipse.osee.framework.ui.skynet.internal.Activator;
import org.eclipse.osee.framework.ui.skynet.render.compare.CompareData;
/**
* @author Theron Virgin
*/
public class VbaWordDiffGenerator implements IVbaDiffGenerator {
private static final String OSEE_WORD_DIFF_SLEEP_MS = "osee.word.diff.sleep.ms";
// private final static String header =
// "Option Explicit\n\nDim oWord\nDim baseDoc\nDim compareDoc\nDim authorName\nDim detectFormatChanges\nDim ver1\nDim ver2\nDim wdCompareTargetSelectedDiff\nDim wdCompareTargetSelectedMerge\nDim wdFormattingFromCurrent\nDim wdFormatXML\nDim wdDoNotSaveChanges\nDim mainDoc\n\nPublic Sub main()\n On error resume next\n wdCompareTargetSelectedDiff = 0\n wdCompareTargetSelectedMerge = 1\n wdDoNotSaveChanges = 0\n wdFormattingFromCurrent = 3\n wdFormatXML = 11\n\n authorName = \"OSEE Doc compare\"\n set oWord = WScript.CreateObject(\"Word.Application\")\n oWord.Visible = False\n detectFormatChanges = ";
private final static String header_begin =
"Option Explicit\n\nDim oWord\nDim baseDoc\nDim compareDoc\nDim authorName\nDim detectFormatChanges\nDim ver1\nDim ver2\nDim wdCompareTargetSelectedDiff\nDim wdCompareTargetSelectedMerge\nDim wdFormattingFromCurrent\nDim wdFormatXML\nDim wdDoNotSaveChanges\nDim mainDoc\n\nPublic Sub main()\n ";
private final static String header_end =
"wdCompareTargetSelectedDiff = 0\n wdCompareTargetSelectedMerge = 1\n wdDoNotSaveChanges = 0\n wdFormattingFromCurrent = 3\n wdFormatXML = 11\n\n authorName = \"OSEE Doc compare\"\n set oWord = WScript.CreateObject(\"Word.Application\")\n oWord.Visible = False\n detectFormatChanges = ";
private static final String Skip_Errors = "On error resume next\n ";
private final static String comparisonCommand =
" baseDoc.Compare ver2, authorName, wdCompareTargetSelectedDiff, detectFormatChanges, False, False\n set compareDoc = oWord.ActiveDocument\n\n";
private final static String comparisonCommandFirst =
" set mainDoc = compareDoc\n baseDoc.close\n set baseDoc = Nothing\n";
private final static String comparisonCommandOthers =
" mainDoc.Range(mainDoc.Range.End-1, mainDoc.Range.End-1).FormattedText = compareDoc.Range.FormattedText\n\n baseDoc.close wdDoNotSaveChanges\n set baseDoc = Nothing\n\n compareDoc.close wdDoNotSaveChanges\n set compareDoc = Nothing\n\n";
private final static String mergeCommand =
" baseDoc.Merge ver2, wdCompareTargetSelectedMerge, detectFormatChanges, wdFormattingFromCurrent, False\n oWord.ActiveDocument.SaveAs %s, wdFormatXML, , , False\n\n";
private final boolean merge;
private final boolean show;
private final boolean detectFormatChanges;
private final boolean executeVbScript;
private final boolean skipErrors;
public VbaWordDiffGenerator(boolean merge, boolean show, boolean detectFormatChanges, boolean executeVbScript, boolean skipErrors) {
this.merge = merge;
this.show = show;
this.detectFormatChanges = detectFormatChanges;
this.executeVbScript = executeVbScript;
this.skipErrors = skipErrors;
}
@Override
public void generate(CompareData compareData) throws OseeCoreException {
Writer writer = null;
try {
writer = new BufferedWriter(new FileWriter(compareData.getGeneratorScriptPath()));
writer.append(header_begin);
if (skipErrors) {
writer.append(Skip_Errors);
}
writer.append(header_end);
writer.append("");
writer.append(Boolean.toString(detectFormatChanges));
writer.append("\n\n");
addComparison(writer, compareData, merge);
writer.append(" oWord.NormalTemplate.Saved = True\n");
if (show) {
writer.append("oWord.Visible = True\n");
}
writer.append(" mainDoc.SaveAs \"" + compareData.getOutputPath() + "\", wdFormatXML, , , False\n\n");
if (!show) {
writer.append(" oWord.Quit()\n");
writer.append(" set oWord = Nothing\n");
}
writer.append("End Sub\n\nmain");
} catch (IOException ex) {
OseeExceptions.wrapAndThrow(ex);
} finally {
Lib.close(writer);
}
if (executeVbScript) {
executeScript(new File(compareData.getGeneratorScriptPath()));
} else {
OseeLog.logf(Activator.class, Level.INFO, "Test - Skip launch of [%s]", compareData.getGeneratorScriptPath());
}
}
private void addComparison(Appendable appendable, CompareData compareData, boolean merge) throws IOException {
boolean first = true;
for (Entry<String, String> entry : compareData.entrySet()) {
//Unforunately Word seems to need a little extra time to close, otherwise Word 2007 will crash periodically if too many files are being compared.
String propertyWordDiffSleepMs = System.getProperty(OSEE_WORD_DIFF_SLEEP_MS, "250");// Quarter second is the default sleep value
appendable.append("WScript.sleep(" + propertyWordDiffSleepMs + ")\n");
appendable.append(" ver1 = \"");
appendable.append(entry.getKey());
appendable.append("\"\n ver2 = \"");
appendable.append(entry.getValue());
appendable.append("\"\n\n set baseDoc = oWord.Documents.Open (ver1)\n");
appendable.append(" baseDoc.TrackRevisions = false\n");
appendable.append(" baseDoc.AcceptAllRevisions\n");
appendable.append("\n\n set compareDoc = oWord.Documents.Open (ver2)\n");
appendable.append(" compareDoc.AcceptAllRevisions\n");
appendable.append(" compareDoc.TrackRevisions = false\n");
appendable.append(" compareDoc.Save\n");
appendable.append(" compareDoc.Close\n\n\n");
if (merge) {
appendable.append(String.format(mergeCommand, "\"" + compareData.getOutputPath() + "\""));
} else {
appendable.append(comparisonCommand);
if (first) {
appendable.append(comparisonCommandFirst);
first = false;
} else {
appendable.append(comparisonCommandOthers);
}
}
}
}
private void executeScript(File vbDiffScript) throws OseeCoreException {
Process process = null;
try {
String target = vbDiffScript.getName();
String cmd[] = {"cmd", "/s", "/c", "\"" + target + "\""};
ProcessBuilder builder = new ProcessBuilder(cmd);
File parentDir = vbDiffScript.getParentFile();
if (parentDir != null) {
builder.directory(parentDir);
}
process = builder.start();
Thread errorCatcher = new StreamLogger(process.getErrorStream()) {
@Override
protected void log(String message) {
OseeLog.log(Activator.class, OseeLevel.SEVERE_POPUP, message);
}
};
Thread outputCatcher = new StreamLogger(process.getInputStream()) {
@Override
protected void log(String message) {
OseeLog.log(Activator.class, Level.INFO, message);
}
};
errorCatcher.start();
outputCatcher.start();
process.waitFor();
} catch (Exception ex) {
OseeExceptions.wrapAndThrow(ex);
} finally {
if (process != null) {
process.destroy();
}
}
}
private static abstract class StreamLogger extends Thread {
private final InputStream inputStream;
protected StreamLogger(InputStream inputStream) {
this.inputStream = inputStream;
}
@Override
public void run() {
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader br = new BufferedReader(isr);
try {
StringBuilder message = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null) {
message.append(line);
message.append("\n");
}
if (message.length() > 0) {
log(message.toString());
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
protected abstract void log(String message);
}
}