From ab208cde4276e58334f92f7607b31e77dde8a52d Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Fri, 14 May 2021 08:16:29 -0700 Subject: [PATCH] Remove jdiff --- lib/pom.xml | 82 ---- lib/readme-lib-module.html | 5 - testing-util/pom.xml | 6 - .../org/aspectj/testing/util/TestUtil.java | 369 ++++++------------ .../org/aspectj/testingutil/TestUtilTest.java | 11 +- .../testing/harness/bridge/DirChanges.java | 146 ------- .../main/java/org/aspectj/util/FileUtil.java | 13 + 7 files changed, 147 insertions(+), 485 deletions(-) diff --git a/lib/pom.xml b/lib/pom.xml index e2a186b38..807d8a344 100644 --- a/lib/pom.xml +++ b/lib/pom.xml @@ -161,25 +161,6 @@ 626e7bee806ea14812f6f95cc2d187ab6ba9114a - - @@ -548,67 +529,6 @@ - - @@ -675,8 +595,6 @@ commons/** docbook/** jarjar/** - - jdtcore-aj/** junit/** regexp/** diff --git a/lib/readme-lib-module.html b/lib/readme-lib-module.html index 1e476fb5a..fe4f03c4d 100644 --- a/lib/readme-lib-module.html +++ b/lib/readme-lib-module.html @@ -32,11 +32,6 @@ This module also contains some bootstrap libraries and test sources. http:jakarta.apache.org/commons. This is used only by the testing module. -
  • jdiff: - JDiff binaries; there is a jdiff project under LGPL at - http:sourceforge.net/projects/javadiff. - This is used only internally by the testing module and is not distributed. -
  • junit: JUnit 3.7 test libraries, available from junit.org and under the CPL. diff --git a/testing-util/pom.xml b/testing-util/pom.xml index 0acc00a08..cd62ba319 100644 --- a/testing-util/pom.xml +++ b/testing-util/pom.xml @@ -33,12 +33,6 @@ compile - - - jdiff - jdiff - 1.3 - diff --git a/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java b/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java index 79ae9a776..51c940277 100644 --- a/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java +++ b/testing-util/src/main/java/org/aspectj/testing/util/TestUtil.java @@ -14,33 +14,38 @@ package org.aspectj.testing.util; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringReader; -import java.io.StringWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.StringTokenizer; import org.aspectj.bridge.IMessageHandler; import org.aspectj.bridge.MessageUtil; import org.aspectj.util.FileUtil; import org.aspectj.util.LangUtil; import org.aspectj.util.Reflection; - -import jdiff.text.FileLine; -import jdiff.util.Diff; -import jdiff.util.DiffNormalOutput; import org.junit.Assert; + import junit.framework.AssertionFailedError; import junit.framework.Test; import junit.framework.TestCase; @@ -48,8 +53,7 @@ import junit.framework.TestResult; import junit.framework.TestSuite; /** - * Things that junit should perhaps have, but doesn't. Note the file-comparison methods require JDiff to run, but JDiff types are - * not required to resolve this class. Also, the bytecode weaver is required to compare class files, but not to compare other files. + * Things that junit should perhaps have, but doesn't. Also, the bytecode weaver is required to compare class files, but not to compare other files. */ public final class TestUtil { private static final String SANDBOX_NAME = "ajcSandbox"; @@ -208,9 +212,9 @@ public final class TestUtil { return path.toString(); } - public static String aspectjrtClasspath() { - return TestUtil.aspectjrtPath().getPath(); - } + public static String aspectjrtClasspath() { + return TestUtil.aspectjrtPath().getPath(); + } /** * @param input the String to parse for [on|off|true|false] @@ -536,76 +540,115 @@ public final class TestUtil { File expectedFile = new File(expectedBaseDir, path); return doSameFile(handler, expectedBaseDir, actualBaseDir, expectedFile, actualFile); } + + public static String disassembleClass(File basedir, File file) { + String basedirPath = FileUtil.normalizedPath(basedir); + String name = FileUtil.fileToClassName(basedir, file); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + String utf8 = StandardCharsets.UTF_8.name(); + try (PrintStream out = new PrintStream(baos, true, utf8)) { + Class c = Class.forName("org.aspectj.weaver.bcel.LazyClassGen"); + Method m = c.getMethod("disassemble", new Class[] { String.class, String.class, PrintStream.class }); + m.invoke(null, new Object[] { basedirPath, name, out }); + return baos.toString(utf8); + } catch (Throwable t) { + throw new IllegalStateException(t); + } + } + + public static List toLines(String inputString) { + List lines = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(new StringReader(inputString))) { + String line = null; + while ((line= br.readLine()) != null) { + lines.add(line); + } + } catch (IOException ioe) { + throw new IllegalStateException("Unable to create lines from string "+inputString,ioe); + } + return lines; + } + + public static String toString(List lines) { + return String.join("\n", lines); + } + + private static int longestLine(List lines) { + int longest = -1; + for (String line: lines) { + if (line.length()>longest) { + longest = line.length(); + } + } + return longest; + } - /** - * This does the work, selecting a lineator subclass and converting public API's to JDiff APIs for comparison. Currently, all - * jdiff interfaces are method-local, so this class will load without it; if we do use it, we can avoid the duplication. - */ private static boolean doSameFile(IMessageHandler handler, File expectedBaseDir, File actualBaseDir, File expectedFile, File actualFile) { String path = expectedFile.getPath(); - // XXX permit user to specify lineator - ILineator lineator = Lineator.TEXT; + List expectedLines = null; + List actualLines = null; + List errorContext = new ArrayList<>(); if (path.endsWith(".class")) { - if (ClassLineator.haveDisassembler()) { - lineator = Lineator.CLASS; - } else { - MessageUtil.abort(handler, "skipping - dissassembler not available"); - return false; - } - } - CanonicalLine[] actualLines = null; - CanonicalLine[] expectedLines = null; - try { - actualLines = lineator.getLines(handler, actualFile, actualBaseDir); - expectedLines = lineator.getLines(handler, expectedFile, expectedBaseDir); - } catch (IOException e) { - MessageUtil.fail(handler, "rendering lines ", e); + expectedLines = toLines(disassembleClass(expectedBaseDir, expectedFile)); + actualLines = toLines(disassembleClass(actualBaseDir, actualFile)); + } else { + expectedLines = FileUtil.readAsLines(expectedFile); + actualLines = FileUtil.readAsLines(actualFile); + } + // TODO replace this section with assertMultiLineStringEquals ? + int longestLine = longestLine(expectedLines); + int actualLongestLine = longestLine(actualLines); + String padding = null; + if (actualLongestLine>longestLine) { + longestLine = actualLongestLine; + } + StringBuilder s = new StringBuilder(); + for (int i=0;iexpectedLines.size()) { + StringBuilder extra = new StringBuilder(); + for (int l=expectedLines.size();l tests = source.tests(); while (tests.hasMoreElements()) { - sink.addTest((Test) tests.nextElement()); + sink.addTest(tests.nextElement()); } } @@ -772,168 +815,6 @@ public final class TestUtil { } } - /** component that reduces file to CanonicalLine[] */ - public interface ILineator { - /** Lineator suitable for text files */ - ILineator TEXT = new TextLineator(); - - /** Lineator suitable for class files (disassembles first) */ - ILineator CLASS = new ClassLineator(); - - /** - * Reduce file to CanonicalLine[]. - * - * @param handler the IMessageHandler for errors (may be null) - * @param file the File to render - * @param basedir the File for the base directory (may be null) - * @return CanonicalLine[] of lines - not null, but perhaps empty - */ - CanonicalLine[] getLines(IMessageHandler handler, File file, File basedir) throws IOException; - } - - /** alias for jdiff FileLine to avoid client binding */ - public static class CanonicalLine { - public static final CanonicalLine[] NO_LINES = new CanonicalLine[0]; - - /** canonical variant of line for comparison */ - public final String canonical; - - /** actual line, for logging */ - public final String line; - - public CanonicalLine(String canonical, String line) { - this.canonical = canonical; - this.line = line; - } - - public String toString() { - return line; - } - } - - private abstract static class Lineator implements ILineator { - /** - * Reduce file to CanonicalLine[]. - * - * @param handler the IMessageHandler for errors (may be null) - * @param file the File to render - * @param basedir the File for the base directory (may be null) - */ - public CanonicalLine[] getLines(IMessageHandler handler, File file, File basedir) throws IOException { - - if (!file.canRead() || !file.isFile()) { - MessageUtil.error(handler, "not readable file: " + basedir + " - " + file); - return null; - } - // capture file as FileLine[] - InputStream in = null; - /* String path = */FileUtil.normalizedPath(file, basedir); - LineStream capture = new LineStream(); - try { - lineate(capture, handler, basedir, file); - } catch (IOException e) { - MessageUtil.fail(handler, "NormalizedCompareFiles IOException reading " + file, e); - return null; - } finally { - if (null != in) { - try { - in.close(); - } catch (IOException e) { - } // ignore - } - capture.flush(); - capture.close(); - } - String missed = capture.getMissed(); - if (!LangUtil.isEmpty(missed)) { - MessageUtil.warn(handler, "NormalizedCompareFiles missed input: " + missed); - return null; - } else { - String[] lines = capture.getLines(); - CanonicalLine[] result = new CanonicalLine[lines.length]; - for (int i = 0; i < lines.length; i++) { - result[i] = new CanonicalLine(lines[i], lines[i]); - } - return result; - } - } - - protected abstract void lineate(PrintStream sink, IMessageHandler handler, File basedir, File file) throws IOException; - } - - private static class TextLineator extends Lineator { - - protected void lineate(PrintStream sink, IMessageHandler handler, File basedir, File file) throws IOException { - InputStream in = null; - try { - in = new FileInputStream(file); - FileUtil.copyStream(new DataInputStream(in), sink); - } finally { - try { - in.close(); - } catch (IOException e) { - } // ignore - } - } - } - - public static class ClassLineator extends Lineator { - - protected void lineate(PrintStream sink, IMessageHandler handler, File basedir, File file) throws IOException { - String name = FileUtil.fileToClassName(basedir, file); - // XXX re-enable preflight? - // if ((null != basedir) && (path.length()-6 != name.length())) { - // MessageUtil.error(handler, "unexpected class name \"" - // + name + "\" for path " + path); - // return null; - // } - disassemble(handler, basedir, name, sink); - } - - public static boolean haveDisassembler() { - try { - return (null != Class.forName("org.aspectj.weaver.bcel.LazyClassGen")); - } catch (ClassNotFoundException e) { - // XXX fix - // System.err.println(e.getMessage()); - // e.printStackTrace(System.err); - return false; - } - } - - /** XXX dependency on bcweaver/bcel */ - private static void disassemble(IMessageHandler handler, File basedir, String name, PrintStream out) throws IOException { - // LazyClassGen.disassemble(FileUtil.normalizedPath(basedir), name, - // capture); - - Throwable thrown = null; - String basedirPath = FileUtil.normalizedPath(basedir); - // XXX use reflection utilities to invoke dissassembler? - try { - // XXX need test to detect when this is refactored - Class c = Class.forName("org.aspectj.weaver.bcel.LazyClassGen"); - Method m = c.getMethod("disassemble", new Class[] { String.class, String.class, PrintStream.class }); - m.invoke(null, new Object[] { basedirPath, name, out }); - } catch (ClassNotFoundException e) { - thrown = e; - } catch (NoSuchMethodException e) { - thrown = e; - } catch (IllegalAccessException e) { - thrown = e; - } catch (InvocationTargetException e) { - Throwable t = e.getTargetException(); - if (t instanceof IOException) { - throw (IOException) t; - } - thrown = t; - } - if (null != thrown) { - MessageUtil.fail(handler, "disassembling " + name + " path: " + basedirPath, thrown); - } - } - } - - public static File createEmptySandbox() { File sandbox; @@ -944,9 +825,9 @@ public final class TestUtil { if (os.startsWith("Windows")) { tempDir = new File("N:\\temp"); if (!tempDir.exists()) { - tempDir = new File("C:\\temp"); - if (!tempDir.exists()) { - tempDir.mkdir(); + tempDir = new File("C:\\temp"); + if (!tempDir.exists()) { + tempDir.mkdir(); } } } else { @@ -1059,4 +940,12 @@ public final class TestUtil { } } + public static boolean haveDisassembler() { + try { + return (Class.forName("org.aspectj.weaver.bcel.LazyClassGen") != null); + } catch (ClassNotFoundException e) { + return false; + } + } + } diff --git a/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java b/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java index 1427ccc8a..6b791da43 100644 --- a/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java +++ b/testing-util/src/test/java/org/aspectj/testingutil/TestUtilTest.java @@ -81,16 +81,14 @@ public class TestUtilTest extends TestCase { public void testFileCompareNonClassStaticNegative() throws IOException { MessageHandler holder = new MessageHandler(); - File basedir = new File("testdata/testCompareTextFiles/differentFile"); + File basedir = new File(UtilTests.TESTING_UTIL_PATH + "/testdata/testCompareTextFiles/differentFile"); File expectedBaseDir = new File(basedir, "expected"); File actualBaseDir = new File(basedir, "actual"); String filename = "TestUtilTest.java"; File expected = new File(expectedBaseDir, filename); File actual = new File(actualBaseDir, filename); - - assertTrue(!TestUtil.sameFiles(holder, expected, actual)); - - assertTrue(!TestUtil.sameFiles(holder, expectedBaseDir, actualBaseDir, filename)); + assertTrue(!TestUtil.sameFiles(holder, expected, actual)); + assertTrue(!TestUtil.sameFiles(holder, expectedBaseDir, actualBaseDir, filename)); } public void testParseBoolean() { @@ -127,8 +125,9 @@ public class TestUtilTest extends TestCase { } } + public void testFileCompareClass() throws IOException { - if (!TestUtil.ClassLineator.haveDisassembler()) { + if (!TestUtil.haveDisassembler()) { System.err.println("skipping testFileCompareClass - no disassembler on classpath"); return; } diff --git a/testing/src/test/java/org/aspectj/testing/harness/bridge/DirChanges.java b/testing/src/test/java/org/aspectj/testing/harness/bridge/DirChanges.java index c19618a3d..603373381 100644 --- a/testing/src/test/java/org/aspectj/testing/harness/bridge/DirChanges.java +++ b/testing/src/test/java/org/aspectj/testing/harness/bridge/DirChanges.java @@ -294,152 +294,6 @@ public class DirChanges { */ boolean checkFile(IMessageHandler handler, String path, File actualFile); } -// File-comparison code with a bit more generality -- too unweildy -// /** -// * Default FileChecker compares files literally, transforming any -// * with registered normalizers. -// */ -// public static class FileChecker implements IFileChecker { -// final File baseExpectedDir; -// NormalizedCompareFiles fileComparer; -// -// public FileChecker(File baseExpectedDir) { -// this.baseExpectedDir = baseExpectedDir; -// fileComparer = new NormalizedCompareFiles(); -// } -// public boolean checkFile(IMessageHandler handler, String path, File actualFile) { -// if (null == baseExpectedDir) { -// MessageUtil.error(handler, "null baseExpectedDir set on construction"); -// } else if (!baseExpectedDir.canRead() || !baseExpectedDir.isDirectory()) { -// MessageUtil.error(handler, "bad baseExpectedDir: " + baseExpectedDir); -// } else { -// File expectedFile = new File(baseExpectedDir, path); -// if (!expectedFile.canRead()) { -// MessageUtil.fail(handler, "cannot read expected file: " + expectedFile); -// } else { -// return doCheckFile(handler, expectedFile, actualFile, path); -// } -// } -// return false; -// } -// -// protected boolean doCheckFile( -// IMessageHandler handler, -// File expectedFile, -// File actualFile, -// String path) { -// fileComparer.setHandler(handler); -// FileLine[] expected = fileComparer.diff(); -// return false; -// } -// } - -// /** -// * CompareFiles implementation that pre-processes input -// * to normalize it. Currently it reads all files except -// * .class files, which it disassembles first. -// */ -// public static class NormalizedCompareFiles extends CompareFiles { -// private final static String[] NO_PATHS = new String[0]; -// private static String normalPath(File file) { // XXX util -// if (null == file) { -// return ""; -// } -// return file.getAbsolutePath().replace('\\', '/'); -// } -// -// private String[] baseDirs; -// private IMessageHandler handler; -// -// public NormalizedCompareFiles() { -// } -// -// void init(IMessageHandler handler, File[] baseDirs) { -// this.handler = handler; -// if (null == baseDirs) { -// this.baseDirs = NO_PATHS; -// } else { -// this.baseDirs = new String[baseDirs.length]; -// for (int i = 0; i < baseDirs.length; i++) { -// this.baseDirs[i] = normalPath(baseDirs[i]) + "/"; -// } -// } -// } -// -// private String getClassName(File file) { -// String result = null; -// String path = normalPath(file); -// if (!path.endsWith(".class")) { -// MessageUtil.error(handler, -// "NormalizedCompareFiles expected " -// + file -// + " to end with .class"); -// } else { -// path = path.substring(0, path.length()-6); -// for (int i = 0; i < baseDirs.length; i++) { -// if (path.startsWith(baseDirs[i])) { -// return path.substring(baseDirs[i].length()).replace('/', '.'); -// } -// } -// MessageUtil.error(handler, -// "NormalizedCompareFiles expected " -// + file -// + " to start with one of " -// + LangUtil.arrayAsList(baseDirs)); -// } -// -// return result; -// } -// -// /** -// * Read file as normalized lines, sending handler any messages -// * ERROR for input failures and FAIL for processing failures. -// * @return NOLINES on error or normalized lines from file otherwise -// */ -// public FileLine[] getFileLines(File file) { -// FileLineator capture = new FileLineator(); -// InputStream in = null; -// try { -// if (!file.getPath().endsWith(".class")) { -// in = new FileInputStream(file); -// FileUtil.copyStream( -// new BufferedReader(new InputStreamReader(in)), -// new PrintWriter(capture)); -// } else { -// String name = getClassName(file); -// if (null == name) { -// return new FileLine[0]; -// } -// String path = normalPath(file); -// path = path.substring(0, path.length()-name.length()); -// // XXX sole dependency on bcweaver/bcel -// LazyClassGen.disassemble(path, name, capture); -// } -// } catch (IOException e) { -// MessageUtil.fail(handler, -// "NormalizedCompareFiles IOException reading " + file, e); -// return null; -// } finally { -// if (null != in) { -// try { in.close(); } -// catch (IOException e) {} // ignore -// } -// capture.flush(); -// capture.close(); -// } -// String missed = capture.getMissed(); -// if (!LangUtil.isEmpty(missed)) { -// MessageUtil.fail(handler, -// "NormalizedCompareFiles missed input: " -// + missed); -// return null; -// } else { -// return capture.getFileLines(); -// } -// } -// -// -// } /** * Specification for a set of File added, removed, or updated diff --git a/util/src/main/java/org/aspectj/util/FileUtil.java b/util/src/main/java/org/aspectj/util/FileUtil.java index 91686dd13..d6bf5b0a6 100644 --- a/util/src/main/java/org/aspectj/util/FileUtil.java +++ b/util/src/main/java/org/aspectj/util/FileUtil.java @@ -36,6 +36,9 @@ import java.io.Writer; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1139,6 +1142,16 @@ public class FileUtil { r.close(); return b.toString(); } + + public static List readAsLines(File file) { + try { + return Files.readAllLines(Paths.get(file.toURI())); + } catch (NoSuchFileException nsfe) { + return Collections.emptyList(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } // /** // * Returns the contents of this stream as a String -- 2.39.5