Coverage Report - org.melati.template.ClassNameTempletLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassNameTempletLoader
99%
66/67
93%
26/28
2.462
 
 1  
 /*
 2  
  * $Source: /usr/cvsroot/melati/melati/src/main/java/org/melati/template/ClassNameTempletLoader.java,v $
 3  
  * $Revision: 1.37 $
 4  
  *
 5  
  * Copyright (C) 2000 William Chesters
 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  
  *     William Chesters <williamc At paneris.org>
 42  
  *     http://paneris.org/~williamc
 43  
  *     Obrechtstraat 114, 2517VX Den Haag, The Netherlands
 44  
  */
 45  
 
 46  
 package org.melati.template;
 47  
 
 48  
 import java.io.IOException;
 49  
 import java.util.Hashtable;
 50  
 
 51  
 import org.melati.poem.FieldAttributes;
 52  
 import org.melati.util.MelatiBugMelatiException;
 53  
 
 54  
 /**
 55  
  * Load a template to render an object based upon the object's class.
 56  
  */
 57  
 public final class ClassNameTempletLoader implements TempletLoader {
 58  
 
 59  
   /** The instance. */
 60  1
   private static ClassNameTempletLoader it = null;
 61  
 
 62  
   // NOTE It is not expected that templates will be added at runtime.
 63  1
   private static Hashtable templetForClassCache = new Hashtable();
 64  
   
 65  1
   private static final Integer FOUND = new Integer(1);
 66  1
   private static final Integer NOT_FOUND = new Integer(0);
 67  1
   private static Hashtable lookedupTemplateNames = new Hashtable();
 68  
 
 69  
   /** Disable instantiation. */
 70  1
   private ClassNameTempletLoader() {}
 71  
 
 72  
   /**
 73  
    * @return the instance
 74  
    */
 75  
   public static ClassNameTempletLoader getInstance() {
 76  419
     if (it == null)
 77  1
       it = new ClassNameTempletLoader();
 78  419
     return it;
 79  
   }
 80  
   protected static String templetsPath(TemplateEngine templateEngine, 
 81  
                                 MarkupLanguage markupLanguage) {
 82  
     /*
 83  
     // Fails to find templates in jars!!
 84  
     return "org" + File.separatorChar + 
 85  
            "melati" + File.separatorChar + 
 86  
            "template" + File.separatorChar + 
 87  
             templateEngine.getName() + File.separatorChar + 
 88  
            "templets" + File.separatorChar +
 89  
             markupLanguage.getName() + File.separatorChar;
 90  
     */
 91  167
     return "org/melati/template/" +  
 92  
            templateEngine.getName() +  
 93  
            "/templets/" + 
 94  
            markupLanguage.getName() + "/";
 95  
     
 96  
     }
 97  
 
 98  
   /**
 99  
    * @return the path in the templets directory
 100  
    */
 101  
   protected static String templetsTempletPath(TemplateEngine templateEngine,
 102  
                                MarkupLanguage markupLanguage,
 103  
                                String purpose, String name) {
 104  167
     if (purpose == null)
 105  164
       return 
 106  
                  templetsPath(templateEngine, markupLanguage) + 
 107  
                  name +
 108  
                  templateEngine.templateExtension();
 109  3
     return 
 110  
                templetsPath(templateEngine, markupLanguage) + 
 111  
                purpose + "/" + 
 112  
                name +
 113  
                templateEngine.templateExtension();
 114  
   }
 115  
 
 116  
   protected static String classpathTempletPath(Class clazz, TemplateEngine templateEngine) { 
 117  108
     return clazz.getName().replace('.', '/') + templateEngine.templateExtension();
 118  
   }
 119  
   /**
 120  
    * Get a templet by name, with optional purpose. 
 121  
    * 
 122  
    * {@inheritDoc}
 123  
    * @see TempletLoader#templet(TemplateEngine, AbstractMarkupLanguage, String, String)
 124  
    */
 125  
   public Template templet(TemplateEngine templateEngine,
 126  
                           MarkupLanguage markupLanguage, String purpose,
 127  
                           String name) throws IOException, NotFoundException {
 128  22
     return templateEngine.template(templetsTempletPath(templateEngine, markupLanguage,
 129  
         purpose, name));
 130  
   }
 131  
 
 132  
   /**
 133  
    * Get a templet by its name, looking only in the templets directory.
 134  
    * 
 135  
    * {@inheritDoc}
 136  
    * @see TempletLoader#templet(TemplateEngine, MarkupLanguage, String)
 137  
    */
 138  
   public Template templet(TemplateEngine templateEngine,
 139  
                           MarkupLanguage markupLanguage, String name) 
 140  
       throws IOException, NotFoundException {
 141  22
     return templet(templateEngine, markupLanguage, null, name);
 142  
   }
 143  
 
 144  
   /**
 145  
    * Get a templet based upon class name and optional purpose, 
 146  
    * looking in the templets directory and also the classpath.
 147  
    * 
 148  
    * {@inheritDoc}
 149  
    * @see TempletLoader#templet(TemplateEngine, MarkupLanguage, 
 150  
    *                            String, Class)
 151  
    */
 152  
   public Template templet(TemplateEngine templateEngine,
 153  
                           MarkupLanguage markupLanguage, String purpose,
 154  
                           Class clazz)
 155  
       throws TemplateEngineException, IOException {
 156  102
     Class lookupClass = clazz;
 157  102
     Template templet = null;
 158  102
     Template fromCache = null;
 159  102
     String originalCacheKey = cacheKey(templateEngine, markupLanguage, purpose, lookupClass);
 160  102
     String lookupCacheKey = originalCacheKey;
 161  102
     String lookupPurpose = purpose;
 162  197
     while (lookupClass != null) {
 163  197
       fromCache = (Template)templetForClassCache.get(lookupCacheKey);
 164  197
       if (fromCache != null) {
 165  52
         templet = fromCache;
 166  52
         break;
 167  
       } 
 168  
       //templet = getSpecialTemplate(lookupClass, lookupPurpose, markupLanguage, templateEngine);
 169  
       //if (templet != null)
 170  
       //  break;
 171  
       
 172  
       // Try to find one in the templets directory
 173  145
       String templetPath = templetsTempletPath(templateEngine, markupLanguage,
 174  
               lookupPurpose, lookupClass.getName());
 175  145
       templet = getTemplate(templateEngine, templetPath);
 176  135
       if (templet != null)
 177  27
         break;
 178  
       // Try to find one on classpath
 179  108
       templetPath = classpathTempletPath(lookupClass, templateEngine);
 180  108
       templet = getTemplate(templateEngine, templetPath);
 181  102
       if (templet != null)
 182  7
         break;
 183  
       
 184  95
       if (lookupPurpose != null)
 185  1
         lookupPurpose = null;
 186  
       else { 
 187  94
         lookupClass = lookupClass.getSuperclass();
 188  94
         lookupPurpose = purpose;
 189  
       }
 190  95
       lookupCacheKey = cacheKey(templateEngine, markupLanguage, lookupPurpose, lookupClass);
 191  95
     }
 192  
     
 193  86
     if (templet == null)
 194  0
       throw new MelatiBugMelatiException("Cannot even find template for Object");
 195  86
     if (fromCache == null)
 196  34
       templetForClassCache.put(originalCacheKey, templet);
 197  86
     if (!lookupCacheKey.equals(originalCacheKey)) { 
 198  44
       if (templetForClassCache.get(lookupCacheKey) == null) 
 199  14
         templetForClassCache.put(lookupCacheKey, templet);
 200  
     } 
 201  86
     return templet;
 202  
   }
 203  
 
 204  
   private String cacheKey(TemplateEngine templateEngine, 
 205  
       MarkupLanguage markupLanguage, 
 206  
       String purpose, 
 207  
       Class lookupClass) {
 208  197
     return  purpose == null ? cacheKey(templateEngine, markupLanguage, lookupClass) 
 209  
                             : lookupClass + "/" + 
 210  
                                purpose + "/" + 
 211  
                                markupLanguage + "/" + 
 212  
                                templateEngine.getName();
 213  
   }
 214  
   
 215  
   private String cacheKey(TemplateEngine templateEngine, 
 216  
       MarkupLanguage markupLanguage, 
 217  
       Class lookupClass) {
 218  192
     return lookupClass + 
 219  
            "/" + markupLanguage + 
 220  
            "/" + templateEngine.getName();
 221  
   }
 222  
 
 223  
   private Template getTemplate(TemplateEngine templateEngine, String templetPath) 
 224  
       throws IOException { 
 225  253
     Template templet = null;
 226  
     try {
 227  253
       Object triedAlready = lookedupTemplateNames.get(templetPath);
 228  253
       if (triedAlready != NOT_FOUND) {
 229  174
         templet = templateEngine.template(templetPath);
 230  34
         lookedupTemplateNames.put(templetPath, FOUND);
 231  
       } 
 232  124
     } catch (NotFoundException e) {
 233  124
       lookedupTemplateNames.put(templetPath, NOT_FOUND);
 234  113
     }
 235  237
     return templet;
 236  
   }
 237  
 
 238  
   /**
 239  
    * Get a templet for a class.
 240  
    * 
 241  
    * {@inheritDoc}
 242  
    * @see TempletLoader#templet(TemplateEngine, MarkupLanguage, Class)
 243  
    */
 244  
   public Template templet(TemplateEngine templateEngine,
 245  
                           MarkupLanguage markupLanguage, Class clazz)
 246  
       throws IOException {
 247  97
     return templet(templateEngine, markupLanguage, null, clazz);
 248  
   }
 249  
 
 250  
   /**
 251  
    * Get a templet either from the FieldAttributes or 
 252  
    * the class name.
 253  
    * 
 254  
    * {@inheritDoc}
 255  
    * @see TempletLoader#templet(TemplateEngine,MarkupLanguage,FieldAttributes)
 256  
    */
 257  
   public Template templet(TemplateEngine templateEngine,
 258  
                           MarkupLanguage markupLanguage,
 259  
                           FieldAttributes attributes)
 260  
       throws IOException {
 261  28
     if (attributes.getRenderInfo() != null) {
 262  9
       String templetName = attributes.getType().getClass().getName() 
 263  
           + "-"
 264  
           + attributes.getRenderInfo();
 265  
       try {
 266  9
         return templet(templateEngine, markupLanguage, 
 267  
                 templetName);
 268  2
       } catch (NotFoundException e) {
 269  2
         throw new MelatiBugMelatiException(
 270  
                 "Templet " + templetName  + " not found", e);
 271  
       }
 272  
     } else {
 273  19
         return templet(templateEngine, markupLanguage,
 274  
                 attributes.getType().getClass());
 275  
     }
 276  
   }
 277  
 }
 278  
 
 279  
 
 280  
 
 281  
 
 282  
 
 283  
 
 284  
 
 285  
 
 286  
 
 287