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.FileInputStream;
25  import java.io.IOException;
26  import java.util.Iterator;
27  
28  import org.apache.cactus.integration.api.version.Version;
29  import org.apache.tools.ant.BuildException;
30  import org.apache.tools.ant.Project;
31  import org.apache.tools.ant.taskdefs.Ear;
32  import org.apache.tools.ant.types.ZipFileSet;
33  import org.apache.tools.ant.util.FileUtils;
34  import org.codehaus.cargo.module.application.ApplicationXml;
35  import org.codehaus.cargo.module.application.ApplicationXmlIo;
36  import org.codehaus.cargo.module.application.DefaultEarArchive;
37  import org.codehaus.cargo.module.application.EarArchive;
38  import org.codehaus.cargo.module.ejb.EjbArchive;
39  import org.codehaus.cargo.module.ejb.EjbJarXml;
40  import org.codehaus.cargo.module.ejb.Entity;
41  import org.codehaus.cargo.module.ejb.Session;
42  import org.codehaus.cargo.module.webapp.EjbRef;
43  import org.jdom.JDOMException;
44  
45  /**
46   * An Ant task that injects elements necessary to run Cactus tests into an
47   * existing EAR file.
48   * 
49   * @version $Id: CactifyEarTask.java 394252 2006-04-15 04:20:17Z felipeal $
50   */
51  public class CactifyEarTask extends Ear
52  {
53      /**
54       * Cactus war configuration holder.
55       */
56      private CactifyWarTask cactusWar;
57      
58      /**
59       * The archive that contains the web-app that should be cactified.
60       */
61      private File srcFile;
62  
63      /**
64       * Indicates whether or not we should add ejb references to local ejbs
65       * in the deployment descriptor.
66       */
67      private boolean addEjbReferences;
68      
69      /**
70       * 
71       * @param theCactusWar CactusWar to set
72       */
73      public void addConfiguredCactuswar(CactifyWarTask theCactusWar)
74      {
75          cactusWar = theCactusWar;
76      }
77      
78      /**
79       * @param theSrcFile The srcFile to set.
80       */
81      public void setSrcFile(File theSrcFile)
82      {
83          srcFile = theSrcFile;
84      }
85      
86      /**
87       * @return Returns the addEjbReferences.
88       */
89      public boolean getAddEjbReferences()
90      {
91          return addEjbReferences;
92      }
93      /**
94       * Indicates whether or not ejb references should be added.
95       * If set to true all local ejbs will be accessible via
96       * java:comp/env/ejb/<EJB_NAME/>
97       * 
98       * @param isAddEjbReferences if ejb references should be added.
99       */
100     public void setAddEjbReferences(boolean isAddEjbReferences)
101     {
102         this.addEjbReferences = isAddEjbReferences;
103     }
104     
105     /**
106      * {@inheritDoc}
107      * @see org.apache.tools.ant.Task#execute()
108      */
109     public void execute() throws BuildException
110     {
111         if (cactusWar == null)
112         {
113             cactusWar = createCactusWarConfig();
114         }
115         //Add everything that's in the source EAR to the destination EAR
116         ZipFileSet currentFiles = new ZipFileSet();
117         currentFiles.setSrc(this.srcFile);
118         currentFiles.createExclude().setName("META-INF/application.xml");
119         addZipfileset(currentFiles);
120         
121         // cactify the application.xml
122         ApplicationXml appXml = null;
123         try 
124         {
125             appXml = getOriginalApplicationXml();
126         } 
127         catch (JDOMException e) 
128         {
129             throw new BuildException("Unable to get the "
130                + "original application.xml", e);
131         }
132         File tmpAppXml = cactifyApplicationXml(appXml);
133         setAppxml(tmpAppXml);
134         
135         // create the cactus war
136         File cactusWarFile = createCactusWar();
137         addFileToEar(cactusWarFile, cactusWar.getFileName());
138         
139         super.execute();
140     }
141     
142     /**
143      * 
144      * @return the application.xml from the source ear
145      * @throws JDOMException in case a JDOM exception is thrown
146      */
147     private ApplicationXml getOriginalApplicationXml() throws JDOMException
148     {
149         ApplicationXml appXml = null;
150         try
151         {
152             EarArchive ear = new DefaultEarArchive(
153                 new FileInputStream(this.srcFile));
154             appXml = ear.getApplicationXml();
155             if (appXml == null)
156             {
157                 throw new BuildException("The EAR source file does not "
158                     + "contain a META-INF/application.xml " 
159                     + "deployment descriptor");
160             }
161         }
162         catch (IOException e)
163         {
164             throw new BuildException("Failed to open EAR", e);
165         }
166         
167         return appXml;
168     }
169     
170     /**
171      * 
172      * @param theAppXml the application.xml to cactify
173      * @return the cactified application.xml
174      */
175     private File cactifyApplicationXml(ApplicationXml theAppXml)
176     {
177         theAppXml.addWebModule(cactusWar.getFileName(), cactusWar.getContext());
178         // serialize the cactified app xml
179         FileUtils fileUtils = FileUtils.newFileUtils();
180         File tmpAppXml = fileUtils.createTempFile("cactus", "application.xml",
181                                                   getProject().getBaseDir());
182         tmpAppXml.deleteOnExit();
183         try
184         {
185             ApplicationXmlIo.writeApplicationXml(theAppXml, 
186                                                  tmpAppXml, 
187                                                  null, true);
188         }
189         catch (IOException ioe)
190         {
191             throw new BuildException(
192                 "Could not write temporary deployment descriptor", ioe);
193         }
194         return tmpAppXml;
195     }
196     
197     /**
198      * 
199      * @return the cactus.war
200      */
201     private File createCactusWar()
202     {
203         FileUtils fileUtils = FileUtils.newFileUtils();
204         File tmpCactusWar = fileUtils.createTempFile("cactus", "cactus.war",
205                                                      getProject().getBaseDir());
206         tmpCactusWar.deleteOnExit();
207         cactusWar.setDestFile(tmpCactusWar);
208         
209         if (addEjbReferences)
210         {
211             try 
212             {
213                 addEjbReferencesToWar(tmpCactusWar);
214             } 
215             catch (JDOMException e) 
216             {
217                 throw new BuildException("Unable to add ejb-references", e);
218             }
219         }
220 
221         cactusWar.execute();
222         
223         return tmpCactusWar;
224     }
225     
226     /**
227      * 
228      * @param theFile the file to add
229      * @param theFullPath the path within the ear
230      */
231     private void addFileToEar(File theFile, String theFullPath)
232     {
233         ZipFileSet fs = new ZipFileSet();
234         fs.setFile(theFile);
235         fs.setFullpath(theFullPath);
236         addZipfileset(fs);
237     }
238     
239     /**
240      * Initialize cactusWar with some default values.
241      *
242      * @return the CactusWar configuration
243      */
244     private CactifyWarTask createCactusWarConfig()
245     {
246         CactifyWarTask cactusWarConfig = new CactifyWarTask();
247         Version version = new Version();
248         version.setValue("2.3");
249         cactusWarConfig.setVersion(version);
250         cactusWarConfig.setContext("/cactus");
251         cactusWarConfig.setProject(getProject());
252         
253         return cactusWarConfig;
254     }
255 
256     /**
257      * Add ejb references.
258      * 
259      * @param theWar temporary cactus war
260      * @throws JDOMException in case a parse exception is thrown 
261      */
262     private void addEjbReferencesToWar(File theWar) throws JDOMException 
263     {
264         try
265         {
266             EarArchive ear = new DefaultEarArchive(
267                 new FileInputStream(srcFile));
268             ApplicationXml appXml = ear.getApplicationXml();
269             Iterator ejbModules = appXml.getEjbModules();
270             while (ejbModules.hasNext())
271             {
272                 String module = (String) ejbModules.next();
273                 EjbArchive ejbArchive = ear.getEjbModule(module);
274                 EjbJarXml descr = ejbArchive.getEjbJarXml();
275                 Iterator vendorDescrIterator = descr.getVendorDescriptors();
276                 if (vendorDescrIterator == null 
277                     || !vendorDescrIterator.hasNext())
278                 {
279                     throw new BuildException("Failed to find vendor " 
280                                              + "deployment descriptor " 
281                                              + "for ejb jar " + module);
282                 }
283                 
284                 Iterator ejbs = descr.getSessionEjbs();
285                 while (ejbs.hasNext())
286                 {
287                     Session ejb = (Session) ejbs.next();
288                     String name = ejb.getName();
289                     String local = ejb.getLocal();
290                     String localHome = ejb.getLocalHome();
291                     if (local != null)
292                     {
293                         log("Adding ejb-ref for local session ejb "
294                             + ejb.getName(),
295                             Project.MSG_VERBOSE);
296                         EjbRef ref = new EjbRef();
297                         ref.setType("Session");
298                         ref.setEjbName(name);
299                         ref.setName("ejb/" + name);
300                         ref.setEjbInterface(local);
301                         ref.setEjbHomeInterface(localHome);
302                         ref.setLocal(true);
303                         
304                         cactusWar.addConfiguredEjbref(ref);
305                     }
306                 }
307                 ejbs = descr.getEntityEjbs();
308                 while (ejbs.hasNext())
309                 {
310                     Entity ejb = (Entity) ejbs.next();
311                     String name = ejb.getName();
312                     String local = ejb.getLocal();
313                     String localHome = ejb.getLocalHome();
314                     if (local != null)
315                     {
316                         log("Adding ejb-ref for local entity ejb "
317                             + ejb.getName(),
318                             Project.MSG_VERBOSE);
319                         EjbRef ref = new EjbRef();
320                         ref.setType("Entity");
321                         ref.setEjbName(name);
322                         ref.setName("ejb/" + name);
323                         ref.setEjbInterface(local);
324                         ref.setEjbHomeInterface(localHome);
325                         ref.setLocal(true);
326                         
327                         cactusWar.addConfiguredEjbref(ref);
328                     }
329                 }
330             }
331         }
332         catch (IOException e)
333         {
334             throw new BuildException("Could not merge deployment " 
335                                      + "descriptors", e);
336         }
337     }
338 }