]> git.argeo.org Git - gpl/argeo-slc.git/blob - maven-argeo-osgi-plugin/src/main/java/org/argeo/slc/maven/plugins/osgi/AbstractBundlesPackagerMojo.java
ee3cd28a3168dd259ca02586c04a4c4ccf32b838
[gpl/argeo-slc.git] / maven-argeo-osgi-plugin / src / main / java / org / argeo / slc / maven / plugins / osgi / AbstractBundlesPackagerMojo.java
1 package org.argeo.slc.maven.plugins.osgi;
2
3 import java.io.File;
4 import java.io.FileFilter;
5 import java.io.FileInputStream;
6 import java.io.FileWriter;
7 import java.io.IOException;
8 import java.text.SimpleDateFormat;
9 import java.util.ArrayList;
10 import java.util.Date;
11 import java.util.List;
12 import java.util.jar.Attributes;
13 import java.util.jar.Manifest;
14
15 import org.apache.commons.io.FileUtils;
16 import org.apache.commons.io.IOUtils;
17 import org.apache.maven.artifact.Artifact;
18 import org.apache.maven.artifact.metadata.ArtifactMetadata;
19 import org.apache.maven.model.Model;
20 import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
21 import org.apache.maven.plugin.MojoExecutionException;
22 import org.apache.maven.project.MavenProject;
23 import org.apache.maven.project.artifact.ProjectArtifactMetadata;
24
25 /**
26 * @author mbaudier
27 *
28 */
29 public abstract class AbstractBundlesPackagerMojo extends AbstractOsgiMojo {
30
31 /**
32 * Directory of the simple bundles
33 *
34 * @parameter expression="${bundlesDirectory}" default-value="."
35 * @required
36 */
37 private File bundlesDirectory;
38
39 /**
40 * Directory containing the packaged bundles.
41 *
42 * @parameter expression="${packagedBundlesDir}"
43 * default-value="${project.build.directory}/argeo-osgi"
44 * @required
45 */
46 protected File packagedBundlesDir;
47
48 /**
49 * Artifact id for the dependency pom
50 *
51 * @parameter expression="${bundlesPomArtifactId}" default-value="bundles"
52 * @required
53 */
54 protected String bundlesPomArtifactId;
55
56 /**
57 * Whether should fail if MANIFEST version are not in line with pom version.
58 *
59 * @parameter expression="${strictManifestVersion}" default-value="false"
60 * @required
61 */
62 protected boolean strictManifestVersion;
63
64 /**
65 * Whether the manifest should be updated with the release version.
66 *
67 * @parameter expression="${updateManifestWhenReleasing}"
68 * default-value="true"
69 * @required
70 */
71 protected boolean updateManifestWhenReleasing;
72
73 /**
74 * Whether should fail if symbolic name does not match artifact id.
75 *
76 * @parameter expression="${strictSymbolicName}" default-value="false"
77 * @required
78 */
79 protected boolean strictSymbolicName;
80
81 private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
82
83 protected List analyze(boolean willGenerate) throws MojoExecutionException {
84 List list = new ArrayList();
85
86 File[] bundleDirs = bundlesDirectory.listFiles(new FileFilter() {
87 public boolean accept(File file) {
88 if (!file.isDirectory())
89 return false;
90
91 return manifestFileFromDir(file).exists();
92 }
93 });
94 for (int i = 0; i < bundleDirs.length; i++) {
95
96 File dir = bundleDirs[i];
97 BundlePackage bundlePackage;
98 try {
99 bundlePackage = processBundleDir(dir, willGenerate);
100 } catch (Exception e) {
101 throw new MojoExecutionException("Could not analyze " + dir, e);
102 }
103 list.add(bundlePackage);
104
105 }
106 return list;
107 }
108
109 protected BundlePackage processBundleDir(File dir, boolean willGenerate)
110 throws Exception {
111 File manifestFile = manifestFileFromDir(dir);
112 String artifactId = dir.getName();
113 File destFile = new File(packagedBundlesDir.getPath() + File.separator
114 + artifactId + ".jar");
115
116 String manifestStr = FileUtils.readFileToString(manifestFile);
117 char lastChar = manifestStr.charAt(manifestStr.length() - 1);
118 if (lastChar != '\n')
119 throw new RuntimeException("Manifest " + manifestFile
120 + " is not valid,"
121 + " it does not end with and endline character.");
122
123 Manifest manifest = readManifest(manifestFile);
124 // Symbolic name
125 String symbolicNameMf = manifest.getMainAttributes().getValue(
126 "Bundle-SymbolicName");
127 if (!artifactId.equals(symbolicNameMf)) {
128 String msg = "Symbolic name " + symbolicNameMf
129 + " does not match with directory name " + artifactId;
130 if (strictSymbolicName)
131 throw new RuntimeException(msg);
132 else
133 getLog().warn(msg);
134 }
135
136 // Version
137 String versionMf = manifest.getMainAttributes().getValue(
138 "Bundle-Version");
139 int qIndex = versionMf.lastIndexOf(".SNAPSHOT");
140 String versionMfMain;
141 if (qIndex >= 0)
142 versionMfMain = versionMf.substring(0, qIndex);
143 else
144 versionMfMain = versionMf;
145
146 int sIndex = project.getModel().getVersion().lastIndexOf("-SNAPSHOT");
147 String versionMain;
148 String buildId;
149 boolean isSnapshot = false;
150 if (sIndex >= 0) {// SNAPSHOT
151 versionMain = project.getVersion().substring(0, sIndex);
152 // buildId = "D_" + sdf.format(new Date());// D for dev
153 buildId = "SNAPSHOT";
154 isSnapshot = true;
155 } else {
156 versionMain = project.getVersion();
157 // buildId = "R_" + sdf.format(new Date());// R for release
158 buildId = "R" + sdf.format(new Date());
159 }
160
161 if (!versionMain.equals(versionMfMain)) {
162 String msg = "Main manifest version " + versionMfMain
163 + " of bundle " + artifactId
164 + " do not match with main project version " + versionMain;
165 if (strictManifestVersion)
166 throw new RuntimeException(msg);
167 else
168 getLog().warn(msg);
169 }
170
171 String newVersionMf = versionMfMain + "." + buildId;
172 String newVersionArt;
173 if (isSnapshot) {
174 newVersionArt = versionMfMain + "-SNAPSHOT";
175 } else {
176 newVersionArt = versionMfMain;
177 }
178
179 // boolean debug = true;
180 boolean debug = getLog().isDebugEnabled();
181 if (debug && willGenerate) {
182 getLog().info("\n## " + artifactId);
183 getLog().info("project.getVersion()=" + project.getVersion());
184 // getLog().info(
185 // "project.getModel().getVersion()="
186 // + project.getModel().getVersion());
187 // getLog().info("versionMf=" + versionMf);
188 // getLog().info("buildId=" + buildId);
189 getLog().info("newVersionMf=" + newVersionMf);
190 }
191
192 manifest.getMainAttributes().putValue("Bundle-Version", newVersionMf);
193 manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION,
194 "1.0");
195
196 Artifact artifact = artifactFactory.createBuildArtifact(project
197 .getGroupId(), artifactId, newVersionArt, "jar");
198 return new BundlePackage(artifact, dir, new Manifest(manifest),
199 destFile);
200 }
201
202 protected File manifestFileFromDir(File dir) {
203 return new File(dir + File.separator + "META-INF" + File.separator
204 + "MANIFEST.MF");
205 }
206
207 protected File bundlesPomFile() {
208 return new File(packagedBundlesDir + File.separator + "bundles.pom");
209 }
210
211 protected Artifact bundlesPomArtifact() {
212 return artifactFactory.createBuildArtifact(project.getGroupId(),
213 bundlesPomArtifactId, project.getVersion(), "pom");
214 }
215
216 protected StringBuffer createPomFileHeader(String parentGroupId,
217 String parentArtifactId, String parentBaseVersion, String groupId,
218 String artifactId, String packaging) {
219 StringBuffer pom = new StringBuffer();
220 // not using append() systematically for the sake of clarity
221 pom.append("<project>\n");
222 pom.append("\t<modelVersion>4.0.0</modelVersion>\n");
223 pom.append("\t<parent>\n");
224 pom.append("\t\t<groupId>" + parentGroupId + "</groupId>\n");
225 pom.append("\t\t<artifactId>" + parentArtifactId + "</artifactId>\n");
226 pom.append("\t\t<version>" + parentBaseVersion + "</version>\n");
227 pom.append("\t</parent>\n");
228 pom.append("\t<groupId>" + groupId + "</groupId>\n");
229 pom.append("\t<artifactId>" + artifactId + "</artifactId>\n");
230 pom.append("\t<packaging>" + packaging + "</packaging>\n");
231 return pom;
232
233 // TODO: use the Model object e.g.: (from install plugin)
234 // Model model = new Model();
235 // model.setModelVersion( "4.0.0" );
236 // model.setGroupId( groupId );
237 // model.setArtifactId( artifactId );
238 // model.setVersion( version );
239 // model.setPackaging( packaging );
240 // model.setDescription( "POM was created from install:install-file" );
241 // fw = new FileWriter( tempFile );
242 // tempFile.deleteOnExit();
243 // new MavenXpp3Writer().write( fw, model );
244 // ArtifactMetadata metadata = new ProjectArtifactMetadata( artifact,
245 // tempFile );
246 // artifact.addMetadata( metadata );
247
248 }
249
250 /** Simple close the project tag */
251 protected String closePomFile(StringBuffer pom) {
252 pom.append("</project>\n");
253 return pom.toString();
254 }
255
256 protected static class BundlePackage {
257 private final Artifact artifact;
258 private final File bundleDir;
259 private final Manifest manifest;
260 private final File packageFile;
261
262 public BundlePackage(Artifact artifact, File bundleDir,
263 Manifest manifest, File packageFile) {
264 super();
265 this.artifact = artifact;
266 this.bundleDir = bundleDir;
267 this.manifest = manifest;
268 this.packageFile = packageFile;
269 }
270
271 public Artifact getArtifact() {
272 return artifact;
273 }
274
275 public File getPackageFile() {
276 return packageFile;
277 }
278
279 public File getBundleDir() {
280 return bundleDir;
281 }
282
283 public Manifest getManifest() {
284 return manifest;
285 }
286
287 public File getManifestFile() {
288 return new File(getPackageFile().getPath() + ".MF");
289 }
290
291 public File getPomFile() {
292 return new File(getPackageFile().getPath() + ".pom.xml");
293 }
294 }
295
296 protected Manifest readManifest(File file) throws IOException {
297 Manifest manifest = new Manifest();
298 FileInputStream in = new FileInputStream(file);
299 manifest.read(in);
300 in.close();
301 return manifest;
302 }
303 }