00001
00054 package org.objectweb.jonas.ant;
00055
00056 import java.io.File;
00057 import java.io.IOException;
00058 import java.util.Hashtable;
00059
00060 import javax.xml.parsers.SAXParser;
00061
00062 import org.apache.tools.ant.AntClassLoader;
00063 import org.apache.tools.ant.BuildException;
00064 import org.apache.tools.ant.Project;
00065 import org.apache.tools.ant.taskdefs.Java;
00066 import org.apache.tools.ant.types.Path;
00067 import org.apache.tools.ant.types.Reference;
00068
00080 public class JonasDeploymentTool extends GenericDeploymentTool {
00081
00083 protected static final String EJB_JAR_1_1_PUBLIC_ID = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN";
00084 protected static final String EJB_JAR_2_0_PUBLIC_ID = "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN";
00085
00087 protected static final String JONAS_EJB_JAR_2_4_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 2.4//EN";
00088 protected static final String JONAS_EJB_JAR_2_5_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 2.5//EN";
00089 protected static final String JONAS_EJB_JAR_3_0_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.0//EN";
00090 protected static final String JONAS_EJB_JAR_3_2_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.2//EN";
00091 protected static final String JONAS_EJB_JAR_3_3_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.3//EN";
00092 protected static final String JONAS_EJB_JAR_3_3_2_PUBLIC_ID = "-//ObjectWeb//DTD JOnAS 3.3.2//EN";
00093
00098 protected static final String EJB_JAR_1_1_DTD = "ejb-jar_1_1.dtd";
00099 protected static final String EJB_JAR_2_0_DTD = "ejb-jar_2_0.dtd";
00100
00105 protected static final String JONAS_EJB_JAR_2_4_DTD = "jonas-ejb-jar_2_4.dtd";
00106 protected static final String JONAS_EJB_JAR_2_5_DTD = "jonas-ejb-jar_2_5.dtd";
00107 protected static final String JONAS_EJB_JAR_3_0_DTD = "jonas-ejb-jar_3_0.dtd";
00108 protected static final String JONAS_EJB_JAR_3_2_DTD = "jonas-ejb-jar_3_2.dtd";
00109 protected static final String JONAS_EJB_JAR_3_3_DTD = "jonas-ejb-jar_3_3.dtd";
00110 protected static final String JONAS_EJB_JAR_3_3_2_DTD = "jonas-ejb-jar_3_3_2.dtd";
00111
00113 protected static final String JONAS_DD = "jonas-ejb-jar.xml";
00114
00116 protected static final String BOOTSTRAP_CLASS = "org.objectweb.jonas.server.Bootstrap";
00117
00119 protected static final String GENIC_CLASS = "org.objectweb.jonas_ejb.genic.GenIC";
00120
00126 private String descriptorName;
00127
00133 private String jonasDescriptorName;
00134
00135
00136
00137
00138
00142 private File outputdir;
00143
00148 private boolean keepgenerated = false;
00149
00154 private boolean nocompil = false;
00155
00160 private boolean invokeCmd = false;
00161
00166 private boolean novalidation = false;
00167
00172 private String javac;
00173
00175 private String javacopts;
00176
00178 private String rmicopts;
00179
00184 private boolean verbose = false;
00185
00187 private String additionalargs;
00188
00190 private String jvmopts = null;
00191
00193 private String protocols = null;
00194
00195
00196
00197
00198
00200 private File jonasroot;
00201
00203 private File jonasbase;
00204
00209 private boolean keepgeneric = false;
00210
00212 private String suffix = ".jar";
00213
00218 private boolean nogenic = false;
00219
00220
00221
00222
00223
00228 public void setKeepgenerated(boolean aBoolean) {
00229 keepgenerated = aBoolean;
00230 }
00231
00236 public void setMappernames(String aString) {
00237 log("'mappernames' attribute ignored (deprecated)", Project.MSG_WARN);
00238 }
00239
00244 public void setProtocols(String aString) {
00245 protocols = aString;
00246 }
00247
00252 public void setClasspathref(Reference r) {
00253 createClasspath().setRefid(r);
00254 }
00259 public void setAdditionalargs(String aString) {
00260 additionalargs = aString;
00261 }
00262
00267 public void setNocompil(boolean aBoolean) {
00268 nocompil = aBoolean;
00269 }
00270
00275 public void setInvokecmd(boolean aBoolean) {
00276 invokeCmd = aBoolean;
00277 }
00278
00283 public void setNovalidation(boolean aBoolean) {
00284 novalidation = aBoolean;
00285 }
00286
00291 public void setJavac(String aString) {
00292 javac = aString;
00293 }
00294
00299 public void setJavacopts(String aString) {
00300 javacopts = aString;
00301 }
00302
00307 public void setRmicopts(String aString) {
00308 rmicopts = aString;
00309 }
00310
00315 public void setVerbose(boolean aBoolean) {
00316 verbose = aBoolean;
00317 }
00318
00319
00320
00321
00322
00327 public void setJonasroot(File aFile) {
00328 jonasroot = aFile;
00329 }
00330
00335 public void setJonasbase(File aFile) {
00336 jonasbase = aFile;
00337 }
00338
00343 public void setKeepgeneric(boolean aBoolean) {
00344 keepgeneric = aBoolean;
00345 }
00346
00351 public void setJarsuffix(String aString) {
00352 suffix = aString;
00353 }
00354
00359 public void setNogenic(boolean aBoolean) {
00360 nogenic = aBoolean;
00361 }
00362
00367 public void setJvmopts(String aString) {
00368 jvmopts = aString;
00369 }
00370
00371
00372
00373
00374
00375 public void processDescriptor(String aDescriptorName, SAXParser saxParser) {
00376
00377 descriptorName = aDescriptorName;
00378
00379 log("JOnAS Deployment Tool processing for JOnAS: " + descriptorName, Project.MSG_VERBOSE);
00380
00381 super.processDescriptor(descriptorName, saxParser);
00382
00383 if (outputdir != null) {
00384
00385
00386 log("Deleting temp output directory '" + outputdir + "'.", Project.MSG_VERBOSE);
00387 deleteAllFiles(outputdir);
00388 }
00389 }
00390
00391 protected void writeJar(String baseName, File jarfile, Hashtable ejbFiles, String publicId,
00392 boolean includeInnerClasses) throws BuildException {
00393
00394
00395 File genericJarFile = super.getVendorOutputJarFile(baseName);
00396
00397 super.writeJar(baseName, genericJarFile, ejbFiles, publicId, true);
00398
00399
00400 addGenICGeneratedFiles(genericJarFile, ejbFiles);
00401
00402
00403 super.writeJar(baseName, getVendorOutputJarFile(baseName), ejbFiles, publicId, false);
00404
00405
00406
00407
00408
00409
00410 if (!keepgeneric) {
00411 log("Deleting generic JAR " + genericJarFile.toString(), Project.MSG_VERBOSE);
00412 genericJarFile.delete();
00413 }
00414 }
00415
00416 protected void addVendorFiles(Hashtable ejbFiles, String ddPrefix) {
00417
00418
00419 jonasDescriptorName = getJonasDescriptorName();
00420 File jonasDD = new File(getConfig().descriptorDir, jonasDescriptorName);
00421
00422 if (jonasDD.exists()) {
00423 ejbFiles.put(META_DIR + JONAS_DD, jonasDD);
00424 } else {
00425 log("Unable to locate the JOnAS deployment descriptor. It was expected to be in: " + jonasDD.getPath()
00426 + ".", Project.MSG_WARN);
00427 }
00428 }
00429
00430 protected File getVendorOutputJarFile(String baseName) {
00431 return new File(getDestDir(), baseName + suffix);
00432 }
00433
00441 private String getJonasDescriptorName() {
00442
00443
00444
00445
00446
00447 String jonasDescriptorName;
00448 boolean jonasConvention = false;
00449
00450 String path;
00451 String fileName;
00452 String baseName;
00453 String remainder;
00454
00455 int startOfFileName = descriptorName.lastIndexOf(File.separatorChar);
00456 if (startOfFileName != -1) {
00457
00458 path = descriptorName.substring(0, startOfFileName + 1);
00459 fileName = descriptorName.substring(startOfFileName + 1);
00460 } else {
00461
00462 path = "";
00463 fileName = descriptorName;
00464 }
00465
00466 if (fileName.startsWith(EJB_DD)) {
00467 return path + JONAS_DD;
00468 }
00469
00470 int endOfBaseName = descriptorName.indexOf(getConfig().baseNameTerminator, startOfFileName);
00471
00472
00473
00474
00475
00476
00477 if (endOfBaseName < 0) {
00478
00479
00480
00481
00482 endOfBaseName = descriptorName.lastIndexOf('.') - 1;
00483 if (endOfBaseName < 0) {
00484
00485 endOfBaseName = descriptorName.length() - 1;
00486 }
00487
00488 jonasConvention = true;
00489 }
00490
00491 baseName = descriptorName.substring(startOfFileName + 1, endOfBaseName + 1);
00492 remainder = descriptorName.substring(endOfBaseName + 1);
00493
00494 if (jonasConvention) {
00495 jonasDescriptorName = path + "jonas-" + baseName + ".xml";
00496 } else {
00497 jonasDescriptorName = path + baseName + "jonas-" + remainder;
00498 }
00499
00500 log("Standard EJB descriptor name: " + descriptorName, Project.MSG_VERBOSE);
00501 log("JOnAS-specific descriptor name: " + jonasDescriptorName, Project.MSG_VERBOSE);
00502
00503 return jonasDescriptorName;
00504 }
00505
00506 protected String getJarBaseName(String descriptorFileName) {
00507
00508 String baseName = null;
00509
00510 if (getConfig().namingScheme.getValue().equals(EjbJar.NamingScheme.DESCRIPTOR)) {
00511
00512
00513 if (descriptorFileName.indexOf(getConfig().baseNameTerminator) == -1) {
00514
00515
00516
00517
00518
00519
00520 String aCanonicalDescriptor = descriptorFileName.replace('\\', '/');
00521 int lastSeparatorIndex = aCanonicalDescriptor.lastIndexOf('/');
00522 int endOfBaseName;
00523
00524 if (lastSeparatorIndex != -1) {
00525 endOfBaseName = descriptorFileName.indexOf(".xml", lastSeparatorIndex);
00526 } else {
00527 endOfBaseName = descriptorFileName.indexOf(".xml");
00528 }
00529
00530 if (endOfBaseName != -1) {
00531 baseName = descriptorFileName.substring(0, endOfBaseName);
00532 }
00533 }
00534 }
00535
00536 if (baseName == null) {
00537
00538 baseName = super.getJarBaseName(descriptorFileName);
00539 }
00540
00541 log("JAR base name: " + baseName, Project.MSG_VERBOSE);
00542
00543 return baseName;
00544 }
00545
00546 protected void registerKnownDTDs(DescriptorHandler handler) {
00547
00548 handler.registerDTD(EJB_JAR_1_1_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00549 + EJB_JAR_1_1_DTD);
00550 handler.registerDTD(EJB_JAR_2_0_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00551 + EJB_JAR_2_0_DTD);
00552
00553 handler.registerDTD(JONAS_EJB_JAR_2_4_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00554 + JONAS_EJB_JAR_2_4_DTD);
00555 handler.registerDTD(JONAS_EJB_JAR_2_5_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00556 + JONAS_EJB_JAR_2_5_DTD);
00557 handler.registerDTD(JONAS_EJB_JAR_3_0_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00558 + JONAS_EJB_JAR_3_0_DTD);
00559 handler.registerDTD(JONAS_EJB_JAR_3_2_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00560 + JONAS_EJB_JAR_3_2_DTD);
00561 handler.registerDTD(JONAS_EJB_JAR_3_3_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00562 + JONAS_EJB_JAR_3_3_DTD);
00563 handler.registerDTD(JONAS_EJB_JAR_3_3_2_PUBLIC_ID, jonasroot + File.separator + "xml" + File.separator
00564 + JONAS_EJB_JAR_3_3_2_DTD);
00565 }
00566
00572 private void addGenICGeneratedFiles(File genericJarFile, Hashtable ejbFiles) {
00573
00574 Java genicTask = null;
00575
00576 if (nogenic) {
00577 return;
00578 }
00579
00580 genicTask = (Java) getTask().getProject().createTask("java");
00581 genicTask.setTaskName("genic");
00582 genicTask.setFork(true);
00583
00584
00585 genicTask.createJvmarg().setValue("-Dinstall.root=" + jonasroot);
00586
00587
00588 genicTask.createJvmarg().setValue("-Djonas.base=" + jonasbase);
00589
00590
00591 File endorsedDir = new File(new File(jonasroot, "lib"), "endorsed");
00592 genicTask.createJvmarg().setValue("-Djava.endorsed.dirs=" + endorsedDir);
00593
00594
00595 String jonasConfigDir = jonasroot + File.separator + "conf";
00596 File javaPolicyFile = new File(jonasConfigDir, "java.policy");
00597 if (javaPolicyFile.exists()) {
00598 genicTask.createJvmarg().setValue("-Djava.security.policy=" + javaPolicyFile.toString());
00599 }
00600
00601
00602 genicTask.createArg().setValue(JonasDeploymentTool.GENIC_CLASS);
00603
00604
00605 try {
00606 outputdir = createTempDir();
00607 } catch (IOException aIOException) {
00608 String msg = "Cannot create temp dir: " + aIOException.getMessage();
00609 throw new BuildException(msg, aIOException);
00610 }
00611 log("Using temporary output directory: " + outputdir, Project.MSG_VERBOSE);
00612
00613 genicTask.createArg().setValue("-d");
00614 genicTask.createArg().setFile(outputdir);
00615
00616
00617 Path classpath = getCombinedClasspath();
00618 if (classpath == null) {
00619 classpath = new Path(getTask().getProject());
00620 }
00621
00622 String bootJar = jonasroot + File.separator + "lib" + File.separator + "common" + File.separator
00623 + "ow_jonas_bootstrap.jar";
00624 Path bootstrap = new Path(getTask().getProject(), bootJar);
00625
00626
00627 classpath.append(new Path(classpath.getProject(), outputdir.toString()));
00628
00629 log("Using classpath: " + bootstrap.toString(), Project.MSG_VERBOSE);
00630 genicTask.setClasspath(bootstrap);
00631
00632 if (!checkBootstrapClassName(bootstrap)) {
00633 log("Cannot find bootstrap class in classpath.", Project.MSG_ERR);
00634 throw new BuildException("Bootstrap class not found, please check the classpath.");
00635 } else {
00636 genicTask.setClassname(JonasDeploymentTool.BOOTSTRAP_CLASS);
00637 }
00638
00639
00640 genicTask.createArg().setValue("-classpath");
00641 genicTask.createArg().setPath(classpath);
00642
00643
00644 if (keepgenerated) {
00645 genicTask.createArg().setValue("-keepgenerated");
00646 }
00647
00648
00649 if (nocompil) {
00650 genicTask.createArg().setValue("-nocompil");
00651 }
00652
00653
00654 if (invokeCmd) {
00655 genicTask.createArg().setValue("-invokecmd");
00656 }
00657
00658
00659 if (novalidation) {
00660 genicTask.createArg().setValue("-novalidation");
00661 }
00662
00663
00664 if (javac != null) {
00665 genicTask.createArg().setValue("-javac");
00666 genicTask.createArg().setLine(javac);
00667 }
00668
00669
00670 if (javacopts != null && !javacopts.equals("")) {
00671 genicTask.createArg().setValue("-javacopts");
00672 genicTask.createArg().setValue(javacopts);
00673 }
00674
00675
00676 if (rmicopts != null && !rmicopts.equals("")) {
00677 genicTask.createArg().setValue("-rmicopts");
00678 genicTask.createArg().setValue(rmicopts);
00679 }
00680
00681
00682 if (verbose) {
00683 genicTask.createArg().setValue("-verbose");
00684 }
00685
00686
00687 if (additionalargs != null) {
00688 genicTask.createArg().setLine(additionalargs);
00689 }
00690
00691
00692 if (protocols != null) {
00693 genicTask.createArg().setValue("-protocols");
00694 genicTask.createArg().setValue(protocols);
00695 }
00696
00697
00698 genicTask.createArg().setValue("-noaddinjar");
00699
00700
00701 if (jvmopts != null && !jvmopts.equals("")) {
00702 genicTask.createJvmarg().setLine(jvmopts);
00703 }
00704
00705
00706 genicTask.createArg().setValue(genericJarFile.getPath());
00707
00708
00709 log("Calling GenIC task for " + getConfig().descriptorDir + File.separator + descriptorName + ".",
00710 Project.MSG_VERBOSE);
00711
00712 if (genicTask.executeJava() != 0) {
00713
00714
00715
00716
00717
00718
00719
00720
00721 if (!keepgeneric) {
00722 log("Deleting generic JAR " + genericJarFile.toString(), Project.MSG_VERBOSE);
00723 genericJarFile.delete();
00724 }
00725
00726 throw new BuildException("GenIC reported an error.");
00727 }
00728
00729
00730 addAllFiles(outputdir, "", ejbFiles);
00731 }
00732
00738 private boolean checkBootstrapClassName(Path classpath) {
00739 log("Looking for bootstrap class in classpath: " + classpath.toString(), Project.MSG_VERBOSE);
00740 AntClassLoader cl = new AntClassLoader(classpath.getProject(), classpath);
00741 try {
00742 cl.loadClass(JonasDeploymentTool.BOOTSTRAP_CLASS);
00743 log("Found Bootstrap class '" + JonasDeploymentTool.BOOTSTRAP_CLASS + "' in classpath.",
00744 Project.MSG_VERBOSE);
00745 } catch (ClassNotFoundException cnf1) {
00746 log("Bootstrap class '" + JonasDeploymentTool.BOOTSTRAP_CLASS + "' not found in classpath.",
00747 Project.MSG_VERBOSE);
00748 return false;
00749 }
00750 return true;
00751 }
00752
00753 protected void checkConfiguration(String descriptorFileName, SAXParser saxParser) throws BuildException {
00754
00755 if (jonasroot == null) {
00756 throw new BuildException("The jonasroot attribute is not set.");
00757 } else if (!jonasroot.isDirectory()) {
00758 throw new BuildException("The jonasroot attribute '" + jonasroot + "' is not a valid directory.");
00759 }
00760
00761 if (jonasbase == null) {
00762 jonasbase = jonasroot;
00763 }
00764
00765
00766 if (additionalargs != null && additionalargs.equals("")) {
00767 throw new BuildException("Empty additionalargs attribute.");
00768 }
00769
00770
00771 if (javac != null && javac.equals("")) {
00772 throw new BuildException("Empty javac attribute.");
00773 }
00774 }
00775
00776
00777
00778
00779
00785 private File createTempDir() throws IOException {
00786 File tmpDir = File.createTempFile("genic", null, null);
00787 tmpDir.delete();
00788 if (!tmpDir.mkdir()) {
00789 throw new IOException("Cannot create the temporary directory '" + tmpDir + "'.");
00790 }
00791 return tmpDir;
00792 }
00793
00799 private void deleteAllFiles(File aFile) {
00800 if (aFile.isDirectory()) {
00801 File someFiles[] = aFile.listFiles();
00802 for (int i = 0; i < someFiles.length; i++) {
00803 deleteAllFiles(someFiles[i]);
00804 }
00805 }
00806 aFile.delete();
00807 }
00808
00816 private void addAllFiles(File file, String rootDir, Hashtable hashtable) {
00817
00818 if (!file.exists()) {
00819 throw new IllegalArgumentException();
00820 }
00821
00822 String newRootDir;
00823 if (file.isDirectory()) {
00824 File[] files = file.listFiles();
00825 for (int i = 0; i < files.length; i++) {
00826 if (rootDir.length() > 0) {
00827 newRootDir = rootDir + File.separator + files[i].getName();
00828 } else {
00829 newRootDir = files[i].getName();
00830 }
00831 addAllFiles(files[i], newRootDir, hashtable);
00832 }
00833 } else {
00834 hashtable.put(rootDir, file);
00835 }
00836 }
00837 }