View Javadoc
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.codehaus.plexus.archiver.war;
18  
19  import javax.inject.Named;
20  
21  import java.io.File;
22  import java.io.IOException;
23  
24  import org.codehaus.plexus.archiver.ArchiveEntry;
25  import org.codehaus.plexus.archiver.ArchiverException;
26  import org.codehaus.plexus.archiver.jar.JarArchiver;
27  import org.codehaus.plexus.archiver.util.ResourceUtils;
28  import org.codehaus.plexus.archiver.zip.ConcurrentJarCreator;
29  
30  /**
31   * An extension of <jar> to create a WAR archive.
32   * Contains special treatment for files that should end up in the
33   * <code>WEB-INF/lib</code>, <code>WEB-INF/classes</code> or
34   * <code>WEB-INF</code> directories of the Web Application Archive.
35   * <p>
36   * (The War task is a shortcut for specifying the particular layout of a WAR file.
37   * The same thing can be accomplished by using the <i>prefix</i> and <i>fullpath</i>
38   * attributes of zipfilesets in a Zip or Jar task.)</p>
39   * <p>
40   * The extended zipfileset element from the zip task
41   * (with attributes <i>prefix</i>, <i>fullpath</i>, and <i>src</i>)
42   * is available in the War task.</p>
43   *
44   * @see JarArchiver
45   */
46  @Named("war")
47  public class WarArchiver extends JarArchiver {
48  
49      /**
50       * our web.xml deployment descriptor
51       */
52      private File deploymentDescriptor;
53  
54      /**
55       * flag set if finding the webxml is to be expected.
56       */
57      private boolean expectWebXml = true;
58  
59      /**
60       * flag set if the descriptor is added
61       */
62      private boolean descriptorAdded;
63  
64      /**
65       * @deprecated Use setExpectWebXml instead !
66       * @param excpectWebXml true if web xml is *expected* from the client
67       */
68      @Deprecated
69      public void setIgnoreWebxml(boolean excpectWebXml) {
70          expectWebXml = excpectWebXml;
71      }
72  
73      /**
74       * Indicates if the client is required to supply web.xml
75       *
76       * @param expectWebXml true if web xml is *expected* from the client
77       */
78      public void setExpectWebXml(boolean expectWebXml) {
79          this.expectWebXml = expectWebXml;
80      }
81  
82      public WarArchiver() {
83          super();
84          archiveType = "war";
85      }
86  
87      /**
88       * set the deployment descriptor to use (WEB-INF/web.xml);
89       * required unless <code>update=true</code>
90       */
91      public void setWebxml(File descr) throws ArchiverException {
92          deploymentDescriptor = descr;
93          if (!deploymentDescriptor.exists()) {
94              throw new ArchiverException("Deployment descriptor: " + deploymentDescriptor + " does not exist.");
95          }
96  
97          addFile(descr, "WEB-INF" + File.separatorChar + "web.xml");
98      }
99  
100     /**
101      * add a file under WEB-INF/lib/
102      */
103     public void addLib(File fileName) throws ArchiverException {
104         addDirectory(fileName.getParentFile(), "WEB-INF/lib/", new String[] {fileName.getName()}, null);
105     }
106 
107     /**
108      * add files under WEB-INF/lib/
109      */
110     public void addLibs(File directoryName, String[] includes, String[] excludes) throws ArchiverException {
111         addDirectory(directoryName, "WEB-INF/lib/", includes, excludes);
112     }
113 
114     /**
115      * add a file under WEB-INF/lib/
116      */
117     public void addClass(File fileName) throws ArchiverException {
118         addDirectory(fileName.getParentFile(), "WEB-INF/classes/", new String[] {fileName.getName()}, null);
119     }
120 
121     /**
122      * add files under WEB-INF/classes
123      */
124     public void addClasses(File directoryName, String[] includes, String[] excludes) throws ArchiverException {
125         addDirectory(directoryName, "WEB-INF/classes/", includes, excludes);
126     }
127 
128     /**
129      * files to add under WEB-INF;
130      */
131     public void addWebinf(File directoryName, String[] includes, String[] excludes) throws ArchiverException {
132         addDirectory(directoryName, "WEB-INF/", includes, excludes);
133     }
134 
135     /**
136      * override of parent; validates configuration
137      * before initializing the output stream.
138      *
139      * @param zOut
140      */
141     @Override
142     protected void initZipOutputStream(ConcurrentJarCreator zOut) throws ArchiverException, IOException {
143         // If no webxml file is specified, it's an error.
144         if (expectWebXml && deploymentDescriptor == null && !isInUpdateMode()) {
145             throw new ArchiverException(
146                     "webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode)");
147         }
148 
149         super.initZipOutputStream(zOut);
150     }
151 
152     /**
153      * Overridden from ZipArchiver class to deal with web.xml
154      */
155     @Override
156     protected void zipFile(ArchiveEntry entry, ConcurrentJarCreator zOut, String vPath)
157             throws IOException, ArchiverException {
158         // If the file being added is WEB-INF/web.xml, we warn if it's
159         // not the one specified in the "webxml" attribute - or if
160         // it's being added twice, meaning the same file is specified
161         // by the "webxml" attribute and in a <fileset> element.
162         if (vPath.equalsIgnoreCase("WEB-INF/web.xml")) {
163             if (descriptorAdded
164                     || (expectWebXml
165                             && (deploymentDescriptor == null
166                                     || !ResourceUtils.isCanonicalizedSame(
167                                             entry.getResource(), deploymentDescriptor)))) {
168                 getLogger()
169                         .warn("Warning: selected " + archiveType
170                                 + " files include a WEB-INF/web.xml which will be ignored "
171                                 + "\n(webxml attribute is missing from "
172                                 + archiveType + " task, or ignoreWebxml attribute is specified as 'true')");
173             } else {
174                 super.zipFile(entry, zOut, vPath);
175                 descriptorAdded = true;
176             }
177         } else {
178             super.zipFile(entry, zOut, vPath);
179         }
180     }
181 
182     /**
183      * Make sure we don't think we already have a web.xml next time this task
184      * gets executed.
185      */
186     @Override
187     protected void cleanUp() throws IOException {
188         descriptorAdded = false;
189         expectWebXml = true;
190         super.cleanUp();
191     }
192 }