001: /*
002: * ========================================================================
003: *
004: * Copyright 2003 The Apache Software Foundation.
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * ========================================================================
019: */
020: package org.apache.cactus.integration.ant;
021:
022: import java.io.File;
023: import java.io.IOException;
024:
025: import javax.xml.parsers.ParserConfigurationException;
026:
027: import org.apache.tools.ant.BuildException;
028: import org.apache.tools.ant.Project;
029: import org.apache.tools.ant.Task;
030: import org.apache.tools.ant.types.XMLCatalog;
031: import org.codehaus.cargo.module.webapp.WebXml;
032: import org.codehaus.cargo.module.webapp.WebXmlIo;
033: import org.codehaus.cargo.module.webapp.WebXmlMerger;
034: import org.codehaus.cargo.util.monitor.AntMonitor;
035: import org.xml.sax.SAXException;
036:
037: /**
038: * Ant task that can merge the definitions from two web deployment descriptors
039: * into one descriptor.
040: *
041: * @since Cactus 1.5
042: * @version $Id: WebXmlMergeTask.java 239162 2005-04-26 09:57:59Z grimsell $
043: */
044: public class WebXmlMergeTask extends Task {
045:
046: // Instance Variables ------------------------------------------------------
047:
048: /**
049: * Location of the original <code>web.xml</code>
050: */
051: private File srcFile;
052:
053: /**
054: * Location of the overriding <code>web.xml</code>
055: */
056: private File mergeFile;
057:
058: /**
059: * Location of the resulting <code>web.xml</code>
060: */
061: private File destFile;
062:
063: /**
064: * Whether the merge should be performed even when the destination file is
065: * up to date.
066: */
067: private boolean force = false;
068:
069: /**
070: * Whether the resulting XML file should be indented.
071: */
072: private boolean indent = false;
073:
074: /**
075: * The encoding of the resulting XML file.
076: */
077: private String encoding;
078:
079: /**
080: * For resolving entities such as DTDs.
081: */
082: private XMLCatalog xmlCatalog = null;
083:
084: // Public Methods ----------------------------------------------------------
085:
086: /**
087: * @see Task#execute()
088: */
089: public void execute() throws BuildException {
090: if ((this .srcFile == null) || !this .srcFile.isFile()) {
091: throw new BuildException(
092: "The [srcfile] attribute is required");
093: }
094: if (this .destFile == null) {
095: throw new BuildException(
096: "The [destfile] attribute is required");
097: }
098:
099: try {
100: if (this .mergeFile != null) {
101: if (!this .mergeFile.isFile()) {
102: throw new BuildException(
103: "The merge file doesn't exist");
104: }
105: if (force
106: || (srcFile.lastModified() > destFile
107: .lastModified())
108: || (mergeFile.lastModified() > destFile
109: .lastModified())) {
110: WebXml srcWebXml = WebXmlIo.parseWebXmlFromFile(
111: this .srcFile, this .xmlCatalog);
112: WebXml mergeWebXml = WebXmlIo.parseWebXmlFromFile(
113: this .mergeFile, this .xmlCatalog);
114: WebXmlMerger merger = new WebXmlMerger(srcWebXml);
115: merger.setMonitor(new AntMonitor(this ));
116: merger.merge(mergeWebXml);
117: WebXmlIo.writeWebXml(srcWebXml, this .destFile,
118: this .encoding, this .indent);
119: } else {
120: log("The destination file is up to date",
121: Project.MSG_VERBOSE);
122: }
123: } else {
124: throw new BuildException(
125: "The [mergefile] attribute is " + "required");
126: }
127: } catch (ParserConfigurationException pce) {
128: throw new BuildException(
129: "XML parser configuration problem: "
130: + pce.getMessage(), pce);
131: } catch (SAXException saxe) {
132: throw new BuildException("Failed to parse descriptor: "
133: + saxe.getMessage(), saxe);
134: } catch (IOException ioe) {
135: throw new BuildException("An I/O error occurred: "
136: + ioe.getMessage(), ioe);
137: }
138: }
139:
140: /**
141: * Adds an XML catalog to the internal catalog.
142: *
143: * @param theXmlCatalog the XMLCatalog instance to use to look up DTDs
144: */
145: public final void addConfiguredXMLCatalog(XMLCatalog theXmlCatalog) {
146: if (this .xmlCatalog == null) {
147: this .xmlCatalog = new XMLCatalog();
148: this .xmlCatalog.setProject(getProject());
149: }
150: this .xmlCatalog.addConfiguredXMLCatalog(theXmlCatalog);
151: }
152:
153: /**
154: * The original web deployment descriptor into which the new elements will
155: * be merged.
156: *
157: * @param theSrcFile the original <code>web.xml</code>
158: */
159: public final void setSrcFile(File theSrcFile) {
160: this .srcFile = theSrcFile;
161: }
162:
163: /**
164: * The descriptor to merge into the original file.
165: *
166: * @param theMergeFile the <code>web.xml</code> to merge
167: */
168: public final void setMergeFile(File theMergeFile) {
169: this .mergeFile = theMergeFile;
170: }
171:
172: /**
173: * The destination file where the result of the merge are stored.
174: *
175: * @param theDestFile the resulting <code>web.xml</code>
176: */
177: public final void setDestFile(File theDestFile) {
178: this .destFile = theDestFile;
179: }
180:
181: /**
182: * Sets whether the merge should be performed even when the destination
183: * file is up to date.
184: *
185: * @param isForce Whether the merge should be forced
186: */
187: public final void setForce(boolean isForce) {
188: this .force = isForce;
189: }
190:
191: /**
192: * Sets the encoding of the resulting XML file. Default is 'UTF-8'.
193: *
194: * @param theEncoding The encoding to set
195: */
196: public final void setEncoding(String theEncoding) {
197: this .encoding = theEncoding;
198: }
199:
200: /**
201: * Whether the result XML file should be indented for better readability.
202: * Default is 'false'.
203: *
204: * @param isIndent Whether the result should be indented
205: */
206: public final void setIndent(boolean isIndent) {
207: this.indent = isIndent;
208: }
209:
210: }
|