View Javadoc

1   /*
2    * VelocityMenuDisplayer.java
3    *
4    * Created on December 7, 2002, 12:35 AM
5    */
6   package net.sf.navigator.displayer;
7   
8   import net.sf.navigator.menu.MenuComponent;
9   import org.apache.commons.lang.StringUtils;
10  import org.apache.commons.logging.Log;
11  import org.apache.commons.logging.LogFactory;
12  import org.apache.velocity.Template;
13  import org.apache.velocity.VelocityContext;
14  import org.apache.velocity.app.VelocityEngine;
15  import org.apache.velocity.app.tools.VelocityFormatter;
16  import org.apache.velocity.runtime.RuntimeConstants;
17  import org.apache.velocity.tools.view.servlet.ServletLogger;
18  import org.apache.velocity.tools.view.servlet.WebappLoader;
19  
20  import javax.servlet.ServletContext;
21  import javax.servlet.http.HttpServletRequest;
22  import javax.servlet.jsp.JspException;
23  import javax.servlet.jsp.PageContext;
24  import java.io.IOException;
25  import java.io.StringWriter;
26  import java.util.*;
27  
28  /**
29   * @author  <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
30   * @version 1.0
31   */
32  public class VelocityMenuDisplayer extends MessageResourcesMenuDisplayer {
33      protected static final Log log = LogFactory.getLog(VelocityMenuDisplayer.class);
34      private static VelocityEngine velocityEngine = new VelocityEngine();
35      private PageContext pageContext = null;
36  
37      public static void initialize(ServletContext context) {
38          velocityEngine.setApplicationAttribute(ServletContext.class.getName(), context);
39  
40          // default to servletlogger, which logs to the servlet engines log
41          velocityEngine.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS,
42                               ServletLogger.class.getName());
43  
44          // by default, load resources with webapp resource loader
45          velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "webapp");
46          velocityEngine.setProperty("webapp.resource.loader.class", WebappLoader.class.getName());
47  
48          // now all is ready - init Velocity
49          try {
50              Properties props = new Properties();
51              ResourceBundle defaults = ResourceBundle.getBundle("net.sf.navigator.displayer.velocity");
52              for (Enumeration keys = defaults.getKeys(); keys.hasMoreElements();) {
53                  String key = (String) keys.nextElement();
54                  props.put(key, defaults.getString(key));
55              }
56  
57              // look to see if the user has overridden velocity.properties by
58              // placing velocity.properties in WEB-INF/classes
59              ResourceBundle custom = null;
60  
61              try {
62                  custom = ResourceBundle.getBundle("velocity");
63                  for (Enumeration keys = custom.getKeys(); keys.hasMoreElements();) {
64                      String key = (String) keys.nextElement();
65                      props.put(key, custom.getString(key));
66                  }
67              } catch (MissingResourceException mre) {
68                  log.debug("No velocity.properties found in classpath, using default settings");
69              }
70  
71              velocityEngine.init(props);
72          } catch (Exception e) {
73              log.error("Error initializing Velocity: " + e.getMessage());
74              e.printStackTrace();
75          }
76      }
77  
78      //~ Methods ================================================================
79  
80      public void init(PageContext pageContext, MenuDisplayerMapping mapping) {
81          super.init(pageContext, mapping);
82          this.pageContext = pageContext;
83      }
84  
85      public void display(MenuComponent menu) throws JspException, IOException {
86          if (isAllowed(menu)) {
87              displayComponents(menu);
88          }
89      }
90  
91      protected void displayComponents(MenuComponent menu)
92      throws JspException, IOException {
93          HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
94          Template t;
95  
96          try {
97              String template = getConfig();
98  
99              if (template == null) {
100                 throw new JspException("You must specify a template using the 'config' attribute.");
101             } else {
102                 log.debug("using template: " + template);
103             }
104 
105             t = velocityEngine.getTemplate(template);
106         } catch (Exception e) {
107             String msg = "Error initializing Velocity: " + e.toString();
108             log.error(msg, e);
109             throw new JspException(msg, e);
110         }
111 
112         StringWriter sw = new StringWriter();
113         VelocityContext context = new VelocityContext();
114 
115         context.put("formatter", new VelocityFormatter(context));
116         context.put("now", Calendar.getInstance().getTime());
117         context.put("ctxPath", request.getContextPath());
118         // add a helper class for string manipulation
119         context.put("stringUtils", new StringUtils());
120 
121         // add a Map for use by the Expandable List Menu
122         context.put("map", new HashMap());
123 
124         // see if a name and property were passed in
125         if (!StringUtils.isEmpty(name)) {
126             Object val1 = pageContext.findAttribute(name);
127 
128             if (val1 != null) {
129                 context.put(name, val1);
130             }
131         }
132 
133         // request-scope attributes
134         Enumeration e = request.getAttributeNames();
135 
136         while (e.hasMoreElements()) {
137             String name = (String) e.nextElement();
138             Object value = request.getAttribute(name);
139             context.put(name, value);
140         }
141 
142         context.put("request", request);
143         context.put("session", request.getSession(false));
144 
145         if (pageContext.getAttribute("menuId") != null) {
146             context.put("menuId", pageContext.getAttribute("menuId"));
147         }
148         context.put("menu", menu);
149         context.put("displayer", this);
150 
151         try {
152             t.merge(context, sw);
153         } catch (Exception ex) {
154             ex.printStackTrace();
155             throw new JspException(ex);
156         }
157 
158         String result = sw.getBuffer().toString();
159 
160         // Print this element to our output writer
161         pageContext.getOut().print(result);
162     }
163 
164     public void end(PageContext context) {
165         this.pageContext = null;
166     }
167 }