001 // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 002 // The Molly framework is freely distributable under the terms of an 003 // MIT-style license. For details, see the molly pages web site at: 004 // http://www.mollypages.org/. Use, modify, have fun ! 005 006 package fc.web.page; 007 008 import java.io.*; 009 import java.util.*; 010 011 import javax.servlet.*; 012 import javax.servlet.http.*; 013 014 /** 015 A page is a cool and sane replacement for JSP's with much better syntax. 016 <p> 017 Server side pages implement this interface via the concrete {@link PageImpl} 018 class. This class has some additional utility methods as well that page 019 authors may find useful. 020 021 @author hursh jain 022 */ 023 public interface Page 024 { 025 //all pages result in java files with this package name; 026 public static String PACKAGE_NAME = "molly.pages"; 027 028 //not used: public static String DEFAULT_ERROR_PAGE = "/molly/error.mp"; 029 public static int DEFAULT_BUFFER_SIZE = 8048; 030 031 /** 032 The default mime-type for each page. Usually, there should be no reason 033 to change this. However, if need be, this can be changed via a page 034 compiler directive or turned off entirely. If it's turned off, then the 035 mime-type should be manually specified via the {@link 036 javax.servlet.ServletResponse.setContentType} method. 037 */ 038 public static String DEFAULT_MIME_TYPE = "text/html"; 039 040 /** 041 The default encoding of the page, specified in the header sent back to 042 the client. This can be changed to utf-8, utf-16 or any other coding by 043 a page directive. Alternately, this can be set to an empty string and a 044 different encoding can also be specified in the <head> section of 045 the html document, for example: 046 <pre> 047 <head><meta http-equiv=content-type content='text/html; charset=UTF-8'></head> 048 </pre> 049 <font color=red>Encodings can be tricky. We are first compiling 050 a page into a java source file, then running the source file and 051 sending it's output to the browser. <b>Read the page 052 <a href="http://www.mollypages.org/page/charset.mp">encoding 053 and charsets</a> if you are using any non-us-ascii or non- 054 ISO-8859-1</b> characters in your molly source page.</font> 055 */ 056 public static String DEFAULT_ENCODING = "ISO-8859-1"; 057 058 public void render(HttpServletRequest req, HttpServletResponse res) throws Exception; 059 060 /** 061 This method is invoked whenever a page is created and before it 062 is run. 063 <p> 064 Pages should override this method to instantiate/set-up page 065 variables as needed. (pages have no-arg constructors so like 066 most of the servlet API, setup and initialization of variables 067 is done in a init method instead). 068 <p> 069 When overriding this class, you must remember to 070 call: <tt>super.init</tt> 071 <p> 072 The page class is reloaded if the page is modified. Variables 073 should therefore be cleaned up in the {@link destory} method 074 as needed. 075 */ 076 public void init(PageServlet servlet, String contextRelativePagePath) throws ServletException; 077 078 /** 079 This method is invoked whenever a page is destoryed/unloaded 080 */ 081 public void destroy(); 082 083 /** 084 Returns the path to this page from the web servers <i>document root</i>. 085 <p>So for example, if the page is at <code>foo/bar.mp</code> and is running 086 under the webapp context of <code>context1</code>, then the page path 087 will be: <code>/context1/foo/bar.mp</code>. If there is no specific 088 web app (i.e., the most common case of a default "" webapp), then the page 089 path will be <code>/foo/bar.mp</code> 090 <p> 091 This page path is essentially what needs to be typed in the browsers 092 URL window to invoke the page. It's also useful as form action parameters. 093 For example, in a molly page: 094 <blockquote> 095 <pre> 096 .. 097 <form action="[=getPagePath(req)]" method="post"> 098 .. 099 </form> 100 </pre> 101 </blockquote> 102 This will submit the form to the same page where the form is defined. This 103 can be hard coded of course but by using <code>getPagePath</code>, the html 104 does not have to be changed if the name of the page changes on disk. 105 */ 106 public String getPagePath(HttpServletRequest req); 107 108 /** 109 Returns the real absolute directory path for the {@link #getPagePath PagePath}. 110 <p> 111 So, for example, for a webserver document root at 112 <code>/web/sites/default/</code> and a page located in 113 <code>foo/bar.mp</code>, the real path will be: 114 <code>/web/sites/default/foo/bar.mp</code> 115 */ 116 public String getRealPath(HttpServletRequest req); 117 118 /** 119 Redirects the client to the new page location. This is a thin (possibly 120 easier to remember) wrapper around the {@link HttpServletResponse.sendRedirect} method. 121 <p> 122 The location parameter can be relative to the specified request's URI or 123 relative to the context root if it contains a leading '/'. The webapp name 124 (if any) does <b>not</b> have to be specified, the redirect will creates a 125 full URL <u>(including the webapp context path)</u> suitable for this 126 purpose. 127 <p> 128 For example: 129 <style> 130 #redirects {background: #cccccc; } 131 #redirects tr {background: white; } 132 #redirects .head {font-weight: bold; } 133 </style> 134 <table id=redirects border=0 cellspacing=1 cellpadding=7> 135 <tr class=head> 136 <td width="25%">webapp context</td> 137 <td width="25%">current page</td> 138 <td width="25%">location parameter</td> 139 <td width="25%">resulting page</td> 140 </tr> 141 <tr> 142 <td>default web app ("/")</td> 143 <td>foo/bar.mp</td> 144 <td>baz.mp</td> 145 <td>foo/baz.mp</td> 146 </tr> 147 <tr> 148 <td>default web app ("/")</td> 149 <td>foo/bar.mp</td> 150 <td>/baz.mp</td> 151 <td>baz.mp</td> 152 </tr> 153 <tr> 154 <td>/myapp</td> 155 <td>foo/bar.mp</td> 156 <td>baz.mp</td> 157 <td>/myapp/foo/baz.mp</td> 158 </tr> 159 <tr> 160 <td>/myapp</td> 161 <td>foo/bar.mp</td> 162 <td>/baz.mp</td> 163 <td>/myapp/baz.mp</td> 164 </tr> 165 </table> 166 167 @param req the current request 168 @param res the current response 169 @param location location to redirect to. 170 */ 171 public void clientRedirect(HttpServletRequest req, HttpServletResponse res, String newLocation) throws IOException; 172 173 /** 174 Returns a thread specific CharArrayWriter that can be passed to this method 175 as various points in the page. The contents of this writer can then be 176 printed on the page when desired. 177 <p> 178 Note: The writer is <b>not</b> reset or flushed when it is retrieved. It 179 must be <font color=blue>reset manually</font> via calling the {@link 180 java.io.CharArrayWriter#reset} method. This design-decision allows request 181 threads to collect debugging data across multiple pages. 182 <p> 183 The suggested usage idiom is: 184 <blockquote> 185 <pre> 186 dbg(true); 187 CharArrayWriter <font color=blue>cw</font> = getThreadLocalWriter(): 188 bug(<font color=blue>cw</font>, "some message"); 189 ... 190 bug(<font color=blue>cw</font>, "other message"); 191 ... 192 <font color=blue> 193 cw.writeTo(out); 194 cw.reset(); 195 </font> 196 </pre> 197 </blockquote> 198 */ 199 public CharArrayWriter getThreadLocalWriter(); 200 201 /* 202 These are in PageImpl but do they need to be in the Page interface as well ? 203 Subject to change so prolly not, thus commented out. hj 204 205 public void startTimer(); 206 public long getTime(); 207 public void dbg(boolean val); 208 public void dbgPrefix(String dbg_prefix); 209 public void dbgSuffix(String dbg_suffix); 210 public void bug(final Writer writer, final Object str1) throws IOException; 211 public void bug(final Writer writer, final Object str1, final Object str2) throws IOException; 212 public void bug(final Writer writer, final Object str1, final Object str2, final Object str3) throws IOException; 213 public void bug(final Writer writer, final Object str1, final Object str2, final Object str3, final Object... args) throws IOException; 214 */ 215 }