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 006package fc.util.pagetemplate; 007 008import java.io.*; 009import java.util.*; 010import java.sql.*; 011 012import fc.util.*; 013import fc.io.*; 014 015/** 016A superclass for generated template pages. All templates derive from this class. Runs 017outside the web environment (intended to be invoked from the command line) 018<p> 019Pages are always assumed to be written in UTF-8 (a superset of regular 020ascii/IS0-8859-1). If the template page is sent as HTML to a device (via some outside 021mechanism that uses the templates as part of its workflow), then the HTML contained in 022the page template should set the appropriate content type/encoding meta header to say 023UTF-8, <b>if</b> UTF-8 characters (such as emojis) are used in the page. 024<p> 025See {@link TemplateMgr} 026 027@author hursh jain 028*/ 029public abstract class TemplatePage 030{ 031static private final boolean internal_dbg = false; 032 033public static String PACKAGE_NAME = "molly.pagetemplate"; 034public static String DEFAULT_ENCODING = "UTF-8"; 035 036/** 037Controls whether debugging is on or off. For expensive debug statements, 038<code>if (dbg) bug(....)</code> type statements can be used in a page. 039*/ 040protected volatile boolean dbg = false; 041 042public Log log = Log.getDefault(); 043public Writer out; 044 045public File templateFile; 046 047public Connection con; 048public Map context; 049 050public void setSourcePath(File templateFile) { 051 this.templateFile = templateFile; 052 } 053 054public String getSourcePath() 055 { 056 return templateFile.getAbsolutePath(); 057 } 058 059/* set a connect that can later be used in render, if needed. code in render can also get 060 a connection directly from a connection mgr, etc as well, of course. The resposibility 061 to close the connection can be inside render() or by the caller, whatever makes sense 062 in a particular use case. 063 */ 064public void setConnection(Connection con) { 065 this.con = con; 066 } 067 068/* set various objects (via a map) that can be later used in render, if needed. */ 069public void setContext(Map m) { 070 this.context = m; 071 } 072 073public void render(Writer out) throws Exception 074 { 075 //writers should already have a charset specified if they are using an outputstreamwriter or 076 //some other output stream. toPrinteWriter() just wraps that 077 078 render(IOUtil.toPrintWriter( 079 IOUtil.bufferWriter(out))); 080 } 081 082public void render(File out) throws Exception 083 { 084 render(new PrintWriter(out, DEFAULT_ENCODING)); 085 } 086 087public void render(OutputStream out) throws Exception 088 { 089 render(new PrintWriter( 090 new BufferedWriter( 091 new OutputStreamWriter(out, DEFAULT_ENCODING)))); 092 } 093 094 095/* 096This is the method that runs the templates and writes the generated contents to the 097specified output destination. Is implemented by generated classes. 098*/ 099public abstract void render(PrintWriter out) throws Exception; 100 101/* 102Starts/stop debugging with no dbg_prefix/dbg_suffix. 103 104@param val true to enable debugging, false to disable. 105*/ 106public final void dbg(final boolean val) 107 { 108 this.dbg = val; 109 } 110 111 112/** 113Prints a debug statement if debugging is turned on for this page. 114 115<p>Typically the implicit page printwriter (the <code>out</code> 116variable) will be passed to this method and debug statements will be 117printed at the point where they are lexically invoked at the page. 118*/ 119public final void bug(final Writer writer, final Object str1) throws IOException 120 { 121 if (! dbg) 122 return; 123 124 writer.append(str1 != null ? str1.toString() : "null"); 125 } 126 127public final void bug(final Writer writer, final Object str1, final Object... args) 128throws IOException 129 { 130 if (! dbg) 131 return; 132 133 writer.append(str1 != null ? str1.toString() : "null"); 134 final int len = args.length; 135 for (int i = 0; i < len; i++) { 136 writer.append(args[i] != null ? args[i].toString() : "null"); 137 } 138 } 139 140}