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 }