1. /*
  2. * Copyright 2000-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.taskdefs;
  18. import java.io.File;
  19. import java.io.IOException;
  20. import org.apache.tools.ant.BuildException;
  21. import org.apache.tools.ant.Project;
  22. import org.apache.tools.ant.types.ZipFileSet;
  23. import org.apache.tools.ant.util.FileUtils;
  24. import org.apache.tools.zip.ZipOutputStream;
  25. /**
  26. * An extension of <jar> to create a WAR archive.
  27. * Contains special treatment for files that should end up in the
  28. * <code>WEB-INF/lib</code>, <code>WEB-INF/classes</code> or
  29. * <code>WEB-INF</code> directories of the Web Application Archive.</p>
  30. * <p>(The War task is a shortcut for specifying the particular layout of a WAR file.
  31. * The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
  32. * attributes of zipfilesets in a Zip or Jar task.)</p>
  33. * <p>The extended zipfileset element from the zip task
  34. * (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>)
  35. * is available in the War task.</p>
  36. *
  37. *
  38. * @since Ant 1.2
  39. *
  40. * @ant.task category="packaging"
  41. * @see Jar
  42. */
  43. public class War extends Jar {
  44. /**
  45. * our web.xml deployment descriptor
  46. */
  47. private File deploymentDescriptor;
  48. /**
  49. * flag set if the descriptor is added
  50. */
  51. private boolean descriptorAdded;
  52. private static final FileUtils fu = FileUtils.newFileUtils();
  53. public War() {
  54. super();
  55. archiveType = "war";
  56. emptyBehavior = "create";
  57. }
  58. /**
  59. * <i>Deprecated<i> name of the file to create
  60. * -use <tt>destfile</tt> instead.
  61. * @deprecated Use setDestFile(File) instead
  62. * @ant.attribute ignore="true"
  63. */
  64. public void setWarfile(File warFile) {
  65. setDestFile(warFile);
  66. }
  67. /**
  68. * set the deployment descriptor to use (WEB-INF/web.xml);
  69. * required unless <tt>update=true</tt>
  70. */
  71. public void setWebxml(File descr) {
  72. deploymentDescriptor = descr;
  73. if (!deploymentDescriptor.exists()) {
  74. throw new BuildException("Deployment descriptor: "
  75. + deploymentDescriptor
  76. + " does not exist.");
  77. }
  78. // Create a ZipFileSet for this file, and pass it up.
  79. ZipFileSet fs = new ZipFileSet();
  80. fs.setFile(deploymentDescriptor);
  81. fs.setFullpath("WEB-INF/web.xml");
  82. super.addFileset(fs);
  83. }
  84. /**
  85. * add files under WEB-INF/lib/
  86. */
  87. public void addLib(ZipFileSet fs) {
  88. // We just set the prefix for this fileset, and pass it up.
  89. fs.setPrefix("WEB-INF/lib/");
  90. super.addFileset(fs);
  91. }
  92. /**
  93. * add files under WEB-INF/classes
  94. */
  95. public void addClasses(ZipFileSet fs) {
  96. // We just set the prefix for this fileset, and pass it up.
  97. fs.setPrefix("WEB-INF/classes/");
  98. super.addFileset(fs);
  99. }
  100. /**
  101. * files to add under WEB-INF;
  102. */
  103. public void addWebinf(ZipFileSet fs) {
  104. // We just set the prefix for this fileset, and pass it up.
  105. fs.setPrefix("WEB-INF/");
  106. super.addFileset(fs);
  107. }
  108. /**
  109. * override of parent; validates configuration
  110. * before initializing the output stream.
  111. */
  112. protected void initZipOutputStream(ZipOutputStream zOut)
  113. throws IOException, BuildException {
  114. // If no webxml file is specified, it's an error.
  115. if (deploymentDescriptor == null && !isInUpdateMode()) {
  116. throw new BuildException("webxml attribute is required", getLocation());
  117. }
  118. super.initZipOutputStream(zOut);
  119. }
  120. /**
  121. * Overridden from Zip class to deal with web.xml
  122. */
  123. protected void zipFile(File file, ZipOutputStream zOut, String vPath,
  124. int mode)
  125. throws IOException {
  126. // If the file being added is WEB-INF/web.xml, we warn if it's
  127. // not the one specified in the "webxml" attribute - or if
  128. // it's being added twice, meaning the same file is specified
  129. // by the "webxml" attribute and in a <fileset> element.
  130. if (vPath.equalsIgnoreCase("WEB-INF/web.xml")) {
  131. if (deploymentDescriptor == null
  132. || !fu.fileNameEquals(deploymentDescriptor, file)
  133. || descriptorAdded) {
  134. log("Warning: selected " + archiveType
  135. + " files include a WEB-INF/web.xml which will be ignored "
  136. + "(please use webxml attribute to "
  137. + archiveType + " task)", Project.MSG_WARN);
  138. } else {
  139. super.zipFile(file, zOut, vPath, mode);
  140. descriptorAdded = true;
  141. }
  142. } else {
  143. super.zipFile(file, zOut, vPath, mode);
  144. }
  145. }
  146. /**
  147. * Make sure we don't think we already have a web.xml next time this task
  148. * gets executed.
  149. */
  150. protected void cleanUp() {
  151. descriptorAdded = false;
  152. super.cleanUp();
  153. }
  154. }