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 }