KickJava   Java API By Example, From Geeks To Geeks.

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


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.Writer JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.LinkedList JavaDoc;
15 import java.util.Set JavaDoc;
16
17 import javassist.CannotCompileException;
18 import javassist.ClassPool;
19 import javassist.CtClass;
20 import javassist.CtConstructor;
21 import javassist.CtField;
22 import javassist.CtMethod;
23 import javassist.CtNewMethod;
24 import javassist.LoaderClassPath;
25 import javassist.Modifier;
26 import javassist.NotFoundException;
27
28 import org.apache.log4j.Logger;
29 import org.dom4j.Document;
30 import org.dom4j.Element;
31 import org.dom4j.Node;
32 import org.dom4j.Text;
33
34 /**
35  * @author <a HREF="mailto:julien@jboss.org">Julien Viet</a>
36  */

37 public class TemplateBuilder
38 {
39
40    private static final String JavaDoc CONTEXT = Context.class.getName();
41    private static final String JavaDoc ITERATOR = Iterator JavaDoc.class.getName();
42
43    private final ClassPool pool;
44    private final Element node;
45    private final int index;
46    private final Logger log;
47    private final Set JavaDoc propertyNames;
48    private CtClass cc;
49
50    public static int classNameCounter = 0;
51
52    public TemplateBuilder(Document doc, Set JavaDoc propertyNames)
53    {
54       this(doc.getRootElement(), propertyNames);
55    }
56
57    public TemplateBuilder(Element node, Set JavaDoc propertyNames)
58    {
59       this(new ClassPool(null), node, propertyNames);
60       pool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
61    }
62
63    public TemplateBuilder(ClassPool pool, Document doc, Set JavaDoc names)
64    {
65       this(pool, doc.getRootElement(), names);
66    }
67
68    public TemplateBuilder(ClassPool pool, Element node, Set JavaDoc names)
69    {
70       this.index = classNameCounter++;
71       this.pool = pool;
72       this.node = node;
73       this.propertyNames = names;
74       this.log = Logger.getLogger(getClass() + "." + index);
75    }
76
77    public CtClass getGeneratedClass()
78    {
79       return cc;
80    }
81
82    public void build() throws BuildException
83    {
84       try
85       {
86          cc = pool.makeClass("org.jboss.nukes.common.template.Generated" + index);
87          cc.setSuperclass(pool.get(Template.class.getName()));
88          cc.setModifiers(Modifier.PUBLIC);
89
90          addConstructor();
91          implementRender();
92       }
93       catch(CannotCompileException e)
94       {
95          throw new BuildException("Unexpected error, cannot build template", e);
96       }
97       catch(NotFoundException e)
98       {
99          throw new BuildException("Unexpected error, cannot build template", e);
100       }
101    }
102
103    private void addConstructor() throws CannotCompileException, NotFoundException
104    {
105       CtConstructor ctor = new CtConstructor(new CtClass[]{pool.get(CONTEXT)}, cc);
106       ctor.setBody("{ super($1); }");
107       cc.addConstructor(ctor);
108       log.debug("Added constructor on template " + cc.getName());
109    }
110
111    private void implementRender() throws CannotCompileException, NotFoundException
112    {
113       LinkedList JavaDoc stack = new LinkedList JavaDoc();
114       stack.add("");
115       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
116       buffer.append("public void render(").append(Context.class.getName()).append(" ctx, ").append(Writer JavaDoc.class.getName()).append(" writer)\n").
117              append("{\n").
118              append(" ").append(CONTEXT).append(" ctx_ = $1;\n");
119       generateRender(stack, buffer, " ", node);
120       buffer.append("}\n");
121       String JavaDoc code = buffer.toString();
122       CtMethod method = CtNewMethod.make(code, cc);
123       cc.addMethod(method);
124       CtField gc = new CtField(pool.get(String JavaDoc.class.getName()), "_generated_code", cc);
125       gc.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
126       CtField.Initializer initializer = CtField.Initializer.constant(code);
127       cc.addField(gc, initializer);
128       log.debug("Created render method on template " + cc.getName() + " with body " + code);
129    }
130
131    private void generateRender(LinkedList JavaDoc stack, StringBuffer JavaDoc buffer, String JavaDoc indent, Element node)
132    {
133       buffer.append(indent).append("String s_").append(stack.size()).append(" = null;\n");
134       for (Iterator JavaDoc i = node.content().iterator();i.hasNext();)
135       {
136          Node item = (Node)i.next();
137          if (item instanceof Text)
138          {
139             String JavaDoc text = item.getText().trim();
140             text = org.jboss.portal.common.util.Tools.replace(text, "\n", "\\n");
141             text = org.jboss.portal.common.util.Tools.replace(text, "\"", "\\\"");
142             buffer.append(indent).append("$2.write(\"").append(text).append("\");\n");
143          }
144          else if (item instanceof Element)
145          {
146             Element elt = (Element)item;
147             if ("loop".equals(elt.getName()))
148             {
149                String JavaDoc name = elt.attributeValue("name");
150                String JavaDoc iterator = "it_" + name;
151                String JavaDoc context = "ctx_" + name;
152                buffer.append(indent).append("for (").append(ITERATOR).append(" ").append(iterator).append(" = ").append("ctx_").append(stack.getLast()).append(".childIterator(\"").append(name).append("\");").
153                                       append(iterator).append(".hasNext();").
154                                       append(")\n").
155                       append(indent).append("{\n").
156                       append(indent).append(" ").append(CONTEXT).append(" ").append(context).append(" = (").append(CONTEXT).append(")").append(iterator).append(".next();\n");
157                stack.add(name);
158                generateRender(stack, buffer, indent + " ", elt.element("node"));
159                stack.removeLast();
160                buffer.append(indent).append("}\n");
161             }
162             else if ("ref".equals(elt.getName()))
163             {
164                String JavaDoc name = elt.attributeValue("name");
165                int depth = Integer.parseInt(elt.attributeValue("depth"));
166                String JavaDoc target = null;
167                if (depth == 0)
168                {
169                   target = propertyNames.contains(name) ? "$0.local" : "ctx_";
170                }
171                else
172                {
173                   target = "ctx_" + (String JavaDoc)stack.get(depth);
174                }
175                if (target != null)
176                {
177                   buffer.append(indent).append("s_").append(stack.size()).append(" = (java.lang.String)").append(target).append(".get(\"").append(name).append("\");\n").
178                          append(indent).append("if (s_").append(stack.size()).append(" != null)\n").
179                          append(indent).append("{\n").
180                          append(indent).append(" $2.write(s_").append(stack.size()).append(");\n").
181                          append(indent).append("}\n").
182                          append(indent).append("else if (log.isDebugEnabled())\n").
183                          append(indent).append("{\n").
184                          append(indent).append(" log.debug(\"field ").append(name).append(" is null\");\n").
185                          append(indent).append("}\n");
186                }
187                else
188                {
189 // log.warn("Path not usable ");
190
}
191             }
192          }
193       }
194    }
195
196 }
197
Popular Tags