KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > aop > deployers > AspectDeployer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, Red Hat Middleware LLC., 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.aop.deployers;
23
24 import org.jboss.aop.AspectAnnotationLoader;
25 import org.jboss.aop.AspectManager;
26 import org.jboss.aop.AspectXmlLoader;
27 import org.jboss.aop.deployment.JBossScopedClassLoaderHelper;
28 import org.jboss.deployers.plugins.deployer.AbstractSimpleDeployer;
29 import org.jboss.deployers.spi.deployer.DeploymentUnit;
30 import org.jboss.deployers.spi.DeploymentException;
31 import org.jboss.virtual.VirtualFile;
32 import org.jboss.virtual.VirtualFileFilter;
33 import org.jboss.virtual.VisitorAttributes;
34 import org.jboss.virtual.plugins.context.jar.JarUtils;
35 import org.jboss.virtual.plugins.vfs.helpers.FilterVirtualFileVisitor;
36 import org.jboss.virtual.plugins.vfs.helpers.SuffixesExcludeFilter;
37 import org.jboss.logging.Logger;
38 import org.w3c.dom.Document JavaDoc;
39
40 import java.io.DataInputStream JavaDoc;
41 import java.io.IOException JavaDoc;
42 import java.io.InputStream JavaDoc;
43 import java.util.List JavaDoc;
44
45 import javassist.bytecode.ClassFile;
46
47 /**
48  * Deployer for Aspects
49  *
50  * @author <a HREF="mailto:bill@jboss.org">Bill Burke</a>
51  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
52  */

