Coverage Report - org.melati.template.AbstractMarkupLanguage
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMarkupLanguage
100%
71/71
93%
13/14
1.273
 
 1  
 /*
 2  
  * $Source$
 3  
  * $Revision$
 4  
  *
 5  
  * Copyright (C) 2006 Tim Pizey
 6  
  *
 7  
  * Part of Melati (http://melati.org), a framework for the rapid
 8  
  * development of clean, maintainable web applications.
 9  
  *
 10  
  * Melati is free software; Permission is granted to copy, distribute
 11  
  * and/or modify this software under the terms either:
 12  
  *
 13  
  * a) the GNU General Public License as published by the Free Software
 14  
  *    Foundation; either version 2 of the License, or (at your option)
 15  
  *    any later version,
 16  
  *
 17  
  *    or
 18  
  *
 19  
  * b) any version of the Melati Software License, as published
 20  
  *    at http://melati.org
 21  
  *
 22  
  * You should have received a copy of the GNU General Public License and
 23  
  * the Melati Software License along with this program;
 24  
  * if not, write to the Free Software Foundation, Inc.,
 25  
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the
 26  
  * GNU General Public License and visit http://melati.org to obtain the
 27  
  * Melati Software License.
 28  
  *
 29  
  * Feel free to contact the Developers of Melati (http://melati.org),
 30  
  * if you would like to work out a different arrangement than the options
 31  
  * outlined here.  It is our intention to allow Melati to be used by as
 32  
  * wide an audience as possible.
 33  
  *
 34  
  * This program is distributed in the hope that it will be useful,
 35  
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 36  
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 37  
  * GNU General Public License for more details.
 38  
  *
 39  
  * Contact details for copyright holder:
 40  
  *
 41  
  *     Tim Pizey <timp At paneris.org>
 42  
  *     http://paneris.org/~timp
 43  
  */
 44  
 
 45  
 package org.melati.template;
 46  
 
 47  
 import java.io.IOException;
 48  
 import java.text.DateFormat;
 49  
 
 50  
 import org.melati.Melati;
 51  
 import org.melati.poem.Field;
 52  
 import org.melati.poem.PoemLocale;
 53  
 import org.melati.util.MelatiStringWriter;
 54  
 import org.melati.util.MelatiWriter;
 55  
 
 56  
 /**
 57  
  * MarkupLanguage provides a variety of methods for rendering objects in a
 58  
  * template.  
 59  
  *
 60  
  * Each object to be rendered has 3 methods:
 61  
  * 1 - String rendered(Object o) - this will render the object to a String
 62  
  * 2 - void render(Object o) - renders the object to melati.getWriter()
 63  
  * 3 - void render(Object o, MelatiWriter w) - render the object to w.
 64  
  *
 65  
  * When this class was written it was thought that for maximum 
 66  
  * efficiency one should render the object direct to the output stream using
 67  
  * method (2) above.  
 68  
  * However now all but (1) is deprecated. 
 69  
  */
 70  
 
 71  
 public abstract class AbstractMarkupLanguage implements MarkupLanguage {
 72  
 
 73  347
   protected TempletLoader templetLoader = null;
 74  347
   protected Melati melati = null;
 75  347
   protected PoemLocale locale = null;
 76  
 
 77  
   /** The maximum number of field possibilites to render.  */
 78  
   public static final int FIELD_POSSIBILITIES_LIMIT = 10000;
 79  
 
 80  
   private String name;
 81  
 
 82  
   /**
 83  
    * Construct a Markup Language object.
 84  
    *
 85  
    * @param name - the name associated with this markup language.
 86  
    *    This is used to determine where to load
 87  
    *    templates from ie 'html' templates are
 88  
    *    found in the 'html' directory.
 89  
    * @param melati - the melati currently in use
 90  
    * @param templetLoader - the template loader in use
 91  
    *       (taken from org.melati.MelatiConfig.properties)
 92  
    * @param locale - the locale in use
 93  
    *    (taken from org.melati.MelatiConfig.properties)
 94  
    */
 95  
   public AbstractMarkupLanguage(String name,
 96  
                         Melati melati,
 97  
                         TempletLoader templetLoader,
 98  347
                         PoemLocale locale) {
 99  347
     this.name = name;
 100  347
     this.melati = melati;
 101  347
     this.templetLoader = templetLoader;
 102  347
     this.locale = locale;
 103  347
   }
 104  
 
 105  
   /**
 106  
    * Construct a new MarkupLanguage given a new name and an
 107  
    * existing MarkupLanguage.
 108  
    *
 109  
    * @param name - the name of the new MarkupLanguage
 110  
    * @param other - the Markup Language to base this one upon
 111  
    */
 112  
   protected AbstractMarkupLanguage(String name, AbstractMarkupLanguage other) {
 113  178
     this(name, other.melati, other.templetLoader, other.locale);
 114  178
   }
 115  
 
 116  
   /**
 117  
    * {@inheritDoc}
 118  
    * @see org.melati.template.MarkupLanguage#getName()
 119  
    */
 120  
   public String getName() {
 121  372
     return name;
 122  
   }
 123  
 
 124  
   /**
 125  
    * Name and locale.
 126  
    * {@inheritDoc}
 127  
    * @see java.lang.Object#toString()
 128  
    */
 129  
   public String toString() {
 130  201
     return getName() + "/" + locale.toString();
 131  
   }
 132  
   
 133  
   private MelatiStringWriter getStringWriter() {
 134  760
     return (MelatiStringWriter)melati.getStringWriter();
 135  
   }
 136  
 
 137  
   /**
 138  
    * {@inheritDoc}
 139  
    * @see org.melati.template.MarkupLanguage#rendered(java.lang.String, int)
 140  
    */
 141  
   public String rendered(String s, int limit) throws IOException {
 142  5
     MelatiStringWriter sw = getStringWriter();
 143  5
     render(s,limit,sw);
 144  5
     return sw.toString();
 145  
   }
 146  
 
 147  
   /**
 148  
    * {@inheritDoc}
 149  
    * @see org.melati.template.MarkupLanguage#rendered(org.melati.poem.Field, int, int)
 150  
    */
 151  
   public String rendered(Field field, int style, int limit)
 152  
       throws TemplateEngineException, IOException {
 153  5
     MelatiStringWriter sw = getStringWriter();
 154  5
     render(field, style, limit, sw);
 155  5
     return sw.toString();
 156  
   }
 157  
 
 158  
   /**
 159  
    * {@inheritDoc}
 160  
    * @see org.melati.template.MarkupLanguage#rendered(org.melati.poem.Field, int)
 161  
    */
 162  
   public String rendered(Field field, int style)
 163  
       throws TemplateEngineException, IOException {
 164  5
     MelatiStringWriter sw = getStringWriter();
 165  5
     render(field, style, FIELD_POSSIBILITIES_LIMIT, sw);
 166  5
     return sw.toString();
 167  
   }
 168  
 
 169  
   /**
 170  
    * {@inheritDoc}
 171  
    * @see org.melati.template.MarkupLanguage#rendered(java.lang.Object)
 172  
    */
 173  
   public String rendered(Object o)
 174  
       throws IOException {
 175  714
     MelatiStringWriter sw = getStringWriter();
 176  714
     if (o instanceof String)
 177  177
       render((String)o, sw);
 178  537
     else if (o instanceof Field) 
 179  444
       render((Field)o, sw);
 180  
     else
 181  93
       render(o, sw);
 182  686
     return sw.toString();
 183  
   }
 184  
 
 185  
 
 186  
   /**
 187  
    * Render a String in a MarkupLanguage specific way, limiting it's length.
 188  
    * Render to a supplied MelatiWriter.
 189  
    *
 190  
    * @param s - the string to be rendered
 191  
    * @param writer - the MelatiWriter to render this String to
 192  
    * @param limit - the lenght to trim the string to
 193  
    * @throws IOException - if there is a problem during rendering
 194  
    */
 195  
   protected void render(String s, int limit, MelatiWriter writer)
 196  
       throws IOException {
 197  464
     render(s.length() < limit + 3 ? s : s.substring(0, limit) + "...", writer);
 198  464
   }
 199  
 
 200  
   /**
 201  
    * Render a String in a MarkupLanguage specific way
 202  
    * to a supplied MelatiWriter.
 203  
    *
 204  
    * @param s - the string to be rendered
 205  
    * @param writer - the MelatiWriter to render this String to
 206  
    * @throws IOException - if there is a problem during rendering
 207  
    */
 208  
   protected abstract void render(String s, MelatiWriter writer) throws IOException;
 209  
 
 210  
   /**
 211  
    * Render a Field Object in a MarkupLanguage specific way, 
 212  
    * rendering to supplied MelatiWriter.
 213  
    *
 214  
    * @param field - the Field to be rendered
 215  
    * @param writer - the MelatiWriter to render this Object to
 216  
    * @throws IOException - if there is a problem during rendering
 217  
    */
 218  
   protected void render(Field field, MelatiWriter writer) throws IOException {
 219  444
     render(field, DateFormat.MEDIUM, FIELD_POSSIBILITIES_LIMIT, writer);
 220  444
   }
 221  
 
 222  
   /**
 223  
    * Render a Field Object in a MarkupLanguage specific way, 
 224  
    * rendering to supplied MelatiWriter.
 225  
    *
 226  
    * @param field - the Field to be rendered
 227  
    * @param style - a style to format this Field.
 228  
    * @see org.melati.poem.DatePoemType#stringOfCooked
 229  
    *              (java.lang.Object,org.melati.poem.PoemLocale, int)
 230  
    * @param limit - the length to trim the rendered string to
 231  
    * @param writer - the MelatiWriter to render this Object to
 232  
    * @throws IOException - if there is a problem during rendering
 233  
    */
 234  
   protected void render(Field field, int style, int limit, MelatiWriter writer)
 235  
       throws IOException {
 236  459
     render(field.getCookedString(locale, style), limit, writer);
 237  459
   }
 238  
 
 239  
 
 240  
   /**
 241  
    * {@inheritDoc}
 242  
    * @see org.melati.template.MarkupLanguage#renderedStart(org.melati.poem.Field)
 243  
    */
 244  
   public String renderedStart(Field field)
 245  
       throws IOException {
 246  5
     MelatiStringWriter sw = getStringWriter();
 247  5
     renderStart(field, sw);
 248  5
     return sw.toString();
 249  
   }
 250  
 
 251  
 
 252  
   protected void renderStart(Field field, MelatiWriter writer)
 253  
       throws IOException {
 254  5
     render(field, DateFormat.MEDIUM, 50, writer);
 255  5
   }
 256  
 
 257  
   /**
 258  
    * Render an Object in a MarkupLanguage specific way, rendering to
 259  
    * the <code>MelatiWriter</code> supplied by <code>melati.getWriter()</code>.
 260  
    *
 261  
    * @param o - the Object to be rendered
 262  
    * @throws IOException - if there is a problem during rendering
 263  
    * @throws TemplateEngineException - if there is a problem with the
 264  
    *                                   ServletTemplateEngine
 265  
    */
 266  
   protected void render(Object o) throws IOException {
 267  8
     MelatiWriter writer = melati.getWriter();
 268  8
     render(o, writer);
 269  4
   }
 270  
 
 271  
   /**
 272  
    * Render an Object in a MarkupLanguage specific way, rendering to
 273  
    * a supplied Writer.
 274  
    *
 275  
    * NOTE The context always contains objects with the names melati, object and  ml  
 276  
    *
 277  
    * @param o - the Object to be rendered
 278  
    * @param writer - the MelatiWriter to render this Object to
 279  
    */
 280  
   protected void render(Object o, MelatiWriter writer) throws IOException {
 281  80
     if (o == null)
 282  5
       throw new NullPointerException();
 283  
     else {
 284  75
         TemplateContext vars =
 285  
           melati.getTemplateEngine().getTemplateContext(melati);
 286  75
         Template templet =
 287  
           templetLoader.templet(melati.getTemplateEngine(), this, o.getClass());
 288  62
         vars.put("object", o);
 289  
         // Not happy but 
 290  62
         if (o instanceof Field) vars.put("field", o);
 291  62
         vars.put("melati", melati);
 292  62
         vars.put("ml", melati.getMarkupLanguage());
 293  62
         expandTemplet(templet, vars, writer);
 294  
     }
 295  56
   }
 296  
 
 297  
 
 298  
   //
 299  
   // =========
 300  
   //  Widgets
 301  
   // =========
 302  
   //
 303  
   
 304  
   /**
 305  
    * {@inheritDoc}
 306  
    * @see org.melati.template.MarkupLanguage#input(org.melati.poem.Field)
 307  
    */
 308  
   public String input(Field field)
 309  
       throws TemplateEngineException,
 310  
              IOException, NotFoundException {
 311  23
     return input(field, null, "", false);
 312  
   }
 313  
 
 314  
   /**
 315  
    * {@inheritDoc}
 316  
    * @see org.melati.template.MarkupLanguage#inputAs(org.melati.poem.Field, java.lang.String)
 317  
    */
 318  
   public String inputAs(Field field, String templetName)
 319  
       throws TemplateEngineException,
 320  
              IOException, NotFoundException {
 321  10
     return input(field, templetName, "", false);
 322  
   }
 323  
 
 324  
   /**
 325  
    * {@inheritDoc}
 326  
    * @see org.melati.template.MarkupLanguage#searchInput(org.melati.poem.Field, java.lang.String)
 327  
    */
 328  
   public String searchInput(Field field, String nullValue)
 329  
       throws TemplateEngineException,
 330  
              IOException, NotFoundException{
 331  5
     return input(field, null, nullValue, true);
 332  
   }
 333  
 
 334  
   protected String input(Field field,
 335  
                          String templetName,
 336  
                          String nullValue,
 337  
                          boolean overrideNullable)
 338  
        throws IOException, NotFoundException {
 339  
 
 340  
     Template templet;
 341  38
     templet =
 342  
       templetName == null ?
 343  
         templetLoader.templet(melati.getTemplateEngine(), this, field) :
 344  
         templetLoader.templet(melati.getTemplateEngine(), this, templetName);
 345  
 
 346  26
     TemplateContext vars =
 347  
         melati.getTemplateEngine().getTemplateContext(melati);
 348  
 
 349  26
     if (overrideNullable) {
 350  4
       field = field.withNullable(true);
 351  4
       vars.put("nullValue", nullValue);
 352  
     }
 353  
 
 354  26
     vars.put("melati", melati);
 355  26
     vars.put("ml", melati.getMarkupLanguage());
 356  26
     vars.put("object", field);
 357  26
     vars.put("field", field);
 358  26
     MelatiStringWriter sw = getStringWriter();
 359  26
     melati.getTemplateEngine().expandTemplate(sw, templet,vars);
 360  
     
 361  26
     return sw.toString(); 
 362  
   }
 363  
 
 364  
   
 365  
   /**
 366  
    * Interpolate a templet and write it out.
 367  
    * 
 368  
    * @param templet {@link Template} to interpolate
 369  
    * @param tc {@link TemplateContext} against which to instantiate variables
 370  
    * @param out {@link MelatiWriter} to write results to 
 371  
    * @throws TemplateEngineException if something unexpected happens
 372  
    */
 373  
   protected void expandTemplet(Template templet, TemplateContext tc,
 374  
                                MelatiWriter out) throws IOException {
 375  62
     melati.getTemplateEngine().expandTemplate(out, templet, tc);
 376  56
   }
 377  
 }
 378  
 
 379