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