KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > deployment > EARStructure


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.deployment;
23
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.jar.Attributes JavaDoc;
29 import java.util.jar.Manifest JavaDoc;
30
31 import org.jboss.deployers.plugins.structure.ContextInfoImpl;
32 import org.jboss.deployers.plugins.structure.vfs.AbstractStructureDeployer;
33 import org.jboss.deployers.spi.structure.vfs.StructureMetaData;
34 import org.jboss.deployers.spi.structure.vfs.StructuredDeployers;
35 import org.jboss.metadata.XmlFileLoader;
36 import org.jboss.virtual.VirtualFile;
37 import org.jboss.virtual.VirtualFileFilter;
38 import org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter;
39 import org.w3c.dom.Element JavaDoc;
40
41 /**
42  * Structure deployer for EARs.
43  *
44  * @author Bill Burke
45  * @author Scott.Stark@jboss.org
46  * @version $Revision: 1.1 $
47  */

48 public class EARStructure extends AbstractStructureDeployer
49 {
50    /**
51     * The default ear/lib filter
52     */

53    public static final VirtualFileFilter DEFAULT_EAR_LIB_FILTER = new SuffixMatchFilter(".jar");
54
55    /**
56     * The ear/lib filter
57     */

58    private VirtualFileFilter earLibFilter = DEFAULT_EAR_LIB_FILTER;
59
60    /**
61     * Set the relative order to 1000 by default
62     *
63     */

64    public EARStructure()
65    {
66       setRelativeOrder(1000);
67    }
68
69    /**
70     * Get the earLibFilter.
71     *
72     * @return the earLibFilter.
73     */

74    public VirtualFileFilter getEarLibFilter()
75    {
76       return earLibFilter;
77    }
78
79    /**
80     * Set the earLibFilter.
81     *
82     * @param earLibFilter the earLibFilter.
83     * @throws IllegalArgumentException for a null filter
84     */

85    public void setEarLibFilter(VirtualFileFilter earLibFilter)
86    {
87       if (earLibFilter == null)
88          throw new IllegalArgumentException JavaDoc("Null filter");
89       this.earLibFilter = earLibFilter;
90    }
91
92    /**
93     * Determine the structure of the ear.
94     * @param root - a candidate ear file
95     * @param metaData - the structure metadata to populate
96     * @param deployers - the deployer chain to use for subdeployment recoginition.
97     */

98    public boolean determineStructure(VirtualFile root,
99       StructureMetaData metaData, StructuredDeployers deployers)
100    {
101       boolean valid = false;
102       try
103       {
104          if( root.isLeaf() == true || root.getName().endsWith(".ear") == false)
105             return false;
106
107          ContextInfoImpl context = new ContextInfoImpl(root.getPathName());
108          context.setMetaDataPath("META-INF");
109
110          VirtualFile applicationXml = getMetaDataFile(root, "META-INF/application.xml");
111          VirtualFile jbossAppXml = getMetaDataFile(root, "META-INF/jboss-app.xml");
112          VirtualFile lib = null;
113          J2eeApplicationMetaData j2eeMetaData = new J2eeApplicationMetaData();
114          boolean scan = true;
115
116          if (applicationXml != null)
117          {
118             InputStream JavaDoc in = applicationXml.openStream();
119             XmlFileLoader xfl = new XmlFileLoader(false);
120             Element JavaDoc application = xfl.getDocument(in, "META-INF/application.xml").getDocumentElement();
121             j2eeMetaData.importXml(application);
122             in.close();
123             scan = false;
124          }
125          if (jbossAppXml != null)
126          {
127             InputStream JavaDoc in = jbossAppXml.openStream();
128             XmlFileLoader xfl = new XmlFileLoader(false);
129             Element JavaDoc jbossApp = xfl.getDocument(in, "META-INF/jboss-app.xml").getDocumentElement();
130             j2eeMetaData.importXml(jbossApp);
131             in.close();
132          }
133
134          // the adding of the context should happen before the lib directory is processed
135
// as the EAR must be the parent to any child DeploymentContexts added in the lib/ directory
136
metaData.addContext(context);
137
138          // Add the ear lib contents to the classpath
139
String JavaDoc libDir = j2eeMetaData.getLibraryDirectory() == null ? "lib" : j2eeMetaData.getLibraryDirectory();
140          if (j2eeMetaData.getLibraryDirectory() != null)
141          {
142             try
143             {
144                lib = root.findChild(libDir);
145                if (lib != null)
146                {
147                   List JavaDoc<VirtualFile> archives = lib.getChildren(earLibFilter);
148                   for (VirtualFile archive : archives)
149                   {
150                      super.addClassPath(root, archive, true, true, context);
151                      // add any jars with persistence.xml as a deployment
152
if (archive.findChild("META-INF/persistence.xml") != null)
153                      {
154                         log.trace(archive.getName() + " in ear lib directory has persistence units");
155                         if (deployers.determineStructure(archive, metaData) == false)
156                         {
157                            throw new RuntimeException JavaDoc(archive.getName()
158                                  + " in lib directory has persistence.xml but is not a recognized deployment, .ear: "
159                                  + root.getName());
160                         }
161                      }
162                   }
163                }
164             }
165             catch (IOException JavaDoc ignored)
166             {
167                // lib directory does not exist
168
}
169          }
170
171          // Add the ear manifest locations?
172
super.addClassPath(root, root, false, true, context);
173
174          // TODO: need to scan for annotationss
175
if( scan )
176          {
177             scanEar(root, j2eeMetaData);
178          }
179
180          // Create subdeployments for the ear modules
181
for (Iterator JavaDoc iter = j2eeMetaData.getModules(); iter.hasNext();)
182          {
183             J2eeModuleMetaData mod = (J2eeModuleMetaData) iter.next();
184             String JavaDoc fileName = mod.getFileName();
185             if (fileName != null && (fileName = fileName.trim()).length() > 0)
186             {
187                try
188                {
189                   VirtualFile module = root.findChild(fileName);
190                   if (module == null)
191                   {
192                      throw new RuntimeException JavaDoc(fileName + " module listed in application.xml does not exist within .ear " + root.getName());
193                   }
194                   // Ask the deployers to analyze this
195
if( deployers.determineStructure(module, metaData) == false )
196                   {
197                      throw new RuntimeException JavaDoc(fileName
198                            + " module listed in application.xml is not a recognized deployment, .ear: "
199                            + root.getName());
200                   }
201                }
202                catch (IOException JavaDoc ignored)
203                {
204                   throw new RuntimeException JavaDoc(fileName + " module listed in application.xml does not exist within .ear " + root.getName(), ignored);
205                }
206             }
207          }
208
209          valid = true;
210       }
211       catch(Exception JavaDoc e)
212       {
213          throw new RuntimeException JavaDoc("Error determining structure: " + root.getName(), e);
214       }
215
216       return valid;
217    }
218
219    /**
220    For an ear without an application.xml, determine modules via:
221    a. All ear modules with an extension of .war are considered web modules. The
222     context root of the web module is the name of the file relative to the root
223     of the application package, with the .war extension removed.
224    b. All ear modules with extension of .rar are considered resource adapters.
225    c. A directory named lib is considered to be the library directory, as
226     described in Section�EE.8.2.1, �Bundled Libraries.�
227    d. For all ear modules with a filename extension of .jar, but not in the lib
228     directory, do the following:
229    i. If the JAR file contains a META-INF/MANIFEST.MF file with a Main-Class
230     attribute, or contains a META-INF/application-client.xml file, consider the
231     jar file to be an application client module.
232    ii. If the JAR file contains a META-INF/ejb-jar.xml file, or contains any
233    class with an EJB component annotation (Stateless, etc.), consider the JAR
234     file to be an EJB module.
235    iii. All other JAR files are ignored unless referenced by a JAR file
236     discovered above using one of the JAR file reference mechanisms such as the
237     Class-Path header in a manifest file.
238     * TODO: rewrite using vfs
239     */

240    private void scanEar(VirtualFile root, J2eeApplicationMetaData j2eeMetaData)
241       throws IOException JavaDoc
242    {
243       List JavaDoc<VirtualFile> archives = root.getChildren();
244       if( archives != null )
245       {
246          String JavaDoc earPath = root.getPathName();
247          for(VirtualFile archive : archives)
248          {
249             String JavaDoc module = earRelativePath(earPath, archive.getPathName());
250             int type = typeFromSuffix(module, archive);
251             if( type >= 0 )
252             {
253                J2eeModuleMetaData mod = new J2eeModuleMetaData(type, module);
254                j2eeMetaData.addModule(mod);
255             }
256          }
257       }
258    }
259
260    private int typeFromSuffix(String JavaDoc path, VirtualFile archive)
261       throws IOException JavaDoc
262    {
263       int type = -1;
264       if( path.endsWith(".war") )
265          type = J2eeModuleMetaData.WEB;
266       else if( path.endsWith(".rar") )
267          type = J2eeModuleMetaData.CONNECTOR;
268       else if( path.endsWith(".har") )
269          type = J2eeModuleMetaData.HAR;
270       else if( path.endsWith(".sar") )
271          type = J2eeModuleMetaData.SERVICE;
272       else if( path.endsWith(".jar") )
273       {
274          // Look for a META-INF/application-client.xml
275
VirtualFile mfFile = getMetaDataFile(archive, "META-INF/MANIFEST.MF");
276          VirtualFile clientXml = getMetaDataFile(archive, "META-INF/application-client.xml");
277          VirtualFile ejbXml = getMetaDataFile(archive, "META-INF/ejb-jar.xml");
278          VirtualFile jbossXml = getMetaDataFile(archive, "META-INF/jboss.xml");
279
280          if( clientXml != null )
281          {
282             type = J2eeModuleMetaData.CLIENT;
283          }
284          else if( mfFile != null )
285          {
286             InputStream JavaDoc is = mfFile.openStream();
287             Manifest JavaDoc mf = new Manifest JavaDoc(is);
288             is.close();
289             Attributes JavaDoc attrs = mf.getMainAttributes();
290             if( attrs.containsKey(Attributes.Name.MAIN_CLASS) )
291             {
292                type = J2eeModuleMetaData.CLIENT;
293             }
294             else
295             {
296                // TODO: scan for annotations. Assume EJB for now
297
type = J2eeModuleMetaData.EJB;
298             }
299          }
300          else if( ejbXml != null || jbossXml != null )
301          {
302             type = J2eeModuleMetaData.EJB;
303          }
304          else
305          {
306             // TODO: scan for annotations. Assume EJB for now
307
type = J2eeModuleMetaData.EJB;
308          }
309       }
310       
311       return type;
312    }
313
314    private String JavaDoc earRelativePath(String JavaDoc earPath, String JavaDoc pathName)
315    {
316       StringBuilder JavaDoc tmp = new StringBuilder JavaDoc(pathName);
317       tmp.delete(0, earPath.length());
318       return tmp.toString();
319    }
320
321    private VirtualFile getMetaDataFile(VirtualFile file, String JavaDoc path)
322    {
323       VirtualFile metaFile = null;
324       try
325       {
326          metaFile = file.findChild(path);
327       }
328       catch(IOException JavaDoc e)
329       {
330       }
331       return metaFile;
332    }
333 }
334
Popular Tags