org.apache.felix.bundleplugin.BundlePlugin Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.felix.bundleplugin;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import org.apache.maven.archiver.ManifestSection;
import org.apache.maven.archiver.MavenArchiveConfiguration;
import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
import org.apache.maven.model.License;
import org.apache.maven.model.Model;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.apache.maven.shared.osgi.DefaultMaven2OsgiConverter;
import org.apache.maven.shared.osgi.Maven2OsgiConverter;
import org.apache.felix.bnd.BlueprintComponent;
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.StringUtils;
import aQute.lib.osgi.Analyzer;
import aQute.lib.osgi.Builder;
import aQute.lib.osgi.EmbeddedResource;
import aQute.lib.osgi.FileResource;
import aQute.lib.osgi.Jar;
import aQute.lib.spring.SpringXMLType;
import aQute.lib.spring.JPAComponent;
/**
* Create an OSGi bundle from Maven project
*
* @goal bundle
* @phase package
* @requiresDependencyResolution test
* @description build an OSGi bundle jar
*/
public class BundlePlugin extends AbstractMojo
{
/**
* Directory where the manifest will be written
*
* @parameter expression="${manifestLocation}" default-value="${project.build.outputDirectory}/META-INF"
*/
protected File manifestLocation;
/**
* When true, unpack the bundle contents to the outputDirectory
*
* @parameter expression="${unpackBundle}"
*/
protected boolean unpackBundle;
/**
* Comma separated list of artifactIds to exclude from the dependency classpath passed to BND (use "true" to exclude everything)
*
* @parameter expression="${excludeDependencies}"
*/
protected String excludeDependencies;
/**
* Classifier type of the bundle to be installed. For example, "jdk14".
* Defaults to none which means this is the project's main bundle.
*
* @parameter
*/
protected String classifier;
/**
* @component
*/
private MavenProjectHelper m_projectHelper;
/**
* @component
*/
private ArchiverManager m_archiverManager;
/**
* @component
*/
private ArtifactHandlerManager m_artifactHandlerManager;
/**
* Project types which this plugin supports.
*
* @parameter
*/
private List supportedProjectTypes = Arrays.asList( new String[]
{ "jar", "bundle" } );
/**
* The directory for the generated bundles.
*
* @parameter expression="${project.build.outputDirectory}"
* @required
*/
private File outputDirectory;
/**
* The directory for the pom
*
* @parameter expression="${basedir}"
* @required
*/
private File baseDir;
/**
* The directory for the generated JAR.
*
* @parameter expression="${project.build.directory}"
* @required
*/
private String buildDirectory;
/**
* The Maven project.
*
* @parameter expression="${project}"
* @required
* @readonly
*/
private MavenProject project;
/**
* The BND instructions for the bundle.
*
* @parameter
*/
private Map instructions = new LinkedHashMap();
/**
* Use locally patched version for now.
*/
private Maven2OsgiConverter m_maven2OsgiConverter = new DefaultMaven2OsgiConverter();
/**
* The archive configuration to use.
*
* @parameter
*/
private MavenArchiveConfiguration archive; // accessed indirectly in JarPluginConfiguration
private static final String MAVEN_SYMBOLICNAME = "maven-symbolicname";
private static final String MAVEN_RESOURCES = "{maven-resources}";
private static final String[] EMPTY_STRING_ARRAY =
{};
private static final String[] DEFAULT_INCLUDES =
{ "**/**" };
protected Maven2OsgiConverter getMaven2OsgiConverter()
{
return m_maven2OsgiConverter;
}
protected void setMaven2OsgiConverter( Maven2OsgiConverter maven2OsgiConverter )
{
m_maven2OsgiConverter = maven2OsgiConverter;
}
protected MavenProject getProject()
{
return project;
}
/**
* @see org.apache.maven.plugin.AbstractMojo#execute()
*/
public void execute() throws MojoExecutionException
{
Properties properties = new Properties();
String projectType = getProject().getArtifact().getType();
// ignore unsupported project types, useful when bundleplugin is configured in parent pom
if ( !supportedProjectTypes.contains( projectType ) )
{
getLog().warn(
"Ignoring project type " + projectType + " - supportedProjectTypes = " + supportedProjectTypes );
return;
}
execute( getProject(), instructions, properties );
}
protected void execute( MavenProject currentProject, Map originalInstructions, Properties properties )
throws MojoExecutionException
{
try
{
execute( currentProject, originalInstructions, properties, getClasspath( currentProject ) );
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error calculating classpath for project " + currentProject, e );
}
}
/* transform directives from their XML form to the expected BND syntax (eg. _include becomes -include) */
protected static Map transformDirectives( Map originalInstructions )
{
Map transformedInstructions = new LinkedHashMap();
for ( Iterator i = originalInstructions.entrySet().iterator(); i.hasNext(); )
{
Map.Entry e = ( Map.Entry ) i.next();
String key = ( String ) e.getKey();
if ( key.startsWith( "_" ) )
{
key = "-" + key.substring( 1 );
}
String value = ( String ) e.getValue();
if ( null == value )
{
value = "";
}
else
{
value = value.replaceAll( "[\r\n]", "" );
}
transformedInstructions.put( key, value );
}
return transformedInstructions;
}
protected void execute( MavenProject currentProject, Map originalInstructions, Properties properties,
Jar[] classpath ) throws MojoExecutionException
{
try
{
File jarFile = new File( getBuildDirectory(), getBundleName( currentProject ) );
Builder builder = buildOSGiBundle( currentProject, originalInstructions, properties, classpath );
List errors = builder.getErrors();
List warnings = builder.getWarnings();
for ( Iterator w = warnings.iterator(); w.hasNext(); )
{
String msg = ( String ) w.next();
getLog().warn( "Warning building bundle " + currentProject.getArtifact() + " : " + msg );
}
for ( Iterator e = errors.iterator(); e.hasNext(); )
{
String msg = ( String ) e.next();
getLog().error( "Error building bundle " + currentProject.getArtifact() + " : " + msg );
}
if ( errors.size() > 0 )
{
String failok = builder.getProperty( "-failok" );
if ( null == failok || "false".equalsIgnoreCase( failok ) )
{
jarFile.delete();
throw new MojoFailureException( "Error(s) found in bundle configuration" );
}
}
// attach bundle to maven project
jarFile.getParentFile().mkdirs();
builder.getJar().write( jarFile );
Artifact mainArtifact = currentProject.getArtifact();
// workaround for MNG-1682: force maven to install artifact using the "jar" handler
mainArtifact.setArtifactHandler( m_artifactHandlerManager.getArtifactHandler( "jar" ) );
if ( null == classifier || classifier.trim().length() == 0 )
{
mainArtifact.setFile( jarFile );
}
else
{
m_projectHelper.attachArtifact( currentProject, jarFile, classifier );
}
if ( unpackBundle )
{
unpackBundle( jarFile );
}
if ( manifestLocation != null )
{
File outputFile = new File( manifestLocation, "MANIFEST.MF" );
try
{
Manifest manifest = builder.getJar().getManifest();
ManifestPlugin.writeManifest( manifest, outputFile );
}
catch ( IOException e )
{
getLog().error( "Error trying to write Manifest to file " + outputFile, e );
}
}
// cleanup...
builder.close();
}
catch ( MojoFailureException e )
{
getLog().error( e.getLocalizedMessage() );
throw new MojoExecutionException( "Error(s) found in bundle configuration", e );
}
catch ( Exception e )
{
getLog().error( "An internal error occurred", e );
throw new MojoExecutionException( "Internal error in maven-bundle-plugin", e );
}
}
protected Builder buildOSGiBundle( MavenProject currentProject, Map originalInstructions, Properties properties,
Jar[] classpath ) throws Exception
{
properties.putAll( getDefaultProperties( currentProject ) );
properties.putAll( transformDirectives( originalInstructions ) );
Builder builder = new Builder();
builder.setBase( currentProject.getBasedir() );
builder.setProperties( properties );
builder.setClasspath( classpath );
// update BND instructions to add included Maven resources
includeMavenResources( currentProject, builder, getLog() );
// calculate default export/private settings based on sources
if ( builder.getProperty( Analyzer.PRIVATE_PACKAGE ) == null
|| builder.getProperty( Analyzer.EXPORT_PACKAGE ) == null )
{
addLocalPackages( currentProject.getCompileSourceRoots(), builder );
}
// update BND instructions to embed selected Maven dependencies
Collection embeddableArtifacts = getEmbeddableArtifacts( currentProject, builder );
new DependencyEmbedder( getLog(), embeddableArtifacts ).processHeaders( builder );
dumpInstructions( "BND Instructions:", builder.getProperties(), getLog() );
dumpClasspath( "BND Classpath:", builder.getClasspath(), getLog() );
builder.build();
Jar jar = builder.getJar();
dumpManifest( "BND Manifest:", jar.getManifest(), getLog() );
String[] removeHeaders = builder.getProperty( Analyzer.REMOVE_HEADERS, "" ).split( "," );
mergeMavenManifest( currentProject, jar, removeHeaders, getLog() );
builder.setJar( jar );
dumpManifest( "Final Manifest:", jar.getManifest(), getLog() );
return builder;
}
protected static void dumpInstructions( String title, Properties properties, Log log )
{
if ( log.isDebugEnabled() )
{
log.debug( title );
log.debug( "------------------------------------------------------------------------" );
for ( Enumeration e = properties.propertyNames(); e.hasMoreElements(); )
{
String key = ( String ) e.nextElement();
log.debug( key + ": " + properties.getProperty( key ) );
}
log.debug( "------------------------------------------------------------------------" );
}
}
protected static void dumpClasspath( String title, List classpath, Log log )
{
if ( log.isDebugEnabled() )
{
log.debug( title );
log.debug( "------------------------------------------------------------------------" );
for ( Iterator i = classpath.iterator(); i.hasNext(); )
{
File path = ( ( Jar ) i.next() ).getSource();
log.debug( null == path ? "null" : path.toString() );
}
log.debug( "------------------------------------------------------------------------" );
}
}
protected static void dumpManifest( String title, Manifest manifest, Log log )
{
if ( log.isDebugEnabled() )
{
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( "------------------------------------------------------------------------" );
}
}
protected static void includeMavenResources( MavenProject currentProject, Analyzer analyzer, Log log )
{
// pass maven resource paths onto BND analyzer
final String mavenResourcePaths = getMavenResourcePaths( currentProject );
final String includeResource = ( String ) analyzer.getProperty( Analyzer.INCLUDE_RESOURCE );
if ( includeResource != null )
{
if ( includeResource.indexOf( MAVEN_RESOURCES ) >= 0 )
{
// if there is no maven resource path, we do a special treatment and replace
// every occurance of MAVEN_RESOURCES and a following comma with an empty string
if ( mavenResourcePaths.length() == 0 )
{
String cleanedResource = removeTagFromInstruction( includeResource, MAVEN_RESOURCES );
if ( cleanedResource.length() > 0 )
{
analyzer.setProperty( Analyzer.INCLUDE_RESOURCE, cleanedResource );
}
else
{
analyzer.unsetProperty( Analyzer.INCLUDE_RESOURCE );
}
}
else
{
String combinedResource = StringUtils
.replace( includeResource, MAVEN_RESOURCES, mavenResourcePaths );
analyzer.setProperty( Analyzer.INCLUDE_RESOURCE, combinedResource );
}
}
else if ( mavenResourcePaths.length() > 0 )
{
log.warn( Analyzer.INCLUDE_RESOURCE + ": overriding " + mavenResourcePaths + " with " + includeResource
+ " (add " + MAVEN_RESOURCES + " if you want to include the maven resources)" );
}
}
else if ( mavenResourcePaths.length() > 0 )
{
analyzer.setProperty( Analyzer.INCLUDE_RESOURCE, mavenResourcePaths );
}
}
protected void mergeMavenManifest( MavenProject currentProject, Jar jar, String[] removeHeaders, Log log )
throws IOException
{
boolean addMavenDescriptor = true;
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 = archiveConfig.isAddMavenDescriptor();
Manifest mavenManifest = new Manifest();
// First grab the external manifest file (if specified)
File externalManifestFile = archiveConfig.getManifestFile();
if ( null != externalManifestFile && externalManifestFile.exists() )
{
InputStream mis = new FileInputStream( externalManifestFile );
mavenManifest.read( mis );
mis.close();
}
// Then apply the customized entries from the jar plugin
mavenManifest.read( new StringInputStream( mavenManifestText ) );
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" );
// 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() );
jar.setManifest( bundleManifest );
}
catch ( Exception e )
{
log.warn( "Unable to merge Maven manifest: " + e.getLocalizedMessage() );
}
if ( addMavenDescriptor )
{
doMavenMetadata( currentProject, jar );
}
}
private void unpackBundle( File jarFile )
{
File outputDir = getOutputDirectory();
if ( null == outputDir )
{
outputDir = new File( getBuildDirectory(), "classes" );
}
try
{
/*
* this directory must exist before unpacking, otherwise the plexus
* unarchiver decides to use the current working directory instead!
*/
if ( !outputDir.exists() )
{
outputDir.mkdirs();
}
UnArchiver unArchiver = m_archiverManager.getUnArchiver( "jar" );
unArchiver.setDestDirectory( outputDir );
unArchiver.setSourceFile( jarFile );
unArchiver.extract();
}
catch ( Exception e )
{
getLog().error( "Problem unpacking " + jarFile + " to " + outputDir, e );
}
}
protected static String removeTagFromInstruction( String instruction, String tag )
{
StringBuffer buf = new StringBuffer();
String[] clauses = instruction.split( "," );
for ( int i = 0; i < clauses.length; i++ )
{
String clause = clauses[i].trim();
if ( !tag.equals( clause ) )
{
if ( buf.length() > 0 )
{
buf.append( ',' );
}
buf.append( clause );
}
}
return buf.toString();
}
private static Map getProperties( Model projectModel, String prefix )
{
Map properties = new LinkedHashMap();
Method methods[] = Model.class.getDeclaredMethods();
for ( int i = 0; i < methods.length; i++ )
{
String name = methods[i].getName();
if ( name.startsWith( "get" ) )
{
try
{
Object v = methods[i].invoke( projectModel, null );
if ( v != null )
{
name = prefix + Character.toLowerCase( name.charAt( 3 ) ) + name.substring( 4 );
if ( v.getClass().isArray() )
properties.put( name, Arrays.asList( ( Object[] ) v ).toString() );
else
properties.put( name, v );
}
}
catch ( Exception e )
{
// too bad
}
}
}
return properties;
}
private static StringBuffer printLicenses( List licenses )
{
if ( licenses == null || licenses.size() == 0 )
return null;
StringBuffer sb = new StringBuffer();
String del = "";
for ( Iterator i = licenses.iterator(); i.hasNext(); )
{
License l = ( License ) i.next();
String url = l.getUrl();
if ( url == null )
continue;
sb.append( del );
sb.append( url );
del = ", ";
}
if ( sb.length() == 0 )
return null;
return sb;
}
/**
* @param jar
* @throws IOException
*/
private void doMavenMetadata( MavenProject currentProject, Jar jar ) throws IOException
{
String path = "META-INF/maven/" + currentProject.getGroupId() + "/" + currentProject.getArtifactId();
File pomFile = new File( baseDir, "pom.xml" );
jar.putResource( path + "/pom.xml", new FileResource( pomFile ) );
Properties p = new Properties();
p.put( "version", currentProject.getVersion() );
p.put( "groupId", currentProject.getGroupId() );
p.put( "artifactId", currentProject.getArtifactId() );
ByteArrayOutputStream out = new ByteArrayOutputStream();
p.store( out, "Generated by org.apache.felix.bundleplugin" );
jar
.putResource( path + "/pom.properties",
new EmbeddedResource( out.toByteArray(), System.currentTimeMillis() ) );
}
protected Jar[] getClasspath( MavenProject currentProject ) throws IOException, MojoExecutionException
{
List list = new ArrayList();
if ( getOutputDirectory() != null && getOutputDirectory().exists() )
{
list.add( new Jar( ".", getOutputDirectory() ) );
}
final Collection artifacts = getSelectedDependencies( currentProject.getArtifacts() );
for ( Iterator it = artifacts.iterator(); it.hasNext(); )
{
Artifact artifact = ( Artifact ) it.next();
if ( artifact.getArtifactHandler().isAddedToClasspath() )
{
if ( !Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
{
File file = getFile( artifact );
if ( file == null )
{
getLog().warn(
"File is not available for artifact " + artifact + " in project "
+ currentProject.getArtifact() );
continue;
}
Jar jar = new Jar( artifact.getArtifactId(), file );
list.add( jar );
}
}
}
Jar[] cp = new Jar[list.size()];
list.toArray( cp );
return cp;
}
private Collection getSelectedDependencies( Collection artifacts ) throws MojoExecutionException
{
if ( null == excludeDependencies || excludeDependencies.length() == 0 )
{
return artifacts;
}
else if ( "true".equalsIgnoreCase( excludeDependencies ) )
{
return Collections.EMPTY_LIST;
}
Collection selectedDependencies = new LinkedHashSet( artifacts );
DependencyExcluder excluder = new DependencyExcluder( artifacts );
excluder.processHeaders( excludeDependencies );
selectedDependencies.removeAll( excluder.getExcludedArtifacts() );
return selectedDependencies;
}
/**
* Get the file for an Artifact
*
* @param artifact
*/
protected File getFile( Artifact artifact )
{
return artifact.getFile();
}
private static void header( Properties properties, String key, Object value )
{
if ( value == null )
return;
if ( value instanceof Collection && ( ( Collection ) value ).isEmpty() )
return;
properties.put( key, value.toString().replaceAll( "[\r\n]", "" ) );
}
/**
* Convert a Maven version into an OSGi compliant version
*
* @param version Maven version
* @return the OSGi version
*/
protected String convertVersionToOsgi( String version )
{
return getMaven2OsgiConverter().getVersion( version );
}
/**
* TODO this should return getMaven2Osgi().getBundleFileName( project.getArtifact() )
*/
protected String getBundleName( MavenProject currentProject )
{
String finalName = currentProject.getBuild().getFinalName();
if ( null != classifier && classifier.trim().length() > 0 )
{
return finalName + '-' + classifier + ".jar";
}
return finalName + ".jar";
}
protected String getBuildDirectory()
{
return buildDirectory;
}
protected void setBuildDirectory( String _buildirectory )
{
buildDirectory = _buildirectory;
}
protected Properties getDefaultProperties( MavenProject currentProject )
{
Properties properties = new Properties();
String bsn;
try
{
bsn = getMaven2OsgiConverter().getBundleSymbolicName( currentProject.getArtifact() );
}
catch ( Exception e )
{
bsn = currentProject.getGroupId() + "." + currentProject.getArtifactId();
}
// Setup defaults
properties.put( MAVEN_SYMBOLICNAME, bsn );
properties.put( Analyzer.BUNDLE_SYMBOLICNAME, bsn );
properties.put( Analyzer.IMPORT_PACKAGE, "*" );
properties.put( Analyzer.BUNDLE_VERSION, currentProject.getVersion() );
// remove the extraneous Include-Resource and Private-Package entries from generated manifest
properties.put( Analyzer.REMOVE_HEADERS, Analyzer.INCLUDE_RESOURCE + ',' + Analyzer.PRIVATE_PACKAGE );
header( properties, Analyzer.BUNDLE_DESCRIPTION, currentProject.getDescription() );
StringBuffer licenseText = printLicenses( currentProject.getLicenses() );
if ( licenseText != null )
{
header( properties, Analyzer.BUNDLE_LICENSE, licenseText );
}
header( properties, Analyzer.BUNDLE_NAME, currentProject.getName() );
if ( currentProject.getOrganization() != null )
{
String organizationName = currentProject.getOrganization().getName();
header( properties, Analyzer.BUNDLE_VENDOR, organizationName );
properties.put( "project.organization.name", organizationName );
properties.put( "pom.organization.name", organizationName );
if ( currentProject.getOrganization().getUrl() != null )
{
String organizationUrl = currentProject.getOrganization().getUrl();
header( properties, Analyzer.BUNDLE_DOCURL, organizationUrl );
properties.put( "project.organization.url", organizationUrl );
properties.put( "pom.organization.url", organizationUrl );
}
}
properties.putAll( currentProject.getProperties() );
properties.putAll( currentProject.getModel().getProperties() );
properties.putAll( getProperties( currentProject.getModel(), "project.build." ) );
properties.putAll( getProperties( currentProject.getModel(), "pom." ) );
properties.putAll( getProperties( currentProject.getModel(), "project." ) );
properties.put( "project.baseDir", baseDir );
properties.put( "project.build.directory", getBuildDirectory() );
properties.put( "project.build.outputdirectory", getOutputDirectory() );
properties.put( "classifier", classifier == null ? "" : classifier );
// Add default plugins
header( properties, Analyzer.PLUGIN,
BlueprintComponent.class.getName() + "," + SpringXMLType.class.getName());
return properties;
}
protected void setBasedir( File _basedir )
{
baseDir = _basedir;
}
protected File getOutputDirectory()
{
return outputDirectory;
}
protected void setOutputDirectory( File _outputDirectory )
{
outputDirectory = _outputDirectory;
}
private static void addLocalPackages( List sourceDirectories, Analyzer analyzer )
{
Collection packages = new LinkedHashSet();
for ( Iterator d = sourceDirectories.iterator(); d.hasNext(); )
{
String sourceDirectory = (String) d.next();
if ( sourceDirectory != null && new File( sourceDirectory ).isDirectory() )
{
// scan local Java sources for potential packages
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( sourceDirectory );
scanner.setIncludes( new String[]
{ "**/*.java" } );
scanner.addDefaultExcludes();
scanner.scan();
String[] paths = scanner.getIncludedFiles();
for ( int i = 0; i < paths.length; i++ )
{
packages.add( getPackageName( paths[i] ) );
}
}
}
StringBuffer exportedPkgs = new StringBuffer();
StringBuffer privatePkgs = new StringBuffer();
for ( Iterator i = packages.iterator(); i.hasNext(); )
{
String pkg = ( String ) i.next();
// mark all source packages as private by default (can be overridden by export list)
privatePkgs.append( pkg ).append( ";-split-package:=merge-first," );
// we can't export the default package (".") and we shouldn't export internal packages
if ( !( ".".equals( pkg ) || pkg.contains( ".internal" ) || pkg.contains( ".impl" ) ) )
{
exportedPkgs.append( pkg ).append( ',' );
}
}
if ( analyzer.getProperty( Analyzer.EXPORT_PACKAGE ) == null )
{
if ( analyzer.getProperty( Analyzer.EXPORT_CONTENTS ) == null )
{
// no -exportcontents overriding the exports, so use our computed list
analyzer.setProperty( Analyzer.EXPORT_PACKAGE, exportedPkgs.toString() );
}
else
{
// leave Export-Package empty (but non-null) as we have -exportcontents
analyzer.setProperty( Analyzer.EXPORT_PACKAGE, "" );
}
}
if ( analyzer.getProperty( Analyzer.PRIVATE_PACKAGE ) == null )
{
// if there are really no private packages then use "!*" as this will keep the Bnd Tool happy
analyzer.setProperty( Analyzer.PRIVATE_PACKAGE, privatePkgs.length() == 0 ? "!*" : privatePkgs.toString() );
}
}
private static String getPackageName( String filename )
{
int n = filename.lastIndexOf( File.separatorChar );
return n < 0 ? "." : filename.substring( 0, n ).replace( File.separatorChar, '.' );
}
private static String getMavenResourcePaths( MavenProject project )
{
final String basePath = project.getBasedir().getAbsolutePath();
Set pathSet = new LinkedHashSet();
for ( Iterator i = project.getResources().iterator(); i.hasNext(); )
{
org.apache.maven.model.Resource resource = ( org.apache.maven.model.Resource ) i.next();
final String sourcePath = resource.getDirectory();
final String targetPath = resource.getTargetPath();
// ignore empty or non-local resources
if ( new File( sourcePath ).exists() && ( ( targetPath == null ) || ( targetPath.indexOf( ".." ) < 0 ) ) )
{
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( resource.getDirectory() );
if ( resource.getIncludes() != null && !resource.getIncludes().isEmpty() )
{
scanner.setIncludes( ( String[] ) resource.getIncludes().toArray( EMPTY_STRING_ARRAY ) );
}
else
{
scanner.setIncludes( DEFAULT_INCLUDES );
}
if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
{
scanner.setExcludes( ( String[] ) resource.getExcludes().toArray( EMPTY_STRING_ARRAY ) );
}
scanner.addDefaultExcludes();
scanner.scan();
List includedFiles = Arrays.asList( scanner.getIncludedFiles() );
for ( Iterator j = includedFiles.iterator(); j.hasNext(); )
{
String name = ( String ) j.next();
String path = sourcePath + '/' + name;
// make relative to project
if ( path.startsWith( basePath ) )
{
if ( path.length() == basePath.length() )
{
path = ".";
}
else
{
path = path.substring( basePath.length() + 1 );
}
}
// replace windows backslash with a slash
// this is a workaround for a problem with bnd 0.0.189
if ( File.separatorChar != '/' )
{
name = name.replace( File.separatorChar, '/' );
path = path.replace( File.separatorChar, '/' );
}
// copy to correct place
path = name + '=' + path;
if ( targetPath != null )
{
path = targetPath + '/' + path;
}
// use Bnd filtering?
if ( resource.isFiltering() )
{
path = '{' + path + '}';
}
pathSet.add( path );
}
}
}
StringBuffer resourcePaths = new StringBuffer();
for ( Iterator i = pathSet.iterator() ; i.hasNext(); )
{
resourcePaths.append( i.next() );
if ( i.hasNext() )
{
resourcePaths.append( ',' );
}
}
return resourcePaths.toString();
}
protected Collection getEmbeddableArtifacts( MavenProject project, Analyzer analyzer )
throws MojoExecutionException
{
final Collection artifacts;
String embedTransitive = analyzer.getProperty( DependencyEmbedder.EMBED_TRANSITIVE );
if ( Boolean.valueOf( embedTransitive ).booleanValue() )
{
// includes transitive dependencies
artifacts = project.getArtifacts();
}
else
{
// only includes direct dependencies
artifacts = project.getDependencyArtifacts();
}
return getSelectedDependencies( artifacts );
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy