Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 1 | package aQute.bnd.maven; |
| 2 | |
| 3 | import java.io.*; |
| 4 | import java.net.*; |
| 5 | import java.util.*; |
| 6 | import java.util.Map.Entry; |
| 7 | import java.util.concurrent.*; |
| 8 | import java.util.jar.*; |
| 9 | import java.util.regex.*; |
| 10 | |
Stuart McCulloch | 39cc9ac | 2012-07-16 13:43:38 +0000 | [diff] [blame] | 11 | import aQute.bnd.header.*; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 12 | import aQute.bnd.maven.support.*; |
| 13 | import aQute.bnd.maven.support.Pom.Scope; |
Stuart McCulloch | 39cc9ac | 2012-07-16 13:43:38 +0000 | [diff] [blame] | 14 | import aQute.bnd.osgi.*; |
| 15 | import aQute.bnd.osgi.Descriptors.PackageRef; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 16 | import aQute.lib.collections.*; |
| 17 | import aQute.lib.io.*; |
Stuart McCulloch | b215bfd | 2012-09-06 18:28:06 +0000 | [diff] [blame] | 18 | import aQute.lib.settings.*; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 19 | import aQute.libg.command.*; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 20 | |
| 21 | public class MavenCommand extends Processor { |
| 22 | final Settings settings = new Settings(); |
| 23 | File temp; |
| 24 | |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 25 | public MavenCommand() {} |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 26 | |
| 27 | public MavenCommand(Processor p) { |
| 28 | super(p); |
| 29 | } |
| 30 | |
| 31 | /** |
| 32 | * maven deploy [-url repo] [-passphrase passphrase] [-homedir homedir] |
| 33 | * [-keyname keyname] bundle ... |
| 34 | * |
| 35 | * @param args |
| 36 | * @param i |
| 37 | * @throws Exception |
| 38 | */ |
| 39 | public void run(String args[], int i) throws Exception { |
| 40 | temp = new File("maven-bundle"); |
| 41 | |
| 42 | if (i >= args.length) { |
| 43 | help(); |
| 44 | return; |
| 45 | } |
| 46 | |
| 47 | while (i < args.length && args[i].startsWith("-")) { |
| 48 | String option = args[i]; |
| 49 | trace("option " + option); |
| 50 | if (option.equals("-temp")) |
| 51 | temp = getFile(args[++i]); |
| 52 | else { |
| 53 | help(); |
| 54 | error("Invalid option " + option); |
| 55 | } |
| 56 | i++; |
| 57 | } |
| 58 | |
| 59 | String cmd = args[i++]; |
| 60 | |
| 61 | trace("temp dir " + temp); |
| 62 | IO.delete(temp); |
Stuart McCulloch | 55d4dfe | 2012-08-07 10:57:21 +0000 | [diff] [blame] | 63 | if (!temp.exists() && !temp.mkdirs()) { |
| 64 | throw new IOException("Could not create directory " + temp); |
| 65 | } |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 66 | if (!temp.isDirectory()) |
| 67 | throw new IOException("Cannot create temp directory"); |
| 68 | |
| 69 | if (cmd.equals("settings")) |
| 70 | settings(); |
| 71 | else if (cmd.equals("help")) |
| 72 | help(); |
| 73 | else if (cmd.equals("bundle")) |
| 74 | bundle(args, i); |
| 75 | else if (cmd.equals("view")) |
| 76 | view(args, i); |
| 77 | else |
| 78 | error("No such command %s, type help", cmd); |
| 79 | } |
| 80 | |
| 81 | private void help() { |
Stuart McCulloch | 7adbc95 | 2012-07-12 22:12:58 +0000 | [diff] [blame] | 82 | System.err.printf("Usage:%n"); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 83 | System.err |
Stuart McCulloch | 7adbc95 | 2012-07-12 22:12:58 +0000 | [diff] [blame] | 84 | .printf(" maven %n" // |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 85 | + " [-temp <dir>] use as temp directory%n" // |
| 86 | + " settings show maven settings%n" // |
| 87 | + " bundle turn a bundle into a maven bundle%n" // |
| 88 | + " [-properties <file>] provide properties, properties starting with javadoc are options for javadoc, like javadoc-tag=...%n" |
| 89 | + " [-javadoc <file|url>] where to find the javadoc (zip/dir), otherwise generated%n" // |
| 90 | + " [-source <file|url>] where to find the source (zip/dir), otherwise from OSGI-OPT/src%n" // |
| 91 | + " [-scm <url>] required scm in pom, otherwise from Bundle-SCM%n" // |
| 92 | + " [-url <url>] required project url in pom%n" // |
| 93 | + " [-bsn bsn] overrides bsn%n" // |
| 94 | + " [-version <version>] overrides version%n" // |
| 95 | + " [-developer <email>] developer email%n" // |
| 96 | + " [-nodelete] do not delete temp files%n" // |
| 97 | + " [-passphrase <gpgp passphrase>] signer password%n"// |
Stuart McCulloch | 7adbc95 | 2012-07-12 22:12:58 +0000 | [diff] [blame] | 98 | + " <file|url>%n"); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 99 | } |
| 100 | |
| 101 | /** |
| 102 | * Show the maven settings |
| 103 | * |
| 104 | * @throws FileNotFoundException |
| 105 | * @throws Exception |
| 106 | */ |
| 107 | private void settings() throws FileNotFoundException, Exception { |
| 108 | File userHome = new File(System.getProperty("user.home")); |
| 109 | File m2 = new File(userHome, ".m2"); |
| 110 | if (!m2.isDirectory()) { |
| 111 | error("There is no m2 directory at %s", userHome); |
| 112 | return; |
| 113 | } |
| 114 | File settings = new File(m2, "settings.xml"); |
| 115 | if (!settings.isFile()) { |
| 116 | error("There is no settings file at '%s'", settings.getAbsolutePath()); |
| 117 | return; |
| 118 | } |
| 119 | LineCollection lc = new LineCollection(IO.reader(settings)); |
| 120 | while (lc.hasNext()) { |
| 121 | System.err.println(lc.next()); |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | /** |
| 126 | * Create a maven bundle. |
| 127 | * |
| 128 | * @param args |
| 129 | * @param i |
| 130 | * @throws Exception |
| 131 | */ |
| 132 | private void bundle(String args[], int i) throws Exception { |
| 133 | List<String> developers = new ArrayList<String>(); |
| 134 | Properties properties = new Properties(); |
| 135 | |
| 136 | String scm = null; |
| 137 | String passphrase = null; |
| 138 | String javadoc = null; |
| 139 | String source = null; |
| 140 | String output = "bundle.jar"; |
| 141 | String url = null; |
| 142 | String artifact = null; |
| 143 | String group = null; |
| 144 | String version = null; |
| 145 | boolean nodelete = false; |
| 146 | |
| 147 | while (i < args.length && args[i].startsWith("-")) { |
| 148 | String option = args[i++]; |
| 149 | trace("bundle option %s", option); |
| 150 | if (option.equals("-scm")) |
| 151 | scm = args[i++]; |
| 152 | else if (option.equals("-group")) |
| 153 | group = args[i++]; |
| 154 | else if (option.equals("-artifact")) |
| 155 | artifact = args[i++]; |
| 156 | else if (option.equals("-version")) |
| 157 | version = args[i++]; |
| 158 | else if (option.equals("-developer")) |
| 159 | developers.add(args[i++]); |
| 160 | else if (option.equals("-passphrase")) { |
| 161 | passphrase = args[i++]; |
| 162 | } else if (option.equals("-url")) { |
| 163 | url = args[i++]; |
| 164 | } else if (option.equals("-javadoc")) |
| 165 | javadoc = args[i++]; |
| 166 | else if (option.equals("-source")) |
| 167 | source = args[i++]; |
| 168 | else if (option.equals("-output")) |
| 169 | output = args[i++]; |
| 170 | else if (option.equals("-nodelete")) |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 171 | nodelete = true; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 172 | else if (option.startsWith("-properties")) { |
| 173 | InputStream in = null; |
| 174 | try { |
| 175 | in = new FileInputStream(args[i++]); |
| 176 | properties.load(in); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 177 | } |
| 178 | catch (Exception e) {} |
| 179 | finally { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 180 | if (in != null) { |
| 181 | in.close(); |
| 182 | } |
| 183 | } |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | if (developers.isEmpty()) { |
Stuart McCulloch | b215bfd | 2012-09-06 18:28:06 +0000 | [diff] [blame] | 188 | String email = settings.remove("email"); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 189 | if (email == null) |
| 190 | error("No developer email set, you can set global default email with: bnd global email Peter.Kriens@aQute.biz"); |
| 191 | else |
| 192 | developers.add(email); |
| 193 | } |
| 194 | |
| 195 | if (i == args.length) { |
| 196 | error("too few arguments, no bundle specified"); |
| 197 | return; |
| 198 | } |
| 199 | |
| 200 | if (i != args.length - 1) { |
| 201 | error("too many arguments, only one bundle allowed"); |
| 202 | return; |
| 203 | } |
| 204 | |
| 205 | String input = args[i++]; |
| 206 | |
| 207 | Jar binaryJar = getJarFromFileOrURL(input); |
| 208 | trace("got %s", binaryJar); |
| 209 | if (binaryJar == null) { |
| 210 | error("JAR does not exist: %s", input); |
| 211 | return; |
| 212 | } |
| 213 | |
| 214 | File original = getFile(temp, "original"); |
Stuart McCulloch | 55d4dfe | 2012-08-07 10:57:21 +0000 | [diff] [blame] | 215 | if (!original.exists() && !original.mkdirs()) { |
| 216 | throw new IOException("Could not create directory " + original); |
| 217 | } |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 218 | binaryJar.expand(original); |
| 219 | binaryJar.calcChecksums(null); |
| 220 | |
| 221 | Manifest manifest = binaryJar.getManifest(); |
| 222 | trace("got manifest"); |
| 223 | |
| 224 | PomFromManifest pom = new PomFromManifest(manifest); |
| 225 | |
| 226 | if (scm != null) |
| 227 | pom.setSCM(scm); |
| 228 | if (url != null) |
| 229 | pom.setURL(url); |
| 230 | if (artifact != null) |
| 231 | pom.setArtifact(artifact); |
| 232 | if (artifact != null) |
| 233 | pom.setGroup(group); |
| 234 | if (version != null) |
| 235 | pom.setVersion(version); |
| 236 | trace(url); |
| 237 | for (String d : developers) |
| 238 | pom.addDeveloper(d); |
| 239 | |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 240 | Set<String> exports = OSGiHeader.parseHeader(manifest.getMainAttributes().getValue(Constants.EXPORT_PACKAGE)) |
| 241 | .keySet(); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 242 | |
| 243 | Jar sourceJar; |
| 244 | if (source == null) { |
| 245 | trace("Splitting source code"); |
| 246 | sourceJar = new Jar("source"); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 247 | for (Map.Entry<String,Resource> entry : binaryJar.getResources().entrySet()) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 248 | if (entry.getKey().startsWith("OSGI-OPT/src")) { |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 249 | sourceJar.putResource(entry.getKey().substring("OSGI-OPT/src/".length()), entry.getValue()); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 250 | } |
| 251 | } |
| 252 | copyInfo(binaryJar, sourceJar, "source"); |
| 253 | } else { |
| 254 | sourceJar = getJarFromFileOrURL(source); |
| 255 | } |
| 256 | sourceJar.calcChecksums(null); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 257 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 258 | Jar javadocJar; |
| 259 | if (javadoc == null) { |
| 260 | trace("creating javadoc because -javadoc not used"); |
| 261 | javadocJar = javadoc(getFile(original, "OSGI-OPT/src"), exports, manifest, properties); |
| 262 | if (javadocJar == null) { |
| 263 | error("Cannot find source code in OSGI-OPT/src to generate Javadoc"); |
| 264 | return; |
| 265 | } |
| 266 | copyInfo(binaryJar, javadocJar, "javadoc"); |
| 267 | } else { |
| 268 | trace("Loading javadoc externally %s", javadoc); |
| 269 | javadocJar = getJarFromFileOrURL(javadoc); |
| 270 | } |
| 271 | javadocJar.calcChecksums(null); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 272 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 273 | addClose(binaryJar); |
| 274 | addClose(sourceJar); |
| 275 | addClose(javadocJar); |
| 276 | |
| 277 | trace("creating bundle dir"); |
| 278 | File bundle = new File(temp, "bundle"); |
Stuart McCulloch | 55d4dfe | 2012-08-07 10:57:21 +0000 | [diff] [blame] | 279 | if (!bundle.exists() && !bundle.mkdirs()) { |
| 280 | throw new IOException("Could not create directory " + bundle); |
| 281 | } |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 282 | |
| 283 | String prefix = pom.getArtifactId() + "-" + pom.getVersion(); |
| 284 | File binaryFile = new File(bundle, prefix + ".jar"); |
| 285 | File sourceFile = new File(bundle, prefix + "-sources.jar"); |
| 286 | File javadocFile = new File(bundle, prefix + "-javadoc.jar"); |
| 287 | File pomFile = new File(bundle, "pom.xml").getAbsoluteFile(); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 288 | trace("creating output files %s, %s,%s, and %s", binaryFile, sourceFile, javadocFile, pomFile); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 289 | |
| 290 | IO.copy(pom.openInputStream(), pomFile); |
| 291 | trace("copied pom"); |
| 292 | |
| 293 | trace("writing binary %s", binaryFile); |
| 294 | binaryJar.write(binaryFile); |
| 295 | |
| 296 | trace("writing source %s", sourceFile); |
| 297 | sourceJar.write(sourceFile); |
| 298 | |
| 299 | trace("writing javadoc %s", javadocFile); |
| 300 | javadocJar.write(javadocFile); |
| 301 | |
| 302 | sign(binaryFile, passphrase); |
| 303 | sign(sourceFile, passphrase); |
| 304 | sign(javadocFile, passphrase); |
| 305 | sign(pomFile, passphrase); |
| 306 | |
| 307 | trace("create bundle"); |
| 308 | Jar bundleJar = new Jar(bundle); |
| 309 | addClose(bundleJar); |
| 310 | File outputFile = getFile(output); |
| 311 | bundleJar.write(outputFile); |
| 312 | trace("created bundle %s", outputFile); |
| 313 | |
| 314 | binaryJar.close(); |
| 315 | sourceJar.close(); |
| 316 | javadocJar.close(); |
| 317 | bundleJar.close(); |
| 318 | if (!nodelete) |
| 319 | IO.delete(temp); |
| 320 | } |
| 321 | |
| 322 | private void copyInfo(Jar source, Jar dest, String type) throws Exception { |
| 323 | source.ensureManifest(); |
| 324 | dest.ensureManifest(); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 325 | copyInfoResource(source, dest, "LICENSE"); |
| 326 | copyInfoResource(source, dest, "LICENSE.html"); |
| 327 | copyInfoResource(source, dest, "about.html"); |
| 328 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 329 | Manifest sm = source.getManifest(); |
| 330 | Manifest dm = dest.getManifest(); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 331 | copyInfoHeader(sm, dm, "Bundle-Description", ""); |
| 332 | copyInfoHeader(sm, dm, "Bundle-Vendor", ""); |
| 333 | copyInfoHeader(sm, dm, "Bundle-Copyright", ""); |
| 334 | copyInfoHeader(sm, dm, "Bundle-DocURL", ""); |
| 335 | copyInfoHeader(sm, dm, "Bundle-License", ""); |
| 336 | copyInfoHeader(sm, dm, "Bundle-Name", " " + type); |
| 337 | copyInfoHeader(sm, dm, "Bundle-SymbolicName", "." + type); |
| 338 | copyInfoHeader(sm, dm, "Bundle-Version", ""); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 339 | } |
| 340 | |
| 341 | private void copyInfoHeader(Manifest sm, Manifest dm, String key, String value) { |
| 342 | String v = sm.getMainAttributes().getValue(key); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 343 | if (v == null) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 344 | trace("no source for " + key); |
| 345 | return; |
| 346 | } |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 347 | |
| 348 | if (dm.getMainAttributes().getValue(key) != null) { |
| 349 | trace("already have " + key); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 350 | return; |
| 351 | } |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 352 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 353 | dm.getMainAttributes().putValue(key, v + value); |
| 354 | } |
| 355 | |
| 356 | private void copyInfoResource(Jar source, Jar dest, String type) { |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 357 | if (source.getResources().containsKey(type) && !dest.getResources().containsKey(type)) |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 358 | dest.putResource(type, source.getResource(type)); |
| 359 | } |
| 360 | |
| 361 | /** |
| 362 | * @return |
| 363 | * @throws IOException |
| 364 | * @throws MalformedURLException |
| 365 | */ |
| 366 | protected Jar getJarFromFileOrURL(String spec) throws IOException, MalformedURLException { |
| 367 | Jar jar; |
| 368 | File jarFile = getFile(spec); |
| 369 | if (jarFile.exists()) { |
| 370 | jar = new Jar(jarFile); |
| 371 | } else { |
| 372 | URL url = new URL(spec); |
| 373 | InputStream in = url.openStream(); |
| 374 | try { |
| 375 | jar = new Jar(url.getFile(), in); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 376 | } |
| 377 | finally { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 378 | in.close(); |
| 379 | } |
| 380 | } |
| 381 | addClose(jar); |
| 382 | return jar; |
| 383 | } |
| 384 | |
| 385 | private void sign(File file, String passphrase) throws Exception { |
| 386 | trace("signing %s", file); |
| 387 | File asc = new File(file.getParentFile(), file.getName() + ".asc"); |
| 388 | asc.delete(); |
| 389 | |
| 390 | Command command = new Command(); |
| 391 | command.setTrace(); |
| 392 | |
| 393 | command.add(getProperty("gpgp", "gpg")); |
| 394 | if (passphrase != null) |
| 395 | command.add("--passphrase", passphrase); |
| 396 | command.add("-ab", "--sign"); // not the -b!! |
| 397 | command.add(file.getAbsolutePath()); |
| 398 | System.err.println(command); |
| 399 | StringBuilder stdout = new StringBuilder(); |
| 400 | StringBuilder stderr = new StringBuilder(); |
| 401 | int result = command.execute(stdout, stderr); |
| 402 | if (result != 0) { |
| 403 | error("gpg signing %s failed because %s", file, "" + stdout + stderr); |
| 404 | } |
| 405 | } |
| 406 | |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 407 | private Jar javadoc(File source, Set<String> exports, Manifest m, Properties p) throws Exception { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 408 | File tmp = new File(temp, "javadoc"); |
Stuart McCulloch | 55d4dfe | 2012-08-07 10:57:21 +0000 | [diff] [blame] | 409 | if (!tmp.exists() && !tmp.mkdirs()) { |
| 410 | throw new IOException("Could not create directory " + tmp); |
| 411 | } |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 412 | |
| 413 | Command command = new Command(); |
| 414 | command.add(getProperty("javadoc", "javadoc")); |
| 415 | command.add("-quiet"); |
| 416 | command.add("-protected"); |
| 417 | // command.add("-classpath"); |
| 418 | // command.add(binary.getAbsolutePath()); |
| 419 | command.add("-d"); |
| 420 | command.add(tmp.getAbsolutePath()); |
| 421 | command.add("-charset"); |
| 422 | command.add("UTF-8"); |
| 423 | command.add("-sourcepath"); |
| 424 | command.add(source.getAbsolutePath()); |
| 425 | |
| 426 | Attributes attr = m.getMainAttributes(); |
| 427 | Properties pp = new Properties(p); |
| 428 | set(pp, "-doctitle", description(attr)); |
| 429 | set(pp, "-header", description(attr)); |
| 430 | set(pp, "-windowtitle", name(attr)); |
| 431 | set(pp, "-bottom", copyright(attr)); |
| 432 | set(pp, "-footer", license(attr)); |
| 433 | |
| 434 | command.add("-tag"); |
| 435 | command.add("Immutable:t:Immutable"); |
| 436 | command.add("-tag"); |
| 437 | command.add("ThreadSafe:t:ThreadSafe"); |
| 438 | command.add("-tag"); |
| 439 | command.add("NotThreadSafe:t:NotThreadSafe"); |
| 440 | command.add("-tag"); |
| 441 | command.add("GuardedBy:mf:Guarded By:"); |
| 442 | command.add("-tag"); |
| 443 | command.add("security:m:Required Permissions"); |
| 444 | command.add("-tag"); |
| 445 | command.add("noimplement:t:Consumers of this API must not implement this interface"); |
| 446 | |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 447 | for (Enumeration< ? > e = pp.propertyNames(); e.hasMoreElements();) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 448 | String key = (String) e.nextElement(); |
| 449 | String value = pp.getProperty(key); |
| 450 | |
| 451 | if (key.startsWith("javadoc")) { |
| 452 | key = key.substring("javadoc".length()); |
| 453 | removeDuplicateMarker(key); |
| 454 | command.add(key); |
| 455 | command.add(value); |
| 456 | } |
| 457 | } |
| 458 | for (String packageName : exports) { |
| 459 | command.add(packageName); |
| 460 | } |
| 461 | |
| 462 | StringBuilder out = new StringBuilder(); |
| 463 | StringBuilder err = new StringBuilder(); |
| 464 | |
| 465 | System.err.println(command); |
| 466 | |
| 467 | int result = command.execute(out, err); |
| 468 | if (result != 0) { |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 469 | warning("Error during execution of javadoc command: %s\n******************\n%s", out, err); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 470 | } |
| 471 | Jar jar = new Jar(tmp); |
| 472 | addClose(jar); |
| 473 | return jar; |
| 474 | } |
| 475 | |
| 476 | /** |
| 477 | * Generate a license string |
| 478 | * |
| 479 | * @param attr |
| 480 | * @return |
| 481 | */ |
| 482 | private String license(Attributes attr) { |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 483 | Parameters map = Processor.parseHeader(attr.getValue(Constants.BUNDLE_LICENSE), null); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 484 | if (map.isEmpty()) |
| 485 | return null; |
| 486 | |
| 487 | StringBuilder sb = new StringBuilder(); |
| 488 | String sep = "Licensed under "; |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 489 | for (Entry<String,Attrs> entry : map.entrySet()) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 490 | sb.append(sep); |
| 491 | String key = entry.getKey(); |
| 492 | String link = entry.getValue().get("link"); |
| 493 | String description = entry.getValue().get("description"); |
| 494 | |
| 495 | if (description == null) |
| 496 | description = key; |
| 497 | |
| 498 | if (link != null) { |
| 499 | sb.append("<a href='"); |
| 500 | sb.append(link); |
| 501 | sb.append("'>"); |
| 502 | } |
| 503 | sb.append(description); |
| 504 | if (link != null) { |
| 505 | sb.append("</a>"); |
| 506 | } |
| 507 | sep = ",<br/>"; |
| 508 | } |
| 509 | |
| 510 | return sb.toString(); |
| 511 | } |
| 512 | |
| 513 | /** |
| 514 | * Generate the copyright statement. |
| 515 | * |
| 516 | * @param attr |
| 517 | * @return |
| 518 | */ |
| 519 | private String copyright(Attributes attr) { |
| 520 | return attr.getValue(Constants.BUNDLE_COPYRIGHT); |
| 521 | } |
| 522 | |
| 523 | private String name(Attributes attr) { |
| 524 | String name = attr.getValue(Constants.BUNDLE_NAME); |
| 525 | if (name == null) |
| 526 | name = attr.getValue(Constants.BUNDLE_SYMBOLICNAME); |
| 527 | return name; |
| 528 | } |
| 529 | |
| 530 | private String description(Attributes attr) { |
| 531 | String descr = attr.getValue(Constants.BUNDLE_DESCRIPTION); |
| 532 | if (descr == null) |
| 533 | descr = attr.getValue(Constants.BUNDLE_NAME); |
| 534 | if (descr == null) |
| 535 | descr = attr.getValue(Constants.BUNDLE_SYMBOLICNAME); |
| 536 | return descr; |
| 537 | } |
| 538 | |
| 539 | private void set(Properties pp, String option, String defaultValue) { |
| 540 | String key = "javadoc" + option; |
| 541 | String existingValue = pp.getProperty(key); |
| 542 | if (existingValue != null) |
| 543 | return; |
| 544 | |
| 545 | pp.setProperty(key, defaultValue); |
| 546 | } |
| 547 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 548 | /** |
| 549 | * View - Show the dependency details of an artifact |
| 550 | */ |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 551 | |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 552 | static Executor executor = Executors.newCachedThreadPool(); |
| 553 | static Pattern GROUP_ARTIFACT_VERSION = Pattern.compile("([^+]+)\\+([^+]+)\\+([^+]+)"); |
| 554 | |
| 555 | void view(String args[], int i) throws Exception { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 556 | Maven maven = new Maven(executor); |
| 557 | OutputStream out = System.err; |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 558 | |
| 559 | List<URI> urls = new ArrayList<URI>(); |
| 560 | |
| 561 | while (i < args.length && args[i].startsWith("-")) { |
| 562 | if ("-r".equals(args[i])) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 563 | URI uri = new URI(args[++i]); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 564 | urls.add(uri); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 565 | System.err.println("URI for repo " + uri); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 566 | } else if ("-o".equals(args[i])) { |
| 567 | out = new FileOutputStream(args[++i]); |
| 568 | } else |
| 569 | throw new IllegalArgumentException("Unknown option: " + args[i]); |
| 570 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 571 | i++; |
| 572 | } |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 573 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 574 | URI[] urls2 = urls.toArray(new URI[urls.size()]); |
| 575 | PrintWriter pw = IO.writer(out); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 576 | |
| 577 | while (i < args.length) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 578 | String ref = args[i++]; |
| 579 | pw.println("Ref " + ref); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 580 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 581 | Matcher matcher = GROUP_ARTIFACT_VERSION.matcher(ref); |
| 582 | if (matcher.matches()) { |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 583 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 584 | String group = matcher.group(1); |
| 585 | String artifact = matcher.group(2); |
| 586 | String version = matcher.group(3); |
| 587 | CachedPom pom = maven.getPom(group, artifact, version, urls2); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 588 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 589 | Builder a = new Builder(); |
| 590 | a.setProperty("Private-Package", "*"); |
| 591 | Set<Pom> dependencies = pom.getDependencies(Scope.compile, urls2); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 592 | for (Pom dep : dependencies) { |
| 593 | System.err.printf("%20s %-20s %10s%n", dep.getGroupId(), dep.getArtifactId(), dep.getVersion()); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 594 | a.addClasspath(dep.getArtifact()); |
| 595 | } |
| 596 | pw.println(a.getClasspath()); |
| 597 | a.build(); |
| 598 | |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 599 | TreeSet<PackageRef> sorted = new TreeSet<PackageRef>(a.getImports().keySet()); |
| 600 | for (PackageRef p : sorted) { |
| 601 | pw.printf("%-40s\n", p); |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 602 | } |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 603 | // for ( Map.Entry<String, Set<String>> entry : |
| 604 | // a.getUses().entrySet()) { |
| 605 | // String from = entry.getKey(); |
| 606 | // for ( String uses : entry.getValue()) { |
| 607 | // System.err.printf("%40s %s\n", from, uses); |
| 608 | // from = ""; |
| 609 | // } |
| 610 | // } |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 611 | a.close(); |
| 612 | } else |
| 613 | System.err.println("Wrong, must look like group+artifact+version, is " + ref); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 614 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 615 | } |
| 616 | } |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame] | 617 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 618 | } |