53 public class AspectDeployer extends AbstractSimpleDeployer
54 {
55    private static final Logger log = Logger.getLogger(AspectDeployer.class);
56    private static final String JavaDoc AOP_JAR_SUFFIX = ".aop";
57    private static final String JavaDoc AOP_DD_SUFFIX = "-aop.xml";
58
59    /**
60     * Set the relative order to POSTPROCESS_CLASSLOADING_DEPLOYER-900 (4100)
61     * by default
62     *
63     */

64    public AspectDeployer()
65    {
66       setRelativeOrder(POSTPROCESS_CLASSLOADING_DEPLOYER-900);
67    }
68
69    public void deploy(DeploymentUnit unit) throws DeploymentException
70    {
71       List JavaDoc<VirtualFile> files = unit.getMetaDataFiles(null, AOP_DD_SUFFIX);
72
73       if (isAopArchiveOrFolder(unit))
74       {
75          deployAnnotations(unit);
76       }
77       
78       if (files.size() > 0)
79       {
80          deployXml(unit, files);
81       }
82    }
83    
84    public void undeploy(DeploymentUnit unit)
85    {
86       List JavaDoc<VirtualFile> files = unit.getMetaDataFiles(null, AOP_DD_SUFFIX);
87
88       if (isAopArchiveOrFolder(unit))
89       {
90          undeployAnnotations(unit);
91       }
92       
93       if (files.size() > 0)
94       {
95          undeployXml(unit, files);
96       }
97    }
98
99    private void deployXml(DeploymentUnit unit, List JavaDoc<VirtualFile> files) throws DeploymentException
100    {
101       ClassLoader JavaDoc scl = getScopedClassLoader(unit);
102
103       if (scl != null)
104       {
105          log.info("AOP deployment is scoped using classloader " + scl);
106       }
107       
108       for (VirtualFile vf : files)
109       {
110          try
111          {
112             log.debug("deploying: " + vf.toURL());
113             InputStream JavaDoc is = vf.openStream();
114             try
115             {
116                Document JavaDoc doc = AspectXmlLoader.loadDocument(is);
117                AspectXmlLoader loader = new AspectXmlLoader();
118       
119                if (scl != null)
120                {
121                   loader.setManager(AspectManager.instance(scl));
122                   loader.setClassLoader(scl);
123                }
124                else
125                {
126                   loader.setManager(AspectManager.instance());
127                }
128                loader.deployXML(doc, vf.toURL(), scl);
129             }
130             finally
131             {
132                is.close();
133             }
134          }
135          catch (Exception JavaDoc e)
136          {
137             throw new DeploymentException(e);
138          }
139       }
140    }
141
142    private void undeployXml(DeploymentUnit unit, List JavaDoc<VirtualFile> files)
143    {
144       ClassLoader JavaDoc scl = getScopedClassLoader(unit);
145
146       for (VirtualFile vf : files)
147       {
148          try
149          {
150             log.debug("undeploying: " + vf.toURL());
151             InputStream JavaDoc is = vf.openStream();
152             try
153             {
154                Document JavaDoc doc = AspectXmlLoader.loadDocument(is);
155                AspectXmlLoader loader = new AspectXmlLoader();
156                
157                AspectManager manager = (scl != null) ? AspectManager.instance(scl) : AspectManager.instance();
158                
159                loader.setManager(manager);
160                loader.undeployXML(doc, vf.toURL());
161             }
162             finally
163             {
164                is.close();
165             }
166          }
167          catch (Exception JavaDoc e)
168          {
169             throw new RuntimeException JavaDoc(e);
170          }
171       }
172       
173       AspectManager.instance().unregisterClassLoader(unit.getClassLoader());
174    }
175
176    private void deployAnnotations(DeploymentUnit unit) throws DeploymentException
177    {
178       ClassLoader JavaDoc scl = getScopedClassLoader(unit);
179
180       if (scl != null)
181       {
182          log.info("AOP deployment is scoped using classloader " + scl);
183       }
184
185       AspectAnnotationLoader loader = getAnnotationLoader(scl);
186       List JavaDoc<VirtualFile> files = getClasses(unit);
187       for(VirtualFile file : files)
188       {
189          ClassFile cf = loadClassFile(file);
190          
191          try
192          {
193             log.debug("Deploying possibly annotated class " + cf.getName());
194             loader.deployClassFile(cf);
195          }
196          catch (Exception JavaDoc e)
197          {
198             throw new DeploymentException("Error reading annotations for " + file, e);
199          }
200       }
201    }
202    
203    private void undeployAnnotations(DeploymentUnit unit)
204    {
205       ClassLoader JavaDoc scl = getScopedClassLoader(unit);
206       AspectAnnotationLoader loader = getAnnotationLoader(scl);
207       List JavaDoc<VirtualFile> files = getClasses(unit);
208       for(VirtualFile file : files)
209       {
210          ClassFile cf = loadClassFile(file);
211          
212          try
213          {
214             log.debug("Undeploying possibly annotated class " + cf.getName());
215             loader.undeployClassFile(cf);
216          }
217          catch (Exception JavaDoc e)
218          {
219             throw new RuntimeException JavaDoc("Error reading annotations for " + file, e);
220          }
221       }
222    }
223
224    private AspectAnnotationLoader getAnnotationLoader(ClassLoader JavaDoc scl)
225    {
226       AspectManager manager = (scl != null) ? AspectManager.instance(scl) : AspectManager.instance();
227       AspectAnnotationLoader loader = new AspectAnnotationLoader(manager);
228       loader.setClassLoader(scl);
229       return loader;
230    }
231    
232    private ClassFile loadClassFile(VirtualFile file)
233    {
234       DataInputStream JavaDoc din = null;
235       ClassFile cf = null;
236       try
237       {
238          InputStream JavaDoc in = file.openStream();
239          din = new DataInputStream JavaDoc(in);
240          cf = new ClassFile(din);
241       }
242       catch (IOException JavaDoc e)
243       {
244          throw new RuntimeException JavaDoc("Error reading " + file, e);
245       }
246       finally
247       {
248          try
249          {
250             din.close();
251          }
252          catch (IOException JavaDoc e)
253          {
254             throw new RuntimeException JavaDoc("Error closing input stream for " + file, e);
255          }
256       }
257       
258       return cf;
259    }
260    
261    private List JavaDoc<VirtualFile> getClasses(DeploymentUnit unit)
262    {
263       VisitorAttributes va = new VisitorAttributes();
264       va.setLeavesOnly(true);
265       ClassFileFilter filter = new ClassFileFilter();
266       SuffixesExcludeFilter noJars = new SuffixesExcludeFilter(JarUtils.getSuffixes());
267       va.setRecurseFilter(noJars);
268       FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, va);
269
270       for (VirtualFile vf : unit.getDeploymentContext().getClassPath())
271       {
272          try
273          {
274             vf.visit(visitor);
275          }
276          catch (IOException JavaDoc e)
277          {
278             throw new RuntimeException JavaDoc(e);
279          }
280       }
281       return visitor.getMatched();
282
283    }
284    
285    private boolean isAopArchiveOrFolder(DeploymentUnit unit)
286    {
287       String JavaDoc name = unit.getName();
288       
289       //If name is of format 'blah-blah.aop!/' get rid of the trailing '!' and '/', and see if it ends with .aop
290
int index = name.length();
291       if (name.charAt(name.length() - 1) == '/')
292       {
293          index--;
294       }
295       if (name.charAt(name.length() - 2) == '!')
296       {
297          index--;
298       }
299       String JavaDoc realName = (index == name.length()) ? name : name.substring(0, index);
300       
301       return (realName.endsWith(AOP_JAR_SUFFIX));
302    }
303    
304    private ClassLoader JavaDoc getScopedClassLoader(DeploymentUnit unit)
305    {
306       //Scoped AOP deployments are only available when deployed as part of a scoped sar, ear etc.
307
//It can contain an aop.xml file, or it can be part of a .aop file
308
//Linking a standalone -aop.xml file onto a scoped deployment is not possible at the moment
309
if (JBossScopedClassLoaderHelper.isScopedClassLoader(unit.getClassLoader()))
310       {
311          return unit.getClassLoader();
312       }
313       
314       return null;
315    }
316
317    private static class ClassFileFilter implements VirtualFileFilter
318    {
319       public boolean accepts(VirtualFile file)
320       {
321          try
322          {
323             return file.isLeaf() && file.getName().endsWith(".class");
324          }
325          catch (IOException JavaDoc e)
326          {
327             throw new RuntimeException JavaDoc(e);
328          }
329       }
330    }
331
332 }
333
Popular Tags