KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > portal > format > template > TemplateRepository


1 /*****************************************
2  * *
3  * JBoss Portal: The OpenSource Portal *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  *****************************************/

9
10 package org.jboss.portal.format.template;
11
12 import java.io.IOException JavaDoc;
13 import java.lang.reflect.Constructor JavaDoc;
14 import java.util.Collection JavaDoc;
15 import java.util.Collections JavaDoc;
16 import java.util.HashMap JavaDoc;
17 import java.util.Map JavaDoc;
18 import java.util.Set JavaDoc;
19
20 import javassist.CannotCompileException;
21 import javassist.CtClass;
22
23 import org.apache.log4j.Logger;
24 import org.dom4j.Document;
25 import org.dom4j.Element;
26
27 /**
28  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
29  */

30 public class TemplateRepository
31 {
32
33    /** The class logger. */
34    private final Logger log = Logger.getLogger(getClass());
35
36    /** Template name -> template object. */
37    private Map JavaDoc templates = new HashMap JavaDoc();
38
39    /** Template name -> Class object. */
40    private Map JavaDoc classes = new HashMap JavaDoc();
41
42    /** Compile the template definitions to bytecode. */
43    private TemplateClassLoader tcl = new TemplateClassLoader(Thread.currentThread().getContextClassLoader());
44
45    public TemplateRepository()
46    {
47    }
48
49    public Template createTemplate(String JavaDoc name)
50    {
51       return createTemplate(name, Context.NULL_CONTEXT);
52    }
53
54    /**
55     * Creates a new template instance.
56     * @param name the template name
57     * @param ctx the context with the template properties
58     * @return the template instance or null if it is not found
59     */

60    public Template createTemplate(String JavaDoc name, Context ctx)
61    {
62       Template template = null;
63       try
64       {
65          Class JavaDoc clazz = (Class JavaDoc)classes.get(name);
66          if (clazz != null)
67          {
68             Constructor JavaDoc ctor = clazz.getConstructor(new Class JavaDoc[]{Context.class});
69             template = (Template)ctor.newInstance(new Object JavaDoc[]{ctx});
70          }
71          else
72          {
73             log.warn("Template " + name + " not found");
74          }
75       }
76       catch(Exception JavaDoc e)
77       {
78          log.error("Cannot instantiate template " + name, e);
79          throw new RuntimeException JavaDoc("An unexpected exception occured during the template instantiation");
80       }
81       return template;
82    }
83
84    public void addTemplate(String JavaDoc name, Document doc) throws BuildException
85    {
86       addTemplate(name, doc, Collections.EMPTY_SET);
87    }
88
89    public void addTemplate(String JavaDoc name, Element node) throws BuildException
90    {
91       addTemplate(name, node, Collections.EMPTY_SET);
92    }
93
94    public void addTemplate(String JavaDoc name, Document doc, Set JavaDoc names) throws BuildException
95    {
96       addTemplate(name, doc.getRootElement(), names);
97    }
98
99    public void addTemplate(String JavaDoc name, Element node, Set JavaDoc names) throws BuildException
100    {
101       // Keep the original template
102
templates.put(name, node);
103       log.debug("Loaded template " + name);
104
105       // Generate the class
106
Class JavaDoc clazz = generate(node, names);
107       log.debug("Template " + name + " generated " + clazz.getName());
108
109       // Save the class for later
110
classes.put(name, clazz);
111    }
112
113    private Class JavaDoc generate(Element node, Set JavaDoc names) throws BuildException
114    {
115       try
116       {
117          // This is the classloader that will load the template
118
String JavaDoc className = tcl.addTemplate(node, names);
119
120          // Return the class corresponding to the template
121
return tcl.loadClass(className);
122       }
123       catch(ClassNotFoundException JavaDoc e)
124       {
125          throw new BuildException("Unexpected error, cannot compile template", e);
126       }
127    }
128
129    public void clear()
130    {
131       classes.clear();
132       templates.clear();
133       tcl = new TemplateClassLoader(Thread.currentThread().getContextClassLoader());
134    }
135
136    public static class TemplateClassLoader extends ClassLoader JavaDoc
137    {
138
139       private final Map JavaDoc classes;
140
141       public TemplateClassLoader(ClassLoader JavaDoc parent)
142       {
143          super(parent);
144          this.classes = new HashMap JavaDoc();
145       }
146
147       public String JavaDoc addTemplate(Document doc, Set JavaDoc names) throws BuildException
148       {
149          return addTemplate(doc.getRootElement(), names);
150       }
151
152       public String JavaDoc addTemplate(Element node, Set JavaDoc names) throws BuildException
153       {
154          try
155          {
156             TemplateBuilder builder = new TemplateBuilder(node, names);
157             builder.build();
158             CtClass cc = builder.getGeneratedClass();
159             classes.put(cc.getName(), cc.toBytecode());
160             return cc.getName();
161          }
162          catch(IOException JavaDoc e)
163          {
164             throw new BuildException("Unexpected error cannot compile template", e);
165          }
166          catch(CannotCompileException e)
167          {
168             throw new BuildException("Unexpected error cannot compile template", e);
169          }
170       }
171
172       public Collection JavaDoc getClassNames()
173       {
174          return Collections.unmodifiableCollection(classes.keySet());
175       }
176
177       protected Class JavaDoc findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc
178       {
179          byte[] bytes = (byte[])classes.get(name);
180          if (bytes == null)
181          {
182             throw new ClassNotFoundException JavaDoc("Class " + name + " does not exists");
183          }
184          return defineClass(name, bytes, 0, bytes.length);
185       }
186    }
187 }
188
Popular Tags