}
protected void mergeMavenManifest( MavenProject currentProject, Builder builder ) throws Exception
{
Jar jar = builder.getJar();
if ( getLog().isDebugEnabled() )
{
getLog().debug( "BND Manifest:" + NL + dumpManifest( jar.getManifest(), new StringBuilder() ) );
}
boolean addMavenDescriptor = currentProject.getBasedir() != null;
try
{
/*
* Grab customized manifest entries from the maven-jar-plugin configuration
*/
MavenArchiveConfiguration archiveConfig = JarPluginConfiguration.getArchiveConfiguration( currentProject );
String mavenManifestText = new MavenArchiver().getManifest( currentProject, archiveConfig ).toString();
addMavenDescriptor = addMavenDescriptor && archiveConfig.isAddMavenDescriptor();
Manifest mavenManifest = new Manifest();
// First grab the external manifest file (if specified and different to target location)
File externalManifestFile = archiveConfig.getManifestFile();
if ( null != externalManifestFile )
{
if ( !externalManifestFile.isAbsolute() )
{
externalManifestFile = new File( currentProject.getBasedir(), externalManifestFile.getPath() );
}
if ( externalManifestFile.exists() && !externalManifestFile.equals( new File( manifestLocation, "MANIFEST.MF" ) ) )
{
InputStream mis = new FileInputStream( externalManifestFile );
mavenManifest.read( mis );
mis.close();
}
}
// Then apply customized entries from the jar plugin; note: manifest encoding is UTF8
mavenManifest.read( new ByteArrayInputStream( mavenManifestText.getBytes( "UTF8" ) ) );
if ( !archiveConfig.isManifestSectionsEmpty() )
{
/*
* Add customized manifest sections (for some reason MavenArchiver doesn't do this for us)
*/
List sections = archiveConfig.getManifestSections();
for ( Iterator i = sections.iterator(); i.hasNext(); )
{
ManifestSection section = ( ManifestSection ) i.next();
Attributes attributes = new Attributes();
if ( !section.isManifestEntriesEmpty() )
{
Map entries = section.getManifestEntries();
for ( Iterator j = entries.entrySet().iterator(); j.hasNext(); )
{
Map.Entry entry = ( Map.Entry ) j.next();
attributes.putValue( ( String ) entry.getKey(), ( String ) entry.getValue() );
}
}
mavenManifest.getEntries().put( section.getName(), attributes );
}
}
Attributes mainMavenAttributes = mavenManifest.getMainAttributes();
mainMavenAttributes.putValue( "Created-By", "Apache Maven Bundle Plugin" );
String[] removeHeaders = builder.getProperty( Constants.REMOVEHEADERS, "" ).split( "," );
// apply -removeheaders to the custom manifest
for ( int i = 0; i < removeHeaders.length; i++ )
{
for ( Iterator j = mainMavenAttributes.keySet().iterator(); j.hasNext(); )
{
if ( j.next().toString().matches( removeHeaders[i].trim() ) )
{
j.remove();
}
}
}
/*
* Overlay generated bundle manifest with customized entries
*/
Manifest bundleManifest = jar.getManifest();
bundleManifest.getMainAttributes().putAll( mainMavenAttributes );
bundleManifest.getEntries().putAll( mavenManifest.getEntries() );
// adjust the import package attributes so that optional dependencies use
// optional resolution.
String importPackages = bundleManifest.getMainAttributes().getValue( "Import-Package" );
if ( importPackages != null )
{
Set optionalPackages = getOptionalPackages( currentProject );
Map<String, ? extends Map<String, String>> values = new Analyzer().parseHeader( importPackages );
for ( Map.Entry<String, ? extends Map<String, String>> entry : values.entrySet() )
{
String pkg = entry.getKey();
Map<String, String> options = entry.getValue();
if ( !options.containsKey( "resolution:" ) && optionalPackages.contains( pkg ) )
{
options.put( "resolution:", "optional" );
}
}
String result = Processor.printClauses( values );
bundleManifest.getMainAttributes().putValue( "Import-Package", result );
}
jar.setManifest( bundleManifest );
}
catch ( Exception e )
{
getLog().warn( "Unable to merge Maven manifest: " + e.getLocalizedMessage() );
}
if ( addMavenDescriptor )
{
doMavenMetadata( currentProject, jar );
}
if ( getLog().isDebugEnabled() )
{
getLog().debug( "Final Manifest:" + NL + dumpManifest( jar.getManifest(), new StringBuilder() ) );
}
builder.setJar( jar );
}