FELIX-4817 : Baseline plugin is not thread safe
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1663247 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index 168849b..f431070 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -109,6 +109,11 @@
<version>3.0.10</version>
</dependency>
<dependency>
+ <groupId>org.sonatype.plexus</groupId>
+ <artifactId>plexus-build-api</artifactId>
+ <version>0.0.7</version>
+ </dependency>
+ <dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-sink-api</artifactId>
<version>1.0</version>
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/AbstractBaselinePlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/AbstractBaselinePlugin.java
index 287f582..441a01b 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/AbstractBaselinePlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/AbstractBaselinePlugin.java
@@ -162,6 +162,12 @@
public final void execute()
throws MojoExecutionException, MojoFailureException
{
+ this.execute(null);
+ }
+
+ protected void execute( Object context)
+ throws MojoExecutionException, MojoFailureException
+ {
if ( skip )
{
getLog().info( "Skipping Baseline execution" );
@@ -204,8 +210,7 @@
}
// go!
-
- init();
+ context = this.init(context);
String generationDate = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm'Z'" ).format( new Date() );
Reporter reporter = new Processor();
@@ -215,7 +220,7 @@
Set<Info> infoSet = new Baseline( reporter, new DiffPluginImpl() )
.baseline( currentBundle, previousBundle, packageFilters );
- startBaseline( generationDate, project.getArtifactId(), project.getVersion(), previousArtifact.getVersion() );
+ startBaseline( context, generationDate, project.getArtifactId(), project.getVersion(), previousArtifact.getVersion() );
final Info[] infos = infoSet.toArray( new Info[infoSet.size()] );
Arrays.sort( infos, new InfoComparator() );
@@ -283,7 +288,7 @@
String suggestedVersionString = String.valueOf( ( info.suggestedVersion == null ) ? "-" : info.suggestedVersion );
Map<String,String> attributes = info.attributes;
- startPackage( mismatch,
+ startPackage( context, mismatch,
packageName,
shortDelta,
deltaString,
@@ -295,13 +300,13 @@
if ( Delta.REMOVED != delta )
{
- doPackageDiff( packageDiff );
+ doPackageDiff( context, packageDiff );
}
- endPackage();
+ endPackage(context);
}
- endBaseline();
+ endBaseline(context);
}
catch ( Exception e )
{
@@ -310,6 +315,7 @@
finally
{
closeJars( currentBundle, previousBundle );
+ this.close(context);
}
// check if it has to fail if some error has been detected
@@ -354,7 +360,7 @@
}
}
- private void doPackageDiff( Diff diff )
+ private void doPackageDiff( Object context, Diff diff )
{
int depth = 1;
@@ -362,38 +368,41 @@
{
if ( Delta.UNCHANGED != curDiff.getDelta() )
{
- doDiff( curDiff, depth );
+ doDiff( context, curDiff, depth );
}
}
}
- private void doDiff( Diff diff, int depth )
+ private void doDiff( Object context, Diff diff, int depth )
{
String type = StringUtils.lowerCase( String.valueOf( diff.getType() ) );
String shortDelta = getShortDelta( diff.getDelta() );
String delta = StringUtils.lowerCase( String.valueOf( diff.getDelta() ) );
String name = diff.getName();
- startDiff( depth, type, name, delta, shortDelta );
+ startDiff( context, depth, type, name, delta, shortDelta );
for ( Diff curDiff : diff.getChildren() )
{
if ( Delta.UNCHANGED != curDiff.getDelta() )
{
- doDiff( curDiff, depth + 1 );
+ doDiff( context, curDiff, depth + 1 );
}
}
- endDiff( depth );
+ endDiff( context, depth );
}
// extensions APIs
- protected abstract void init();
+ protected abstract Object init(final Object initialContext);
- protected abstract void startBaseline( String generationDate, String bundleName, String currentVersion, String previousVersion );
+ protected abstract void close(final Object context);
- protected abstract void startPackage( boolean mismatch,
+ protected abstract void startBaseline( final Object context, String generationDate, String bundleName, String currentVersion, String previousVersion );
+
+ protected abstract void startPackage( final Object context,
+ boolean mismatch,
String name,
String shortDelta,
String delta,
@@ -403,17 +412,18 @@
DiffMessage diffMessage,
Map<String,String> attributes );
- protected abstract void startDiff( int depth,
+ protected abstract void startDiff( final Object context,
+ int depth,
String type,
String name,
String delta,
String shortDelta );
- protected abstract void endDiff( int depth );
+ protected abstract void endDiff( final Object context, int depth );
- protected abstract void endPackage();
+ protected abstract void endPackage(final Object context);
- protected abstract void endBaseline();
+ protected abstract void endBaseline(final Object context);
// internals
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselinePlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselinePlugin.java
index 0a46a26..722e0b6 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselinePlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselinePlugin.java
@@ -24,8 +24,9 @@
import java.util.Map;
import java.util.Map.Entry;
-import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
+import org.codehaus.plexus.util.xml.XMLWriter;
+import org.sonatype.plexus.build.incremental.BuildContext;
/**
* BND Baseline check between two bundles.
@@ -55,32 +56,60 @@
*/
private boolean logResults;
- private FileWriter xmlFileWriter;
+ /**
+ * @component
+ */
+ private BuildContext buildContext;
- private PrettyPrintXMLWriter xmlWriter;
+ private static final class Context {
+ public FileWriter writer;
+ public XMLWriter xmlWriter;
+ }
- protected void init()
+ @Override
+ protected Object init(final Object noContext)
{
if ( xmlOutputFile != null )
{
xmlOutputFile.getParentFile().mkdirs();
try
{
- xmlFileWriter = new FileWriter( xmlOutputFile );
- xmlWriter = new PrettyPrintXMLWriter( xmlFileWriter );
+ final Context ctx = new Context();
+ ctx.writer = new FileWriter( xmlOutputFile );
+ ctx.xmlWriter = new PrettyPrintXMLWriter( ctx.writer );
+ return ctx;
}
catch ( IOException e )
{
getLog().warn( "No XML report will be produced, cannot write data to " + xmlOutputFile, e );
}
}
+ return null;
}
- protected void startBaseline( String generationDate,
+ @Override
+ protected void close(final Object writer)
+ {
+ if ( writer != null )
+ {
+ try {
+
+ ((Context)writer).writer.close();
+ }
+ catch (IOException e)
+ {
+ // ignore
+ }
+ }
+ }
+ @Override
+ protected void startBaseline( Object context,
+ String generationDate,
String bundleName,
String currentVersion,
String previousVersion )
{
+ final XMLWriter xmlWriter = context == null ? null : ((Context)context).xmlWriter;
if ( isLoggingResults() )
{
log( "Baseline Report - Generated by Apache Felix Maven Bundle Plugin on %s based on Bnd - see http://www.aqute.biz/Bnd/Bnd",
@@ -107,7 +136,7 @@
"==========" );
}
- if ( isProducingXml() )
+ if ( xmlWriter != null )
{
xmlWriter.startElement( "baseline" );
xmlWriter.addAttribute( "version", "1.0.0" );
@@ -124,7 +153,9 @@
}
}
- protected void startPackage( boolean mismatch,
+ @Override
+ protected void startPackage( Object context,
+ boolean mismatch,
String name,
String shortDelta,
String delta,
@@ -134,6 +165,7 @@
DiffMessage diffMessage,
Map<String,String> attributes )
{
+ final XMLWriter xmlWriter = context == null ? null : ((Context)context).xmlWriter;
if ( isLoggingResults() )
{
log( TABLE_PATTERN,
@@ -147,19 +179,19 @@
attributes );
}
- if ( isProducingXml() )
+ if ( xmlWriter != null )
{
xmlWriter.startElement( "package" );
xmlWriter.addAttribute( "name", name );
xmlWriter.addAttribute( "delta", delta );
- simpleElement( "mismatch", String.valueOf( mismatch ) );
- simpleElement( "newerVersion", newerVersion );
- simpleElement( "olderVersion", olderVersion );
- simpleElement( "suggestedVersion", suggestedVersion );
+ simpleElement( xmlWriter, "mismatch", String.valueOf( mismatch ) );
+ simpleElement( xmlWriter, "newerVersion", newerVersion );
+ simpleElement( xmlWriter, "olderVersion", olderVersion );
+ simpleElement( xmlWriter, "suggestedVersion", suggestedVersion );
if ( diffMessage != null )
{
- simpleElement( diffMessage.getType().name(), diffMessage.getMessage() );
+ simpleElement( xmlWriter, diffMessage.getType().name(), diffMessage.getMessage() );
}
xmlWriter.startElement( "attributes" );
@@ -183,8 +215,10 @@
}
}
- protected void startDiff( int depth, String type, String name, String delta, String shortDelta )
+ @Override
+ protected void startDiff( Object context, int depth, String type, String name, String delta, String shortDelta )
{
+ final XMLWriter xmlWriter = context == null ? null : ((Context)context).xmlWriter;
if ( isLoggingResults() )
{
log( "%-" + (depth * 4) + "s %s %s %s",
@@ -194,7 +228,7 @@
name );
}
- if ( isProducingXml() )
+ if ( xmlWriter != null )
{
xmlWriter.startElement( type );
xmlWriter.addAttribute( "name", name );
@@ -202,39 +236,39 @@
}
}
- protected void endDiff( int depth )
+ @Override
+ protected void endDiff( Object context, int depth )
{
- if ( isProducingXml() )
+ final XMLWriter xmlWriter = context == null ? null : ((Context)context).xmlWriter;
+ if ( xmlWriter != null )
{
xmlWriter.endElement();
}
}
- protected void endPackage()
+ @Override
+ protected void endPackage(Object context)
{
+ final XMLWriter xmlWriter = context == null ? null : ((Context)context).xmlWriter;
if ( isLoggingResults() )
{
log( "-----------------------------------------------------------------------------------------------------------" );
}
- if ( isProducingXml() )
- {
- xmlWriter.endElement();
- }
- }
-
- protected void endBaseline()
- {
if ( xmlWriter != null )
{
xmlWriter.endElement();
- IOUtil.close( xmlFileWriter );
}
}
- private boolean isProducingXml()
+ @Override
+ protected void endBaseline(Object context)
{
- return xmlFileWriter!= null && xmlWriter != null;
+ final XMLWriter xmlWriter = context == null ? null : ((Context)context).xmlWriter;
+ if ( xmlWriter != null )
+ {
+ xmlWriter.endElement();
+ }
}
private boolean isLoggingResults()
@@ -247,7 +281,7 @@
getLog().info( String.format( format, args ) );
}
- private void simpleElement( String name, String value )
+ private void simpleElement( XMLWriter xmlWriter, String name, String value )
{
xmlWriter.startElement( name );
xmlWriter.writeText( value );
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselineReport.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselineReport.java
index 39e9e42..b25f1ad 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselineReport.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/baseline/BaselineReport.java
@@ -53,16 +53,18 @@
*/
private File outputDirectory;
- private Sink sink;
+ private static final class Context {
+ public Sink sink;
- private Locale locale;
+ public Locale locale;
- private int currentDepth = 0;
+ public int currentDepth = 0;
+ }
// AbstractBaselinePlugin events
@Override
- protected void init()
+ protected Object init(final Object context)
{
failOnError = false;
failOnWarning = false;
@@ -109,14 +111,25 @@
IOUtil.close( target );
}
}
+ return context;
}
- protected void startBaseline( String generationDate, String bundleName, String currentVersion, String previousVersion )
+ @Override
+ protected void close(final Object context)
{
+ // nothing to do
+ }
+
+ @Override
+ protected void startBaseline( final Object context, String generationDate, String bundleName, String currentVersion, String previousVersion )
+ {
+ final Context ctx = (Context)context;
+ final Sink sink = ctx.sink;
+
sink.head();
sink.title();
- String title = getBundle( locale ).getString( "report.baseline.title" );
+ String title = getBundle( ctx.locale ).getString( "report.baseline.title" );
sink.text( title );
sink.title_();
sink.head_();
@@ -129,7 +142,7 @@
sink.sectionTitle1_();
sink.paragraph();
- sink.text( getBundle( locale ).getString( "report.baseline.bndlink" ) + " " );
+ sink.text( getBundle( ctx.locale ).getString( "report.baseline.bndlink" ) + " " );
sink.link( "http://www.aqute.biz/Bnd/Bnd" );
sink.text( "Bnd" );
sink.link_();
@@ -137,7 +150,7 @@
sink.paragraph_();
sink.paragraph();
- sink.text( getBundle( locale ).getString( "report.baseline.bundle" ) + " " );
+ sink.text( getBundle( ctx.locale ).getString( "report.baseline.bundle" ) + " " );
sink.figure();
sink.figureGraphics( "images/baseline/bundle.gif" );
sink.figure_();
@@ -148,21 +161,21 @@
sink.listItem_();
sink.paragraph();
- sink.text( getBundle( locale ).getString( "report.baseline.version.current" ) + " " );
+ sink.text( getBundle( ctx.locale ).getString( "report.baseline.version.current" ) + " " );
sink.bold();
sink.text( currentVersion );
sink.bold_();
sink.paragraph_();
sink.paragraph();
- sink.text( getBundle( locale ).getString( "report.baseline.version.comparison" ) + " " );
+ sink.text( getBundle( ctx.locale ).getString( "report.baseline.version.comparison" ) + " " );
sink.bold();
sink.text( comparisonVersion );
sink.bold_();
sink.paragraph_();
sink.paragraph();
- sink.text( getBundle( locale ).getString( "report.baseline.generationdate" ) + " " );
+ sink.text( getBundle( ctx.locale ).getString( "report.baseline.generationdate" ) + " " );
sink.bold();
sink.text( generationDate );
sink.bold_();
@@ -171,7 +184,9 @@
sink.section1_();
}
- protected void startPackage( boolean mismatch,
+ @Override
+ protected void startPackage( final Object context,
+ boolean mismatch,
String packageName,
String shortDelta,
String delta,
@@ -181,6 +196,9 @@
DiffMessage diffMessage,
Map<String,String> attributes )
{
+ final Context ctx = (Context)context;
+ final Sink sink = ctx.sink;
+
sink.list();
sink.listItem();
@@ -219,18 +237,23 @@
}
}
- protected void startDiff( int depth,
+ @Override
+ protected void startDiff( final Object context,
+ int depth,
String type,
String name,
String delta,
String shortDelta )
{
- if ( currentDepth < depth )
+ final Context ctx = (Context)context;
+ final Sink sink = ctx.sink;
+
+ if ( ctx.currentDepth < depth )
{
sink.list();
}
- currentDepth = depth;
+ ctx.currentDepth = depth;
sink.listItem();
sink.figure();
@@ -249,35 +272,44 @@
sink.italic_();
}
- protected void endDiff( int depth )
+ @Override
+ protected void endDiff( final Object context, int depth )
{
+ final Context ctx = (Context)context;
+ final Sink sink = ctx.sink;
+
sink.listItem_();
- if ( currentDepth > depth )
+ if ( ctx.currentDepth > depth )
{
sink.list_();
}
- currentDepth = depth;
+ ctx.currentDepth = depth;
}
- protected void endPackage()
+ @Override
+ protected void endPackage(final Object context)
{
- if ( currentDepth > 0 )
+ final Context ctx = (Context)context;
+ final Sink sink = ctx.sink;
+ if ( ctx.currentDepth > 0 )
{
sink.list_();
- currentDepth = 0;
+ ctx.currentDepth = 0;
}
sink.listItem_();
sink.list_();
}
- protected void endBaseline()
+ @Override
+ protected void endBaseline(final Object context)
{
- sink.body_();
- sink.flush();
- sink.close();
+ final Context ctx = (Context)context;
+ ctx.sink.body_();
+ ctx.sink.flush();
+ ctx.sink.close();
}
// MavenReport methods
@@ -290,12 +322,13 @@
public void generate( @SuppressWarnings( "deprecation" ) org.codehaus.doxia.sink.Sink sink, Locale locale )
throws MavenReportException
{
- this.sink = sink;
- this.locale = locale;
+ final Context ctx = new Context();
+ ctx.sink = sink;
+ ctx.locale = locale;
try
{
- execute();
+ execute(ctx);
}
catch ( Exception e )
{