Skip to content

Commit

Permalink
Merge pull request #565 from jsight/WINDUP-415
Browse files Browse the repository at this point in the history
WINDUP-415: Rule level time estimation and some performance bugfixes
  • Loading branch information
lincolnthree committed May 27, 2015
2 parents 14167a0 + 7ecf4d6 commit 1813133
Show file tree
Hide file tree
Showing 27 changed files with 676 additions and 266 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ public void beforeRuleEvaluation(GraphRewrite event, Rule rule, EvaluationContex
{
}

@Override
public void ruleEvaluationProgress(GraphRewrite event, String name, int currentPosition, int total, int timeRemainingInSeconds)
{
}

@Override
public void afterRuleConditionEvaluation(GraphRewrite event, EvaluationContext context, Rule rule, boolean result)
{
Expand Down
19 changes: 19 additions & 0 deletions config/api/src/main/java/org/jboss/windup/config/GraphRewrite.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/
package org.jboss.windup.config;

import java.util.Collections;

import org.jboss.windup.graph.GraphContext;
import org.ocpsoft.rewrite.AbstractRewrite;
import org.ocpsoft.rewrite.event.Flow;
Expand All @@ -18,9 +20,17 @@
public class GraphRewrite extends AbstractRewrite implements Rewrite
{
private final GraphContext graphContext;
private final Iterable<RuleLifecycleListener> listeners;

public GraphRewrite(GraphContext context)
{
this.listeners = Collections.emptyList();
this.graphContext = context;
}

public GraphRewrite(Iterable<RuleLifecycleListener> listeners, GraphContext context)
{
this.listeners = listeners;
this.graphContext = context;
}

Expand Down Expand Up @@ -48,4 +58,13 @@ public GraphContext getGraphContext()
{
return graphContext;
}

/**
* This is optionally called by long-running rules to indicate their current progress and estimated time-remaining.
*/
public void ruleEvaluationProgress(String name, int currentPosition, int total, int timeRemainingInSeconds)
{
for (RuleLifecycleListener listener : listeners)
listener.ruleEvaluationProgress(this, name, currentPosition, total, timeRemainingInSeconds);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,37 +13,42 @@ public interface RuleLifecycleListener
/**
* Called immediately before any {@link Rule} instances are executed.
*/
public void beforeExecution(GraphRewrite event);
void beforeExecution(GraphRewrite event);

/**
* Called immediately before the given {@link Rule} is executed.
*/
public void beforeRuleEvaluation(GraphRewrite event, Rule rule, EvaluationContext context);
void beforeRuleEvaluation(GraphRewrite event, Rule rule, EvaluationContext context);

/**
* This is optionally called by long-running rules to indicate their current progress and estimated time-remaining.
*/
void ruleEvaluationProgress(GraphRewrite event, String name, int currentPosition, int total, int timeRemainingInSeconds);

/**
* Called immediately after execution of the each {@link Rule}.
*/
public void afterRuleConditionEvaluation(GraphRewrite event, EvaluationContext context, Rule rule, boolean result);
void afterRuleConditionEvaluation(GraphRewrite event, EvaluationContext context, Rule rule, boolean result);

/**
* Called immediately before {@link Rule} operations are performed (Only called if
* {@link Rule#evaluate(org.ocpsoft.rewrite.event.Rewrite, EvaluationContext)} returned <code>true</code>).
*/
public void beforeRuleOperationsPerformed(GraphRewrite event, EvaluationContext context, Rule rule);
void beforeRuleOperationsPerformed(GraphRewrite event, EvaluationContext context, Rule rule);

/**
* Called immediately after {@link Rule} operations are performed (Only called if
* {@link Rule#evaluate(org.ocpsoft.rewrite.event.Rewrite, EvaluationContext)} returned <code>true</code>).
*/
public void afterRuleOperationsPerformed(GraphRewrite event, EvaluationContext context, Rule rule);
void afterRuleOperationsPerformed(GraphRewrite event, EvaluationContext context, Rule rule);

/**
* Called immediately after a a {@link Rule} has thrown an exception, to indicate a failure of some kind
*/
public void afterRuleExecutionFailed(GraphRewrite event, EvaluationContext context, Rule rule, Throwable failureCause);
void afterRuleExecutionFailed(GraphRewrite event, EvaluationContext context, Rule rule, Throwable failureCause);

/**
* Called immediately after any {@link Rule} instances are executed.
*/
public void afterExecution(GraphRewrite event);
void afterExecution(GraphRewrite event);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.jboss.windup.config.operation.iteration.AbstractIterationOperation;
import org.jboss.windup.graph.model.WindupVertexFrame;
import org.jboss.windup.util.Logging;
import org.jboss.windup.util.ProgressEstimate;
import org.ocpsoft.rewrite.context.EvaluationContext;

/**
Expand All @@ -22,7 +23,8 @@ public class IterationProgress extends AbstractIterationOperation<WindupVertexFr
private String messagePrefix;
private int interval;
private int totalIterations = -1;
private int currentIteration = 0;
private boolean estimateTimeRemaining = true;
private ProgressEstimate progressEstimate;

public IterationProgress(String messagePrefix, int interval)
{
Expand All @@ -35,6 +37,12 @@ public static IterationProgress monitoring(String messagePrefix, int interval)
return new IterationProgress(messagePrefix, interval);
}

public IterationProgress disableTimeEstimation()
{
estimateTimeRemaining = false;
return this;
}

@Override
public void perform(GraphRewrite event, EvaluationContext context, WindupVertexFrame payload)
{
Expand All @@ -44,11 +52,18 @@ public void perform(GraphRewrite event, EvaluationContext context, WindupVertexF
Iterable<WindupVertexFrame> frames = (Iterable<WindupVertexFrame>) event.getRewriteContext().get(
Iteration.DEFAULT_VARIABLE_LIST_STRING);
totalIterations = Iterators.asList(frames).size();
progressEstimate = new ProgressEstimate(totalIterations);
}
currentIteration++;
if (currentIteration % interval == 0)
progressEstimate.addWork(1);
if (progressEstimate.getWorked() % interval == 0)
{
LOG.info(messagePrefix + currentIteration + " / " + totalIterations);
if (estimateTimeRemaining)
{
long remainingTimeMillis = progressEstimate.getTimeRemainingInMillis();
if (remainingTimeMillis > 1000)
event.ruleEvaluationProgress(messagePrefix, progressEstimate.getWorked(), totalIterations, (int) remainingTimeMillis / 1000);
}
LOG.info(messagePrefix + ": " + progressEstimate.getWorked() + " / " + totalIterations);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ public interface DecompilationListener
/**
* Indicates that the file at inputPath has been decompiled to outputPath
*/
public void fileDecompiled(String inputPath, String outputPath);
void fileDecompiled(String inputPath, String outputPath);

/**
* Called to indicate that decompilation of this particular file has failed for the specified reason.
*/
void decompilationFailed(String inputPath, String message);

/**
* Indicates that the decompilation process is complete for all files within the archive (or directory).
*
* This allows for cleanup, such as committing all results to disk.
*/
public void decompilationProcessComplete();
void decompilationProcessComplete();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.jboss.windup.decompiler.api;

import java.io.File;
import java.nio.file.Path;
import java.util.zip.ZipEntry;

Expand All @@ -21,7 +20,7 @@ public interface Decompiler
* @param classFile the .class file to be decompiled.
* @param outputDir The directory where decompiled .java files will be placed.
*/
public DecompilationResult decompileClassFile(File rootDir, Path classFilePath, File outputDir)
public DecompilationResult decompileClassFile(Path rootDir, Path classFilePath, Path outputDir)
throws DecompilationException;

/**
Expand All @@ -40,7 +39,7 @@ public DecompilationResult decompileClassFile(File rootDir, Path classFilePath,
* @param classesDir The directory containing source files and archives.
* @param outputDir The directory where decompiled .java files will be placed.
*/
public DecompilationResult decompileDirectory(File classesDir, File outputDir) throws DecompilationException;
public DecompilationResult decompileDirectory(Path classesDir, Path outputDir) throws DecompilationException;

/**
* Decompiles all .class files and nested archives in the given archive.
Expand All @@ -54,7 +53,7 @@ public DecompilationResult decompileClassFile(File rootDir, Path classFilePath,
* @param outputDir The directory where decompiled .java files will be placed.
* @param listener This is called after each successful decompilation
*/
public DecompilationResult decompileArchive(File archive, File outputDir, DecompilationListener listener) throws DecompilationException;
public DecompilationResult decompileArchive(Path archive, Path outputDir, DecompilationListener listener) throws DecompilationException;

/**
* Decompiles all .class files and nested archives in the given archive.
Expand All @@ -63,12 +62,12 @@ public DecompilationResult decompileClassFile(File rootDir, Path classFilePath,
* <code>foo.ear/bar.jar/src/com/foo/bar/Baz.java</code>.
* <p>
* Required directories will be created as needed.
*
*
* @param archive The archive containing source files and archives.
* @param outputDir The directory where decompiled .java files will be placed.
* @param filter Decides what files from the archive to decompile.
* @param listener This is called after each successful decompilation
*/
public DecompilationResult decompileArchive(File archive, File outputDir, Filter<ZipEntry> filter, DecompilationListener listener)
public DecompilationResult decompileArchive(Path archive, Path outputDir, Filter<ZipEntry> filter, DecompilationListener listener)
throws DecompilationException;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.jboss.windup.decompiler;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -29,9 +28,9 @@
*/
public abstract class DecompilerTestBase
{
private static final Logger log = Logger.getLogger(DecompilerTestBase.class.getName());
protected static final Logger log = Logger.getLogger(DecompilerTestBase.class.getName());

private File testTempDir;
protected Path testTempDir;

/**
* Get an instance of the {@link Decompiler} under test.
Expand All @@ -46,9 +45,9 @@ public abstract class DecompilerTestBase
@Before
public void setUp() throws IOException
{
this.testTempDir = new File("target/testTmp");
FileUtils.deleteQuietly(testTempDir);
Files.createDirectory(this.testTempDir.toPath());
this.testTempDir = Paths.get("target").resolve("testTmp");
FileUtils.deleteQuietly(testTempDir.toFile());
Files.createDirectory(this.testTempDir);
}

@After
Expand All @@ -64,14 +63,14 @@ public void testDecompileSingleClass() throws DecompilationException, IOExceptio
{
final Decompiler dec = this.getDecompiler();

File archive = new File("target/TestJars/wicket-core-6.11.0.jar");
File decompDir = new File(testTempDir, "decompiled");
File unzipDir = new File(testTempDir, "unzipped");
Path archive = Paths.get("target/TestJars/wicket-core-6.11.0.jar");
Path decompDir = testTempDir.resolve("decompiled");
Path unzipDir = testTempDir.resolve("unzipped");

ZipUtil.unzip(archive, unzipDir);
ZipUtil.unzip(archive.toFile(), unzipDir.toFile());

// DECOMPILE
Path clsFile = Paths.get("org/apache/wicket/ajax/AbstractAjaxResponse.class");
Path clsFile = unzipDir.resolve("org/apache/wicket/ajax/AbstractAjaxResponse.class");
final DecompilationResult res = dec.decompileClassFile(unzipDir, clsFile, decompDir);

Assert.assertNotNull("Results object was returned.", res);
Expand Down Expand Up @@ -99,8 +98,8 @@ public void testDecompileSingleClass() throws DecompilationException, IOExceptio
log.info("Compilation results: " + res.getDecompiledFiles().size() + " succeeded, " + res.getFailures().size()
+ " failed.");

final File sampleFile = new File(decompDir, "org/apache/wicket/ajax/AbstractAjaxResponse.java");
Assert.assertTrue("Decompiled class did not exist in: " + sampleFile.getAbsolutePath(), sampleFile.exists());
final Path sampleFile = decompDir.resolve("org").resolve("apache").resolve("wicket").resolve("ajax").resolve("AbstractAjaxResponse.java");
Assert.assertTrue("Decompiled class did not exist in: " + sampleFile.toString(), Files.exists(sampleFile));
dec.close();
}

Expand All @@ -110,8 +109,8 @@ public void testDecompileSingleClass() throws DecompilationException, IOExceptio
@Test
public void testDecompileWicketJar() throws DecompilationException
{
File archive = new File("target/TestJars/wicket-core-6.11.0.jar");
File decompDir = new File(testTempDir, "decompiled");
Path archive = Paths.get("target/TestJars/wicket-core-6.11.0.jar");
Path decompDir = testTempDir.resolve("decompiled");

final Decompiler dec = this.getDecompiler();
final DecompilationResult res = dec.decompileArchive(archive, decompDir, new CountClassesFilter(100), new DecompilationListener()
Expand All @@ -122,6 +121,12 @@ public void decompilationProcessComplete()
// noop
}

@Override
public void decompilationFailed(String inputPath, String message)
{

}

@Override
public void fileDecompiled(String inputPath, String outputPath)
{
Expand All @@ -148,8 +153,8 @@ public void fileDecompiled(String inputPath, String outputPath)
log.info("Compilation results: " + res.getDecompiledFiles().size() + " succeeded, " + res.getFailures().size()
+ " failed.");

final File sampleFile = new File(decompDir, "org/apache/wicket/ajax/AbstractAjaxResponse.java");
Assert.assertTrue("Decompiled class files exist:\n " + sampleFile.getAbsolutePath(), sampleFile.exists());
final Path sampleFile = decompDir.resolve("org").resolve("apache").resolve("wicket").resolve("ajax").resolve("AbstractAjaxResponse.java");
Assert.assertTrue("Decompiled class files exist:\n " + sampleFile.toString(), Files.exists(sampleFile));
dec.close();
}

Expand All @@ -159,11 +164,11 @@ public void testDecompileWicketJarDirectory() throws DecompilationException, IOE
{
final Decompiler dec = this.getDecompiler();

File archive = new File("target/TestJars/wicket-core-6.11.0.jar");
File decompDir = new File(testTempDir, "decompiled");
File unzipDir = new File(testTempDir, "unzipped");
Path archive = Paths.get("target/TestJars/wicket-core-6.11.0.jar");
Path decompDir = testTempDir.resolve("decompiled");
Path unzipDir = testTempDir.resolve("unzipped");

ZipUtil.unzipWithFilter(archive, unzipDir, new CountClassesFilter(100));
ZipUtil.unzipWithFilter(archive.toFile(), unzipDir.toFile(), new CountClassesFilter(100));

final DecompilationResult res = dec.decompileDirectory(unzipDir, decompDir);

Expand All @@ -186,8 +191,8 @@ public void testDecompileWicketJarDirectory() throws DecompilationException, IOE
log.info("Compilation results: " + res.getDecompiledFiles().size() + " succeeded, " + res.getFailures().size()
+ " failed.");

final File sampleFile = new File(decompDir, "org/apache/wicket/ajax/AbstractAjaxResponse.java");
Assert.assertTrue("Decompiled class did not exist in: " + sampleFile.getAbsolutePath(), sampleFile.exists());
final Path sampleFile = decompDir.resolve("org").resolve("apache").resolve("wicket").resolve("ajax").resolve("AbstractAjaxResponse.java");
Assert.assertTrue("Decompiled class did not exist in: " + sampleFile, Files.exists(sampleFile));
dec.close();
}

Expand Down
Loading

0 comments on commit 1813133

Please sign in to comment.