KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
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.File JavaDoc;
25 import java.io.FileFilter JavaDoc;
26 import java.net.JarURLConnection JavaDoc;
27 import java.net.URL JavaDoc;
28 import java.net.URLConnection JavaDoc;
29 import java.util.Arrays JavaDoc;
30 import java.util.Enumeration JavaDoc;
31 import java.util.jar.JarEntry JavaDoc;
32 import java.util.jar.JarFile JavaDoc;
33
34 import org.jboss.util.Strings;
35
36 /**
37  * This deployer exists to prevent deployment of packages whose deployers are not yet
38  * deployed. It will accept only jar/zip format files or directories that don't
39  * have a META-INF directory, or if they do, don't have any .xml files there. It
40  * assumes any package with a META-INF/*.xml file needs a specialized deployer.
41  *
42  * @todo find a way to scan just the META-INF files, not the whole jar.
43  *
44  * @author <a HREF="mailto:scott.stark@jboss.org">Scott Stark</a>
45  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
46  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
47  * @version $Revision: 57108 $
48  */

49 public class JARDeployer extends SubDeployerSupport
50    implements JARDeployerMBean
51 {
52    /**
53     * The suffixes we accept, along with their relative order.
54     *
55     * For JARDeployer, this is only used to populate the MainDeployer's
56     * SuffixOrder list, it is not used to actually match deployment suffixes
57     */

58    private static final String JavaDoc[] DEFAULT_ENHANCED_SUFFIXES = new String JavaDoc[] {
59          "700:.jar", // normal .jar
60
"750:.zip", // normal .zip
61
"900:.last" // make content of .last dirs/archives deploy last
62
};
63    
64    private String JavaDoc[] descriptorNames = {
65       ".xml"
66    };
67
68    /**
69     * Default CTOR
70     */

71    public JARDeployer()
72    {
73       super.setEnhancedSuffixes(DEFAULT_ENHANCED_SUFFIXES);
74    }
75    
76    public String JavaDoc[] getDescriptorNames()
77    {
78       return descriptorNames;
79    }
80    
81    public void setDescriptorNames(String JavaDoc[] descriptorNames)
82    {
83       this.descriptorNames = descriptorNames;
84    }
85    
86    // ServiceMBeanSupport methods
87

88    protected void stopService()
89    {
90       // This can't be run right now since the JARDeployer is started before the MainDeployer,
91
// so the MainDeployer is stopped first... so the JARDeployer can't unregister.
92

93       // super.stopService();
94
}
95
96    // SubDeployer implementation
97

98    /**
99     * The <code>accepts</code> method is called by MainDeployer to
100     * determine which deployer is suitable for a DeploymentInfo.
101     *
102     * @todo find a way to scan just the META-INF files, not the whole jar.
103     *
104     * @param di a <code>DeploymentInfo</code> value
105     * @return a <code>boolean</code> value
106     */

107    public boolean accepts(DeploymentInfo di)
108    {
109       boolean trace = log.isTraceEnabled();
110       
111       try
112       {
113          // Reject extensions not configured in this subdeployer
114
// but do consider accepting non-dotted deployments,
115
// like deploy-hasingleton
116
if (di.shortName.indexOf('.') != -1 && super.accepts(di) == false)
117          {
118             return false;
119          }
120          
121          // Reject deployments with a WEB-INF/ directory
122
URL JavaDoc wdDir = di.localCl.findResource("WEB-INF/");
123          if (wdDir != null)
124          {
125             return false;
126          }
127          
128          // Since a META-INF directory exists within rt.jar, we can't just do a
129
// getResource (it will always return rt.jar's version).
130
// The method we want is findResource, but it is marked protected in
131
// ClassLoader. Fortunately, URLClassLoader exposes it which makes
132
// this hack possible. Anybody have a better way to check a URL
133
// for the existance of a META-INF??
134
URL JavaDoc ddDir;
135          try
136          {
137             ddDir = di.localCl.findResource("META-INF/");
138             if (ddDir == null)
139             {
140                log.debug("No META-INF or WEB-INF resource found, assuming it if for us");
141                return true;
142             }
143          }
144          catch (ClassCastException JavaDoc e)
145          {
146              // assume there is a META-INF...
147
ddDir = new URL JavaDoc(di.url, "META-INF/");
148          }
149
150          if (ddDir.getProtocol().equals("file"))
151          {
152             log.trace("File protocol: "+ddDir);
153             File JavaDoc file = new File JavaDoc(ddDir.getFile());
154             if (!file.exists())
155             {
156                log.warn("File not found: " + file);
157                return true;
158             }
159             
160             // Scan for any xml files in the META-INF dir
161
File JavaDoc[] entries = file.listFiles(
162                new FileFilter JavaDoc()
163                {
164                   public boolean accept(File JavaDoc pathname)
165                   {
166                      boolean accept = false;
167                      String JavaDoc name = pathname.getName();
168                      for(int n = 0; accept == false && n < descriptorNames.length; n ++)
169                      {
170                         String JavaDoc d = descriptorNames[n];
171                         accept = name.endsWith(d);
172                      }
173                      return accept;
174                   }
175                }
176             );
177             log.debug("XML entries found: " + entries.length);
178             return entries.length == 0;
179          } // end of if ()
180
else if (ddDir.getProtocol().equals("jar") == true)
181          {
182             log.trace("jar protocol: " + ddDir);
183             JarFile JavaDoc jarFile = null;
184       
185             try
186             {
187                URLConnection JavaDoc con = ddDir.openConnection();
188                JarURLConnection JavaDoc jarConn = (JarURLConnection JavaDoc) con;
189                /* Need to set caching to false otherwise closing the jarfile
190                ends up conflicting with other users of the cached jar.
191                */

192                jarConn.setUseCaches(false);
193                jarFile = jarConn.getJarFile();
194
195                // Scan for any xml files in the META-INF dir
196
if (trace)
197                   log.trace("Descriptor names=" + Arrays.asList(descriptorNames));
198                for (Enumeration JavaDoc e = jarFile.entries(); e.hasMoreElements();)
199                {
200                   JarEntry JavaDoc entry = (JarEntry JavaDoc)e.nextElement();
201                   String JavaDoc name = entry.getName();
202                   if (trace)
203                      log.trace("Looking at entry: '" + name + "'");
204                   
205                   // JBAS-2949 - Look for xml descriptors directly
206
// under META-INF/, not in META-INF/ subdirectories
207
if (name.startsWith("META-INF/") && Strings.count(name, "/") == 1)
208                   {
209                      for (int n = 0; n < descriptorNames.length; n ++)
210                      {
211                         if (name.endsWith(descriptorNames[n]))
212                         {
213                            log.debug("Found entry: '" + name + "', matching: '"
214                                  + descriptorNames[n] + "', rejecting jar");
215                            
216                            // Do not accept this as jar file
217
return false;
218                         }
219                      }
220                   }
221                }
222             }
223             catch (Exception JavaDoc e)
224             {
225                log.warn("Looking inside jar failed; ignoring", e);
226                return false;
227             }
228             finally
229             {
230                if (jarFile != null)
231                   jarFile.close();
232                jarFile = null;
233             }
234
235             log.debug("No xml files found");
236             return true;
237          }
238          else
239          {
240             log.debug("Unrecognized protocol: " + ddDir.getProtocol());
241          }
242
243          return false;
244       }
245       catch (Exception JavaDoc e)
246       {
247          log.trace("Ignored error", e);
248          return false;
249       }
250    }
251 }
252
Popular Tags