001: /*
002: * ========================================================================
003: *
004: * Copyright 2005 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: import java.util.Iterator;
025:
026: import javax.xml.parsers.ParserConfigurationException;
027:
028: import org.apache.tools.ant.BuildException;
029: import org.apache.tools.ant.Project;
030: import org.apache.tools.ant.taskdefs.Ear;
031: import org.apache.tools.ant.types.ZipFileSet;
032: import org.apache.tools.ant.util.FileUtils;
033: import org.codehaus.cargo.module.application.ApplicationXml;
034: import org.codehaus.cargo.module.application.ApplicationXmlIo;
035: import org.codehaus.cargo.module.application.DefaultEarArchive;
036: import org.codehaus.cargo.module.application.EarArchive;
037: import org.codehaus.cargo.module.ejb.EjbArchive;
038: import org.codehaus.cargo.module.ejb.EjbJarXml;
039: import org.codehaus.cargo.module.ejb.Entity;
040: import org.codehaus.cargo.module.ejb.Session;
041: import org.codehaus.cargo.module.ejb.VendorEjbDescriptor;
042: import org.xml.sax.SAXException;
043:
044: /**
045: * An Ant task that injects elements necessary to run Cactus tests into an
046: * existing EAR file.
047: *
048: * @version $Id: CactifyEarTask.java 239173 2005-05-24 12:02:31Z grimsell $
049: */
050: public class CactifyEarTask extends Ear {
051: /**
052: * Cactus war configuration holder
053: */
054: private CactusWar cactusWar;
055:
056: /**
057: * The archive that contains the web-app that should be cactified.
058: */
059: private File srcFile;
060:
061: /**
062: * Indicates whether or not we should add ejb references to local ejbs
063: * in the deployment descriptor.
064: */
065: private boolean addEjbReferences;
066:
067: /**
068: *
069: * @param theCactusWar CactusWar to set
070: */
071: public void addConfiguredCactuswar(CactusWar theCactusWar) {
072: cactusWar = theCactusWar;
073: }
074:
075: /**
076: * @param theSrcFile The srcFile to set.
077: */
078: public void setSrcFile(File theSrcFile) {
079: srcFile = theSrcFile;
080: }
081:
082: /**
083: * @return Returns the addEjbReferences.
084: */
085: public boolean getAddEjbReferences() {
086: return addEjbReferences;
087: }
088:
089: /**
090: * Indicates whether or not ejb references should be added.
091: * If set to true all local ejbs will be accessible via
092: * java:comp/env/ejb/<EJB_NAME>
093: *
094: * @param isAddEjbReferences if ejb references should be added.
095: */
096: public void setAddEjbReferences(boolean isAddEjbReferences) {
097: this .addEjbReferences = isAddEjbReferences;
098: }
099:
100: /**
101: * @see org.apache.tools.ant.Task#execute()
102: */
103: public void execute() throws BuildException {
104: if (cactusWar == null) {
105: cactusWar = createCactusWarConfig();
106: }
107: //Add everything that's in the source EAR to the destination EAR
108: ZipFileSet currentFiles = new ZipFileSet();
109: currentFiles.setSrc(this .srcFile);
110: currentFiles.createExclude()
111: .setName("META-INF/application.xml");
112: addZipfileset(currentFiles);
113:
114: // cactify the application.xml
115: ApplicationXml appXml = getOriginalApplicationXml();
116: File tmpAppXml = cactifyApplicationXml(appXml);
117: setAppxml(tmpAppXml);
118:
119: // create the cactus war
120: File cactusWarFile = createCactusWar();
121: addFileToEar(cactusWarFile, cactusWar.getFileName());
122:
123: super .execute();
124: }
125:
126: /**
127: *
128: * @return the application.xml from the source ear
129: */
130: private ApplicationXml getOriginalApplicationXml() {
131: ApplicationXml appXml = null;
132: try {
133: EarArchive ear = new DefaultEarArchive(this .srcFile);
134: appXml = ear.getApplicationXml();
135: if (appXml == null) {
136: throw new BuildException(
137: "The EAR source file does not "
138: + "contain a META-INF/application.xml "
139: + "deployment descriptor");
140: }
141: } catch (SAXException e) {
142: throw new BuildException(
143: "Parsing of application.xml deployment descriptor failed",
144: e);
145: } catch (IOException e) {
146: throw new BuildException("Failed to open EAR", e);
147: } catch (ParserConfigurationException e) {
148: throw new BuildException("XML parser configuration error",
149: e);
150: }
151:
152: return appXml;
153: }
154:
155: /**
156: *
157: * @param theAppXml the application.xml to cactify
158: * @return the cactified application.xml
159: */
160: private File cactifyApplicationXml(ApplicationXml theAppXml) {
161: theAppXml.addWebModule(cactusWar.getFileName(), cactusWar
162: .getContext());
163: // serialize the cactified app xml
164: FileUtils fileUtils = FileUtils.newFileUtils();
165: File tmpAppXml = fileUtils.createTempFile("cactus",
166: "application.xml", getProject().getBaseDir());
167: tmpAppXml.deleteOnExit();
168: try {
169: ApplicationXmlIo.writeApplicationXml(theAppXml, tmpAppXml,
170: null, true);
171: } catch (IOException ioe) {
172: throw new BuildException(
173: "Could not write temporary deployment descriptor",
174: ioe);
175: }
176: return tmpAppXml;
177: }
178:
179: /**
180: *
181: * @return the cactus.war
182: */
183: private File createCactusWar() {
184: FileUtils fileUtils = FileUtils.newFileUtils();
185: File tmpCactusWar = fileUtils.createTempFile("cactus",
186: "cactus.war", getProject().getBaseDir());
187: tmpCactusWar.deleteOnExit();
188: cactusWar.setDestFile(tmpCactusWar);
189:
190: if (addEjbReferences) {
191: addEjbReferencesToWar(tmpCactusWar);
192: }
193:
194: cactusWar.execute();
195:
196: return tmpCactusWar;
197: }
198:
199: /**
200: *
201: * @param theFile the file to add
202: * @param theFullPath the path within the ear
203: */
204: private void addFileToEar(File theFile, String theFullPath) {
205: ZipFileSet fs = new ZipFileSet();
206: fs.setFile(theFile);
207: fs.setFullpath(theFullPath);
208: addZipfileset(fs);
209: }
210:
211: /**
212: * Initialize cactusWar with some default values.
213: *
214: * @return the CactusWar configuration
215: */
216: private CactusWar createCactusWarConfig() {
217: CactusWar cactusWarConfig = new CactusWar();
218: CactusWar.Version version = new CactusWar.Version();
219: version.setValue("2.3");
220: cactusWarConfig.setVersion(version);
221: cactusWarConfig.setContext("/cactus");
222: cactusWarConfig.setProject(getProject());
223:
224: return cactusWarConfig;
225: }
226:
227: /**
228: * Add ejb references.
229: *
230: * @param theWar temporary cactus war
231: */
232: private void addEjbReferencesToWar(File theWar) {
233: try {
234: EarArchive ear = new DefaultEarArchive(srcFile);
235: ApplicationXml appXml = ear.getApplicationXml();
236: Iterator ejbModules = appXml.getEjbModules();
237: while (ejbModules.hasNext()) {
238: String module = (String) ejbModules.next();
239: EjbArchive ejbArchive = ear.getEjbModule(module);
240: EjbJarXml descr = ejbArchive.getEjbJarXml();
241: VendorEjbDescriptor vendorDescr = descr
242: .getVendorDescriptor();
243: if (vendorDescr == null) {
244: throw new BuildException("Failed to find vendor "
245: + "deployment descriptor " + "for ejb jar "
246: + module);
247: }
248: Iterator ejbs = descr.getSessionEjbs();
249: while (ejbs.hasNext()) {
250: Session ejb = (Session) ejbs.next();
251: String name = ejb.getName();
252: String local = ejb.getLocal();
253: String localHome = ejb.getLocalHome();
254: if (local != null) {
255: log("Adding ejb-ref for local session ejb "
256: + ejb.getName(), Project.MSG_VERBOSE);
257: CactifyWarTask.EjbRef ref = new CactifyWarTask.EjbRef();
258: ref.setType("Session");
259: ref.setName("ejb/" + name);
260: ref.setLocalInterface(local);
261: ref.setLocalHomeInterface(localHome);
262:
263: String jndiName = vendorDescr.getJndiName(ejb);
264: ref.setJndiName(jndiName);
265: cactusWar.addConfiguredEjbref(ref);
266: }
267: }
268: ejbs = descr.getEntityEjbs();
269: while (ejbs.hasNext()) {
270: Entity ejb = (Entity) ejbs.next();
271: String name = ejb.getName();
272: String local = ejb.getLocal();
273: String localHome = ejb.getLocalHome();
274: if (local != null) {
275: log("Adding ejb-ref for local entity ejb "
276: + ejb.getName(), Project.MSG_VERBOSE);
277: CactifyWarTask.EjbRef ref = new CactifyWarTask.EjbRef();
278: ref.setType("Entity");
279: ref.setName("ejb/" + name);
280: ref.setLocalInterface(local);
281: ref.setLocalHomeInterface(localHome);
282:
283: String jndiName = vendorDescr.getJndiName(ejb);
284: ref.setJndiName(jndiName);
285: cactusWar.addConfiguredEjbref(ref);
286: }
287: }
288: }
289: } catch (IOException e) {
290: throw new BuildException("Could not merge deployment "
291: + "descriptors", e);
292: } catch (SAXException e) {
293: throw new BuildException("Parsing of merge file failed", e);
294: } catch (ParserConfigurationException e) {
295: throw new BuildException("XML parser configuration error",
296: e);
297: }
298: }
299: }
|