Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 1 | /* |
| 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. Hall | 01a56ce | 2007-05-20 22:31:11 +0000 | [diff] [blame] | 19 | package org.apache.felix.bundleplugin; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 20 | |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 21 | |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 22 | import java.io.File; |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 23 | import java.io.FileInputStream; |
Stuart McCulloch | 12b1d70 | 2007-09-11 07:48:10 +0000 | [diff] [blame] | 24 | import java.io.FileNotFoundException; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 25 | import java.io.FileOutputStream; |
| 26 | import java.io.IOException; |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 27 | import java.io.InputStream; |
Stuart McCulloch | 8cefad5 | 2011-10-16 17:53:16 +0000 | [diff] [blame] | 28 | import java.io.OutputStream; |
Stuart McCulloch | 07025e1 | 2012-02-11 17:28:48 +0000 | [diff] [blame] | 29 | import java.util.Iterator; |
Stuart McCulloch | d00f971 | 2009-07-13 10:06:47 +0000 | [diff] [blame] | 30 | import java.util.LinkedHashMap; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 31 | import java.util.Map; |
Stuart McCulloch | 8cefad5 | 2011-10-16 17:53:16 +0000 | [diff] [blame] | 32 | import java.util.Map.Entry; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 33 | import java.util.Properties; |
| 34 | import java.util.jar.Manifest; |
| 35 | |
Guillaume Nodet | 88239df | 2015-07-09 19:45:59 +0000 | [diff] [blame] | 36 | import aQute.bnd.header.Parameters; |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 37 | import aQute.bnd.osgi.Instructions; |
Guillaume Nodet | 88239df | 2015-07-09 19:45:59 +0000 | [diff] [blame] | 38 | import aQute.bnd.osgi.Processor; |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 39 | import aQute.lib.collections.ExtList; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 40 | import org.apache.maven.plugin.MojoExecutionException; |
Stuart McCulloch | 034a147 | 2008-07-07 09:38:32 +0000 | [diff] [blame] | 41 | import org.apache.maven.plugin.MojoFailureException; |
Carsten Ziegeler | 318c2cb | 2015-03-09 13:57:23 +0000 | [diff] [blame] | 42 | import org.apache.maven.plugins.annotations.LifecyclePhase; |
| 43 | import org.apache.maven.plugins.annotations.Mojo; |
| 44 | import org.apache.maven.plugins.annotations.Parameter; |
| 45 | import org.apache.maven.plugins.annotations.ResolutionScope; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 46 | import org.apache.maven.project.MavenProject; |
| 47 | |
Stuart McCulloch | 42151ee | 2012-07-16 13:43:38 +0000 | [diff] [blame] | 48 | import aQute.bnd.osgi.Analyzer; |
| 49 | import aQute.bnd.osgi.Builder; |
| 50 | import aQute.bnd.osgi.Jar; |
| 51 | import aQute.bnd.osgi.Resource; |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 52 | import org.apache.maven.shared.dependency.graph.DependencyNode; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 53 | |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 54 | |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 55 | /** |
| 56 | * Generate an OSGi manifest for this project |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 57 | */ |
Carsten Ziegeler | 0a4eff1 | 2015-05-12 06:04:41 +0000 | [diff] [blame] | 58 | @Mojo( name = "manifest", requiresDependencyResolution = ResolutionScope.TEST, |
| 59 | threadSafe = true, |
| 60 | defaultPhase = LifecyclePhase.PROCESS_CLASSES) |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 61 | public class ManifestPlugin extends BundlePlugin |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 62 | { |
Stuart McCulloch | 9811fea | 2011-11-28 15:35:44 +0000 | [diff] [blame] | 63 | /** |
Carsten Ziegeler | 82d8740 | 2015-03-04 13:26:21 +0000 | [diff] [blame] | 64 | * When true, generate the manifest by rebuilding the full bundle in memory |
Stuart McCulloch | 9811fea | 2011-11-28 15:35:44 +0000 | [diff] [blame] | 65 | */ |
Carsten Ziegeler | 318c2cb | 2015-03-09 13:57:23 +0000 | [diff] [blame] | 66 | @Parameter( property = "rebuildBundle" ) |
Stuart McCulloch | 9811fea | 2011-11-28 15:35:44 +0000 | [diff] [blame] | 67 | protected boolean rebuildBundle; |
| 68 | |
Guillaume Nodet | 88239df | 2015-07-09 19:45:59 +0000 | [diff] [blame] | 69 | /** |
| 70 | * Directory where the SCR files will be written |
| 71 | * |
| 72 | * @parameter expression="${scrLocation}" default-value="${project.build.outputDirectory}" |
| 73 | */ |
| 74 | protected File scrLocation; |
| 75 | |
| 76 | /** |
| 77 | * When true, dump the generated SCR files |
| 78 | * @parameter |
| 79 | */ |
| 80 | protected boolean exportScr; |
Stuart McCulloch | 9811fea | 2011-11-28 15:35:44 +0000 | [diff] [blame] | 81 | |
Stuart McCulloch | 8cefad5 | 2011-10-16 17:53:16 +0000 | [diff] [blame] | 82 | @Override |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 83 | protected void execute( MavenProject project, DependencyNode dependencyGraph, Map<String, String> instructions, Properties properties, Jar[] classpath ) |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 84 | throws MojoExecutionException |
| 85 | { |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 86 | Analyzer analyzer; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 87 | try |
| 88 | { |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 89 | analyzer = getAnalyzer(project, dependencyGraph, instructions, properties, classpath); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 90 | } |
Stuart McCulloch | 12b1d70 | 2007-09-11 07:48:10 +0000 | [diff] [blame] | 91 | catch ( FileNotFoundException e ) |
| 92 | { |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 93 | throw new MojoExecutionException( "Cannot find " + e.getMessage() |
| 94 | + " (manifest goal must be run after compile phase)", e ); |
Stuart McCulloch | 12b1d70 | 2007-09-11 07:48:10 +0000 | [diff] [blame] | 95 | } |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 96 | catch ( IOException e ) |
| 97 | { |
| 98 | throw new MojoExecutionException( "Error trying to generate Manifest", e ); |
| 99 | } |
Stuart McCulloch | 034a147 | 2008-07-07 09:38:32 +0000 | [diff] [blame] | 100 | catch ( MojoFailureException e ) |
| 101 | { |
| 102 | getLog().error( e.getLocalizedMessage() ); |
| 103 | throw new MojoExecutionException( "Error(s) found in manifest configuration", e ); |
| 104 | } |
Stuart McCulloch | a2f5759 | 2008-01-30 08:03:57 +0000 | [diff] [blame] | 105 | catch ( Exception e ) |
| 106 | { |
| 107 | getLog().error( "An internal error occurred", e ); |
| 108 | throw new MojoExecutionException( "Internal error in maven-bundle-plugin", e ); |
| 109 | } |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 110 | |
Stuart McCulloch | 9366a82 | 2008-01-29 07:45:57 +0000 | [diff] [blame] | 111 | File outputFile = new File( manifestLocation, "MANIFEST.MF" ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 112 | |
| 113 | try |
| 114 | { |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 115 | writeManifest( analyzer, outputFile, niceManifest ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 116 | } |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 117 | catch ( Exception e ) |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 118 | { |
| 119 | throw new MojoExecutionException( "Error trying to write Manifest to file " + outputFile, e ); |
| 120 | } |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 121 | finally |
| 122 | { |
| 123 | analyzer.close(); |
| 124 | } |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 125 | } |
| 126 | |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 127 | |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 128 | public Manifest getManifest( MavenProject project, DependencyNode dependencyGraph, Jar[] classpath ) throws IOException, MojoFailureException, |
Richard S. Hall | 2c9e592 | 2010-10-25 19:07:06 +0000 | [diff] [blame] | 129 | MojoExecutionException, Exception |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 130 | { |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 131 | return getManifest( project, dependencyGraph, new LinkedHashMap<String, String>(), new Properties(), classpath ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 132 | } |
| 133 | |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 134 | |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 135 | public Manifest getManifest( MavenProject project, DependencyNode dependencyGraph, Map<String, String> instructions, Properties properties, Jar[] classpath ) |
Richard S. Hall | 2c9e592 | 2010-10-25 19:07:06 +0000 | [diff] [blame] | 136 | throws IOException, MojoFailureException, MojoExecutionException, Exception |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 137 | { |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 138 | Analyzer analyzer = getAnalyzer(project, dependencyGraph, instructions, properties, classpath); |
Stuart McCulloch | 034a147 | 2008-07-07 09:38:32 +0000 | [diff] [blame] | 139 | |
Guillaume Nodet | 88239df | 2015-07-09 19:45:59 +0000 | [diff] [blame] | 140 | Jar jar = analyzer.getJar(); |
| 141 | Manifest manifest = jar.getManifest(); |
| 142 | |
| 143 | if (exportScr) |
| 144 | { |
| 145 | scrLocation.mkdirs(); |
| 146 | |
| 147 | String bpHeader = analyzer.getProperty(Analyzer.SERVICE_COMPONENT); |
| 148 | Parameters map = Processor.parseHeader(bpHeader, null); |
| 149 | for (String root : map.keySet()) |
| 150 | { |
| 151 | Map<String, Resource> dir = jar.getDirectories().get(root); |
| 152 | File location = new File(scrLocation, root); |
| 153 | if (dir == null || dir.isEmpty()) |
| 154 | { |
| 155 | Resource resource = jar.getResource(root); |
| 156 | if (resource != null) |
| 157 | { |
| 158 | writeSCR(resource, location); |
| 159 | } |
| 160 | } |
| 161 | else |
| 162 | { |
| 163 | for (Map.Entry<String, Resource> entry : dir.entrySet()) |
| 164 | { |
| 165 | String path = entry.getKey(); |
| 166 | Resource resource = entry.getValue(); |
| 167 | writeSCR(resource, new File(location, path)); |
| 168 | } |
| 169 | } |
| 170 | } |
| 171 | } |
Stuart McCulloch | d8a04c5 | 2008-08-06 16:05:23 +0000 | [diff] [blame] | 172 | |
| 173 | // cleanup... |
| 174 | analyzer.close(); |
| 175 | |
| 176 | return manifest; |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 177 | } |
| 178 | |
Guillaume Nodet | 88239df | 2015-07-09 19:45:59 +0000 | [diff] [blame] | 179 | protected void writeSCR(Resource resource, File destination) throws Exception |
| 180 | { |
| 181 | destination.getParentFile().mkdirs(); |
| 182 | OutputStream os = new FileOutputStream(destination); |
| 183 | try |
| 184 | { |
| 185 | resource.write(os); |
| 186 | } |
| 187 | finally |
| 188 | { |
| 189 | os.close(); |
| 190 | } |
| 191 | } |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 192 | |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 193 | protected Analyzer getAnalyzer( MavenProject project, DependencyNode dependencyGraph, Jar[] classpath ) throws IOException, MojoExecutionException, |
Stuart McCulloch | d98b02e | 2011-06-28 23:20:37 +0000 | [diff] [blame] | 194 | Exception |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 195 | { |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 196 | return getAnalyzer( project, dependencyGraph, new LinkedHashMap<String, String>(), new Properties(), classpath ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 197 | } |
| 198 | |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 199 | |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 200 | protected Analyzer getAnalyzer( MavenProject project, DependencyNode dependencyGraph, Map<String, String> instructions, Properties properties, Jar[] classpath ) |
Richard S. Hall | 2c9e592 | 2010-10-25 19:07:06 +0000 | [diff] [blame] | 201 | throws IOException, MojoExecutionException, Exception |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 202 | { |
Stuart McCulloch | 9811fea | 2011-11-28 15:35:44 +0000 | [diff] [blame] | 203 | if ( rebuildBundle && supportedProjectTypes.contains( project.getArtifact().getType() ) ) |
Stuart McCulloch | 8cefad5 | 2011-10-16 17:53:16 +0000 | [diff] [blame] | 204 | { |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 205 | return buildOSGiBundle( project, dependencyGraph, instructions, properties, classpath ); |
Stuart McCulloch | 8cefad5 | 2011-10-16 17:53:16 +0000 | [diff] [blame] | 206 | } |
| 207 | |
Guillaume Nodet | 09194e6 | 2014-06-16 07:07:12 +0000 | [diff] [blame] | 208 | File file = getOutputDirectory(); |
Karl Pauls | e816f1e | 2007-07-13 13:31:25 +0000 | [diff] [blame] | 209 | if ( file == null ) |
Richard S. Hall | 47a1816 | 2007-07-05 19:02:51 +0000 | [diff] [blame] | 210 | { |
Guillaume Nodet | 09194e6 | 2014-06-16 07:07:12 +0000 | [diff] [blame] | 211 | file = project.getArtifact().getFile(); |
Richard S. Hall | 47a1816 | 2007-07-05 19:02:51 +0000 | [diff] [blame] | 212 | } |
Stuart McCulloch | 12b1d70 | 2007-09-11 07:48:10 +0000 | [diff] [blame] | 213 | |
| 214 | if ( !file.exists() ) |
Karl Pauls | 9eb6255 | 2007-07-11 14:58:35 +0000 | [diff] [blame] | 215 | { |
Stuart McCulloch | 2ae5d3d | 2012-07-26 17:49:28 +0000 | [diff] [blame] | 216 | if ( file.equals( getOutputDirectory() ) ) |
| 217 | { |
| 218 | file.mkdirs(); |
| 219 | } |
| 220 | else |
| 221 | { |
| 222 | throw new FileNotFoundException( file.getPath() ); |
| 223 | } |
Karl Pauls | 9eb6255 | 2007-07-11 14:58:35 +0000 | [diff] [blame] | 224 | } |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 225 | |
Stuart McCulloch | 5fcbe4a | 2011-06-28 18:26:45 +0000 | [diff] [blame] | 226 | Builder analyzer = getOSGiBuilder( project, instructions, properties, classpath ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 227 | |
Stuart McCulloch | 62cf56b | 2008-07-07 13:04:51 +0000 | [diff] [blame] | 228 | analyzer.setJar( file ); |
| 229 | |
Stuart McCulloch | 07025e1 | 2012-02-11 17:28:48 +0000 | [diff] [blame] | 230 | // calculateExportsFromContents when we have no explicit instructions defining |
| 231 | // the contents of the bundle *and* we are not analyzing the output directory, |
| 232 | // otherwise fall-back to addMavenInstructions approach |
| 233 | |
Stuart McCulloch | 417fe90 | 2012-02-11 18:31:45 +0000 | [diff] [blame] | 234 | boolean isOutputDirectory = file.equals( getOutputDirectory() ); |
| 235 | |
Stuart McCulloch | d98b02e | 2011-06-28 23:20:37 +0000 | [diff] [blame] | 236 | if ( analyzer.getProperty( Analyzer.EXPORT_PACKAGE ) == null |
| 237 | && analyzer.getProperty( Analyzer.EXPORT_CONTENTS ) == null |
Stuart McCulloch | 417fe90 | 2012-02-11 18:31:45 +0000 | [diff] [blame] | 238 | && analyzer.getProperty( Analyzer.PRIVATE_PACKAGE ) == null && !isOutputDirectory ) |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 239 | { |
Stuart McCulloch | 07025e1 | 2012-02-11 17:28:48 +0000 | [diff] [blame] | 240 | String export = calculateExportsFromContents( analyzer.getJar() ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 241 | analyzer.setProperty( Analyzer.EXPORT_PACKAGE, export ); |
| 242 | } |
| 243 | |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 244 | addMavenInstructions( project, dependencyGraph, analyzer ); |
Stuart McCulloch | 598d2bd | 2009-09-02 22:06:58 +0000 | [diff] [blame] | 245 | |
Stuart McCulloch | 417fe90 | 2012-02-11 18:31:45 +0000 | [diff] [blame] | 246 | // if we spot Embed-Dependency and the bundle is "target/classes", assume we need to rebuild |
| 247 | if ( analyzer.getProperty( DependencyEmbedder.EMBED_DEPENDENCY ) != null && isOutputDirectory ) |
| 248 | { |
| 249 | analyzer.build(); |
| 250 | } |
| 251 | else |
| 252 | { |
| 253 | analyzer.mergeManifest( analyzer.getJar().getManifest() ); |
Stuart McCulloch | 2ae5d3d | 2012-07-26 17:49:28 +0000 | [diff] [blame] | 254 | analyzer.getJar().setManifest( analyzer.calcManifest() ); |
Stuart McCulloch | 417fe90 | 2012-02-11 18:31:45 +0000 | [diff] [blame] | 255 | } |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 256 | |
Guillaume Nodet | ed7b110 | 2015-07-09 19:45:09 +0000 | [diff] [blame] | 257 | mergeMavenManifest( project, dependencyGraph, analyzer ); |
Stuart McCulloch | 598d2bd | 2009-09-02 22:06:58 +0000 | [diff] [blame] | 258 | |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 259 | boolean hasErrors = reportErrors( "Manifest " + project.getArtifact(), analyzer ); |
| 260 | if ( hasErrors ) |
| 261 | { |
| 262 | String failok = analyzer.getProperty( "-failok" ); |
| 263 | if ( null == failok || "false".equalsIgnoreCase( failok ) ) |
| 264 | { |
| 265 | throw new MojoFailureException( "Error(s) found in manifest configuration" ); |
| 266 | } |
| 267 | } |
| 268 | |
| 269 | Jar jar = analyzer.getJar(); |
| 270 | |
| 271 | if ( unpackBundle ) |
| 272 | { |
| 273 | File outputFile = getOutputDirectory(); |
| 274 | for ( Entry<String, Resource> entry : jar.getResources().entrySet() ) |
| 275 | { |
| 276 | File entryFile = new File( outputFile, entry.getKey() ); |
| 277 | if ( !entryFile.exists() || entry.getValue().lastModified() == 0 ) |
| 278 | { |
| 279 | entryFile.getParentFile().mkdirs(); |
| 280 | OutputStream os = new FileOutputStream( entryFile ); |
| 281 | entry.getValue().write( os ); |
| 282 | os.close(); |
| 283 | } |
| 284 | } |
| 285 | } |
| 286 | |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 287 | return analyzer; |
| 288 | } |
| 289 | |
Stuart McCulloch | 5ae5914 | 2008-01-29 06:21:05 +0000 | [diff] [blame] | 290 | |
Guillaume Nodet | dfe0fe7 | 2015-07-09 19:45:35 +0000 | [diff] [blame] | 291 | public static void writeManifest( Analyzer analyzer, File outputFile, boolean niceManifest ) throws Exception |
| 292 | { |
| 293 | Properties properties = analyzer.getProperties(); |
| 294 | Manifest manifest = analyzer.getJar().getManifest(); |
| 295 | if ( outputFile.exists() && properties.containsKey( "Merge-Headers" ) ) |
| 296 | { |
| 297 | Manifest analyzerManifest = manifest; |
| 298 | manifest = new Manifest(); |
| 299 | InputStream inputStream = new FileInputStream( outputFile ); |
| 300 | try |
| 301 | { |
| 302 | manifest.read( inputStream ); |
| 303 | } |
| 304 | finally |
| 305 | { |
| 306 | inputStream.close(); |
| 307 | } |
| 308 | Instructions instructions = new Instructions( ExtList.from( analyzer.getProperty("Merge-Headers") ) ); |
| 309 | mergeManifest( instructions, manifest, analyzerManifest ); |
| 310 | } |
| 311 | else |
| 312 | { |
| 313 | File parentFile = outputFile.getParentFile(); |
| 314 | parentFile.mkdirs(); |
| 315 | } |
| 316 | writeManifest( manifest, outputFile, niceManifest ); |
| 317 | } |
| 318 | |
| 319 | |
Stuart McCulloch | 9a710e5 | 2014-06-23 12:01:53 +0000 | [diff] [blame] | 320 | public static void writeManifest( Manifest manifest, File outputFile, boolean niceManifest ) throws IOException |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 321 | { |
| 322 | outputFile.getParentFile().mkdirs(); |
| 323 | |
| 324 | FileOutputStream os; |
| 325 | os = new FileOutputStream( outputFile ); |
| 326 | try |
| 327 | { |
Stuart McCulloch | 9a710e5 | 2014-06-23 12:01:53 +0000 | [diff] [blame] | 328 | ManifestWriter.outputManifest( manifest, os, niceManifest ); |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 329 | } |
| 330 | finally |
| 331 | { |
Stuart McCulloch | f806f86 | 2008-02-04 07:57:09 +0000 | [diff] [blame] | 332 | try |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 333 | { |
Stuart McCulloch | f806f86 | 2008-02-04 07:57:09 +0000 | [diff] [blame] | 334 | os.close(); |
| 335 | } |
| 336 | catch ( IOException e ) |
| 337 | { |
| 338 | // nothing we can do here |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 339 | } |
| 340 | } |
| 341 | } |
Stuart McCulloch | 07025e1 | 2012-02-11 17:28:48 +0000 | [diff] [blame] | 342 | |
| 343 | |
| 344 | /* |
| 345 | * Patched version of bnd's Analyzer.calculateExportsFromContents |
| 346 | */ |
| 347 | public static String calculateExportsFromContents( Jar bundle ) |
| 348 | { |
| 349 | String ddel = ""; |
| 350 | StringBuffer sb = new StringBuffer(); |
| 351 | Map<String, Map<String, Resource>> map = bundle.getDirectories(); |
| 352 | for ( Iterator<Entry<String, Map<String, Resource>>> i = map.entrySet().iterator(); i.hasNext(); ) |
| 353 | { |
| 354 | //---------------------------------------------------- |
| 355 | // should also ignore directories with no resources |
| 356 | //---------------------------------------------------- |
| 357 | Entry<String, Map<String, Resource>> entry = i.next(); |
| 358 | if ( entry.getValue() == null || entry.getValue().isEmpty() ) |
| 359 | continue; |
| 360 | //---------------------------------------------------- |
| 361 | String directory = entry.getKey(); |
| 362 | if ( directory.equals( "META-INF" ) || directory.startsWith( "META-INF/" ) ) |
| 363 | continue; |
| 364 | if ( directory.equals( "OSGI-OPT" ) || directory.startsWith( "OSGI-OPT/" ) ) |
| 365 | continue; |
| 366 | if ( directory.equals( "/" ) ) |
| 367 | continue; |
| 368 | |
| 369 | if ( directory.endsWith( "/" ) ) |
| 370 | directory = directory.substring( 0, directory.length() - 1 ); |
| 371 | |
| 372 | directory = directory.replace( '/', '.' ); |
| 373 | sb.append( ddel ); |
| 374 | sb.append( directory ); |
| 375 | ddel = ","; |
| 376 | } |
| 377 | return sb.toString(); |
| 378 | } |
Richard S. Hall | 6cf6f0b | 2007-04-10 16:50:31 +0000 | [diff] [blame] | 379 | } |