blob: a3c4d92244aaea89b167cd44fbc24d61679ca996 [file] [log] [blame]
Richard S. Hallf3120092006-10-31 17:32:16 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Richard S. Hall01a56ce2007-05-20 22:31:11 +000019package org.apache.felix.bundleplugin;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000020
Stuart McCulloch5ae59142008-01-29 06:21:05 +000021
Stuart McCulloch340a8dd2011-06-28 22:47:10 +000022import java.io.ByteArrayInputStream;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000023import java.io.ByteArrayOutputStream;
24import java.io.File;
Stuart McCulloch3d34d502008-01-09 15:19:32 +000025import java.io.FileInputStream;
Guillaume Nodet457f4302014-06-14 10:39:55 +000026import java.io.FileOutputStream;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000027import java.io.IOException;
Stuart McCulloch3d34d502008-01-09 15:19:32 +000028import java.io.InputStream;
Stuart McCulloch9e631952011-11-09 00:45:12 +000029import java.lang.reflect.Array;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000030import java.lang.reflect.Method;
Stuart McCulloche71aa492011-06-24 18:21:16 +000031import java.util.ArrayList;
32import java.util.Arrays;
33import java.util.Collection;
34import java.util.Collections;
35import java.util.Enumeration;
36import java.util.HashSet;
37import java.util.Iterator;
38import java.util.LinkedHashMap;
39import java.util.LinkedHashSet;
40import java.util.List;
41import java.util.Map;
42import java.util.Properties;
43import java.util.Set;
Stuart McCulloch3d34d502008-01-09 15:19:32 +000044import java.util.jar.Attributes;
Stuart McCulloch717740b2007-09-21 11:18:31 +000045import java.util.jar.Manifest;
Richard S. Hall420d2782007-06-14 12:31:48 +000046
Stuart McCulloch3d34d502008-01-09 15:19:32 +000047import org.apache.maven.archiver.ManifestSection;
Stuart McCullochf978c532007-12-27 09:16:34 +000048import org.apache.maven.archiver.MavenArchiveConfiguration;
49import org.apache.maven.archiver.MavenArchiver;
Richard S. Hallf3120092006-10-31 17:32:16 +000050import org.apache.maven.artifact.Artifact;
Stuart McCullochffadcf62007-08-24 10:39:35 +000051import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
Stuart McCullochcdad75f2011-06-28 00:03:15 +000052import org.apache.maven.execution.MavenSession;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000053import org.apache.maven.model.License;
54import org.apache.maven.model.Model;
Stuart McCulloche71aa492011-06-24 18:21:16 +000055import org.apache.maven.model.Resource;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000056import org.apache.maven.plugin.AbstractMojo;
57import org.apache.maven.plugin.MojoExecutionException;
58import org.apache.maven.plugin.MojoFailureException;
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +000059import org.apache.maven.plugin.logging.Log;
Richard S. Hallf3120092006-10-31 17:32:16 +000060import org.apache.maven.project.MavenProject;
Stuart McCulloch2d301732008-02-18 09:01:17 +000061import org.apache.maven.project.MavenProjectHelper;
Stuart McCulloch99f4aa62009-02-17 13:40:44 +000062import org.apache.maven.shared.osgi.DefaultMaven2OsgiConverter;
Richard S. Hall17b8e3d2007-06-13 16:20:40 +000063import org.apache.maven.shared.osgi.Maven2OsgiConverter;
Stuart McCullochdd0d9ba2007-12-07 08:22:20 +000064import org.codehaus.plexus.archiver.UnArchiver;
65import org.codehaus.plexus.archiver.manager.ArchiverManager;
Stuart McCulloch44deaef2007-11-18 04:36:21 +000066import org.codehaus.plexus.util.DirectoryScanner;
Stuart McCulloch340a8dd2011-06-28 22:47:10 +000067import org.codehaus.plexus.util.FileUtils;
Stuart McCulloch437f4872013-06-07 21:24:26 +000068import org.codehaus.plexus.util.PropertyUtils;
Stuart McCulloch6cb86db2008-03-15 21:38:26 +000069import org.codehaus.plexus.util.StringUtils;
Richard S. Hall420d2782007-06-14 12:31:48 +000070
Stuart McCulloch1648f402013-06-07 22:21:11 +000071import aQute.bnd.header.Attrs;
Stuart McCulloch42151ee2012-07-16 13:43:38 +000072import aQute.bnd.osgi.Analyzer;
73import aQute.bnd.osgi.Builder;
74import aQute.bnd.osgi.Constants;
Stuart McCulloch1648f402013-06-07 22:21:11 +000075import aQute.bnd.osgi.Descriptors.PackageRef;
Stuart McCulloch42151ee2012-07-16 13:43:38 +000076import aQute.bnd.osgi.EmbeddedResource;
77import aQute.bnd.osgi.FileResource;
78import aQute.bnd.osgi.Jar;
Stuart McCulloch1648f402013-06-07 22:21:11 +000079import aQute.bnd.osgi.Packages;
Stuart McCulloch42151ee2012-07-16 13:43:38 +000080import aQute.bnd.osgi.Processor;
Guillaume Nodet459eaed2009-09-02 21:15:28 +000081import aQute.lib.spring.SpringXMLType;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000082
Stuart McCulloch5ae59142008-01-29 06:21:05 +000083
Richard S. Hallf3120092006-10-31 17:32:16 +000084/**
Richard S. Hall420d2782007-06-14 12:31:48 +000085 * Create an OSGi bundle from Maven project
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000086 *
Richard S. Hallf3120092006-10-31 17:32:16 +000087 * @goal bundle
88 * @phase package
Stuart McCullochf7d0c7c2009-01-29 07:23:06 +000089 * @requiresDependencyResolution test
Richard S. Hallf3120092006-10-31 17:32:16 +000090 * @description build an OSGi bundle jar
Stuart McCulloch23ebd782011-06-27 22:02:27 +000091 * @threadSafe
Richard S. Hallf3120092006-10-31 17:32:16 +000092 */
Stuart McCulloch5ae59142008-01-29 06:21:05 +000093public class BundlePlugin extends AbstractMojo
94{
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +000095 /**
Stuart McCulloch717740b2007-09-21 11:18:31 +000096 * Directory where the manifest will be written
Carsten Ziegelerb39d23d2007-09-24 12:22:32 +000097 *
Stuart McCulloch717740b2007-09-21 11:18:31 +000098 * @parameter expression="${manifestLocation}" default-value="${project.build.outputDirectory}/META-INF"
99 */
Stuart McCulloch0ab63892007-10-19 11:43:24 +0000100 protected File manifestLocation;
Stuart McCulloch717740b2007-09-21 11:18:31 +0000101
102 /**
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000103 * File where the BND instructions will be dumped
104 *
105 * @parameter expression="${dumpInstructions}"
106 */
107 protected File dumpInstructions;
108
109 /**
110 * File where the BND class-path will be dumped
111 *
112 * @parameter expression="${dumpClasspath}"
113 */
114 protected File dumpClasspath;
115
116 /**
Stuart McCullochdd0d9ba2007-12-07 08:22:20 +0000117 * When true, unpack the bundle contents to the outputDirectory
118 *
119 * @parameter expression="${unpackBundle}"
120 */
121 protected boolean unpackBundle;
122
123 /**
Stuart McCulloch5ffc3fe2008-02-20 05:37:57 +0000124 * Comma separated list of artifactIds to exclude from the dependency classpath passed to BND (use "true" to exclude everything)
Stuart McCullochcb02d6a2008-01-09 16:42:16 +0000125 *
126 * @parameter expression="${excludeDependencies}"
127 */
Stuart McCulloch5ffc3fe2008-02-20 05:37:57 +0000128 protected String excludeDependencies;
Stuart McCullochcb02d6a2008-01-09 16:42:16 +0000129
130 /**
Stuart McCulloch0614c702013-06-07 20:00:40 +0000131 * Final name of the bundle (without classifier or extension)
132 *
133 * @parameter expression="${project.build.finalName}"
134 */
135 private String finalName;
136
137 /**
Stuart McCulloch2d301732008-02-18 09:01:17 +0000138 * Classifier type of the bundle to be installed. For example, "jdk14".
139 * Defaults to none which means this is the project's main bundle.
140 *
Stuart McCulloch96f089c2009-09-02 16:42:51 +0000141 * @parameter
Stuart McCulloch2d301732008-02-18 09:01:17 +0000142 */
143 protected String classifier;
144
145 /**
Stuart McCulloch01c93bd2013-06-07 18:23:07 +0000146 * Packaging type of the bundle to be installed. For example, "jar".
147 * Defaults to none which means use the same packaging as the project.
148 *
149 * @parameter
150 */
151 protected String packaging;
152
153 /**
Stuart McCulloch2d301732008-02-18 09:01:17 +0000154 * @component
155 */
156 private MavenProjectHelper m_projectHelper;
157
158 /**
Stuart McCullochdd0d9ba2007-12-07 08:22:20 +0000159 * @component
160 */
Stuart McCulloch9366a822008-01-29 07:45:57 +0000161 private ArchiverManager m_archiverManager;
Stuart McCullochdd0d9ba2007-12-07 08:22:20 +0000162
163 /**
Stuart McCullochffadcf62007-08-24 10:39:35 +0000164 * @component
165 */
Stuart McCulloch9366a822008-01-29 07:45:57 +0000166 private ArtifactHandlerManager m_artifactHandlerManager;
Stuart McCullochffadcf62007-08-24 10:39:35 +0000167
168 /**
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000169 * Project types which this plugin supports.
170 *
171 * @parameter
172 */
Hiram R. Chirino12264ad2011-02-01 20:54:49 +0000173 protected List supportedProjectTypes = Arrays.asList( new String[]
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000174 { "jar", "bundle" } );
Richard S. Hall3c0051d2007-04-27 17:07:17 +0000175
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000176 /**
177 * The directory for the generated bundles.
178 *
179 * @parameter expression="${project.build.outputDirectory}"
180 * @required
181 */
182 private File outputDirectory;
Richard S. Hall17b8e3d2007-06-13 16:20:40 +0000183
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000184 /**
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000185 * The directory for the generated JAR.
186 *
187 * @parameter expression="${project.build.directory}"
188 * @required
189 */
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000190 private String buildDirectory;
Richard S. Hall17b8e3d2007-06-13 16:20:40 +0000191
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000192 /**
193 * The Maven project.
194 *
195 * @parameter expression="${project}"
196 * @required
197 * @readonly
198 */
199 private MavenProject project;
Richard S. Hall420d2782007-06-14 12:31:48 +0000200
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000201 /**
Stuart McCulloch2d301732008-02-18 09:01:17 +0000202 * The BND instructions for the bundle.
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000203 *
204 * @parameter
205 */
Stuart McCullochd00f9712009-07-13 10:06:47 +0000206 private Map instructions = new LinkedHashMap();
Richard S. Hall6cf6f0b2007-04-10 16:50:31 +0000207
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000208 /**
Stuart McCulloch99f4aa62009-02-17 13:40:44 +0000209 * Use locally patched version for now.
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000210 */
Stuart McCulloch99f4aa62009-02-17 13:40:44 +0000211 private Maven2OsgiConverter m_maven2OsgiConverter = new DefaultMaven2OsgiConverter();
Richard S. Hall6cf6f0b2007-04-10 16:50:31 +0000212
Stuart McCulloch378e76c2009-01-30 09:51:35 +0000213 /**
214 * The archive configuration to use.
215 *
216 * @parameter
217 */
218 private MavenArchiveConfiguration archive; // accessed indirectly in JarPluginConfiguration
219
Stuart McCullochcdad75f2011-06-28 00:03:15 +0000220 /**
221 * @parameter default-value="${session}"
222 * @required
223 * @readonly
224 */
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000225 private MavenSession m_mavenSession;
Stuart McCullochcdad75f2011-06-28 00:03:15 +0000226
Guillaume Nodet457f4302014-06-14 10:39:55 +0000227 /**
228 * @parameter
229 */
230 private boolean niceManifest = false;
231
Stuart McCulloch6d4c8372009-02-16 06:49:21 +0000232 private static final String MAVEN_SYMBOLICNAME = "maven-symbolicname";
Stuart McCulloch9c406b12007-08-23 09:41:08 +0000233 private static final String MAVEN_RESOURCES = "{maven-resources}";
Guillaume Nodete5f5c7a2010-11-17 08:09:42 +0000234 private static final String LOCAL_PACKAGES = "{local-packages}";
Stuart McCullochfe58ad52011-11-28 15:05:51 +0000235 private static final String MAVEN_SOURCES = "{maven-sources}";
Stuart McCulloch6cb86db2008-03-15 21:38:26 +0000236
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000237 private static final String[] EMPTY_STRING_ARRAY =
238 {};
239 private static final String[] DEFAULT_INCLUDES =
240 { "**/**" };
Stuart McCulloch9c406b12007-08-23 09:41:08 +0000241
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000242 private static final String NL = System.getProperty( "line.separator" );
243
Stuart McCulloch9c406b12007-08-23 09:41:08 +0000244
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000245 protected Maven2OsgiConverter getMaven2OsgiConverter()
246 {
Stuart McCulloch9366a822008-01-29 07:45:57 +0000247 return m_maven2OsgiConverter;
Richard S. Hall5b521ff2007-04-11 14:25:20 +0000248 }
Richard S. Hallbec8dc42007-05-18 14:33:55 +0000249
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000250
Stuart McCulloch9366a822008-01-29 07:45:57 +0000251 protected void setMaven2OsgiConverter( Maven2OsgiConverter maven2OsgiConverter )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000252 {
Stuart McCulloch9366a822008-01-29 07:45:57 +0000253 m_maven2OsgiConverter = maven2OsgiConverter;
Richard S. Hallbec8dc42007-05-18 14:33:55 +0000254 }
255
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000256
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000257 protected MavenProject getProject()
258 {
Stuart McCulloch9366a822008-01-29 07:45:57 +0000259 return project;
Richard S. Hallf3120092006-10-31 17:32:16 +0000260 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000261
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000262
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000263 /**
264 * @see org.apache.maven.plugin.AbstractMojo#execute()
265 */
266 public void execute() throws MojoExecutionException
267 {
268 Properties properties = new Properties();
Stuart McCulloch3a965b92008-03-24 02:34:11 +0000269 String projectType = getProject().getArtifact().getType();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000270
Stuart McCulloch3a965b92008-03-24 02:34:11 +0000271 // ignore unsupported project types, useful when bundleplugin is configured in parent pom
272 if ( !supportedProjectTypes.contains( projectType ) )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000273 {
Stuart McCulloch464dbac2008-08-03 09:47:04 +0000274 getLog().warn(
275 "Ignoring project type " + projectType + " - supportedProjectTypes = " + supportedProjectTypes );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000276 return;
277 }
278
Stuart McCulloch9366a822008-01-29 07:45:57 +0000279 execute( getProject(), instructions, properties );
Richard S. Hallf3120092006-10-31 17:32:16 +0000280 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000281
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000282
Stuart McCulloch83e0da02008-01-29 08:25:27 +0000283 protected void execute( MavenProject currentProject, Map originalInstructions, Properties properties )
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000284 throws MojoExecutionException
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000285 {
286 try
287 {
Stuart McCulloch83e0da02008-01-29 08:25:27 +0000288 execute( currentProject, originalInstructions, properties, getClasspath( currentProject ) );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000289 }
290 catch ( IOException e )
291 {
Stuart McCulloch9366a822008-01-29 07:45:57 +0000292 throw new MojoExecutionException( "Error calculating classpath for project " + currentProject, e );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000293 }
Richard S. Hallf3120092006-10-31 17:32:16 +0000294 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000295
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000296
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000297 /* transform directives from their XML form to the expected BND syntax (eg. _include becomes -include) */
Stuart McCulloch9366a822008-01-29 07:45:57 +0000298 protected static Map transformDirectives( Map originalInstructions )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000299 {
Stuart McCullochd00f9712009-07-13 10:06:47 +0000300 Map transformedInstructions = new LinkedHashMap();
Stuart McCulloch9366a822008-01-29 07:45:57 +0000301 for ( Iterator i = originalInstructions.entrySet().iterator(); i.hasNext(); )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000302 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000303 Map.Entry e = ( Map.Entry ) i.next();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000304
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000305 String key = ( String ) e.getKey();
306 if ( key.startsWith( "_" ) )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000307 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000308 key = "-" + key.substring( 1 );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000309 }
310
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000311 String value = ( String ) e.getValue();
312 if ( null == value )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000313 {
314 value = "";
315 }
Richard S. Hall6be327f2007-08-13 16:47:27 +0000316 else
317 {
Guillaume Nodet4eb49be2010-02-19 23:10:08 +0000318 value = value.replaceAll( "\\p{Blank}*[\r\n]\\p{Blank}*", "" );
Richard S. Hall6be327f2007-08-13 16:47:27 +0000319 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000320
Stuart McCulloch85927eb2011-06-24 20:55:37 +0000321 if ( Analyzer.WAB.equals( key ) && value.length() == 0 )
322 {
323 // provide useful default
324 value = "src/main/webapp/";
325 }
326
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000327 transformedInstructions.put( key, value );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000328 }
329 return transformedInstructions;
Richard S. Hall6cf6f0b2007-04-10 16:50:31 +0000330 }
Richard S. Hall6cf6f0b2007-04-10 16:50:31 +0000331
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000332
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000333 protected boolean reportErrors( String prefix, Analyzer analyzer )
Stuart McCulloch1228d3f2011-06-28 16:14:52 +0000334 {
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000335 List errors = analyzer.getErrors();
336 List warnings = analyzer.getWarnings();
Stuart McCulloch1228d3f2011-06-28 16:14:52 +0000337
338 for ( Iterator w = warnings.iterator(); w.hasNext(); )
339 {
340 String msg = ( String ) w.next();
341 getLog().warn( prefix + " : " + msg );
342 }
343
344 boolean hasErrors = false;
345 String fileNotFound = "Input file does not exist: ";
346 for ( Iterator e = errors.iterator(); e.hasNext(); )
347 {
348 String msg = ( String ) e.next();
349 if ( msg.startsWith( fileNotFound ) && msg.endsWith( "~" ) )
350 {
351 // treat as warning; this error happens when you have duplicate entries in Include-Resource
352 String duplicate = Processor.removeDuplicateMarker( msg.substring( fileNotFound.length() ) );
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000353 getLog().warn( prefix + " : Duplicate path '" + duplicate + "' in Include-Resource" );
Stuart McCulloch1228d3f2011-06-28 16:14:52 +0000354 }
355 else
356 {
357 getLog().error( prefix + " : " + msg );
358 hasErrors = true;
359 }
360 }
361 return hasErrors;
362 }
363
364
Stuart McCulloch83e0da02008-01-29 08:25:27 +0000365 protected void execute( MavenProject currentProject, Map originalInstructions, Properties properties,
366 Jar[] classpath ) throws MojoExecutionException
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000367 {
368 try
369 {
Stuart McCulloch9366a822008-01-29 07:45:57 +0000370 File jarFile = new File( getBuildDirectory(), getBundleName( currentProject ) );
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000371 Builder builder = buildOSGiBundle( currentProject, originalInstructions, properties, classpath );
Stuart McCulloch1228d3f2011-06-28 16:14:52 +0000372 boolean hasErrors = reportErrors( "Bundle " + currentProject.getArtifact(), builder );
Stuart McCulloch737abc72011-06-25 19:53:50 +0000373 if ( hasErrors )
Stuart McCulloch6d3e62a2007-09-21 15:07:36 +0000374 {
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000375 String failok = builder.getProperty( "-failok" );
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000376 if ( null == failok || "false".equalsIgnoreCase( failok ) )
Stuart McCulloch6d3e62a2007-09-21 15:07:36 +0000377 {
378 jarFile.delete();
379
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000380 throw new MojoFailureException( "Error(s) found in bundle configuration" );
Stuart McCulloch6d3e62a2007-09-21 15:07:36 +0000381 }
382 }
383
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000384 // attach bundle to maven project
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000385 jarFile.getParentFile().mkdirs();
386 builder.getJar().write( jarFile );
Stuart McCulloch2d301732008-02-18 09:01:17 +0000387
388 Artifact mainArtifact = currentProject.getArtifact();
389
Stuart McCulloche68ebd22011-06-24 21:50:07 +0000390 if ( "bundle".equals( mainArtifact.getType() ) )
391 {
392 // workaround for MNG-1682: force maven to install artifact using the "jar" handler
393 mainArtifact.setArtifactHandler( m_artifactHandlerManager.getArtifactHandler( "jar" ) );
394 }
Stuart McCulloch2d301732008-02-18 09:01:17 +0000395
Stuart McCulloch01c93bd2013-06-07 18:23:07 +0000396 boolean customClassifier = null != classifier && classifier.trim().length() > 0;
397 boolean customPackaging = null != packaging && packaging.trim().length() > 0;
398
399 if ( customClassifier && customPackaging )
Stuart McCulloch2d301732008-02-18 09:01:17 +0000400 {
Stuart McCulloch01c93bd2013-06-07 18:23:07 +0000401 m_projectHelper.attachArtifact( currentProject, packaging, classifier, jarFile );
402 }
403 else if ( customClassifier )
404 {
405 m_projectHelper.attachArtifact( currentProject, jarFile, classifier );
406 }
407 else if ( customPackaging )
408 {
409 m_projectHelper.attachArtifact( currentProject, packaging, jarFile );
Stuart McCulloch2d301732008-02-18 09:01:17 +0000410 }
411 else
412 {
Stuart McCulloch01c93bd2013-06-07 18:23:07 +0000413 mainArtifact.setFile( jarFile );
Stuart McCulloch2d301732008-02-18 09:01:17 +0000414 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000415
416 if ( unpackBundle )
Stuart McCullochdd0d9ba2007-12-07 08:22:20 +0000417 {
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000418 unpackBundle( jarFile );
Stuart McCullochdd0d9ba2007-12-07 08:22:20 +0000419 }
420
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000421 if ( manifestLocation != null )
Stuart McCulloch6d3e62a2007-09-21 15:07:36 +0000422 {
423 File outputFile = new File( manifestLocation, "MANIFEST.MF" );
424
425 try
426 {
427 Manifest manifest = builder.getJar().getManifest();
Guillaume Nodet457f4302014-06-14 10:39:55 +0000428 FileOutputStream fos = new FileOutputStream( outputFile );
429 try
430 {
431 ManifestWriter.outputManifest( manifest, fos, niceManifest );
432 }
433 finally
434 {
435 fos.close();
436 }
Stuart McCulloch6d3e62a2007-09-21 15:07:36 +0000437 }
438 catch ( IOException e )
439 {
440 getLog().error( "Error trying to write Manifest to file " + outputFile, e );
441 }
442 }
Stuart McCullochd8a04c52008-08-06 16:05:23 +0000443
444 // cleanup...
445 builder.close();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000446 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000447 catch ( MojoFailureException e )
Stuart McCulloch6787ce42007-10-26 08:07:14 +0000448 {
449 getLog().error( e.getLocalizedMessage() );
450 throw new MojoExecutionException( "Error(s) found in bundle configuration", e );
451 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000452 catch ( Exception e )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000453 {
Stuart McCulloch6787ce42007-10-26 08:07:14 +0000454 getLog().error( "An internal error occurred", e );
455 throw new MojoExecutionException( "Internal error in maven-bundle-plugin", e );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +0000456 }
457 }
Richard S. Hall6cf6f0b2007-04-10 16:50:31 +0000458
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000459
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000460 protected Builder getOSGiBuilder( MavenProject currentProject, Map originalInstructions, Properties properties,
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000461 Jar[] classpath ) throws Exception
462 {
463 properties.putAll( getDefaultProperties( currentProject ) );
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000464 properties.putAll( transformDirectives( originalInstructions ) );
Guillaume Nodet7bf509f2014-05-19 07:12:48 +0000465 if (properties.getProperty("Bundle-Activator") != null
466 && properties.getProperty("Bundle-Activator").isEmpty())
467 {
468 properties.remove("Bundle-Activator");
469 }
Guillaume Nodet5ddb13c2014-05-20 09:09:12 +0000470 if (properties.containsKey("-disable-plugin"))
471 {
472 String[] disabled = properties.remove("-disable-plugin").toString().replaceAll(" ", "").split(",");
473 String[] enabled = properties.getProperty(Analyzer.PLUGIN, "").replaceAll(" ", "").split(",");
474 Set<String> plugin = new LinkedHashSet<String>();
475 plugin.addAll(Arrays.asList(enabled));
476 plugin.removeAll(Arrays.asList(disabled));
477 StringBuilder sb = new StringBuilder();
478 for (String s : plugin)
479 {
480 if (sb.length() > 0)
481 {
482 sb.append(",");
483 }
484 sb.append(sb);
485 }
486 properties.setProperty(Analyzer.PLUGIN, sb.toString());
487 }
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000488
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000489 Builder builder = new Builder();
Stuart McCulloche1e06932013-06-07 17:32:51 +0000490 synchronized ( BundlePlugin.class ) // protect setBase...getBndLastModified which uses static DateFormat
491 {
492 builder.setBase( getBase( currentProject ) );
493 }
Stuart McCulloch9e631952011-11-09 00:45:12 +0000494 builder.setProperties( sanitize( properties ) );
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000495 if ( classpath != null )
496 {
497 builder.setClasspath( classpath );
498 }
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000499
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000500 return builder;
501 }
502
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000503
Stuart McCulloch9e631952011-11-09 00:45:12 +0000504 protected static Properties sanitize( Properties properties )
505 {
506 // convert any non-String keys/values to Strings
507 Properties sanitizedEntries = new Properties();
508 for ( Iterator itr = properties.entrySet().iterator(); itr.hasNext(); )
509 {
510 Map.Entry entry = ( Map.Entry ) itr.next();
511 if ( entry.getKey() instanceof String == false )
512 {
513 String key = sanitize( entry.getKey() );
514 if ( !properties.containsKey( key ) )
515 {
516 sanitizedEntries.setProperty( key, sanitize( entry.getValue() ) );
517 }
518 itr.remove();
519 }
520 else if ( entry.getValue() instanceof String == false )
521 {
522 entry.setValue( sanitize( entry.getValue() ) );
523 }
524 }
525 properties.putAll( sanitizedEntries );
526 return properties;
527 }
528
529
530 protected static String sanitize( Object value )
531 {
532 if ( value instanceof String )
533 {
534 return ( String ) value;
535 }
536 else if ( value instanceof Iterable )
537 {
538 String delim = "";
539 StringBuilder buf = new StringBuilder();
540 for ( Object i : ( Iterable<?> ) value )
541 {
542 buf.append( delim ).append( i );
543 delim = ", ";
544 }
545 return buf.toString();
546 }
547 else if ( value.getClass().isArray() )
548 {
549 String delim = "";
550 StringBuilder buf = new StringBuilder();
551 for ( int i = 0, len = Array.getLength( value ); i < len; i++ )
552 {
553 buf.append( delim ).append( Array.get( value, i ) );
554 delim = ", ";
555 }
556 return buf.toString();
557 }
558 else
559 {
560 return String.valueOf( value );
561 }
562 }
563
564
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000565 protected void addMavenInstructions( MavenProject currentProject, Builder builder ) throws Exception
566 {
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000567 if ( currentProject.getBasedir() != null )
568 {
569 // update BND instructions to add included Maven resources
570 includeMavenResources( currentProject, builder, getLog() );
Stuart McCullocha8cfd1b2008-04-01 06:54:26 +0000571
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000572 // calculate default export/private settings based on sources
573 addLocalPackages( outputDirectory, builder );
Stuart McCullochfe58ad52011-11-28 15:05:51 +0000574
575 // tell BND where the current project source resides
576 addMavenSourcePath( currentProject, builder, getLog() );
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000577 }
Stuart McCulloch9c4a94d2008-01-30 09:56:30 +0000578
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000579 // update BND instructions to embed selected Maven dependencies
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000580 Collection embeddableArtifacts = getEmbeddableArtifacts( currentProject, builder );
Stuart McCullochcb2a3b22009-09-02 17:44:00 +0000581 new DependencyEmbedder( getLog(), embeddableArtifacts ).processHeaders( builder );
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000582
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000583 if ( dumpInstructions != null || getLog().isDebugEnabled() )
584 {
585 StringBuilder buf = new StringBuilder();
586 getLog().debug( "BND Instructions:" + NL + dumpInstructions( builder.getProperties(), buf ) );
587 if ( dumpInstructions != null )
588 {
Stuart McCullochc5e7c352011-06-28 23:02:57 +0000589 getLog().info( "Writing BND instructions to " + dumpInstructions );
590 dumpInstructions.getParentFile().mkdirs();
591 FileUtils.fileWrite( dumpInstructions, "# BND instructions" + NL + buf );
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000592 }
593 }
594
595 if ( dumpClasspath != null || getLog().isDebugEnabled() )
596 {
597 StringBuilder buf = new StringBuilder();
598 getLog().debug( "BND Classpath:" + NL + dumpClasspath( builder.getClasspath(), buf ) );
599 if ( dumpClasspath != null )
600 {
Stuart McCullochc5e7c352011-06-28 23:02:57 +0000601 getLog().info( "Writing BND classpath to " + dumpClasspath );
602 dumpClasspath.getParentFile().mkdirs();
603 FileUtils.fileWrite( dumpClasspath, "# BND classpath" + NL + buf );
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000604 }
605 }
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000606 }
607
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000608
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000609 protected Builder buildOSGiBundle( MavenProject currentProject, Map originalInstructions, Properties properties,
610 Jar[] classpath ) throws Exception
611 {
612 Builder builder = getOSGiBuilder( currentProject, originalInstructions, properties, classpath );
613
614 addMavenInstructions( currentProject, builder );
Stuart McCulloche8125182008-12-05 10:41:46 +0000615
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000616 builder.build();
Stuart McCulloche8125182008-12-05 10:41:46 +0000617
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000618 mergeMavenManifest( currentProject, builder );
Stuart McCulloch1a42bfa2008-01-30 07:50:33 +0000619
620 return builder;
621 }
622
623
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000624 protected static StringBuilder dumpInstructions( Properties properties, StringBuilder buf )
Stuart McCulloche8125182008-12-05 10:41:46 +0000625 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000626 try
Stuart McCulloche8125182008-12-05 10:41:46 +0000627 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000628 buf.append( "#-----------------------------------------------------------------------" + NL );
629 Properties stringProperties = new Properties();
Stuart McCulloche8125182008-12-05 10:41:46 +0000630 for ( Enumeration e = properties.propertyNames(); e.hasMoreElements(); )
631 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000632 // we can only store String properties
Stuart McCulloch378e76c2009-01-30 09:51:35 +0000633 String key = ( String ) e.nextElement();
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000634 String value = properties.getProperty( key );
635 if ( value != null )
636 {
637 stringProperties.setProperty( key, value );
638 }
Stuart McCulloche8125182008-12-05 10:41:46 +0000639 }
Stuart McCulloch65271c82011-07-01 11:57:08 +0000640 ByteArrayOutputStream out = new ByteArrayOutputStream();
641 stringProperties.store( out, null ); // properties encoding is 8859_1
642 buf.append( out.toString( "8859_1" ) );
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000643 buf.append( "#-----------------------------------------------------------------------" + NL );
Stuart McCulloche8125182008-12-05 10:41:46 +0000644 }
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000645 catch ( Throwable e )
646 {
647 // ignore...
648 }
649 return buf;
Stuart McCulloche8125182008-12-05 10:41:46 +0000650 }
651
652
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000653 protected static StringBuilder dumpClasspath( List classpath, StringBuilder buf )
Stuart McCulloch53e42e12009-01-29 08:45:51 +0000654 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000655 try
Stuart McCulloch53e42e12009-01-29 08:45:51 +0000656 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000657 buf.append( "#-----------------------------------------------------------------------" + NL );
658 buf.append( "-classpath:\\" + NL );
Stuart McCulloch53e42e12009-01-29 08:45:51 +0000659 for ( Iterator i = classpath.iterator(); i.hasNext(); )
660 {
Stuart McCulloch378e76c2009-01-30 09:51:35 +0000661 File path = ( ( Jar ) i.next() ).getSource();
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000662 if ( path != null )
663 {
664 buf.append( ' ' + path.toString() + ( i.hasNext() ? ",\\" : "" ) + NL );
665 }
Stuart McCulloch53e42e12009-01-29 08:45:51 +0000666 }
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000667 buf.append( "#-----------------------------------------------------------------------" + NL );
Stuart McCulloch53e42e12009-01-29 08:45:51 +0000668 }
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000669 catch ( Throwable e )
670 {
671 // ignore...
672 }
673 return buf;
Stuart McCulloch53e42e12009-01-29 08:45:51 +0000674 }
675
676
Guillaume Nodet457f4302014-06-14 10:39:55 +0000677 protected StringBuilder dumpManifest( Manifest manifest, StringBuilder buf )
Stuart McCulloche8125182008-12-05 10:41:46 +0000678 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000679 try
Stuart McCulloche8125182008-12-05 10:41:46 +0000680 {
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000681 buf.append( "#-----------------------------------------------------------------------" + NL );
682 ByteArrayOutputStream out = new ByteArrayOutputStream();
Guillaume Nodet457f4302014-06-14 10:39:55 +0000683 ManifestWriter.outputManifest( manifest, out, false ); // manifest encoding is UTF8
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000684 buf.append( out.toString( "UTF8" ) );
685 buf.append( "#-----------------------------------------------------------------------" + NL );
Stuart McCulloche8125182008-12-05 10:41:46 +0000686 }
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000687 catch ( Throwable e )
688 {
689 // ignore...
690 }
691 return buf;
Stuart McCulloche8125182008-12-05 10:41:46 +0000692 }
693
694
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000695 protected static void includeMavenResources( MavenProject currentProject, Analyzer analyzer, Log log )
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000696 {
697 // pass maven resource paths onto BND analyzer
698 final String mavenResourcePaths = getMavenResourcePaths( currentProject );
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000699 final String includeResource = ( String ) analyzer.getProperty( Analyzer.INCLUDE_RESOURCE );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000700 if ( includeResource != null )
701 {
702 if ( includeResource.indexOf( MAVEN_RESOURCES ) >= 0 )
703 {
704 // if there is no maven resource path, we do a special treatment and replace
705 // every occurance of MAVEN_RESOURCES and a following comma with an empty string
706 if ( mavenResourcePaths.length() == 0 )
707 {
708 String cleanedResource = removeTagFromInstruction( includeResource, MAVEN_RESOURCES );
709 if ( cleanedResource.length() > 0 )
710 {
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000711 analyzer.setProperty( Analyzer.INCLUDE_RESOURCE, cleanedResource );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000712 }
713 else
714 {
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000715 analyzer.unsetProperty( Analyzer.INCLUDE_RESOURCE );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000716 }
717 }
718 else
719 {
Stuart McCulloch464dbac2008-08-03 09:47:04 +0000720 String combinedResource = StringUtils
721 .replace( includeResource, MAVEN_RESOURCES, mavenResourcePaths );
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000722 analyzer.setProperty( Analyzer.INCLUDE_RESOURCE, combinedResource );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000723 }
724 }
725 else if ( mavenResourcePaths.length() > 0 )
726 {
727 log.warn( Analyzer.INCLUDE_RESOURCE + ": overriding " + mavenResourcePaths + " with " + includeResource
728 + " (add " + MAVEN_RESOURCES + " if you want to include the maven resources)" );
729 }
730 }
731 else if ( mavenResourcePaths.length() > 0 )
732 {
Stuart McCulloch84bf81e2008-12-03 14:07:08 +0000733 analyzer.setProperty( Analyzer.INCLUDE_RESOURCE, mavenResourcePaths );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000734 }
735 }
736
737
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000738 protected void mergeMavenManifest( MavenProject currentProject, Builder builder ) throws Exception
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000739 {
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000740 Jar jar = builder.getJar();
741
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000742 if ( getLog().isDebugEnabled() )
743 {
744 getLog().debug( "BND Manifest:" + NL + dumpManifest( jar.getManifest(), new StringBuilder() ) );
745 }
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000746
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000747 boolean addMavenDescriptor = currentProject.getBasedir() != null;
Stuart McCulloch378e76c2009-01-30 09:51:35 +0000748
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000749 try
750 {
751 /*
752 * Grab customized manifest entries from the maven-jar-plugin configuration
753 */
754 MavenArchiveConfiguration archiveConfig = JarPluginConfiguration.getArchiveConfiguration( currentProject );
755 String mavenManifestText = new MavenArchiver().getManifest( currentProject, archiveConfig ).toString();
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +0000756 addMavenDescriptor = addMavenDescriptor && archiveConfig.isAddMavenDescriptor();
Stuart McCulloch378e76c2009-01-30 09:51:35 +0000757
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000758 Manifest mavenManifest = new Manifest();
759
Stuart McCullochbc90bf82011-10-17 17:28:09 +0000760 // First grab the external manifest file (if specified and different to target location)
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000761 File externalManifestFile = archiveConfig.getManifestFile();
Stuart McCulloche6cc8132013-06-07 21:45:18 +0000762 if ( null != externalManifestFile )
Stuart McCulloch6f241f02013-06-07 21:42:04 +0000763 {
Stuart McCulloche6cc8132013-06-07 21:45:18 +0000764 if ( !externalManifestFile.isAbsolute() )
765 {
766 externalManifestFile = new File( currentProject.getBasedir(), externalManifestFile.getPath() );
767 }
768 if ( externalManifestFile.exists() && !externalManifestFile.equals( new File( manifestLocation, "MANIFEST.MF" ) ) )
769 {
770 InputStream mis = new FileInputStream( externalManifestFile );
771 mavenManifest.read( mis );
772 mis.close();
773 }
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000774 }
775
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000776 // Then apply customized entries from the jar plugin; note: manifest encoding is UTF8
777 mavenManifest.read( new ByteArrayInputStream( mavenManifestText.getBytes( "UTF8" ) ) );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000778
779 if ( !archiveConfig.isManifestSectionsEmpty() )
780 {
781 /*
782 * Add customized manifest sections (for some reason MavenArchiver doesn't do this for us)
783 */
784 List sections = archiveConfig.getManifestSections();
785 for ( Iterator i = sections.iterator(); i.hasNext(); )
786 {
787 ManifestSection section = ( ManifestSection ) i.next();
788 Attributes attributes = new Attributes();
789
790 if ( !section.isManifestEntriesEmpty() )
791 {
792 Map entries = section.getManifestEntries();
793 for ( Iterator j = entries.entrySet().iterator(); j.hasNext(); )
794 {
795 Map.Entry entry = ( Map.Entry ) j.next();
796 attributes.putValue( ( String ) entry.getKey(), ( String ) entry.getValue() );
797 }
798 }
799
800 mavenManifest.getEntries().put( section.getName(), attributes );
801 }
802 }
803
Stuart McCulloche19d4092008-01-30 08:42:48 +0000804 Attributes mainMavenAttributes = mavenManifest.getMainAttributes();
805 mainMavenAttributes.putValue( "Created-By", "Apache Maven Bundle Plugin" );
806
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000807 String[] removeHeaders = builder.getProperty( Constants.REMOVEHEADERS, "" ).split( "," );
808
Stuart McCulloche19d4092008-01-30 08:42:48 +0000809 // apply -removeheaders to the custom manifest
810 for ( int i = 0; i < removeHeaders.length; i++ )
811 {
812 for ( Iterator j = mainMavenAttributes.keySet().iterator(); j.hasNext(); )
813 {
814 if ( j.next().toString().matches( removeHeaders[i].trim() ) )
815 {
816 j.remove();
817 }
818 }
819 }
820
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000821 /*
822 * Overlay generated bundle manifest with customized entries
823 */
824 Manifest bundleManifest = jar.getManifest();
Stuart McCulloche19d4092008-01-30 08:42:48 +0000825 bundleManifest.getMainAttributes().putAll( mainMavenAttributes );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000826 bundleManifest.getEntries().putAll( mavenManifest.getEntries() );
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000827
828 // adjust the import package attributes so that optional dependencies use
829 // optional resolution.
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000830 String importPackages = bundleManifest.getMainAttributes().getValue( "Import-Package" );
831 if ( importPackages != null )
832 {
833 Set optionalPackages = getOptionalPackages( currentProject );
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000834
Stuart McCullochf3173222012-06-07 21:57:32 +0000835 Map<String, ? extends Map<String, String>> values = new Analyzer().parseHeader( importPackages );
836 for ( Map.Entry<String, ? extends Map<String, String>> entry : values.entrySet() )
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000837 {
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000838 String pkg = entry.getKey();
839 Map<String, String> options = entry.getValue();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000840 if ( !options.containsKey( "resolution:" ) && optionalPackages.contains( pkg ) )
841 {
842 options.put( "resolution:", "optional" );
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000843 }
844 }
Stuart McCulloch26e7a5a2011-10-17 10:31:43 +0000845 String result = Processor.printClauses( values );
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000846 bundleManifest.getMainAttributes().putValue( "Import-Package", result );
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000847 }
848
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000849 jar.setManifest( bundleManifest );
850 }
851 catch ( Exception e )
852 {
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000853 getLog().warn( "Unable to merge Maven manifest: " + e.getLocalizedMessage() );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000854 }
Stuart McCulloch378e76c2009-01-30 09:51:35 +0000855
856 if ( addMavenDescriptor )
857 {
858 doMavenMetadata( currentProject, jar );
859 }
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000860
Stuart McCulloch340a8dd2011-06-28 22:47:10 +0000861 if ( getLog().isDebugEnabled() )
862 {
863 getLog().debug( "Final Manifest:" + NL + dumpManifest( jar.getManifest(), new StringBuilder() ) );
864 }
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +0000865
866 builder.setJar( jar );
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000867 }
868
869
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000870 protected Set getOptionalPackages( MavenProject currentProject ) throws IOException, MojoExecutionException
871 {
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000872 ArrayList inscope = new ArrayList();
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000873 final Collection artifacts = getSelectedDependencies( currentProject.getArtifacts() );
874 for ( Iterator it = artifacts.iterator(); it.hasNext(); )
875 {
876 Artifact artifact = ( Artifact ) it.next();
877 if ( artifact.getArtifactHandler().isAddedToClasspath() )
878 {
879 if ( !Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
880 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000881 inscope.add( artifact );
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000882 }
883 }
884 }
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000885
886 HashSet optionalArtifactIds = new HashSet();
887 for ( Iterator it = inscope.iterator(); it.hasNext(); )
888 {
889 Artifact artifact = ( Artifact ) it.next();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000890 if ( artifact.isOptional() )
891 {
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000892 String id = artifact.toString();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000893 if ( artifact.getScope() != null )
894 {
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000895 // strip the scope...
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000896 id = id.replaceFirst( ":[^:]*$", "" );
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000897 }
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000898 optionalArtifactIds.add( id );
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000899 }
900
901 }
902
903 HashSet required = new HashSet();
904 HashSet optional = new HashSet();
905 for ( Iterator it = inscope.iterator(); it.hasNext(); )
906 {
907 Artifact artifact = ( Artifact ) it.next();
908 File file = getFile( artifact );
909 if ( file == null )
910 {
911 continue;
912 }
913
914 Jar jar = new Jar( artifact.getArtifactId(), file );
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000915 if ( isTransitivelyOptional( optionalArtifactIds, artifact ) )
916 {
917 optional.addAll( jar.getPackages() );
918 }
919 else
920 {
921 required.addAll( jar.getPackages() );
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000922 }
923 jar.close();
924 }
925
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000926 optional.removeAll( required );
Hiram R. Chirino2d401a32011-01-27 20:58:44 +0000927 return optional;
928 }
929
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000930
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000931 /**
932 * Check to see if any dependency along the dependency trail of
933 * the artifact is optional.
934 *
935 * @param artifact
936 */
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000937 protected boolean isTransitivelyOptional( HashSet optionalArtifactIds, Artifact artifact )
938 {
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000939 List trail = artifact.getDependencyTrail();
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000940 for ( Iterator iterator = trail.iterator(); iterator.hasNext(); )
941 {
942 String next = ( String ) iterator.next();
943 if ( optionalArtifactIds.contains( next ) )
944 {
Hiram R. Chirino922498b2011-01-28 15:13:33 +0000945 return true;
946 }
947 }
948 return false;
949 }
950
Stuart McCullochd98b02e2011-06-28 23:20:37 +0000951
Stuart McCulloch48fcb1e2008-01-30 06:58:34 +0000952 private void unpackBundle( File jarFile )
953 {
954 File outputDir = getOutputDirectory();
955 if ( null == outputDir )
956 {
957 outputDir = new File( getBuildDirectory(), "classes" );
958 }
959
960 try
961 {
962 /*
963 * this directory must exist before unpacking, otherwise the plexus
964 * unarchiver decides to use the current working directory instead!
965 */
966 if ( !outputDir.exists() )
967 {
968 outputDir.mkdirs();
969 }
970
971 UnArchiver unArchiver = m_archiverManager.getUnArchiver( "jar" );
972 unArchiver.setDestDirectory( outputDir );
973 unArchiver.setSourceFile( jarFile );
974 unArchiver.extract();
975 }
976 catch ( Exception e )
977 {
978 getLog().error( "Problem unpacking " + jarFile + " to " + outputDir, e );
979 }
980 }
981
982
Stuart McCulloch5abb4c22008-01-29 11:26:33 +0000983 protected static String removeTagFromInstruction( String instruction, String tag )
Stuart McCulloch00b06942007-09-24 14:14:09 +0000984 {
985 StringBuffer buf = new StringBuffer();
986
Stuart McCulloch5abb4c22008-01-29 11:26:33 +0000987 String[] clauses = instruction.split( "," );
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000988 for ( int i = 0; i < clauses.length; i++ )
Stuart McCulloch00b06942007-09-24 14:14:09 +0000989 {
990 String clause = clauses[i].trim();
Stuart McCulloch5abb4c22008-01-29 11:26:33 +0000991 if ( !tag.equals( clause ) )
Stuart McCulloch00b06942007-09-24 14:14:09 +0000992 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000993 if ( buf.length() > 0 )
Stuart McCulloch00b06942007-09-24 14:14:09 +0000994 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000995 buf.append( ',' );
Stuart McCulloch00b06942007-09-24 14:14:09 +0000996 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +0000997 buf.append( clause );
Stuart McCulloch00b06942007-09-24 14:14:09 +0000998 }
999 }
1000
1001 return buf.toString();
1002 }
1003
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001004
Stuart McCullochf806f862008-02-04 07:57:09 +00001005 private static Map getProperties( Model projectModel, String prefix )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001006 {
Stuart McCullochd00f9712009-07-13 10:06:47 +00001007 Map properties = new LinkedHashMap();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001008 Method methods[] = Model.class.getDeclaredMethods();
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001009 for ( int i = 0; i < methods.length; i++ )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001010 {
1011 String name = methods[i].getName();
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001012 if ( name.startsWith( "get" ) )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001013 {
1014 try
1015 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001016 Object v = methods[i].invoke( projectModel, null );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001017 if ( v != null )
1018 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001019 name = prefix + Character.toLowerCase( name.charAt( 3 ) ) + name.substring( 4 );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001020 if ( v.getClass().isArray() )
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001021 properties.put( name, Arrays.asList( ( Object[] ) v ).toString() );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001022 else
1023 properties.put( name, v );
Richard S. Hall420d2782007-06-14 12:31:48 +00001024
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001025 }
1026 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001027 catch ( Exception e )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001028 {
1029 // too bad
1030 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001031 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001032 }
1033 return properties;
1034 }
Richard S. Hall46e7a852007-05-17 14:47:48 +00001035
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001036
Stuart McCulloch9366a822008-01-29 07:45:57 +00001037 private static StringBuffer printLicenses( List licenses )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001038 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001039 if ( licenses == null || licenses.size() == 0 )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001040 return null;
1041 StringBuffer sb = new StringBuffer();
1042 String del = "";
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001043 for ( Iterator i = licenses.iterator(); i.hasNext(); )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001044 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001045 License l = ( License ) i.next();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001046 String url = l.getUrl();
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001047 if ( url == null )
1048 continue;
1049 sb.append( del );
1050 sb.append( url );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001051 del = ", ";
1052 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001053 if ( sb.length() == 0 )
1054 return null;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001055 return sb;
1056 }
Richard S. Hall46e7a852007-05-17 14:47:48 +00001057
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001058
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001059 /**
1060 * @param jar
1061 * @throws IOException
1062 */
Stuart McCulloch9366a822008-01-29 07:45:57 +00001063 private void doMavenMetadata( MavenProject currentProject, Jar jar ) throws IOException
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001064 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001065 String path = "META-INF/maven/" + currentProject.getGroupId() + "/" + currentProject.getArtifactId();
Stuart McCulloch5c9b67d02011-06-28 16:06:24 +00001066 File pomFile = new File( currentProject.getBasedir(), "pom.xml" );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001067 jar.putResource( path + "/pom.xml", new FileResource( pomFile ) );
Richard S. Hall46e7a852007-05-17 14:47:48 +00001068
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001069 Properties p = new Properties();
Stuart McCulloch9366a822008-01-29 07:45:57 +00001070 p.put( "version", currentProject.getVersion() );
1071 p.put( "groupId", currentProject.getGroupId() );
1072 p.put( "artifactId", currentProject.getArtifactId() );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001073 ByteArrayOutputStream out = new ByteArrayOutputStream();
Stuart McCulloch9366a822008-01-29 07:45:57 +00001074 p.store( out, "Generated by org.apache.felix.bundleplugin" );
Stuart McCullochd98b02e2011-06-28 23:20:37 +00001075 jar.putResource( path + "/pom.properties", new EmbeddedResource( out.toByteArray(), System.currentTimeMillis() ) );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001076 }
Richard S. Hall46e7a852007-05-17 14:47:48 +00001077
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001078
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001079 protected Jar[] getClasspath( MavenProject currentProject ) throws IOException, MojoExecutionException
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001080 {
1081 List list = new ArrayList();
Richard S. Hall46e7a852007-05-17 14:47:48 +00001082
Stuart McCulloch9366a822008-01-29 07:45:57 +00001083 if ( getOutputDirectory() != null && getOutputDirectory().exists() )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001084 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001085 list.add( new Jar( ".", getOutputDirectory() ) );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001086 }
Richard S. Hall46e7a852007-05-17 14:47:48 +00001087
Stuart McCulloch5ffc3fe2008-02-20 05:37:57 +00001088 final Collection artifacts = getSelectedDependencies( currentProject.getArtifacts() );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001089 for ( Iterator it = artifacts.iterator(); it.hasNext(); )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001090 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001091 Artifact artifact = ( Artifact ) it.next();
1092 if ( artifact.getArtifactHandler().isAddedToClasspath() )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001093 {
Stuart McCullochf7d0c7c2009-01-29 07:23:06 +00001094 if ( !Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001095 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001096 File file = getFile( artifact );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001097 if ( file == null )
Stuart McCulloch55fcffd2007-08-22 03:19:15 +00001098 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001099 getLog().warn(
Stuart McCulloch9366a822008-01-29 07:45:57 +00001100 "File is not available for artifact " + artifact + " in project "
1101 + currentProject.getArtifact() );
Stuart McCullocha719bc02007-09-25 13:48:58 +00001102 continue;
Stuart McCulloch55fcffd2007-08-22 03:19:15 +00001103 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001104 Jar jar = new Jar( artifact.getArtifactId(), file );
1105 list.add( jar );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001106 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001107 }
1108 }
1109 Jar[] cp = new Jar[list.size()];
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001110 list.toArray( cp );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001111 return cp;
1112 }
Richard S. Hall46e7a852007-05-17 14:47:48 +00001113
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001114
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001115 private Collection getSelectedDependencies( Collection artifacts ) throws MojoExecutionException
Stuart McCulloch5ffc3fe2008-02-20 05:37:57 +00001116 {
1117 if ( null == excludeDependencies || excludeDependencies.length() == 0 )
1118 {
1119 return artifacts;
1120 }
1121 else if ( "true".equalsIgnoreCase( excludeDependencies ) )
1122 {
1123 return Collections.EMPTY_LIST;
1124 }
1125
Stuart McCullochd00f9712009-07-13 10:06:47 +00001126 Collection selectedDependencies = new LinkedHashSet( artifacts );
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001127 DependencyExcluder excluder = new DependencyExcluder( artifacts );
1128 excluder.processHeaders( excludeDependencies );
1129 selectedDependencies.removeAll( excluder.getExcludedArtifacts() );
Stuart McCulloch5ffc3fe2008-02-20 05:37:57 +00001130
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001131 return selectedDependencies;
Stuart McCulloch5ffc3fe2008-02-20 05:37:57 +00001132 }
1133
1134
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001135 /**
1136 * Get the file for an Artifact
1137 *
1138 * @param artifact
1139 */
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001140 protected File getFile( Artifact artifact )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001141 {
1142 return artifact.getFile();
1143 }
Richard S. Hall46e7a852007-05-17 14:47:48 +00001144
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001145
Stuart McCulloch9366a822008-01-29 07:45:57 +00001146 private static void header( Properties properties, String key, Object value )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001147 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001148 if ( value == null )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001149 return;
Richard S. Hall46e7a852007-05-17 14:47:48 +00001150
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001151 if ( value instanceof Collection && ( ( Collection ) value ).isEmpty() )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001152 return;
1153
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001154 properties.put( key, value.toString().replaceAll( "[\r\n]", "" ) );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001155 }
1156
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001157
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001158 /**
1159 * Convert a Maven version into an OSGi compliant version
1160 *
1161 * @param version Maven version
1162 * @return the OSGi version
1163 */
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001164 protected String convertVersionToOsgi( String version )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001165 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001166 return getMaven2OsgiConverter().getVersion( version );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001167 }
1168
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001169
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001170 /**
1171 * TODO this should return getMaven2Osgi().getBundleFileName( project.getArtifact() )
1172 */
Stuart McCulloch9366a822008-01-29 07:45:57 +00001173 protected String getBundleName( MavenProject currentProject )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001174 {
Stuart McCulloche68ebd22011-06-24 21:50:07 +00001175 String extension;
1176 try
1177 {
1178 extension = currentProject.getArtifact().getArtifactHandler().getExtension();
1179 }
1180 catch ( Throwable e )
1181 {
1182 extension = currentProject.getArtifact().getType();
1183 }
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001184 if ( StringUtils.isEmpty( extension ) || "bundle".equals( extension ) || "pom".equals( extension ) )
Stuart McCulloche68ebd22011-06-24 21:50:07 +00001185 {
1186 extension = "jar"; // just in case maven gets confused
1187 }
Stuart McCulloch0491afa2008-02-19 05:06:41 +00001188 if ( null != classifier && classifier.trim().length() > 0 )
1189 {
Stuart McCulloche68ebd22011-06-24 21:50:07 +00001190 return finalName + '-' + classifier + '.' + extension;
Stuart McCulloch0491afa2008-02-19 05:06:41 +00001191 }
Stuart McCulloche68ebd22011-06-24 21:50:07 +00001192 return finalName + '.' + extension;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001193 }
1194
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001195
Stuart McCulloch1a862e92007-10-16 14:13:49 +00001196 protected String getBuildDirectory()
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001197 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001198 return buildDirectory;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001199 }
1200
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001201
Stuart McCulloch9366a822008-01-29 07:45:57 +00001202 protected void setBuildDirectory( String _buildirectory )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001203 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001204 buildDirectory = _buildirectory;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001205 }
1206
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001207
Stuart McCulloch9366a822008-01-29 07:45:57 +00001208 protected Properties getDefaultProperties( MavenProject currentProject )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001209 {
1210 Properties properties = new Properties();
Stuart McCulloch02afa5f2007-10-04 17:23:30 +00001211
1212 String bsn;
1213 try
1214 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001215 bsn = getMaven2OsgiConverter().getBundleSymbolicName( currentProject.getArtifact() );
Stuart McCulloch02afa5f2007-10-04 17:23:30 +00001216 }
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001217 catch ( Exception e )
Stuart McCulloch02afa5f2007-10-04 17:23:30 +00001218 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001219 bsn = currentProject.getGroupId() + "." + currentProject.getArtifactId();
Stuart McCulloch02afa5f2007-10-04 17:23:30 +00001220 }
1221
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001222 // Setup defaults
Stuart McCulloch6d4c8372009-02-16 06:49:21 +00001223 properties.put( MAVEN_SYMBOLICNAME, bsn );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001224 properties.put( Analyzer.BUNDLE_SYMBOLICNAME, bsn );
1225 properties.put( Analyzer.IMPORT_PACKAGE, "*" );
Stuart McCullochd98b02e2011-06-28 23:20:37 +00001226 properties.put( Analyzer.BUNDLE_VERSION, getMaven2OsgiConverter().getVersion( currentProject.getVersion() ) );
Stuart McCulloch02afa5f2007-10-04 17:23:30 +00001227
Stuart McCullochc966ef62009-09-02 18:02:59 +00001228 // remove the extraneous Include-Resource and Private-Package entries from generated manifest
Richard S. Hall2c9e5922010-10-25 19:07:06 +00001229 properties.put( Constants.REMOVEHEADERS, Analyzer.INCLUDE_RESOURCE + ',' + Analyzer.PRIVATE_PACKAGE );
Stuart McCulloch8f21a4a2008-01-09 17:08:32 +00001230
Stuart McCulloch9366a822008-01-29 07:45:57 +00001231 header( properties, Analyzer.BUNDLE_DESCRIPTION, currentProject.getDescription() );
1232 StringBuffer licenseText = printLicenses( currentProject.getLicenses() );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001233 if ( licenseText != null )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001234 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001235 header( properties, Analyzer.BUNDLE_LICENSE, licenseText );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001236 }
Stuart McCulloch9366a822008-01-29 07:45:57 +00001237 header( properties, Analyzer.BUNDLE_NAME, currentProject.getName() );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001238
Stuart McCulloch9366a822008-01-29 07:45:57 +00001239 if ( currentProject.getOrganization() != null )
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001240 {
Stuart McCulloch007f8c82011-06-24 12:45:17 +00001241 if ( currentProject.getOrganization().getName() != null )
1242 {
1243 String organizationName = currentProject.getOrganization().getName();
1244 header( properties, Analyzer.BUNDLE_VENDOR, organizationName );
1245 properties.put( "project.organization.name", organizationName );
1246 properties.put( "pom.organization.name", organizationName );
1247 }
Stuart McCulloch9366a822008-01-29 07:45:57 +00001248 if ( currentProject.getOrganization().getUrl() != null )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001249 {
Stuart McCulloch6dd4dd22009-09-02 22:45:33 +00001250 String organizationUrl = currentProject.getOrganization().getUrl();
1251 header( properties, Analyzer.BUNDLE_DOCURL, organizationUrl );
1252 properties.put( "project.organization.url", organizationUrl );
1253 properties.put( "pom.organization.url", organizationUrl );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001254 }
1255 }
1256
Stuart McCulloch9366a822008-01-29 07:45:57 +00001257 properties.putAll( currentProject.getProperties() );
1258 properties.putAll( currentProject.getModel().getProperties() );
Stuart McCulloch437f4872013-06-07 21:24:26 +00001259
1260 for ( Iterator i = currentProject.getFilters().iterator(); i.hasNext(); )
1261 {
1262 File filterFile = new File( ( String ) i.next() );
1263 if ( filterFile.isFile() )
1264 {
1265 properties.putAll( PropertyUtils.loadProperties( filterFile ) );
1266 }
1267 }
1268
Stuart McCullochcdad75f2011-06-28 00:03:15 +00001269 if ( m_mavenSession != null )
1270 {
Stuart McCulloche98965e2012-02-11 14:17:41 +00001271 try
1272 {
Stuart McCulloch8eb17522012-02-11 14:26:57 +00001273 // don't pass upper-case session settings to bnd as they end up in the manifest
Stuart McCulloche98965e2012-02-11 14:17:41 +00001274 Properties sessionProperties = m_mavenSession.getExecutionProperties();
1275 for ( Enumeration e = sessionProperties.propertyNames(); e.hasMoreElements(); )
1276 {
Stuart McCulloche98965e2012-02-11 14:17:41 +00001277 String key = ( String ) e.nextElement();
1278 if ( key.length() > 0 && !Character.isUpperCase( key.charAt( 0 ) ) )
1279 {
1280 properties.put( key, sessionProperties.getProperty( key ) );
1281 }
1282 }
1283 }
1284 catch ( Exception e )
1285 {
1286 getLog().warn( "Problem with Maven session properties: " + e.getLocalizedMessage() );
1287 }
Stuart McCullochcdad75f2011-06-28 00:03:15 +00001288 }
1289
Stuart McCullochf806f862008-02-04 07:57:09 +00001290 properties.putAll( getProperties( currentProject.getModel(), "project.build." ) );
1291 properties.putAll( getProperties( currentProject.getModel(), "pom." ) );
1292 properties.putAll( getProperties( currentProject.getModel(), "project." ) );
Stuart McCullochcdad75f2011-06-28 00:03:15 +00001293
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001294 properties.put( "project.baseDir", getBase( currentProject ) );
Stuart McCulloch9366a822008-01-29 07:45:57 +00001295 properties.put( "project.build.directory", getBuildDirectory() );
1296 properties.put( "project.build.outputdirectory", getOutputDirectory() );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001297
Stuart McCulloch1d3a0a02008-04-30 05:38:03 +00001298 properties.put( "classifier", classifier == null ? "" : classifier );
1299
Guillaume Nodet459eaed2009-09-02 21:15:28 +00001300 // Add default plugins
Guillaume Nodet7bf509f2014-05-19 07:12:48 +00001301 header( properties, Analyzer.PLUGIN, ScrPlugin.class.getName() + ","
1302 + BlueprintPlugin.class.getName() + ","
1303 + SpringXMLType.class.getName() );
Guillaume Nodet459eaed2009-09-02 21:15:28 +00001304
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001305 return properties;
1306 }
1307
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001308
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001309 protected static File getBase( MavenProject currentProject )
1310 {
1311 return currentProject.getBasedir() != null ? currentProject.getBasedir() : new File( "" );
1312 }
1313
1314
Stuart McCulloch9366a822008-01-29 07:45:57 +00001315 protected File getOutputDirectory()
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001316 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001317 return outputDirectory;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001318 }
1319
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001320
Stuart McCulloch9366a822008-01-29 07:45:57 +00001321 protected void setOutputDirectory( File _outputDirectory )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001322 {
Stuart McCulloch9366a822008-01-29 07:45:57 +00001323 outputDirectory = _outputDirectory;
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001324 }
1325
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001326
Stuart McCulloch1648f402013-06-07 22:21:11 +00001327 private static void addLocalPackages( File outputDirectory, Analyzer analyzer ) throws IOException
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001328 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001329 Packages packages = new Packages();
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001330
Hiram R. Chirino4f5f2272011-01-27 18:32:03 +00001331 if ( outputDirectory != null && outputDirectory.isDirectory() )
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001332 {
Hiram R. Chirino4f5f2272011-01-27 18:32:03 +00001333 // scan classes directory for potential packages
1334 DirectoryScanner scanner = new DirectoryScanner();
1335 scanner.setBasedir( outputDirectory );
1336 scanner.setIncludes( new String[]
1337 { "**/*.class" } );
1338
1339 scanner.addDefaultExcludes();
1340 scanner.scan();
1341
1342 String[] paths = scanner.getIncludedFiles();
1343 for ( int i = 0; i < paths.length; i++ )
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001344 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001345 packages.put( analyzer.getPackageRef( getPackageName( paths[i] ) ) );
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001346 }
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001347 }
1348
Stuart McCulloch1648f402013-06-07 22:21:11 +00001349 Packages exportedPkgs = new Packages();
1350 Packages privatePkgs = new Packages();
Stuart McCullochd98b02e2011-06-28 23:20:37 +00001351
1352 boolean noprivatePackages = "!*".equals( analyzer.getProperty( Analyzer.PRIVATE_PACKAGE ) );
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001353
Stuart McCulloch1648f402013-06-07 22:21:11 +00001354 for ( PackageRef pkg : packages.keySet() )
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001355 {
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001356 // mark all source packages as private by default (can be overridden by export list)
Stuart McCulloch1648f402013-06-07 22:21:11 +00001357 privatePkgs.put( pkg );
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001358
1359 // we can't export the default package (".") and we shouldn't export internal packages
Stuart McCulloch1648f402013-06-07 22:21:11 +00001360 String fqn = pkg.getFQN();
1361 if ( noprivatePackages || !( ".".equals( fqn ) || fqn.contains( ".internal" ) || fqn.contains( ".impl" ) ) )
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001362 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001363 exportedPkgs.put( pkg );
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001364 }
1365 }
1366
Stuart McCulloch1648f402013-06-07 22:21:11 +00001367 Properties properties = analyzer.getProperties();
1368 String exported = properties.getProperty( Analyzer.EXPORT_PACKAGE );
1369 if ( exported == null )
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001370 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001371 if ( !properties.containsKey( Analyzer.EXPORT_CONTENTS ) )
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001372 {
1373 // no -exportcontents overriding the exports, so use our computed list
Stuart McCulloch1648f402013-06-07 22:21:11 +00001374 for ( Attrs attrs : exportedPkgs.values() )
1375 {
1376 attrs.put( Constants.SPLIT_PACKAGE_DIRECTIVE, "merge-first" );
1377 }
1378 properties.setProperty( Analyzer.EXPORT_PACKAGE, Processor.printClauses( exportedPkgs ) );
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001379 }
1380 else
1381 {
1382 // leave Export-Package empty (but non-null) as we have -exportcontents
Stuart McCulloch1648f402013-06-07 22:21:11 +00001383 properties.setProperty( Analyzer.EXPORT_PACKAGE, "" );
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001384 }
1385 }
Stuart McCulloch1648f402013-06-07 22:21:11 +00001386 else if ( exported.indexOf( LOCAL_PACKAGES ) >= 0 )
Guillaume Nodete5f5c7a2010-11-17 08:09:42 +00001387 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001388 String newExported = StringUtils.replace( exported, LOCAL_PACKAGES, Processor.printClauses( exportedPkgs ) );
1389 properties.setProperty( Analyzer.EXPORT_PACKAGE, newExported );
Guillaume Nodete5f5c7a2010-11-17 08:09:42 +00001390 }
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001391
Stuart McCulloch1648f402013-06-07 22:21:11 +00001392 String internal = properties.getProperty( Analyzer.PRIVATE_PACKAGE );
Stuart McCullochba6fc122011-11-28 14:22:26 +00001393 if ( internal == null )
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001394 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001395 if ( !privatePkgs.isEmpty() )
Stuart McCullochba6fc122011-11-28 14:22:26 +00001396 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001397 for ( Attrs attrs : privatePkgs.values() )
1398 {
1399 attrs.put( Constants.SPLIT_PACKAGE_DIRECTIVE, "merge-first" );
1400 }
1401 properties.setProperty( Analyzer.PRIVATE_PACKAGE, Processor.printClauses( privatePkgs ) );
Stuart McCullochba6fc122011-11-28 14:22:26 +00001402 }
1403 else
1404 {
1405 // if there are really no private packages then use "!*" as this will keep the Bnd Tool happy
Stuart McCulloch1648f402013-06-07 22:21:11 +00001406 properties.setProperty( Analyzer.PRIVATE_PACKAGE, "!*" );
Stuart McCullochba6fc122011-11-28 14:22:26 +00001407 }
1408 }
1409 else if ( internal.indexOf( LOCAL_PACKAGES ) >= 0 )
1410 {
Stuart McCulloch1648f402013-06-07 22:21:11 +00001411 String newInternal = StringUtils.replace( internal, LOCAL_PACKAGES, Processor.printClauses( privatePkgs ) );
1412 properties.setProperty( Analyzer.PRIVATE_PACKAGE, newInternal );
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001413 }
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001414 }
1415
1416
Stuart McCullochb371e7e2009-02-17 11:58:12 +00001417 private static String getPackageName( String filename )
Stuart McCulloch5341ef02009-02-16 09:44:47 +00001418 {
1419 int n = filename.lastIndexOf( File.separatorChar );
1420 return n < 0 ? "." : filename.substring( 0, n ).replace( File.separatorChar, '.' );
1421 }
1422
1423
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001424 private static List getMavenResources( MavenProject currentProject )
Stuart McCulloche71aa492011-06-24 18:21:16 +00001425 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +00001426 List resources = new ArrayList( currentProject.getResources() );
Stuart McCulloche71aa492011-06-24 18:21:16 +00001427
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001428 if ( currentProject.getCompileSourceRoots() != null )
Stuart McCulloche71aa492011-06-24 18:21:16 +00001429 {
Stuart McCulloch1228d3f2011-06-28 16:14:52 +00001430 // also scan for any "packageinfo" files lurking in the source folders
1431 List packageInfoIncludes = Collections.singletonList( "**/packageinfo" );
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001432 for ( Iterator i = currentProject.getCompileSourceRoots().iterator(); i.hasNext(); )
Stuart McCulloch1228d3f2011-06-28 16:14:52 +00001433 {
Stuart McCullochd98b02e2011-06-28 23:20:37 +00001434 String sourceRoot = ( String ) i.next();
Stuart McCulloch1228d3f2011-06-28 16:14:52 +00001435 Resource packageInfoResource = new Resource();
1436 packageInfoResource.setDirectory( sourceRoot );
1437 packageInfoResource.setIncludes( packageInfoIncludes );
1438 resources.add( packageInfoResource );
1439 }
Stuart McCulloche71aa492011-06-24 18:21:16 +00001440 }
1441
1442 return resources;
1443 }
1444
1445
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001446 protected static String getMavenResourcePaths( MavenProject currentProject )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001447 {
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001448 final String basePath = currentProject.getBasedir().getAbsolutePath();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001449
Stuart McCulloch63682bf2009-07-13 10:59:39 +00001450 Set pathSet = new LinkedHashSet();
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001451 for ( Iterator i = getMavenResources( currentProject ).iterator(); i.hasNext(); )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001452 {
Stuart McCulloche71aa492011-06-24 18:21:16 +00001453 Resource resource = ( Resource ) i.next();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001454
1455 final String sourcePath = resource.getDirectory();
1456 final String targetPath = resource.getTargetPath();
1457
1458 // ignore empty or non-local resources
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001459 if ( new File( sourcePath ).exists() && ( ( targetPath == null ) || ( targetPath.indexOf( ".." ) < 0 ) ) )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001460 {
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001461 DirectoryScanner scanner = new DirectoryScanner();
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001462
Stuart McCulloche71aa492011-06-24 18:21:16 +00001463 scanner.setBasedir( sourcePath );
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001464 if ( resource.getIncludes() != null && !resource.getIncludes().isEmpty() )
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001465 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001466 scanner.setIncludes( ( String[] ) resource.getIncludes().toArray( EMPTY_STRING_ARRAY ) );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001467 }
1468 else
1469 {
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001470 scanner.setIncludes( DEFAULT_INCLUDES );
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001471 }
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001472
1473 if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
1474 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001475 scanner.setExcludes( ( String[] ) resource.getExcludes().toArray( EMPTY_STRING_ARRAY ) );
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001476 }
1477
1478 scanner.addDefaultExcludes();
1479 scanner.scan();
1480
1481 List includedFiles = Arrays.asList( scanner.getIncludedFiles() );
1482
1483 for ( Iterator j = includedFiles.iterator(); j.hasNext(); )
1484 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001485 String name = ( String ) j.next();
Stuart McCulloch7c16d692007-11-18 05:02:09 +00001486 String path = sourcePath + '/' + name;
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001487
1488 // make relative to project
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001489 if ( path.startsWith( basePath ) )
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001490 {
1491 if ( path.length() == basePath.length() )
1492 {
1493 path = ".";
1494 }
1495 else
1496 {
1497 path = path.substring( basePath.length() + 1 );
1498 }
1499 }
1500
1501 // replace windows backslash with a slash
1502 // this is a workaround for a problem with bnd 0.0.189
1503 if ( File.separatorChar != '/' )
1504 {
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001505 name = name.replace( File.separatorChar, '/' );
1506 path = path.replace( File.separatorChar, '/' );
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001507 }
1508
Stuart McCulloch7c16d692007-11-18 05:02:09 +00001509 // copy to correct place
1510 path = name + '=' + path;
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001511 if ( targetPath != null )
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001512 {
Stuart McCulloch7c16d692007-11-18 05:02:09 +00001513 path = targetPath + '/' + path;
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001514 }
1515
Stuart McCulloch63682bf2009-07-13 10:59:39 +00001516 // use Bnd filtering?
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001517 if ( resource.isFiltering() )
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001518 {
Stuart McCulloch63682bf2009-07-13 10:59:39 +00001519 path = '{' + path + '}';
Stuart McCulloch44deaef2007-11-18 04:36:21 +00001520 }
Stuart McCulloch63682bf2009-07-13 10:59:39 +00001521
1522 pathSet.add( path );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001523 }
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001524 }
1525 }
1526
Stuart McCulloch63682bf2009-07-13 10:59:39 +00001527 StringBuffer resourcePaths = new StringBuffer();
Stuart McCullochd98b02e2011-06-28 23:20:37 +00001528 for ( Iterator i = pathSet.iterator(); i.hasNext(); )
Stuart McCulloch63682bf2009-07-13 10:59:39 +00001529 {
1530 resourcePaths.append( i.next() );
1531 if ( i.hasNext() )
1532 {
1533 resourcePaths.append( ',' );
1534 }
1535 }
1536
Carsten Ziegeler8fb2f052007-08-01 08:28:54 +00001537 return resourcePaths.toString();
1538 }
Stuart McCullochf7c44882007-08-23 08:10:03 +00001539
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001540
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001541 protected Collection getEmbeddableArtifacts( MavenProject currentProject, Analyzer analyzer )
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001542 throws MojoExecutionException
Stuart McCullochf7c44882007-08-23 08:10:03 +00001543 {
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001544 final Collection artifacts;
1545
Stuart McCulloch84bf81e2008-12-03 14:07:08 +00001546 String embedTransitive = analyzer.getProperty( DependencyEmbedder.EMBED_TRANSITIVE );
Stuart McCulloch5ae59142008-01-29 06:21:05 +00001547 if ( Boolean.valueOf( embedTransitive ).booleanValue() )
Stuart McCullochf7c44882007-08-23 08:10:03 +00001548 {
1549 // includes transitive dependencies
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001550 artifacts = currentProject.getArtifacts();
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001551 }
1552 else
1553 {
1554 // only includes direct dependencies
Stuart McCulloch5fcbe4a2011-06-28 18:26:45 +00001555 artifacts = currentProject.getDependencyArtifacts();
Stuart McCullochf7c44882007-08-23 08:10:03 +00001556 }
Stuart McCullochf806f862008-02-04 07:57:09 +00001557
Stuart McCulloch888d6da2009-02-16 08:25:03 +00001558 return getSelectedDependencies( artifacts );
Stuart McCullochf7c44882007-08-23 08:10:03 +00001559 }
Stuart McCullochfe58ad52011-11-28 15:05:51 +00001560
1561
1562 protected static void addMavenSourcePath( MavenProject currentProject, Analyzer analyzer, Log log )
1563 {
1564 // pass maven source paths onto BND analyzer
1565 StringBuilder mavenSourcePaths = new StringBuilder();
1566 if ( currentProject.getCompileSourceRoots() != null )
1567 {
1568 for ( Iterator i = currentProject.getCompileSourceRoots().iterator(); i.hasNext(); )
1569 {
1570 if ( mavenSourcePaths.length() > 0 )
1571 {
1572 mavenSourcePaths.append( ',' );
1573 }
1574 mavenSourcePaths.append( ( String ) i.next() );
1575 }
1576 }
1577 final String sourcePath = ( String ) analyzer.getProperty( Analyzer.SOURCEPATH );
1578 if ( sourcePath != null )
1579 {
1580 if ( sourcePath.indexOf( MAVEN_SOURCES ) >= 0 )
1581 {
1582 // if there is no maven source path, we do a special treatment and replace
1583 // every occurance of MAVEN_SOURCES and a following comma with an empty string
1584 if ( mavenSourcePaths.length() == 0 )
1585 {
1586 String cleanedSource = removeTagFromInstruction( sourcePath, MAVEN_SOURCES );
1587 if ( cleanedSource.length() > 0 )
1588 {
1589 analyzer.setProperty( Analyzer.SOURCEPATH, cleanedSource );
1590 }
1591 else
1592 {
1593 analyzer.unsetProperty( Analyzer.SOURCEPATH );
1594 }
1595 }
1596 else
1597 {
1598 String combinedSource = StringUtils
1599 .replace( sourcePath, MAVEN_SOURCES, mavenSourcePaths.toString() );
1600 analyzer.setProperty( Analyzer.SOURCEPATH, combinedSource );
1601 }
1602 }
1603 else if ( mavenSourcePaths.length() > 0 )
1604 {
1605 log.warn( Analyzer.SOURCEPATH + ": overriding " + mavenSourcePaths + " with " + sourcePath + " (add "
1606 + MAVEN_SOURCES + " if you want to include the maven sources)" );
1607 }
1608 }
1609 else if ( mavenSourcePaths.length() > 0 )
1610 {
1611 analyzer.setProperty( Analyzer.SOURCEPATH, mavenSourcePaths.toString() );
1612 }
1613 }
Richard S. Hallf3120092006-10-31 17:32:16 +00001614}