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.util.pagetemplate;
007    
008    import java.io.*;
009    import java.util.*;
010    import java.sql.*;
011    
012    import fc.util.*;
013    import fc.io.*;
014    
015    /** 
016    A superclass for generated template pages. All templates derive from this class. Runs
017    outside the web environment (intended to be invoked from the command line)
018    <p>
019    Pages are always assumed to be written in UTF-8 (a superset of regular
020    ascii/IS0-8859-1). If the template page is sent as HTML to a device (via some outside
021    mechanism that uses the templates as part of its workflow), then the HTML contained in
022    the page template should set the appropriate content type/encoding meta header to say
023    UTF-8, <b>if</b> UTF-8 characters (such as emojis) are used in the page.
024    <p>
025    See {@link TemplateMgr}
026    
027    @author hursh jain
028    */
029    public abstract class TemplatePage 
030    {
031    static private  final boolean internal_dbg = false;
032    
033    public static String  PACKAGE_NAME = "molly.pagetemplate";
034    public static String  DEFAULT_ENCODING    = "UTF-8";
035    
036    /** 
037    Controls 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    */
040    protected volatile  boolean  dbg = false;
041    
042    public Log      log = Log.getDefault(); 
043    public  Writer  out;
044    
045    public File templateFile;
046    
047    public Connection con;
048    public Map context;
049    
050    public void setSourcePath(File templateFile) {
051      this.templateFile = templateFile;
052      }
053    
054    public 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       */
064    public 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. */
069    public void setContext(Map m) {
070      this.context = m;
071      }
072      
073    public 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    
082    public void render(File out) throws Exception
083      {
084      render(new PrintWriter(out, DEFAULT_ENCODING));
085      }
086    
087    public void render(OutputStream out) throws Exception
088      {
089      render(new PrintWriter(
090          new BufferedWriter(
091            new OutputStreamWriter(out, DEFAULT_ENCODING))));
092      }
093    
094    
095    /* 
096    This is the method that runs the templates and writes the generated contents to the
097    specified output destination. Is implemented by generated classes. 
098    */
099    public abstract void render(PrintWriter out) throws Exception;
100    
101    /*
102    Starts/stop debugging with no dbg_prefix/dbg_suffix.
103    
104    @param  val   true to enable debugging, false to disable.
105    */
106    public final void dbg(final boolean val)
107      {
108      this.dbg = val;
109      }
110    
111    
112    /**
113    Prints a debug statement if debugging is turned on for this page.
114    
115    <p>Typically the implicit page printwriter (the <code>out</code>
116    variable) will be passed to this method and debug statements will be
117    printed at the point where they are lexically invoked at the page.
118    */
119    public 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        
127    public final void bug(final Writer writer, final Object str1, final Object... args) 
128    throws 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    }