Coverage Report - org.melati.template.AbstractMarkupLanguage
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractMarkupLanguage
96%
71/74
93%
13/14
1.25
 
 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  863
   protected TempletLoader templetLoader = null;
 74  863
   protected Melati melati = null;
 75  863
   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  863
                         PoemLocale locale) {
 99  863
     this.name = name;
 100  863
     this.melati = melati;
 101  863
     this.templetLoader = templetLoader;
 102  863
     this.locale = locale;
 103  863
   }
 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  248
     this(name, other.melati, other.templetLoader, other.locale);
 114  248
   }
 115  
 
 116  
   /**
 117  
    * {@inheritDoc}
 118  
    * @see org.melati.template.MarkupLanguage#getName()
 119  
    */
 120  
   public String getName() {
 121  772
     return name;
 122  
   }
 123  
 
 124  
   /**
 125  
    * Name and locale.
 126  
    * {@inheritDoc}
 127  
    * @see java.lang.Object#toString()
 128  
    */
 129  
   public String toString() {
 130  481
     return getName() + "/" + locale.toString();
 131  
   }
 132  
   
 133  
   private MelatiStringWriter getStringWriter() {
 134  5803
     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  4679
     MelatiStringWriter sw = getStringWriter();
 176  4679
     if (o instanceof String)
 177  3470
       render((String)o, sw);
 178  1209
     else if (o instanceof Field) 
 179  1080
       render((Field)o, sw);
 180  
     else
 181  129
       render(o, sw);
 182  4651
     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  
       throws IOException {
 191  0
     MelatiStringWriter sw = getStringWriter();
 192  0
     renderMarkup(s, sw);
 193  0
     return sw.toString();    
 194  
   }
 195  
 
 196  
   /**
 197  
    * Render a String in a MarkupLanguage specific way, limiting it's length.
 198  
    * Render to a supplied MelatiWriter.
 199  
    *
 200  
    * @param s - the string to be rendered
 201  
    * @param writer - the MelatiWriter to render this String to
 202  
    * @param limit - the lenght to trim the string to
 203  
    * @throws IOException - if there is a problem during rendering
 204  
    */
 205  
   protected void render(String s, int limit, MelatiWriter writer)
 206  
       throws IOException {
 207  2006
     render(s.length() < limit + 3 ? s : s.substring(0, limit) + "...", writer);
 208  2006
   }
 209  
 
 210  
   /**
 211  
    * Render a String in a MarkupLanguage specific way
 212  
    * to a supplied MelatiWriter.
 213  
    *
 214  
    * @param s - the string to be rendered
 215  
    * @param writer - the MelatiWriter to render this String to
 216  
    * @throws IOException - if there is a problem during rendering
 217  
    */
 218  
   protected abstract void render(String s, MelatiWriter writer) throws IOException;
 219  
   
 220  
   /**
 221  
    * Render a markup fragment in a MarkupLanguage specific way
 222  
    * to a supplied MelatiWriter.
 223  
    *
 224  
    * @param s - the fragment to be rendered
 225  
    * @param writer - the MelatiWriter to render this String to
 226  
    * @throws IOException - if there is a problem during rendering
 227  
    */
 228  
   protected abstract void renderMarkup(String s, MelatiWriter writer) throws IOException;
 229  
 
 230  
   /**
 231  
    * Render a Field Object in a MarkupLanguage specific way, 
 232  
    * rendering to supplied MelatiWriter.
 233  
    *
 234  
    * @param field - the Field to be rendered
 235  
    * @param writer - the MelatiWriter to render this Object to
 236  
    * @throws IOException - if there is a problem during rendering
 237  
    */
 238  
   protected void render(Field field, MelatiWriter writer) throws IOException {
 239  1080
     render(field, DateFormat.MEDIUM, FIELD_POSSIBILITIES_LIMIT, writer);
 240  1080
   }
 241  
 
 242  
   /**
 243  
    * Render a Field Object in a MarkupLanguage specific way, 
 244  
    * rendering to supplied MelatiWriter.
 245  
    *
 246  
    * @param field - the Field to be rendered
 247  
    * @param style - a style to format this Field.
 248  
    * @see org.melati.poem.DatePoemType#stringOfCooked
 249  
    *              (java.lang.Object,org.melati.poem.PoemLocale, int)
 250  
    * @param limit - the length to trim the rendered string to
 251  
    * @param writer - the MelatiWriter to render this Object to
 252  
    * @throws IOException - if there is a problem during rendering
 253  
    */
 254  
   protected void render(Field field, int style, int limit, MelatiWriter writer)
 255  
       throws IOException {
 256  2001
     render(field.getCookedString(locale, style), limit, writer);
 257  2001
   }
 258  
 
 259  
 
 260  
   /**
 261  
    * {@inheritDoc}
 262  
    * @see org.melati.template.MarkupLanguage#renderedStart(org.melati.poem.Field)
 263  
    */
 264  
   public String renderedStart(Field field)
 265  
       throws IOException {
 266  911
     MelatiStringWriter sw = getStringWriter();
 267  911
     renderStart(field, sw);
 268  911
     return sw.toString();
 269  
   }
 270  
 
 271  
 
 272  
   protected void renderStart(Field field, MelatiWriter writer)
 273  
       throws IOException {
 274  911
     render(field, DateFormat.MEDIUM, 50, writer);
 275  911
   }
 276  
 
 277  
   /**
 278  
    * Render an Object in a MarkupLanguage specific way, rendering to
 279  
    * the <code>MelatiWriter</code> supplied by <code>melati.getWriter()</code>.
 280  
    *
 281  
    * @param o - the Object to be rendered
 282  
    * @throws IOException - if there is a problem during rendering
 283  
    * @throws TemplateEngineException - if there is a problem with the
 284  
    *                                   ServletTemplateEngine
 285  
    */
 286  
   protected void render(Object o) throws IOException {
 287  8
     MelatiWriter writer = melati.getWriter();
 288  8
     render(o, writer);
 289  4
   }
 290  
 
 291  
   /**
 292  
    * Render an Object in a MarkupLanguage specific way, rendering to
 293  
    * a supplied Writer.
 294  
    *
 295  
    * NOTE The context always contains objects with the names melati, object and  ml  
 296  
    *
 297  
    * @param o - the Object to be rendered
 298  
    * @param writer - the MelatiWriter to render this Object to
 299  
    */
 300  
   protected void render(Object o, MelatiWriter writer) throws IOException {
 301  111
     if (o == null)
 302  5
       throw new NullPointerException();
 303  
     else {
 304  106
         TemplateContext vars =
 305  
           melati.getTemplateEngine().getTemplateContext(melati);
 306  106
         Template templet =
 307  
           templetLoader.templet(melati.getTemplateEngine(), this, o.getClass());
 308  93
         vars.put("object", o);
 309  
         // Not happy but 
 310  93
         if (o instanceof Field) vars.put("field", o);
 311  93
         vars.put("melati", melati);
 312  93
         vars.put("ml", melati.getMarkupLanguage());
 313  93
         expandTemplet(templet, vars, writer);
 314  
     }
 315  87
   }
 316  
 
 317  
 
 318  
   //
 319  
   // =========
 320  
   //  Widgets
 321  
   // =========
 322  
   //
 323  
   
 324  
   /**
 325  
    * {@inheritDoc}
 326  
    * @see org.melati.template.MarkupLanguage#input(org.melati.poem.Field)
 327  
    */
 328  
   public String input(Field field)
 329  
       throws TemplateEngineException,
 330  
              IOException, NotFoundException {
 331  177
     return input(field, null, "", false);
 332  
   }
 333  
 
 334  
   /**
 335  
    * {@inheritDoc}
 336  
    * @see org.melati.template.MarkupLanguage#inputAs(org.melati.poem.Field, java.lang.String)
 337  
    */
 338  
   public String inputAs(Field field, String templetName)
 339  
       throws TemplateEngineException,
 340  
              IOException, NotFoundException {
 341  28
     return input(field, templetName, "", false);
 342  
   }
 343  
 
 344  
   /**
 345  
    * {@inheritDoc}
 346  
    * @see org.melati.template.MarkupLanguage#searchInput(org.melati.poem.Field, java.lang.String)
 347  
    */
 348  
   public String searchInput(Field field, String nullValue)
 349  
       throws TemplateEngineException,
 350  
              IOException, NotFoundException{
 351  5
     return input(field, null, nullValue, true);
 352  
   }
 353  
 
 354  
   protected String input(Field field,
 355  
                          String templetName,
 356  
                          String nullValue,
 357  
                          boolean overrideNullable)
 358  
        throws IOException, NotFoundException {
 359  
 
 360  
     Template templet;
 361  210
     templet =
 362  
       templetName == null ?
 363  
         templetLoader.templet(melati.getTemplateEngine(), this, field) :
 364  
         templetLoader.templet(melati.getTemplateEngine(), this, templetName);
 365  
 
 366  198
     TemplateContext vars =
 367  
         melati.getTemplateEngine().getTemplateContext(melati);
 368  
 
 369  198
     if (overrideNullable) {
 370  4
       field = field.withNullable(true);
 371  4
       vars.put("nullValue", nullValue);
 372  
     }
 373  
 
 374  198
     vars.put("melati", melati);
 375  198
     vars.put("ml", melati.getMarkupLanguage());
 376  198
     vars.put("object", field);
 377  198
     vars.put("field", field);
 378  198
     MelatiStringWriter sw = getStringWriter();
 379  198
     melati.getTemplateEngine().expandTemplate(sw, templet,vars);
 380  
     
 381  198
     return sw.toString(); 
 382  
   }
 383  
 
 384  
   
 385  
   /**
 386  
    * Interpolate a templet and write it out.
 387  
    * 
 388  
    * @param templet {@link Template} to interpolate
 389  
    * @param tc {@link TemplateContext} against which to instantiate variables
 390  
    * @param out {@link MelatiWriter} to write results to 
 391  
    * @throws TemplateEngineException if something unexpected happens
 392  
    */
 393  
   protected void expandTemplet(Template templet, TemplateContext tc,
 394  
                                MelatiWriter out) throws IOException {
 395  93
     melati.getTemplateEngine().expandTemplate(out, templet, tc);
 396  87
   }
 397  
 }
 398  
 
 399