1 22 package org.objectweb.petals.tools.jbiplugin; 23 24 import java.io.ByteArrayInputStream ; 25 import java.io.DataInputStream ; 26 import java.io.File ; 27 import java.io.FileInputStream ; 28 import java.io.FileNotFoundException ; 29 import java.io.FileOutputStream ; 30 import java.io.InputStream ; 31 import java.io.StringWriter ; 32 import java.nio.ByteBuffer ; 33 import java.nio.channels.Channels ; 34 import java.nio.channels.FileChannel ; 35 import java.nio.channels.ReadableByteChannel ; 36 import java.util.HashSet ; 37 import java.util.Set ; 38 import java.util.jar.JarFile ; 39 import java.util.zip.ZipEntry ; 40 import java.util.zip.ZipException ; 41 import java.util.zip.ZipOutputStream ; 42 43 import javax.xml.parsers.DocumentBuilder ; 44 import javax.xml.parsers.DocumentBuilderFactory ; 45 import javax.xml.transform.Result ; 46 import javax.xml.transform.Source ; 47 import javax.xml.transform.Transformer ; 48 import javax.xml.transform.TransformerFactory ; 49 import javax.xml.transform.dom.DOMSource ; 50 import javax.xml.transform.stream.StreamResult ; 51 52 import org.apache.commons.io.FileUtils; 53 import org.apache.maven.artifact.repository.ArtifactRepository; 54 import org.apache.maven.artifact.resolver.ArtifactResolver; 55 import org.apache.maven.embedder.MavenEmbedder; 56 import org.apache.maven.model.Dependency; 57 import org.apache.maven.plugin.AbstractMojo; 58 import org.apache.maven.plugin.MojoExecutionException; 59 import org.apache.maven.project.MavenProject; 60 import org.w3c.dom.Document ; 61 import org.w3c.dom.Element ; 62 import org.w3c.dom.NodeList ; 63 64 73 public class JBIPluginMojo extends AbstractMojo { 74 75 78 protected ArtifactResolver artifactResolver; 79 80 88 protected File componentJar; 89 90 97 protected File jbiDirectory; 98 99 107 protected String jbiName; 108 109 117 protected boolean includeSubDependencies; 118 119 127 protected boolean verbose; 128 129 138 protected boolean updateJBIXml; 139 140 147 protected ArtifactRepository localRepository; 148 149 155 protected File outputDirectory; 156 157 165 protected String toExcludes; 166 167 174 protected MavenProject project; 175 176 179 private Set <String > entries = new HashSet <String >(); 180 181 184 private Set <String > entriesToExclude = new HashSet <String >(); 185 186 198 private void recurseDirectory(ZipOutputStream zipOutputStream, 199 File directory, String entryDirectoryName) throws Exception { 200 for (File file : directory.listFiles()) { 201 if (file.isFile()) { 202 if (!updateJBIXml 203 || (updateJBIXml && !file.getName().equals("jbi.xml"))) { 204 ZipEntry zipEntry = new ZipEntry (entryDirectoryName 205 + File.separator + file.getName()); 206 DataInputStream dis = new DataInputStream ( 207 new FileInputStream (file)); 208 byte[] content = new byte[dis.available()]; 209 dis.readFully(content); 210 zipOutputStream.putNextEntry(zipEntry); 211 zipOutputStream.write(content); 212 zipOutputStream.closeEntry(); 213 } 214 } else { 215 if (!file.getName().startsWith(".")) { 216 recurseDirectory(zipOutputStream, file, entryDirectoryName 218 + File.separator + file.getName()); 219 } 220 } 221 } 222 } 223 224 228 private void extractExcludeValues() { 229 if (!"foo".equals(toExcludes)) { 231 toExcludes = toExcludes.replace(" ", ""); 232 for (String jar : toExcludes.split(",")) { 233 entriesToExclude.add(jar); 234 } 235 } 236 } 237 238 241 public void execute() throws MojoExecutionException { 242 try { 243 project.getArtifact().setFile(new File (outputDirectory 244 + File.separator + jbiName + ".zip")); 245 if (jbiDirectory.exists()) { 246 if (verbose) { 247 System.out.println("Start building JBI archive " 248 + new File (outputDirectory 249 + File.separator + jbiName + ".zip") 250 .getAbsolutePath()); 251 } 252 new File (outputDirectory 253 + File.separator + jbiName + ".zip").delete(); 254 255 extractExcludeValues(); 257 258 ZipOutputStream zipOutputStream = new ZipOutputStream ( 260 new FileOutputStream (new File (outputDirectory 261 + File.separator + jbiName + ".zip"))); 262 recurseDirectory(zipOutputStream, jbiDirectory, "META-INF"); 263 zipOutputStream.flush(); 264 265 ZipEntry zipEntry = new ZipEntry (componentJar.getName()); 267 DataInputStream dis = new DataInputStream (new FileInputStream ( 268 componentJar)); 269 byte[] content = new byte[dis.available()]; 270 dis.readFully(content); 271 zipOutputStream.putNextEntry(zipEntry); 272 zipOutputStream.write(content); 273 zipOutputStream.closeEntry(); 274 275 includeProject(zipOutputStream, project); 277 278 if (updateJBIXml) { 279 updateJBIXmlFile(zipOutputStream); 281 } 282 283 zipOutputStream.flush(); 284 if (project.getDependencies().size() > 0) { 285 zipOutputStream.close(); 286 } 287 if (verbose) { 288 System.out.println("JBI archive building done.\n"); 289 } 290 } 291 } catch (Exception e) { 292 e.printStackTrace(); 293 throw new MojoExecutionException(e.getLocalizedMessage(), e); 294 } 295 } 296 297 303 private Set <String > cloneSet(Set <String > setToClone) { 304 Set <String > outSet = new HashSet <String >(); 305 for (String string : setToClone) { 306 outSet.add(string); 307 } 308 return outSet; 309 } 310 311 317 private void updateJBIXmlFile(ZipOutputStream zipOutputStream) 318 throws FileNotFoundException { 319 InputStream inputStream = null; 320 try { 321 DocumentBuilderFactory factory = DocumentBuilderFactory 322 .newInstance(); 323 DocumentBuilder builder = factory.newDocumentBuilder(); 324 Document document = builder.parse(new File (jbiDirectory 325 + File.separator + "jbi.xml")); 326 Element element = document.getDocumentElement(); 327 328 330 Element compoClassPath = (Element ) element.getElementsByTagName( 331 "component-class-path").item(0); 332 NodeList compoElems = compoClassPath 333 .getElementsByTagName("path-element"); 334 Set <String > elemsToAdd = cloneSet(entries); 335 for (int i = 0; i < compoElems.getLength(); i++) { 336 Element elem = (Element ) compoElems.item(i); 337 if (entries.contains(elem.getTextContent())) { 338 elemsToAdd.remove(elem.getTextContent()); 339 } 340 } 341 if (elemsToAdd.size() > 0) { 342 for (String jar : elemsToAdd) { 344 Element elem = document.createElement("path-element"); 345 elem.setTextContent(jar); 346 compoClassPath.appendChild(elem); 347 } 348 } 349 Element mainElem = document.createElement("path-element"); 351 mainElem.setTextContent(componentJar.getName()); 352 compoClassPath.appendChild(mainElem); 353 354 356 Element bootClassPath = (Element ) element.getElementsByTagName( 357 "bootstrap-class-path").item(0); 358 NodeList bootElems = bootClassPath 359 .getElementsByTagName("path-element"); 360 elemsToAdd = cloneSet(entries); 361 for (int i = 0; i < bootElems.getLength(); i++) { 362 Element elem = (Element ) bootElems.item(i); 363 if (elemsToAdd.contains(elem.getTextContent())) { 364 elemsToAdd.remove(elem.getTextContent()); 365 } 366 } 367 if (elemsToAdd.size() > 0) { 368 for (String jar : elemsToAdd) { 370 Element elem = document.createElement("path-element"); 371 elem.setTextContent(jar); 372 bootClassPath.appendChild(elem); 373 } 374 } 375 mainElem = document.createElement("path-element"); 377 mainElem.setTextContent(componentJar.getName()); 378 bootClassPath.appendChild(mainElem); 379 380 381 document.normalize(); 382 Source source = new DOMSource (document); 383 StringWriter out = new StringWriter (); 384 Result resultStream = new StreamResult (out); 385 TransformerFactory tFactory = TransformerFactory.newInstance(); 386 Transformer transformer; 387 transformer = tFactory.newTransformer(); 388 transformer.transform(source, resultStream); 389 390 inputStream = new ByteArrayInputStream (out.toString().getBytes()); 391 392 } catch (Exception e) { 393 if (verbose) { 394 System.out 395 .println("Problem while updating jbi.xml file. We add it like it is"); 396 } 397 inputStream = new FileInputStream (new File (jbiDirectory 398 + File.separator + "jbi.xml")); 399 } 400 401 try { 403 ZipEntry zipEntry = new ZipEntry ("META-INF/jbi.xml"); 404 DataInputStream dis = new DataInputStream (inputStream); 405 byte[] content = new byte[dis.available()]; 406 dis.readFully(content); 407 zipOutputStream.putNextEntry(zipEntry); 408 zipOutputStream.write(content); 409 zipOutputStream.closeEntry(); 410 } catch (Exception e) { 411 if (verbose) { 412 System.out.println("Fail to add jbi.xml file"); 413 } 414 } 415 } 416 417 423 private void recurseDepencies(ZipOutputStream zipOutputStream, 424 Dependency dependency) throws Exception { 425 426 MavenEmbedder maven = new MavenEmbedder(); 427 ClassLoader classLoader = Thread.currentThread() 428 .getContextClassLoader(); 429 maven.setClassLoader(classLoader); 430 maven.setLogger(null); 431 maven.start(); 432 433 String pomName = dependency.getArtifactId() 434 + "-" + dependency.getVersion() + ".pom"; 435 436 File pomFile = new File (localRepository.getBasedir() 437 + File.separator 438 + dependency.getGroupId().replace(".", File.separator) 439 + File.separator + dependency.getArtifactId() + File.separator 440 + dependency.getVersion() + File.separator + pomName); 441 if (pomFile.exists()) { 442 MavenProject project = null; 443 try { 444 project = maven.readProject(pomFile); 445 } catch (Exception e) { 446 String jarName=null; 447 try { 448 jarName = localRepository.getBasedir() 449 + File.separator 450 + dependency.getGroupId().replace(".", File.separator) 451 + File.separator + dependency.getArtifactId() 452 + File.separator + dependency.getVersion() + File.separator 453 + dependency.getArtifactId() + "-" 454 + dependency.getVersion() + ".jar"; 455 456 JarFile jarFile = new JarFile (jarName); 457 String pomEntryName = "META-INF/maven/" 458 + dependency.getGroupId() + "/" 459 + dependency.getArtifactId() + "/pom.xml"; 460 ZipEntry jarEntry = jarFile.getEntry(pomEntryName); 461 if (jarEntry != null) { 462 File tmpFile = new File (outputDirectory 464 + File.separator + "temp.xml"); 465 copyStreamToFile(jarFile.getInputStream(jarEntry), tmpFile); 466 project = maven.readProject(tmpFile); 467 FileUtils.forceDelete(tmpFile); 468 } 469 } catch (ZipException e1) { 470 if (verbose) { 471 System.out.println("Problem while adding " 472 + jarName + " to JBI archive"); 473 } 474 } 475 } 476 if (project != null) { 477 includeProject(zipOutputStream, project); 478 } 479 } 480 } 481 482 489 private void includeProject(ZipOutputStream zipOutputStream, 490 MavenProject project) throws Exception { 491 492 for (Object object : project.getDependencies()) { 493 if (object instanceof Dependency) { 494 Dependency dep = (Dependency) object; 495 String jarName = dep.getArtifactId() 496 + "-" + dep.getVersion() + ".jar"; 497 498 String scope = "test"; 499 if (dep.getScope() == null 500 || (dep.getScope() != null && !dep.getScope() 501 .equals("test"))) { 502 scope = "other"; 503 } 504 if (!"test".equals(scope) 505 && !entriesToExclude.contains(jarName)) { 506 507 zipDependency(zipOutputStream, dep); 509 recurseDepencies(zipOutputStream, dep); 511 } 512 } 513 } 514 } 515 516 523 private void copyStreamToFile(InputStream inputStream, File tmpFile) 524 throws Exception { 525 ReadableByteChannel inputChannel = Channels.newChannel(inputStream); 526 FileOutputStream fos = new FileOutputStream (tmpFile); 527 FileChannel outputChannel = fos.getChannel(); 528 ByteBuffer buffer = ByteBuffer.allocate(4096); 529 int readBytes; 530 while ((readBytes = inputChannel.read(buffer)) != -1) { 531 if (readBytes > 0) { 532 buffer.flip(); 533 outputChannel.write(buffer); 534 buffer.clear(); 535 } 536 } 537 inputChannel.close(); 538 outputChannel.close(); 539 fos.close(); 540 } 541 542 548 private void zipDependency(ZipOutputStream zipOutputStream, 549 Dependency dependency) { 550 String jarName = dependency.getArtifactId() 551 + "-" + dependency.getVersion() + ".jar"; 552 try { 553 if (!entries.contains(jarName)) { 554 ZipEntry zipEntry = new ZipEntry (jarName); 555 DataInputStream dis = new DataInputStream (new FileInputStream ( 556 new File (localRepository.getBasedir() 557 + File.separator 558 + dependency.getGroupId().replace(".", File.separator) 559 + File.separator + dependency.getArtifactId() 560 + File.separator + dependency.getVersion() 561 + File.separator + jarName))); 562 byte[] content = new byte[dis.available()]; 563 dis.readFully(content); 564 zipOutputStream.putNextEntry(zipEntry); 565 zipOutputStream.write(content); 566 zipOutputStream.closeEntry(); 567 entries.add(jarName); 568 if (verbose) { 569 System.out.println(" " 570 + jarName + " added to JBI archive"); 571 } 572 } 573 } catch (Exception e) { 574 entriesToExclude.add(jarName); 575 if (verbose) { 576 System.out.println("Problem while adding " 577 + jarName + " to JBI archive"); 578 } 579 } 580 } 581 } 582 | Popular Tags |