##### Coverage Report - org.webmacro.directive.DirectiveProvider

Classes in this File | Line Coverage | Branch Coverage | Complexity
DirectiveProvider |
67% | 33/49
41% | 5/12
| 2.7777777777777777;2.778
DirectiveProvider$1 |
N/A | N/A
N/A | N/A
| 2.7777777777777777;2.778
DirectiveProvider$SettingHandler |
66% | 4/6
N/A | N/A
| 2.7777777777777777;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 |  |