KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > kohsuke > stapler > jelly > CustomTagLibrary


1 package org.kohsuke.stapler.jelly;
2
3 import org.apache.commons.jelly.JellyContext;
4 import org.apache.commons.jelly.JellyException;
5 import org.apache.commons.jelly.Script;
6 import org.apache.commons.jelly.Tag;
7 import org.apache.commons.jelly.TagLibrary;
8 import org.apache.commons.jelly.impl.DynamicTag;
9 import org.apache.commons.jelly.impl.TagFactory;
10 import org.apache.commons.jelly.impl.TagScript;
11 import org.kohsuke.stapler.MetaClass;
12 import org.kohsuke.stapler.MetaClassLoader;
13 import org.kohsuke.stapler.jelly.groovy.GroovyClassLoaderTearOff;
14 import org.xml.sax.Attributes JavaDoc;
15
16 import java.io.IOException JavaDoc;
17 import java.net.URL JavaDoc;
18 import java.util.Hashtable JavaDoc;
19 import java.util.Map JavaDoc;
20
21 /**
22  * {@link TagLibrary} that loads tags from tag files in a directory.
23  *
24  * @author Kohsuke Kawaguchi
25  */

26 public final class CustomTagLibrary extends TagLibrary {
27
28     /**
29      * Inherits values from this context.
30      * This context would be shared by multiple threads,
31      * but as long as we all just read it, it should be OK.
32      */

33     private final JellyContext master;
34
35     private final ClassLoader JavaDoc classLoader;
36     private final MetaClassLoader metaClassLoader;
37     private final String JavaDoc basePath;
38     /**
39      * Compiled tag files.
40      */

41     private final Map JavaDoc<String JavaDoc,Script> scripts = new Hashtable JavaDoc<String JavaDoc,Script>();
42
43     public CustomTagLibrary(JellyContext master, ClassLoader JavaDoc classLoader, String JavaDoc basePath) {
44         this.master = master;
45         this.classLoader = classLoader;
46         this.basePath = basePath;
47         this.metaClassLoader = MetaClassLoader.get(classLoader);
48     }
49
50     public TagScript createTagScript(String JavaDoc name, Attributes JavaDoc attributes) throws JellyException {
51         final Script s = load(name);
52         if(s==null) return null;
53
54         return new TagScript(new TagFactory() {
55             public Tag createTag(String JavaDoc name, Attributes JavaDoc attributes) {
56                 return new DynamicTag(s);
57             }
58         });
59     }
60
61     public Tag createTag(String JavaDoc name, Attributes JavaDoc attributes) throws JellyException {
62         Script s = load(name);
63         if(s==null)
64             return null;
65         return new DynamicTag(s);
66     }
67
68     /**
69      * Obtains the script for the given tag name. Loads if necessary.
70      *
71      * <p>
72      * Synchronizing this method would have a potential race condition
73      * if two threads try to load two tags that are referencing each other.
74      *
75      * <p>
76      * So we synchronize {@link #scripts}, even though this means
77      * we may end up compiling the same script twice.
78      */

79     private Script load(String JavaDoc name) throws JellyException {
80
81         Script script = scripts.get(name);
82         if(script!=null && !MetaClass.NO_CACHE)
83             return script;
84
85         URL JavaDoc res = classLoader.getResource(basePath + '/' + name + ".jelly");
86         if(res!=null) {
87             script = loadJellyScript(res);
88             scripts.put(name,script);
89             return script;
90         }
91
92         res = classLoader.getResource(basePath + '/' + name + ".groovy");
93         if(res!=null) {
94             try {
95                 GroovyClassLoaderTearOff gcl = metaClassLoader.getTearOff(GroovyClassLoaderTearOff.class);
96                 script = gcl.parse(res);
97                 scripts.put(name,script);
98                 return script;
99             } catch (LinkageError JavaDoc e) {
100                 // no groovy. ignore
101
} catch (IOException JavaDoc e) {
102                 throw new JellyException(e);
103             }
104         }
105
106         return null;
107     }
108
109     private Script loadJellyScript(URL JavaDoc res) throws JellyException {
110         // compile script
111
JellyContext context = new JellyContext(master);
112         context.setClassLoader(classLoader);
113         return context.compileScript(res);
114     }
115 }
116
Popular Tags