Clover coverage report - Ledge Web - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:20:55 CET
file stats: LOC: 365   Methods: 15
NCLOC: 233   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
MVCFinder.java 87.5% 94.1% 100% 92.9%
coverage coverage
 1    //
 2    // Copyright (c) 2003, Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    // All rights reserved.
 4    //
 5    // Redistribution and use in source and binary forms, with or without modification,
 6    // are permitted provided that the following conditions are met:
 7    //
 8    // * Redistributions of source code must retain the above copyright notice,
 9    // this list of conditions and the following disclaimer.
 10    // * Redistributions in binary form must reproduce the above copyright notice,
 11    // this list of conditions and the following disclaimer in the documentation
 12    // and/or other materials provided with the distribution.
 13    // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    // nor the names of its contributors may be used to endorse or promote products
 15    // derived from this software without specific prior written permission.
 16    //
 17    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    // POSSIBILITY OF SUCH DAMAGE.
 27    //
 28    package org.objectledge.web.mvc.finders;
 29   
 30    import java.util.HashMap;
 31   
 32    import org.jcontainer.dna.Logger;
 33    import org.objectledge.pipeline.Valve;
 34    import org.objectledge.templating.Template;
 35    import org.objectledge.templating.TemplateNotFoundException;
 36    import org.objectledge.templating.Templating;
 37    import org.objectledge.web.mvc.builders.Builder;
 38    import org.objectledge.web.mvc.components.Component;
 39    import org.picocontainer.MutablePicoContainer;
 40   
 41    /**
 42    * Implementation of MVC finding services.
 43    *
 44    * @author <a href="mailto:dgajda@caltha.pl">Damian Gajda</a>
 45    * @version $Id: MVCFinder.java,v 1.36 2005/07/29 11:57:18 rafal Exp $
 46    */
 47    public class MVCFinder implements MVCTemplateFinder, MVCClassFinder
 48    {
 49    /**
 50    * Different kinds of UI elements handled by the finder.
 51    */
 52    protected enum Kind
 53    {
 54    /** View element. */
 55    VIEW("views"),
 56    /** Action element. */
 57    ACTION("actions"),
 58    /** Component element. */
 59    COMPONENT("components");
 60   
 61  552 private Kind(String infix)
 62    {
 63  552 this.infix = infix;
 64    }
 65   
 66    private final String infix;
 67   
 68    /**
 69    * Returns the path infix used by name sequences.
 70    *
 71    * @return the path infix used by name sequences.
 72    */
 73  3404 public String getInfix()
 74    {
 75  3404 return infix;
 76    }
 77    }
 78   
 79    /** Internal constant for choosing "views" package name part. */
 80    private static final String VIEWS = "views";
 81    /** Internal constant for choosing "actions" package name part. */
 82    private static final String ACTIONS = "actions";
 83    /** Internal constant for choosing "components" package name part. */
 84    private static final String COMPONENTS = "components";
 85   
 86    private MutablePicoContainer container;
 87   
 88    /** the logger. */
 89    private Logger logger;
 90   
 91    /** The Templating component. */
 92    private Templating templating;
 93   
 94    /** The name sequence factory. */
 95    private NameSequenceFactory nameSequenceFactory;
 96   
 97    /** The class instances cache */
 98    private HashMap<String, Object> classInstanceCache = new HashMap<String, Object>();
 99   
 100    /** Special marker object for the classInstanceCache */
 101    private static final Object MISSING = new Object();
 102   
 103    /**
 104    * Creates a MVCFinder component.
 105    *
 106    * @param container the container to store loaded classes.
 107    * @param logger the logger to use.
 108    * @param templating the templating component.
 109    * @param nameSequenceFactory the name sequence factory component.
 110    */
 111  690 public MVCFinder(MutablePicoContainer container, Logger logger, Templating templating,
 112    NameSequenceFactory nameSequenceFactory)
 113    {
 114  690 this.container = container;
 115  690 this.logger = logger;
 116  690 this.templating = templating;
 117  690 this.nameSequenceFactory = nameSequenceFactory;
 118    }
 119   
 120    // templates ////////////////////////////////////////////////////////////////////////////////
 121   
 122    // builder templates ////////////////////////////////////////////////////////////////////////
 123   
 124    /**
 125    * {@inheritDoc}
 126    */
 127  1012 public MVCTemplateFinder.Result findBuilderTemplate(String view)
 128    {
 129  1012 return findBuilderTemplate(view, "findBuilderTemplate");
 130    }
 131   
 132    // component templates ////////////////////////////////////////////////////////////////////////
 133   
 134    /**
 135    * {@inheritDoc}
 136    */
 137  414 public Template getComponentTemplate(String name)
 138    {
 139  414 return findTemplate(Kind.COMPONENT, name, false, "getComponentTemplate");
 140    }
 141   
 142    // actions //////////////////////////////////////////////////////////////////////////////////
 143   
 144    /**
 145    * {@inheritDoc}
 146    */
 147  184 public Valve getAction(String actionName)
 148    {
 149  184 return (Valve)findObject(Kind.ACTION, actionName, false, "getAction");
 150    }
 151   
 152    // builders /////////////////////////////////////////////////////////////////////////////////
 153   
 154    /**
 155    * {@inheritDoc}
 156    */
 157  1656 public MVCClassFinder.Result findBuilder(String view)
 158    {
 159  1656 return findBuilder(view, "findBuilder");
 160    }
 161   
 162    /**
 163    * {@inheritDoc}
 164    */
 165  368 public String findEnclosingViewName(String viewName)
 166    {
 167  368 if(viewName != null && viewName.length() != 0)
 168    {
 169  368 Sequence classSequence = nameSequenceFactory.
 170    getClassNameSequence(VIEWS, viewName, true, true);
 171   
 172  368 Sequence templateSequence = nameSequenceFactory.
 173    getTemplateNameSequence(VIEWS, viewName, true, true);
 174   
 175  368 while(classSequence.hasNext() && templateSequence.hasNext())
 176    {
 177  322 String className = classSequence.next();
 178  322 String templateName = templateSequence.next();
 179  322 logger.debug("findEnclosingViewName: trying "+className+" and "+templateName);
 180   
 181  322 if(getClassInstance(className) != null)
 182    {
 183  230 break;
 184    }
 185   
 186  92 if(templating.templateExists(templateName))
 187    {
 188  92 break;
 189    }
 190    }
 191   
 192  368 String classSequenceViewName = classSequence.currentView();
 193  368 String templateSequenceViewName = templateSequence.currentView();
 194  368 if((classSequenceViewName == templateSequenceViewName) // both nulls
 195    || classSequenceViewName.equals(templateSequenceViewName))
 196    {
 197  368 return classSequenceViewName;
 198    }
 199    else
 200    {
 201  0 throw new IllegalStateException("Sequences produced different view names: "+
 202    classSequenceViewName+" (class sequence) "+
 203    templateSequenceViewName+" (template sequence)");
 204    }
 205    }
 206  0 return null;
 207    }
 208   
 209    // components ///////////////////////////////////////////////////////////////////////////////
 210   
 211    /**
 212    * {@inheritDoc}
 213    */
 214  368 public Component getComponent(String componentName)
 215    {
 216  368 return (Component)
 217    findObject(Kind.COMPONENT, componentName, false, "getComponent");
 218    }
 219   
 220    // implementation ///////////////////////////////////////////////////////////////////////////
 221   
 222  414 private Template findTemplate(Kind kind, String templateName, boolean fallback,
 223    String methodName)
 224    {
 225  414 if(templateName != null && templateName.length() != 0)
 226    {
 227  368 Sequence sequence = getTemplateNameSequence(kind, templateName, fallback, false);
 228  368 while(sequence.hasNext())
 229    {
 230  368 String name = sequence.next();
 231  368 logger.debug(methodName+": trying "+name);
 232  368 if(templating.templateExists(name))
 233    {
 234  184 try
 235    {
 236  184 return templating.getTemplate(name);
 237    }
 238    catch(TemplateNotFoundException e)
 239    {
 240  0 throw new IllegalStateException("Existing template disappeared", e);
 241    }
 242    }
 243    }
 244    }
 245  230 return null;
 246    }
 247   
 248  1012 private MVCTemplateFinder.Result findBuilderTemplate(String templateName, String methodName)
 249    {
 250  1012 if(templateName != null && templateName.length() != 0)
 251    {
 252  966 Sequence sequence = getTemplateNameSequence(Kind.VIEW, templateName, true, false);
 253  1518 while(sequence.hasNext())
 254    {
 255  1518 String name = sequence.next();
 256  1518 logger.debug(methodName+": trying "+name);
 257  1518 if(templating.templateExists(name))
 258    {
 259  966 try
 260    {
 261  966 Template template = templating.getTemplate(name);
 262  966 return new MVCTemplateFinder.Result(
 263    templateName, template, sequence.currentView());
 264    }
 265    catch(TemplateNotFoundException e)
 266    {
 267  0 throw new IllegalStateException("Existing template disappeared", e);
 268    }
 269    }
 270    }
 271  0 return new MVCTemplateFinder.Result(templateName, null, sequence.currentView());
 272    }
 273  46 return new MVCTemplateFinder.Result(templateName, null, null);
 274    }
 275   
 276    /**
 277    * Return a template lookup sequence.
 278    *
 279    * @param kind the kind of template being looked up.
 280    * @param templateName the view name.
 281    * @param fallback perform fallback.
 282    * @param enclosing obsolete paramter.
 283    * @return a lookup sequence.
 284    */
 285  1334 protected Sequence getTemplateNameSequence(Kind kind, String templateName,
 286    boolean fallback, boolean enclosing)
 287    {
 288  1334 return nameSequenceFactory.
 289    getTemplateNameSequence(kind.getInfix(), templateName, fallback, enclosing);
 290    }
 291   
 292  552 private Object findObject(Kind kind, String className, boolean fallback, String methodName)
 293    {
 294  552 if(className != null && className.length() != 0)
 295    {
 296  506 Sequence sequence = nameSequenceFactory.
 297    getClassNameSequence(kind.getInfix(), className, fallback, false);
 298  506 while(sequence.hasNext())
 299    {
 300  506 String name = sequence.next();
 301  506 logger.debug(methodName+": trying "+name);
 302  506 Object obj = getClassInstance(name);
 303  506 if(obj != null)
 304    {
 305  230 return obj;
 306    }
 307    }
 308    }
 309  322 return null;
 310    }
 311   
 312  1656 private MVCClassFinder.Result findBuilder(String className, String methodName)
 313    {
 314  1656 if(className != null && className.length() != 0)
 315    {
 316  1564 Sequence sequence = nameSequenceFactory.
 317    getClassNameSequence(Kind.VIEW.getInfix(), className, true, false);
 318  1564 while(sequence.hasNext())
 319    {
 320  1886 String name = sequence.next();
 321  1886 logger.debug(methodName+": trying "+name);
 322  1886 Object obj = getClassInstance(name);
 323  1886 if(obj != null)
 324    {
 325  1426 return new MVCClassFinder.Result(className, (Builder)obj, sequence
 326    .currentView());
 327    }
 328    }
 329  138 return new MVCClassFinder.Result(className, (Builder) null, sequence.currentView());
 330    }
 331  92 return new MVCClassFinder.Result(className, (Builder) null, null);
 332    }
 333   
 334  2714 private Object getClassInstance(String className)
 335    {
 336  2714 Object instance;
 337  2714 synchronized(classInstanceCache)
 338    {
 339  2714 instance = classInstanceCache.get(className);
 340  2714 if(instance == MISSING)
 341    {
 342  230 return null;
 343    }
 344  2484 if(instance == null)
 345    {
 346  1518 try
 347    {
 348  1518 Class clazz = Class.forName(className);
 349  920 if(container.getComponentAdapter(clazz) == null)
 350    {
 351  920 container.registerComponentImplementation(clazz);
 352    }
 353  920 instance = container.getComponentInstance(clazz);
 354  920 classInstanceCache.put(className, instance);
 355    }
 356    catch(ClassNotFoundException e)
 357    {
 358  598 classInstanceCache.put(className, MISSING);
 359  598 return null;
 360    }
 361    }
 362  1886 return instance;
 363    }
 364    }
 365    }