Skip to content
This repository has been archived by the owner on Apr 6, 2022. It is now read-only.

Commit

Permalink
[FIXED JENKINS-14383] Parse the groovy script only once.
Browse files Browse the repository at this point in the history
  • Loading branch information
uhafner committed Jul 12, 2012
1 parent 6e10b5c commit 976c8cd
Show file tree
Hide file tree
Showing 5 changed files with 4,157 additions and 5 deletions.
Expand Up @@ -27,7 +27,7 @@ public class DynamicParser extends RegexpLineParser {
* the name of the trend report
*/
public DynamicParser(final String name, final String regexp, final String script, final String linkName, final String trendName) {
super(localize(name), localize(linkName), localize(trendName), regexp, true);
super(localize(name), localize(linkName), localize(trendName), regexp);

expressionMatcher = new GroovyExpressionMatcher(script, FALSE_POSITIVE);
}
Expand Down
Expand Up @@ -2,13 +2,16 @@

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import hudson.plugins.warnings.WarningsDescriptor;

import java.io.Serializable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;

import org.codehaus.groovy.control.CompilationFailedException;

/**
* Creates a warning based on a regular expression match and groovy script.
*
Expand All @@ -17,8 +20,10 @@
public class GroovyExpressionMatcher implements Serializable {
private static final long serialVersionUID = -2218299240520838315L;

private final String script;
private final Warning falsePositive;
private final String script;

private transient Script compiled;

/**
* Creates a new instance of {@link GroovyExpressionMatcher}.
Expand All @@ -31,6 +36,29 @@ public class GroovyExpressionMatcher implements Serializable {
public GroovyExpressionMatcher(final String script, final Warning falsePositive) {
this.script = script;
this.falsePositive = falsePositive;

compileScript();
}

private void compileScript() {
GroovyShell shell = new GroovyShell(WarningsDescriptor.class.getClassLoader());
try {
compiled = shell.parse(script);
}
catch (CompilationFailedException exception) {
LOGGER.log(Level.SEVERE, "Groovy dynamic warnings parser: exception during compiling: ", exception);
}
}

/**
* Compiles the script.
*
* @return this
*/
protected Object readResolve() {
compileScript();

return this;
}

/**
Expand All @@ -43,10 +71,10 @@ public GroovyExpressionMatcher(final String script, final Warning falsePositive)
public Warning createWarning(final Matcher matcher) {
Binding binding = new Binding();
binding.setVariable("matcher", matcher);
GroovyShell shell = new GroovyShell(WarningsDescriptor.class.getClassLoader(), binding);
Object result = null;
try {
result = shell.evaluate(script);
compiled.setBinding(binding);
result = compiled.run();
if (result instanceof Warning) {
return (Warning)result;
}
Expand Down
Expand Up @@ -40,7 +40,6 @@ protected AbstractWarningsParser createParser() {
TYPE, TYPE);
}


/**
* Parses a file with 9 warnings of a custom parser.
*
Expand Down
38 changes: 38 additions & 0 deletions src/test/java/hudson/plugins/warnings/parser/ParserSpeed.java
Expand Up @@ -5,6 +5,7 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.commons.lang.StringUtils;
Expand All @@ -14,6 +15,8 @@
* Speed test of the parsers in the {@link ParserRegistry}.
*/
public class ParserSpeed {
private static final String TEST = "test";

/**
* Runs all parsers and logs the results to the console.
*
Expand All @@ -34,6 +37,41 @@ public void testAllParsersOnOneFile() throws IOException {
}
}

/**
* Measures the performance of the dynamic parser.
*
* @throws IOException
* if the file could not be read
* @see <a href="http://issues.jenkins-ci.org/browse/JENKINS-14383">Issue 14383</a>
*/
@Test
public void issue14383() throws IOException {
DynamicParser dynamicParser = new DynamicParser(TEST, "^([A-Z]+):(\\s)*\\[(.*)\\].*at:\\s(\\w+\\.java)\\((\\d+)\\)(\\s)*$",
"import hudson.plugins.warnings.parser.Warning\n"
+ "return new Warning(\"fileName\", 1, \"Dynamic Parser\", \"category\" , \"normal\")",
TEST, TEST);
long start = System.currentTimeMillis();
dynamicParser.parse(openFile("issue14383.txt"));
long end = System.currentTimeMillis();
System.out.println("Dynamic parser: " + (end-start) + "ms"); // NOCHECKSTYLE NOPMD
}

/**
* Returns an input stream with the warnings.
*
* @param fileName
* the file to read
* @return an input stream
*/
protected Reader openFile(final String fileName) {
try {
return new InputStreamReader(ParserTester.class.getResourceAsStream(fileName), "UTF-8");
}
catch (UnsupportedEncodingException exception) {
return new InputStreamReader(ParserTester.class.getResourceAsStream(fileName));
}
}

/**
* Creates the {@link ParserRegistry}.
*
Expand Down

0 comments on commit 976c8cd

Please sign in to comment.