FELIX-3011: add 'dumpInstructions' and 'dumpClasspath' parameters that let you dump the BND instructions/classpath to a file

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1140878 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
index 07e087c..81aaee9 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BlueprintPlugin.java
@@ -26,7 +26,6 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URL;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -48,6 +47,7 @@
 import aQute.libg.qtokens.QuotedTokenizer;
 import aQute.libg.reporter.Reporter;
 
+
 public class BlueprintPlugin implements AnalyzerPlugin {
 
 
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
index d716c0d..6417cdd 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/BundlePlugin.java
@@ -19,11 +19,13 @@
 package org.apache.felix.bundleplugin;
 
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.StringWriter;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -61,7 +63,7 @@
 import org.codehaus.plexus.archiver.UnArchiver;
 import org.codehaus.plexus.archiver.manager.ArchiverManager;
 import org.codehaus.plexus.util.DirectoryScanner;
-import org.codehaus.plexus.util.StringInputStream;
+import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.StringUtils;
 
 import aQute.lib.osgi.Analyzer;
@@ -93,6 +95,20 @@
     protected File manifestLocation;
 
     /**
+     * File where the BND instructions will be dumped
+     *
+     * @parameter expression="${dumpInstructions}"
+     */
+    protected File dumpInstructions;
+
+    /**
+     * File where the BND class-path will be dumped
+     *
+     * @parameter expression="${dumpClasspath}"
+     */
+    protected File dumpClasspath;
+
+    /**
      * When true, unpack the bundle contents to the outputDirectory
      *
      * @parameter expression="${unpackBundle}"
@@ -197,6 +213,8 @@
     private static final String[] DEFAULT_INCLUDES =
         { "**/**" };
 
+    private static final String NL = System.getProperty( "line.separator" );
+
 
     protected Maven2OsgiConverter getMaven2OsgiConverter()
     {
@@ -426,10 +444,28 @@
         Collection embeddableArtifacts = getEmbeddableArtifacts( currentProject, builder );
         new DependencyEmbedder( getLog(), embeddableArtifacts ).processHeaders( builder );
 
-        dumpInstructions( "BND Instructions:", builder.getProperties(), getLog() );
-        dumpClasspath( "BND Classpath:", builder.getClasspath(), getLog() );
+        if ( dumpInstructions != null || getLog().isDebugEnabled() )
+        {
+            StringBuilder buf = new StringBuilder();
+            getLog().debug( "BND Instructions:" + NL + dumpInstructions( builder.getProperties(), buf ) );
+            if ( dumpInstructions != null )
+            {
+                FileUtils.fileWrite( dumpInstructions, buf.toString() );
+            }
+        }
+
+        if ( dumpClasspath != null || getLog().isDebugEnabled() )
+        {
+            StringBuilder buf = new StringBuilder();
+            getLog().debug( "BND Classpath:" + NL + dumpClasspath( builder.getClasspath(), buf ) );
+            if ( dumpClasspath != null )
+            {
+                FileUtils.fileWrite( dumpClasspath, buf.toString() );
+            }
+        }
     }
 
+
     protected Builder buildOSGiBundle( MavenProject currentProject, Map originalInstructions, Properties properties,
         Jar[] classpath ) throws Exception
     {
@@ -445,51 +481,74 @@
     }
 
 
-    protected static void dumpInstructions( String title, Properties properties, Log log )
+    protected static StringBuilder dumpInstructions( Properties properties, StringBuilder buf )
     {
-        if ( log.isDebugEnabled() )
+        try
         {
-            log.debug( title );
-            log.debug( "------------------------------------------------------------------------" );
+            buf.append( "#-----------------------------------------------------------------------" + NL );
+            Properties stringProperties = new Properties();
             for ( Enumeration e = properties.propertyNames(); e.hasMoreElements(); )
             {
+                // we can only store String properties
                 String key = ( String ) e.nextElement();
-                log.debug( key + ": " + properties.getProperty( key ) );
+                String value = properties.getProperty( key );
+                if ( value != null )
+                {
+                    stringProperties.setProperty( key, value );
+                }
             }
-            log.debug( "------------------------------------------------------------------------" );
+            StringWriter writer = new StringWriter();
+            stringProperties.store( writer, null );
+            buf.append( writer );
+            buf.append( "#-----------------------------------------------------------------------" + NL );
         }
+        catch ( Throwable e )
+        {
+            // ignore...
+        }
+        return buf;
     }
 
 
-    protected static void dumpClasspath( String title, List classpath, Log log )
+    protected static StringBuilder dumpClasspath( List classpath, StringBuilder buf )
     {
-        if ( log.isDebugEnabled() )
+        try
         {
-            log.debug( title );
-            log.debug( "------------------------------------------------------------------------" );
+            buf.append( "#-----------------------------------------------------------------------" + NL );
+            buf.append( "-classpath:\\" + NL );
             for ( Iterator i = classpath.iterator(); i.hasNext(); )
             {
                 File path = ( ( Jar ) i.next() ).getSource();
-                log.debug( null == path ? "null" : path.toString() );
+                if ( path != null )
+                {
+                    buf.append( ' ' + path.toString() + ( i.hasNext() ? ",\\" : "" ) + NL );
+                }
             }
-            log.debug( "------------------------------------------------------------------------" );
+            buf.append( "#-----------------------------------------------------------------------" + NL );
         }
+        catch ( Throwable e )
+        {
+            // ignore...
+        }
+        return buf;
     }
 
 
-    protected static void dumpManifest( String title, Manifest manifest, Log log )
+    protected static StringBuilder dumpManifest( Manifest manifest, StringBuilder buf )
     {
-        if ( log.isDebugEnabled() )
+        try
         {
-            log.debug( title );
-            log.debug( "------------------------------------------------------------------------" );
-            for ( Iterator i = manifest.getMainAttributes().entrySet().iterator(); i.hasNext(); )
-            {
-                Map.Entry entry = ( Map.Entry ) i.next();
-                log.debug( entry.getKey() + ": " + entry.getValue() );
-            }
-            log.debug( "------------------------------------------------------------------------" );
+            buf.append( "#-----------------------------------------------------------------------" + NL );
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            manifest.write( out ); // manifest encoding is UTF8
+            buf.append( out.toString( "UTF8" ) );
+            buf.append( "#-----------------------------------------------------------------------" + NL );
         }
+        catch ( Throwable e )
+        {
+            // ignore...
+        }
+        return buf;
     }
 
 
@@ -541,7 +600,10 @@
     {
         Jar jar = builder.getJar();
 
-        dumpManifest( "BND Manifest:", jar.getManifest(), getLog() );
+        if ( getLog().isDebugEnabled() )
+        {
+            getLog().debug( "BND Manifest:" + NL + dumpManifest( jar.getManifest(), new StringBuilder() ) );
+        }
 
         boolean addMavenDescriptor = currentProject.getBasedir() != null;
 
@@ -565,8 +627,8 @@
                 mis.close();
             }
 
-            // Then apply the customized entries from the jar plugin
-            mavenManifest.read( new StringInputStream( mavenManifestText ) );
+            // Then apply customized entries from the jar plugin; note: manifest encoding is UTF8
+            mavenManifest.read( new ByteArrayInputStream( mavenManifestText.getBytes( "UTF8" ) ) );
 
             if ( !archiveConfig.isManifestSectionsEmpty() )
             {
@@ -647,7 +709,10 @@
             doMavenMetadata( currentProject, jar );
         }
 
-        dumpManifest( "Final Manifest:", builder.getJar().getManifest(), getLog() );
+        if ( getLog().isDebugEnabled() )
+        {
+            getLog().debug( "Final Manifest:" + NL + dumpManifest( jar.getManifest(), new StringBuilder() ) );
+        }
 
         builder.setJar( jar );
     }
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java
index e690d87..4d46efd 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/ManifestPlugin.java
@@ -23,10 +23,7 @@
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.util.Collection;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.jar.Manifest;
diff --git a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/PackageVersionAnalyzer.java b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/PackageVersionAnalyzer.java
index 7273e02..e6ee34b 100644
--- a/bundleplugin/src/main/java/org/apache/felix/bundleplugin/PackageVersionAnalyzer.java
+++ b/bundleplugin/src/main/java/org/apache/felix/bundleplugin/PackageVersionAnalyzer.java
@@ -19,12 +19,7 @@
 package org.apache.felix.bundleplugin;
 
 
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
-
 import aQute.lib.osgi.Builder;
-import aQute.lib.osgi.Jar;
 
 
 /**
diff --git a/bundleplugin/src/main/java/org/apache/felix/obrplugin/ObrUtils.java b/bundleplugin/src/main/java/org/apache/felix/obrplugin/ObrUtils.java
index 84b39aa..3cf2e66 100644
--- a/bundleplugin/src/main/java/org/apache/felix/obrplugin/ObrUtils.java
+++ b/bundleplugin/src/main/java/org/apache/felix/obrplugin/ObrUtils.java
@@ -21,7 +21,6 @@
 
 import java.io.File;
 import java.net.URI;
-import java.util.Collection;
 import java.util.Iterator;
 import java.util.regex.Pattern;