Coverage Report - org.melati.template.AbstractMarkupLanguage
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMarkupLanguage
100%
78/78
100%
12/12
1.292
 
 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.text.DateFormat;
 48  
 
 49  
 import org.melati.Melati;
 50  
 import org.melati.poem.Field;
 51  
 import org.melati.poem.PoemLocale;
 52  
 import org.melati.util.MelatiStringWriter;
 53  
 import org.melati.util.MelatiWriter;
 54  
 
 55  
 /**
 56  
  * MarkupLanguage provides a variety of methods for rendering objects in a
 57  
  * template.  
 58  
  *
 59  
  * Each object to be rendered has 3 methods:
 60  
  * 1 - String rendered(Object o) - this will render the object to a String
 61  
  * 2 - void render(Object o) - renders the object to melati.getWriter()
 62  
  * 3 - void render(Object o, MelatiWriter w) - render the object to w.
 63  
  *
 64  
  * When this class was written it was thought that for maximum 
 65  
  * efficiency one should render the object direct to the output stream using
 66  
  * method (2) above.  
 67  
  * However now all but (1) is deprecated. 
 68  
  */
 69  
 
 70  
 public abstract class AbstractMarkupLanguage implements MarkupLanguage {
 71  
 
 72  968
   protected TempletLoader templetLoader = null;
 73  968
   protected Melati melati = null;
 74  968
   protected PoemLocale locale = null;
 75  
 
 76  
   /** The maximum number of field possibilities to render.  */
 77  
   public static final int FIELD_POSSIBILITIES_LIMIT = 10000;
 78  
   /** The maximum number of date field possibilities to render.  */
 79  
   public static final int DATE_FIELD_POSSIBILITIES_LIMIT = 50;
 80  
 
 81  
   private String name;
 82  
 
 83  
   /**
 84  
    * Construct a Markup Language object.
 85  
    *
 86  
    * @param name - the name associated with this markup language.
 87  
    *    This is used to determine where to load
 88  
    *    templates from ie 'html' templates are
 89  
    *    found in the 'html' directory.
 90  
    * @param melati - the melati currently in use
 91  
    * @param templetLoader - the template loader in use
 92  
    *       (taken from org.melati.MelatiConfig.properties)
 93  
    * @param locale - the locale in use
 94  
    *    (taken from org.melati.MelatiConfig.properties)
 95  
    */
 96  
   public AbstractMarkupLanguage(String name,
 97  
                         Melati melati,
 98  
                         TempletLoader templetLoader,
 99  968
                         PoemLocale locale) {
 100  968
     this.name = name;
 101  968
     this.melati = melati;
 102  968
     this.templetLoader = templetLoader;
 103  968
     this.locale = locale;
 104  968
   }
 105  
 
 106  
   /**
 107  
    * Construct a new MarkupLanguage given a new name and an
 108  
    * existing MarkupLanguage.
 109  
    *
 110  
    * @param name - the name of the new MarkupLanguage
 111  
    * @param other - the Markup Language to base this one upon
 112  
    */
 113  
   protected AbstractMarkupLanguage(String name, AbstractMarkupLanguage other) {
 114  256
     this(name, other.melati, other.templetLoader, other.locale);
 115  256
   }
 116  
 
 117  
   /**
 118  
    * {@inheritDoc}
 119  
    * @see org.melati.template.MarkupLanguage#getName()
 120  
    */
 121  
   public String getName() {
 122  1063
     return name;
 123  
   }
 124  
 
 125  
   /**
 126  
    * Name and locale.
 127  
    * {@inheritDoc}
 128  
    * @see java.lang.Object#toString()
 129  
    */
 130  
   public String toString() {
 131  654
     return getName() + "/" + locale.toString();
 132  
   }
 133  
   
 134  
   private MelatiStringWriter getStringWriter() {
 135  8728
     return (MelatiStringWriter)melati.getStringWriter();
 136  
   }
 137  
 
 138  
   /**
 139  
    * {@inheritDoc}
 140  
    * @see org.melati.template.MarkupLanguage#rendered(java.lang.String, int)
 141  
    */
 142  
   public String rendered(String s, int limit) {
 143  6
     MelatiStringWriter sw = getStringWriter();
 144  6
     render(s,limit,sw);
 145  6
     return sw.toString();
 146  
   }
 147  
 
 148  
   /**
 149  
    * {@inheritDoc}
 150  
    * @see org.melati.template.MarkupLanguage#rendered(org.melati.poem.Field, int, int)
 151  
    */
 152  
   public String rendered(Field<?> field, int style, int limit)
 153  
       throws TemplateEngineException {
 154  6
     MelatiStringWriter sw = getStringWriter();
 155  6
     render(field, style, limit, sw);
 156  6
     return sw.toString();
 157  
   }
 158  
 
 159  
   /**
 160  
    * {@inheritDoc}
 161  
    * @see org.melati.template.MarkupLanguage#rendered(org.melati.poem.Field, int)
 162  
    */
 163  
   public String rendered(Field<?> field, int style)
 164  
       throws TemplateEngineException {
 165  6
     MelatiStringWriter sw = getStringWriter();
 166  6
     render(field, style, FIELD_POSSIBILITIES_LIMIT, sw);
 167  6
     return sw.toString();
 168  
   }
 169  
 
 170  
   /**
 171  
    * {@inheritDoc}
 172  
    * @see org.melati.template.MarkupLanguage#rendered(java.lang.Object)
 173  
    */
 174  
   public String rendered(Object o) {
 175  6680
     MelatiStringWriter sw = getStringWriter();
 176  6680
     if (o instanceof String)
 177  4995
       render((String)o, sw);
 178  1685
     else if (o instanceof Field) 
 179  1496
       render((Field<?>)o, sw);
 180  
     else
 181  189
       render(o, sw);
 182  6642
     return sw.toString();
 183  
   }
 184  
 
 185  
   /**
 186  
    * {@inheritDoc}
 187  
    * @see org.melati.template.MarkupLanguage#renderedMarkup(java.lang.String)
 188  
    */
 189  
   public String renderedMarkup(String s) {
 190  6
     MelatiStringWriter sw = getStringWriter();
 191  6
     renderMarkup(s, sw);
 192  5
     return sw.toString();    
 193  
   }
 194  
 
 195  
   /**
 196  
    * Render a String in a MarkupLanguage specific way, limiting it's length.
 197  
    * Render to a supplied MelatiWriter.
 198  
    *
 199  
    * @param s - the string to be rendered
 200  
    * @param writer - the MelatiWriter to render this String to
 201  
    * @param limit - the length to trim the string to
 202  
    */
 203  
   protected void render(String s, int limit, MelatiWriter writer) {
 204  3286
     render(s.length() < limit + 3 ? s : s.substring(0, limit) + "...", writer);
 205  3286
   }
 206  
 
 207  
   /**
 208  
    * Render a String in a MarkupLanguage specific way
 209  
    * to a supplied MelatiWriter.
 210  
    *
 211  
    * @param s - the string to be rendered
 212  
    * @param writer - the MelatiWriter to render this String to
 213  
    */
 214  
   protected abstract void render(String s, MelatiWriter writer);
 215  
   
 216  
   /**
 217  
    * Render a markup fragment in a MarkupLanguage specific way
 218  
    * to a supplied MelatiWriter.
 219  
    *
 220  
    * @param s - the fragment to be rendered
 221  
    * @param writer - the MelatiWriter to render this String to
 222  
    */
 223  
   protected abstract void renderMarkup(String s, MelatiWriter writer);
 224  
 
 225  
   /**
 226  
    * Render a Field Object in a MarkupLanguage specific way, 
 227  
    * rendering to supplied MelatiWriter.
 228  
    *
 229  
    * @param field - the Field to be rendered
 230  
    * @param writer - the MelatiWriter to render this Object to
 231  
    */
 232  
   protected void render(Field<?> field, MelatiWriter writer) {
 233  1496
     render(field, DateFormat.MEDIUM, FIELD_POSSIBILITIES_LIMIT, writer);
 234  1496
   }
 235  
 
 236  
   /**
 237  
    * Render a Field Object in a MarkupLanguage specific way, 
 238  
    * rendering to supplied MelatiWriter.
 239  
    *
 240  
    * @param field - the Field to be rendered
 241  
    * @param style - a style to format this Field.
 242  
    * @see org.melati.poem.DatePoemType#stringOfCooked
 243  
    *              (java.lang.Object,org.melati.poem.PoemLocale, int)
 244  
    * @param limit - the length to trim the rendered string to
 245  
    * @param writer - the MelatiWriter to render this Object to
 246  
    */
 247  
   protected void render(Field<?> field, int style, int limit, MelatiWriter writer) {
 248  3280
     render(field.getCookedString(locale, style), limit, writer);
 249  3280
   }
 250  
 
 251  
 
 252  
   /**
 253  
    * {@inheritDoc}
 254  
    * @see org.melati.template.MarkupLanguage#renderedStart(org.melati.poem.Field)
 255  
    */
 256  
   public String renderedStart(Field<?> field) {
 257  1772
     MelatiStringWriter sw = getStringWriter();
 258  1772
     renderStart(field, sw);
 259  1772
     return sw.toString();
 260  
   }
 261  
   
 262  
 
 263  
   protected void renderStart(Field<?> field, MelatiWriter writer) {
 264  1772
     render(field, DateFormat.MEDIUM, DATE_FIELD_POSSIBILITIES_LIMIT, writer);
 265  1772
   }
 266  
 
 267  
   /**
 268  
    * Render an Object in a MarkupLanguage specific way, rendering to
 269  
    * the <code>MelatiWriter</code> supplied by <code>melati.getWriter()</code>.
 270  
    *
 271  
    * @param o - the Object to be rendered
 272  
    * @throws TemplateEngineException - if there is a problem with the
 273  
    *                                   ServletTemplateEngine
 274  
    */
 275  
   protected void render(Object o) {
 276  8
     MelatiWriter writer = melati.getWriter();
 277  8
     render(o, writer);
 278  4
   }
 279  
 
 280  
   /**
 281  
    * Render an Object in a MarkupLanguage specific way, rendering to
 282  
    * a supplied Writer.
 283  
    *
 284  
    * NOTE The context always contains objects with the names melati, object and  ml  
 285  
    *
 286  
    * @param o - the Object to be rendered
 287  
    * @param writer - the MelatiWriter to render this Object to
 288  
    */
 289  
   protected void render(Object o, MelatiWriter writer) {
 290  146
     if (o == null)
 291  5
       throw new NullPointerException();
 292  
     else {
 293  141
         TemplateContext vars =
 294  141
           melati.getTemplateEngine().getTemplateContext();
 295  132
         Template templet =
 296  132
           templetLoader.templet(melati.getTemplateEngine(), this, o.getClass());
 297  126
         vars.put("object", o);
 298  126
         vars.put("melati", melati);
 299  126
         vars.put("ml", melati.getMarkupLanguage());
 300  126
         expandTemplet(templet, vars, writer);
 301  
     }
 302  116
   }
 303  
 
 304  
 
 305  
   //
 306  
   // =========
 307  
   //  Widgets
 308  
   // =========
 309  
   //
 310  
   
 311  
   /**
 312  
    * {@inheritDoc}
 313  
    * @see org.melati.template.MarkupLanguage#input(org.melati.poem.Field)
 314  
    */
 315  
   public String input(Field<?> field)
 316  
       throws TemplateEngineException,
 317  
              NotFoundException {
 318  225
     return input(field, null, "", false);
 319  
   }
 320  
 
 321  
   /**
 322  
    * {@inheritDoc}
 323  
    * @see org.melati.template.MarkupLanguage#inputAs(org.melati.poem.Field, java.lang.String)
 324  
    */
 325  
   public String inputAs(Field<?> field, String templetName)
 326  
       throws TemplateEngineException,
 327  
              NotFoundException {
 328  34
     return input(field, templetName, "", false);
 329  
   }
 330  
 
 331  
   /**
 332  
    * {@inheritDoc}
 333  
    * @see org.melati.template.MarkupLanguage#searchInput(org.melati.poem.Field, java.lang.String)
 334  
    */
 335  
   public String searchInput(Field<?> field, String nullValue)
 336  
       throws TemplateEngineException,
 337  
              NotFoundException{
 338  5
     return input(field, null, nullValue, true);
 339  
   }
 340  
 
 341  
   protected String input(Field<?> field,
 342  
                          String templetName,
 343  
                          String nullValue,
 344  
                          boolean overrideNullable)
 345  
        throws NotFoundException {
 346  
 
 347  
     Template templet;
 348  264
     if (templetName == null) 
 349  230
       templet = templetLoader.templet(melati.getTemplateEngine(), this, field) ;
 350  
     else
 351  34
       templet = templetLoader.templet(melati.getTemplateEngine(), this, templetName);
 352  
 
 353  252
     TemplateContext vars =
 354  252
         melati.getTemplateEngine().getTemplateContext();
 355  
 
 356  252
     if (overrideNullable) {
 357  4
       field = field.withNullable(true);
 358  4
       vars.put("nullValue", nullValue);
 359  
     }
 360  
 
 361  252
     vars.put("melati", melati);
 362  252
     vars.put("ml", melati.getMarkupLanguage());
 363  252
     vars.put("object", field);
 364  252
     vars.put("field", field);
 365  252
     MelatiStringWriter sw = getStringWriter();
 366  252
     melati.getTemplateEngine().expandTemplate(sw, templet,vars);
 367  
     
 368  252
     return sw.toString(); 
 369  
   }
 370  
 
 371  
   
 372  
   /**
 373  
    * Interpolate a templet and write it out.
 374  
    * 
 375  
    * @param templet {@link Template} to interpolate
 376  
    * @param tc {@link TemplateContext} against which to instantiate variables
 377  
    * @param out {@link MelatiWriter} to write results to 
 378  
    */
 379  
   protected void expandTemplet(Template templet, TemplateContext tc,
 380  
                                MelatiWriter out) {
 381  138
     melati.getTemplateEngine().expandTemplate(out, templet, tc);
 382  125
   }
 383  
 }
 384  
 
 385