Coverage Report - org.webmacro.directive.DirectiveProvider
 
Classes in this File Line Coverage Branch Coverage Complexity
DirectiveProvider
67%
33/49
41%
5/12
2.778
DirectiveProvider$1
N/A
N/A
2.778
DirectiveProvider$SettingHandler
66%
4/6
N/A
2.778
 
 1  
 /*
 2  
  * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
 3  
  *
 4  
  * Redistribution and use in source and binary forms, with or without
 5  
  * modification, are permitted under the terms of either of the following
 6  
  * Open Source licenses:
 7  
  *
 8  
  * The GNU General Public License, version 2, or any later version, as
 9  
  * published by the Free Software Foundation
 10  
  * (http://www.fsf.org/copyleft/gpl.html);
 11  
  *
 12  
  *  or
 13  
  *
 14  
  * The Semiotek Public License (http://webmacro.org/LICENSE.)
 15  
  *
 16  
  * This software is provided "as is", with NO WARRANTY, not even the
 17  
  * implied warranties of fitness to purpose, or merchantability. You
 18  
  * assume all risks and liabilities associated with its use.
 19  
  *
 20  
  * See www.webmacro.org for more information on the WebMacro project.
 21  
  */
 22  
 
 23  
 package org.webmacro.directive;
 24  
 
 25  
 import org.slf4j.Logger;
 26  
 import org.slf4j.LoggerFactory;
 27  
 import org.webmacro.Broker;
 28  
 import org.webmacro.InitException;
 29  
 import org.webmacro.Provider;
 30  
 import org.webmacro.engine.IntrospectionException;
 31  
 import org.webmacro.util.Settings;
 32  
 
 33  
 import java.util.Hashtable;
 34  
 
 35  
 /**
 36  
  * Utility class to assist in the creation of directives.
 37  
  */
 38  6
 public final class DirectiveProvider implements Provider
 39  
 {
 40  
 
 41  2
     static Logger _log =  LoggerFactory.getLogger(DirectiveProvider.class);
 42  
 
 43  
     public static final String DIRECTIVE_KEY = "directive";
 44  
 
 45  
     // BULDER CLASS MANAGEMENT
 46  
 
 47  6
     private final Hashtable _descriptors = new Hashtable();
 48  
     private Broker _broker;
 49  
 
 50  
 
 51  
     /**
 52  
      * a simple class to take care of registering Directives specified
 53  
      * in the Settings of the Broker.
 54  
      */
 55  12
     private class SettingHandler extends Settings.ListSettingHandler
 56  
     {
 57  
 
 58  
         public void processSetting (String settingKey, String settingValue)
 59  
         {
 60  
             try
 61  
             {
 62  120
                 registerDirective(settingValue, settingKey);
 63  
             }
 64  0
             catch (Exception ce)
 65  
             {
 66  0
                 _log.warn("Exception loading directive " + settingValue, ce);
 67  120
             }
 68  120
         }
 69  
     }
 70  
 
 71  
 
 72  
     /**
 73  
      * Register an org.webmacro.directive.DirectiveDescriptor to be used
 74  
      * as if it were a real Directive named <code>dirName</code>.<p>
 75  
      *
 76  
      * If the specified <code>dirName</code> is already registered, it is
 77  
      * happily, and silently replaced.<p>
 78  
      *
 79  
      * Once registered, one can use this "directive" from a template like so:<pre>
 80  
      *    #dirName arg1 arg2 argN
 81  
      *
 82  
      * where the args are dependant on the DirectiveDescriptor
 83  
      * </pre>
 84  
      *
 85  
      * @param dd the DirectiveDescriptor
 86  
      * @param dirName name of the "directive"
 87  
      */
 88  
     public final void registerDescriptor (DirectiveDescriptor dd, String dirName)
 89  
     {
 90  0
         _descriptors.put(dirName, dd);
 91  0
     }
 92  
 
 93  
 
 94  
     /**
 95  
      * Register a new directive class, so that a builder
 96  
      * of this type can be retrieved later.
 97  
      * @exception IntrospectionException something wrong with the class
 98  
      * @exception InitException duplicate registration
 99  
      */
 100  
     public final void registerDirective (String dirClassName, String dirName)
 101  
             throws IntrospectionException, InitException
 102  
     {
 103  120
         Class directive = null;
 104  
         DirectiveDescriptor templateDesc, newDesc, oldDesc;
 105  
         try
 106  
         {
 107  120
             directive = _broker.classForName(dirClassName);
 108  
         }
 109  0
         catch (Exception e)
 110  
         {
 111  0
             throw new IntrospectionException("No class " + dirClassName, e);
 112  120
         }
 113  
 
 114  
         // Make sure this class is an instance of o.w.directive.Directive
 115  120
         if (Directive.class.isAssignableFrom(directive))
 116  
         {
 117  
             try
 118  
             {
 119  120
                 templateDesc = (DirectiveDescriptor)
 120  
                         directive.getMethod("getDescriptor", (Class[])null).invoke(null, (Object[])null);
 121  120
                 newDesc = new DirectiveDescriptor(templateDesc.name,
 122  
                         templateDesc.dirClass,
 123  
                         templateDesc.args,
 124  
                         templateDesc.subdirectives);
 125  120
                 if (newDesc.dirClass == null)
 126  120
                     newDesc.dirClass = directive;
 127  
             }
 128  0
             catch (Exception e)
 129  
             {
 130  0
                 throw new IntrospectionException("Class " + dirClassName
 131  
                         + " does not have a getDescriptor() method", e);
 132  120
             }
 133  
 
 134  
             // added by Keats 5Jul01
 135  
             // use introspection to invoke the static init method of directive, if it exists
 136  120
             Class[] cArg = {Broker.class};
 137  
             try
 138  
             {
 139  120
                 java.lang.reflect.Method m = directive.getMethod("init", cArg);
 140  6
                 Object[] brokerArg = {_broker};
 141  
                 try
 142  
                 {
 143  6
                     m.invoke(null, brokerArg);
 144  
                 }
 145  0
                 catch (Exception e)
 146  
                 {
 147  0
                     _log.warn("Unable to invoke the init method for the directive "
 148  
                             + directive.getName(), e);
 149  6
                 }
 150  
             }
 151  114
             catch (Exception e)
 152  
             {
 153  6
             }
 154  
 
 155  120
             newDesc.name = (dirName != null && !dirName.equals(""))
 156  
                     ? dirName : templateDesc.name;
 157  120
             oldDesc = (DirectiveDescriptor) _descriptors.get(newDesc.name);
 158  120
             if (oldDesc == null)
 159  
             {
 160  120
                 _descriptors.put(newDesc.name, newDesc);
 161  120
                 _log.info("Registered directive: " + newDesc.name);
 162  
             }
 163  0
             else if (newDesc.dirClass != oldDesc.dirClass)
 164  
             {
 165  0
                 throw new InitException("Attempt to register directive " + directive
 166  
                         + " failed because " + oldDesc.dirClass.getName()
 167  
                         + " is already registered for type " + newDesc.name);
 168  
             }
 169  
         }
 170  120
     }
 171  
 
 172  
     /**
 173  
      * Create a builder for the named directive
 174  
      */
 175  
     private final DirectiveDescriptor getDescriptor (String directiveName)
 176  
     {
 177  1288
         return (DirectiveDescriptor) _descriptors.get(directiveName);
 178  
     }
 179  
 
 180  
 
 181  
 
 182  
     // RESOURCE PROVIDER API
 183  
 
 184  
     public String getType ()
 185  
     {
 186  6
         return DIRECTIVE_KEY;
 187  
     }
 188  
 
 189  
     public void init (Broker broker, Settings config) throws InitException
 190  
     {
 191  6
         _broker = broker;
 192  
         try
 193  
         {
 194  6
             config.processListSetting("Directives", new SettingHandler());
 195  
         }
 196  0
         catch (Exception e)
 197  
         {
 198  0
             _log.warn("Error initializing DirectiveProvider", e);
 199  0
             throw new InitException("Could not initialize DirectiveProvider", e);
 200  6
         }
 201  6
     }
 202  
 
 203  
     public void destroy ()
 204  
     {
 205  0
         _descriptors.clear();
 206  0
     }
 207  
 
 208  
     /**
 209  
      * The DirectiveProvider doesn't throw an exception when it can't find
 210  
      * the directive -- it just returns null.
 211  
      */
 212  
     public Object get (String name)
 213  
     {
 214  1288
         return getDescriptor(name);
 215  
     }
 216  
 
 217  
     public void flush ()
 218  
     {
 219  0
     }
 220  
 }
 221  
 
 222