2011/08/05 - Jakarta Cactus has been retired.

For more information, please explore the Attic.

View Javadoc

1   /* 
2    * ========================================================================
3    * 
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements.  See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache License, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License.  You may obtain a copy of the License at
10   * 
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   * 
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * 
19   * ========================================================================
20   */
21  package org.apache.cactus.integration.ant;
22  
23  import java.io.File;
24  import java.io.IOException;
25  
26  import org.apache.tools.ant.BuildException;
27  import org.apache.tools.ant.Project;
28  import org.apache.tools.ant.Task;
29  import org.apache.tools.ant.types.XMLCatalog;
30  import org.codehaus.cargo.module.webapp.WebXml;
31  import org.codehaus.cargo.module.webapp.WebXmlIo;
32  import org.codehaus.cargo.module.webapp.merge.WebXmlMerger;
33  import org.codehaus.cargo.util.log.AntLogger;
34  import org.jdom.JDOMException;
35  
36  /**
37   * Ant task that can merge the definitions from two web deployment descriptors
38   * into one descriptor.
39   * 
40   * @since Cactus 1.5
41   * @version $Id: WebXmlMergeTask.java 394252 2006-04-15 04:20:17Z felipeal $
42   */
43  public class WebXmlMergeTask extends Task
44  {
45      
46      // Instance Variables ------------------------------------------------------
47      
48      /**
49       * Location of the original <code>web.xml</code>.
50       */
51      private File srcFile;  
52  
53      /**
54       * Location of the overriding <code>web.xml</code>.
55       */
56      private File mergeFile;  
57  
58      /**
59       * Location of the resulting <code>web.xml</code>.
60       */
61      private File destFile;
62  
63      /**
64       * Whether the merge should be performed even when the destination file is
65       * up to date.
66       */
67      private boolean force = false;
68      
69      /**
70       * Whether the resulting XML file should be indented.
71       */
72      private boolean indent = false;
73      
74      /**
75       * The encoding of the resulting XML file.
76       */
77      private String encoding;
78  
79      /**
80       * For resolving entities such as DTDs.
81       */
82      private XMLCatalog xmlCatalog = null;
83  
84      // Public Methods ----------------------------------------------------------
85      
86      /**
87       * {@inheritDoc}
88       * @see Task#execute()
89       */
90      public void execute() throws BuildException
91      {
92          if ((this.srcFile == null) || !this.srcFile.isFile())
93          {
94              throw new BuildException("The [srcfile] attribute is required");
95          }
96          if (this.destFile == null)
97          {
98              throw new BuildException("The [destfile] attribute is required");
99          }
100         
101         try
102         {
103             if (this.mergeFile != null)
104             {
105                 if (!this.mergeFile.isFile())
106                 {
107                     throw new BuildException("The merge file doesn't exist");
108                 }
109                 if (force
110                  || (srcFile.lastModified() > destFile.lastModified())
111                  || (mergeFile.lastModified() > destFile.lastModified()))
112                 {
113                     WebXml srcWebXml;
114                     try 
115                     {
116                         srcWebXml = WebXmlIo.parseWebXmlFromFile(
117                             this.srcFile, this.xmlCatalog);
118                     } 
119                     catch (JDOMException e) 
120                     {
121                         throw new BuildException("Unable to get the web.xml " 
122                            + "from the specified archive", e);
123                     }
124                     WebXml mergeWebXml = null;
125                     try 
126                     {
127                         mergeWebXml = WebXmlIo.parseWebXmlFromFile(
128                             this.mergeFile, this.xmlCatalog);
129                     } 
130                     catch (JDOMException e) 
131                     {
132                         throw new BuildException("Unable to parse the " 
133                             + "web.xml from the specified file.", e);
134                     }
135                     WebXmlMerger merger = new WebXmlMerger(srcWebXml);
136                     merger.setLogger(new AntLogger(this));
137                     merger.merge(mergeWebXml);
138                     WebXmlIo.writeDescriptor(srcWebXml, this.destFile,
139                         this.encoding, this.indent);
140                 }
141                 else
142                 {
143                     log("The destination file is up to date",
144                         Project.MSG_VERBOSE);
145                 }
146             }
147             else
148             {
149                 throw new BuildException("The [mergefile] attribute is "
150                     + "required");
151             }
152         }
153         catch (IOException ioe)
154         {
155             throw new BuildException("An I/O error occurred: "
156                 + ioe.getMessage(), ioe);
157         }
158     }
159 
160     /**
161      * Adds an XML catalog to the internal catalog.
162      *
163      * @param theXmlCatalog the XMLCatalog instance to use to look up DTDs
164      */
165     public final void addConfiguredXMLCatalog(XMLCatalog theXmlCatalog)
166     {
167         if (this.xmlCatalog == null)
168         {
169             this.xmlCatalog = new XMLCatalog();
170             this.xmlCatalog.setProject(getProject());
171         }
172         this.xmlCatalog.addConfiguredXMLCatalog(theXmlCatalog);
173     }
174 
175     /**
176      * The original web deployment descriptor into which the new elements will
177      * be merged.
178      * 
179      * @param theSrcFile the original <code>web.xml</code>
180      */
181     public final void setSrcFile(File theSrcFile)
182     {
183         this.srcFile = theSrcFile;
184     }
185 
186     /**
187      * The descriptor to merge into the original file.
188      * 
189      * @param theMergeFile the <code>web.xml</code> to merge
190      */
191     public final void setMergeFile(File theMergeFile)
192     {
193         this.mergeFile = theMergeFile;
194     }
195 
196     /**
197      * The destination file where the result of the merge are stored.
198      * 
199      * @param theDestFile the resulting <code>web.xml</code>
200      */
201     public final void setDestFile(File theDestFile)
202     {
203         this.destFile = theDestFile;
204     }
205     
206     /**
207      * Sets whether the merge should be performed even when the destination 
208      * file is up to date.
209      * 
210      * @param isForce Whether the merge should be forced
211      */
212     public final void setForce(boolean isForce)
213     {
214         this.force = isForce;
215     }
216 
217     /**
218      * Sets the encoding of the resulting XML file. Default is 'UTF-8'.
219      * 
220      * @param theEncoding The encoding to set
221      */
222     public final void setEncoding(String theEncoding)
223     {
224         this.encoding = theEncoding;
225     }
226 
227     /**
228      * Whether the result XML file should be indented for better readability.
229      * Default is 'false'.
230      *  
231      * @param isIndent Whether the result should be indented
232      */
233     public final void setIndent(boolean isIndent)
234     {
235         this.indent = isIndent;
236     }
237 
238 }