View Javadoc
1   /*
2    * $Source$
3    * $Revision$
4    *
5    * Copyright (c) 1998, 1999, 2000 Semiotek Inc. All Rights Reserved.
6    *
7    * This software is the confidential intellectual property of
8    * of Semiotek Inc.; it is copyrighted and licensed, not sold.
9    * You may use it under the terms of the GNU General Public License,
10   * version 2, as published by the Free Software Foundation. If you 
11   * do not want to use the GPL, you may still use the software after
12   * purchasing a proprietary developers license from Semiotek Inc.
13   *
14   * This software is provided "as is", with NO WARRANTY, not even the 
15   * implied warranties of fitness to purpose, or merchantability. You
16   * assume all risks and liabilities associated with its use.
17   *
18   * See the attached License.html file for details, or contact us
19   * by e-mail at info@semiotek.com to get a copy.
20   */
21  
22  package org.melati.test;
23  
24  import java.io.IOException;
25  import java.util.Date;
26  
27  import javax.servlet.ServletConfig;
28  import javax.servlet.ServletException;
29  import javax.servlet.http.HttpServlet;
30  import javax.servlet.http.HttpServletRequest;
31  import javax.servlet.http.HttpServletResponse;
32  
33  import org.melati.util.MelatiBugMelatiException;
34  import org.webmacro.FastWriter;
35  import org.webmacro.InitException;
36  import org.webmacro.ResourceException;
37  import org.webmacro.Template;
38  import org.webmacro.WM;
39  import org.webmacro.WebMacro;
40  import org.webmacro.servlet.WebContext;
41  
42  /**
43   * This example demonstrates using WebMacro in "standalone" mode. Instead of
44   * subclassing from WMServlet you create and maintain your own WebMacro object
45   * and you are free to subclass from another servlet. Also, this technique can
46   * be used outside the servlet context.
47   * <p>
48   * The WebMacro master object is initialized when the servlet is initialized and
49   * destroyed when the servlet is destroyed. There is some overhead involved in
50   * creating the interface so you should prefer not to create one on every
51   * request, although it is not too expensive.
52   * <p>
53   * This servlet can be compiled and installed as an ordinary servlet. You need
54   * to ensure that your WebMacro.properties file is properly configured and
55   * available on your CLASSPATH. When setting up WebMacro.properties make sure
56   * that the TemplatePath is correctly set and that the template used by this
57   * servlet, "standalone.wm", is available on that path.
58   */
59  public class WebmacroStandalone extends HttpServlet {
60    private static final long serialVersionUID = 1L;
61  
62    /**
63     * This is the core WebMacro interface which we use to create Contexts, load
64     * Templates, and begin other WebMacro operations.
65     */
66    private WebMacro _wm = null;
67  
68    /**
69     * The init() method will be called by your servlet runner whenever it wants
70     * to instantiate a new copy of your servlet. We initialize WebMacro here so
71     * as to avoid the expense of initializing it on every request.
72     */
73    public void init(ServletConfig sc) throws ServletException {
74      try {
75        if (_wm == null) {
76          _wm = new WM();
77        }
78      } catch (InitException e) {
79        throw new ServletException("Could not initialize WebMacro: " + e);
80      }
81    }
82  
83    /**
84     * It's not strictly necessary to destroy the WebMacro object when you're done
85     * with it--garbage collection will eventually get it--but it makes sure the
86     * resources get freed. You really ought to do this, since it might be a lot
87     * of resources.
88     */
89    public void destroy() {
90      // It could of course be null already, but cheaper to re-null;
91      // and you get better test coverage.
92     _wm = null;
93    }
94  
95    /**
96     * We only implement the GET method in this servlet.
97     * <p>
98     * We create a WebContext object, populate it with some data, select a
99     * template, and write the output of that template to the output stream. Note
100    * that you need to pass the WebContext object to the template in order to
101    * write it, you also need an output stream, in this case the
102    * HttpServletResponse output stream is used.
103    * <p>
104    * If you were using WebMacro outside a servlet context you would not be able
105    * to construct a WebContext object, since you would not have the
106    * HttpServletRequest and HttpServletResponse objects which you need in order
107    * to do that. WebContext is a subclass of Context, so outside of a servlet
108    * just construct a TemplateContext object. You will obviously lose the
109    * ability to talk about servlet specific things in your templates (such as
110    * "Cookies") but otherwise it's the same.
111    * <p>
112    * There are a few exceptions you have to deal with. First, WebMacro may not
113    * be able to locate the template you've requested in which case it'll throw a
114    * NotFoundException. Second, the template will expect to find certain
115    * information in the TemplateContext, and if you fail to provide that
116    * information a ContextException will be thrown.
117    */
118   public void doGet(HttpServletRequest req, HttpServletResponse resp)
119       throws IOException {
120     String templateName = "org/melati/test/WebmacroStandalone.wm";
121 
122     WebContext context = new WebContext(_wm.getBroker(), req, resp);
123 
124     // fill up the context with our data
125     context.put("Today", new Date());
126     context.put("Number", new Long(23));
127 
128     // WebContext provides some utilities as well
129     String other = context.getForm("other");
130     if (other == null) {
131       context.put("hello", "Hello again!"); // put this into the hash
132     } else {
133       context.put("hello", other); // else put this in
134     }
135     String templateNameFromForm = context.getForm("templateName");
136     if (templateNameFromForm != null )
137       templateName = templateNameFromForm;
138     FastWriter fw = new FastWriter(_wm.getBroker(), resp.getOutputStream(),
139         resp.getCharacterEncoding());
140     // get the template we intend to execute
141     Template template = null;
142     try {
143       template = _wm.getTemplate(templateName);
144     } catch (ResourceException e) {
145 
146       fw.write("ERROR!  Could not locate template "
147               + templateName
148               + ", if you are not using a modified WebMacro.properties then it should be on the CLASSPATH.");
149       e.printStackTrace();
150       fw.close();
151       return;
152     }
153     try {
154       // write the template to the output, using our context
155       template.write(fw.getOutputStream(), context);
156     } catch (org.webmacro.ContextException e) {
157        throw new MelatiBugMelatiException("You have misconfigured WebMacro.", e);
158     } finally { 
159       fw.close();
160     }
161   }
162 
163 }