KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > config > BaseConfigService


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.config;
18
19 import java.io.InputStream JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24
25 import org.alfresco.config.evaluator.Evaluator;
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28
29 /**
30  * Base class for all config service implementations. This class implements the
31  * basic algorithm for performing lookups, concrete classes read their
32  * configuration medium and populate this object ready for lookups.
33  *
34  * The algorithm used is as follows:
35  * <p>
36  * Lookup methods go through the list of sections (maybe restricted to an area)
37  * and looks at the evaluator for each one. The Evaluator implementation is
38  * extracted and applies() is called on it. If applies() returns true all the
39  * ConfigElements from it are added to the Config object. If the ConfigElement
40  * already exists in the Config object being built up the new one is combined()
41  * with the existing one.
42  * </p>
43  *
44  * @author gavinc
45  */

46 public abstract class BaseConfigService implements ConfigService
47 {
48     private static final Log logger = LogFactory.getLog(BaseConfigService.class);
49
50     protected ConfigSource configSource;
51     protected ConfigImpl globalConfig;
52     protected Map JavaDoc<String JavaDoc, Evaluator> evaluators;
53     protected Map JavaDoc<String JavaDoc, List JavaDoc<ConfigSection>> sectionsByArea;
54     protected List JavaDoc<ConfigSection> sections;
55
56     /**
57      * Construct the service with the source from which it must read
58      *
59      * @param configSource
60      * the source of the configurations
61      */

62     public BaseConfigService(ConfigSource configSource)
63     {
64         if (configSource == null)
65         {
66             throw new IllegalArgumentException JavaDoc("The config source is mandatory");
67         }
68         this.configSource = configSource;
69     }
70
71     /**
72      * Initialises the config service
73      */

74     public void init()
75     {
76         this.sections = new ArrayList JavaDoc<ConfigSection>();
77         this.sectionsByArea = new HashMap JavaDoc<String JavaDoc, List JavaDoc<ConfigSection>>();
78         this.evaluators = new HashMap JavaDoc<String JavaDoc, Evaluator>();
79         this.globalConfig = new ConfigImpl();
80
81         // Add the built-in evaluators
82
addEvaluator("string-compare", "org.alfresco.config.evaluator.StringEvaluator");
83         addEvaluator("object-type", "org.alfresco.config.evaluator.ObjectTypeEvaluator");
84     }
85
86     /**
87      * Cleans up all the resources used by the config service
88      */

89     public void destroy()
90     {
91         this.sections.clear();
92         this.sectionsByArea.clear();
93         this.evaluators.clear();
94
95         this.sections = null;
96         this.sectionsByArea = null;
97         this.evaluators = null;
98     }
99     
100     /**
101      * Resets the config service
102      */

103     public void reset()
104     {
105        if (logger.isDebugEnabled())
106          logger.debug("Resetting config service");
107        
108        destroy();
109        init();
110     }
111
112     /**
113      * @see org.alfresco.config.ConfigService#getConfig(java.lang.Object)
114      */

115     public Config getConfig(Object JavaDoc object)
116     {
117         return getConfig(object, new ConfigLookupContext());
118     }
119
120     /**
121      * @see org.alfresco.config.ConfigService#getConfig(java.lang.Object, org.alfresco.config.ConfigLookupContext)
122      */

123     public Config getConfig(Object JavaDoc object, ConfigLookupContext context)
124     {
125         if (logger.isDebugEnabled())
126             logger.debug("Retrieving configuration for " + object);
127
128         ConfigImpl results = null;
129
130         if (context.includeGlobalSection())
131         {
132             results = new ConfigImpl(this.globalConfig);
133
134             if (logger.isDebugEnabled())
135                 logger.debug("Created initial config results using global section");
136         }
137         else
138         {
139             results = new ConfigImpl();
140
141             if (logger.isDebugEnabled())
142                 logger.debug("Created initial config results ignoring the global section");
143         }
144
145         if (context.getAreas().size() > 0)
146         {
147             if (logger.isDebugEnabled())
148                 logger.debug("Restricting search within following areas: " + context.getAreas());
149
150             // add all the config elements from all sections (that match) in
151
// each named area to the results
152
for (String JavaDoc area : context.getAreas())
153             {
154                 List JavaDoc<ConfigSection> areaSections = this.sectionsByArea.get(area);
155                 if (areaSections == null)
156                 {
157                     throw new ConfigException("Requested area '" + area + "' has not been defined");
158                 }
159
160                 for (ConfigSection section: areaSections)
161                 {
162                     processSection(section, object, context, results);
163                 }
164             }
165         }
166         else
167         {
168             // add all the config elements from all sections (that match) to the results
169
for (ConfigSection section: this.sections)
170             {
171                 processSection(section, object, context, results);
172             }
173         }
174
175         return results;
176     }
177
178     /**
179      * @see org.alfresco.config.ConfigService#getGlobalConfig()
180      */

181     public Config getGlobalConfig()
182     {
183         return this.globalConfig;
184     }
185
186     /**
187      * Parses all the files passed to this config service
188      */

189     protected void parse()
190     {
191         for (InputStream JavaDoc inputStream : this.configSource)
192         {
193             if (logger.isDebugEnabled())
194                logger.debug("Commencing parse of input stream");
195             
196             parse(inputStream);
197             
198             if (logger.isDebugEnabled())
199                logger.debug("Completed parse of input stream");
200         }
201     }
202
203     /**
204      * Parses the given config stream
205      *
206      * @param stream
207      * The input stream representing the config data
208      */

209     protected abstract void parse(InputStream JavaDoc stream);
210
211     /**
212      * Adds the given config section to the config service and optionally within
213      * a named area
214      *
215      * @param section
216      * The config section to add
217      * @param area
218      * The name of the area to add the section to, if null the
219      * section is only added to the global section list
220      */

221     protected void addConfigSection(ConfigSection section, String JavaDoc area)
222     {
223         if (section.isGlobal())
224         {
225             // get all the config elements from this section and add them to the
226
// global section, if any already exist we must combine or replace them
227
for (ConfigElement ce : section.getConfigElements())
228             {
229                ConfigElement existing = this.globalConfig.getConfigElement(ce.getName());
230                
231                if (existing != null)
232                {
233                   if (section.isReplace())
234                   {
235                      // if the section has been marked as 'replace' and a config element
236
// with this name has already been found, replace it
237
this.globalConfig.putConfigElement(ce);
238                      
239                      if (logger.isDebugEnabled())
240                         logger.debug("Replaced " + existing + " with " + ce);
241                   }
242                   else
243                   {
244                      // combine the config elements
245
ConfigElement combined = existing.combine(ce);
246                      this.globalConfig.putConfigElement(combined);
247                      
248                      if (logger.isDebugEnabled())
249                      {
250                         logger.debug("Combined " + existing + " with " + ce +
251                                      " to create " + combined);
252                      }
253                   }
254                }
255                else
256                {
257                   this.globalConfig.putConfigElement(ce);
258                }
259             }
260             
261
262             if (logger.isDebugEnabled())
263                 logger.debug("Added config elements from " + section + " to the global section");
264         }
265         else
266         {
267             if (area != null && area.length() > 0)
268             {
269                 // get the list of sections for the given area name (create the
270
// list if required)
271
List JavaDoc<ConfigSection> areaSections = this.sectionsByArea.get(area);
272                 if (areaSections == null)
273                 {
274                     areaSections = new ArrayList JavaDoc<ConfigSection>();
275                     this.sectionsByArea.put(area, areaSections);
276                 }
277
278                 // add the section to the list
279
areaSections.add(section);
280
281                 if (logger.isDebugEnabled())
282                     logger.debug("Added " + section + " to the '" + area + "' area");
283             }
284             else
285             {
286                 // add the section to the relevant collections
287
this.sections.add(section);
288
289                 if (logger.isDebugEnabled())
290                     logger.debug("Added " + section + " to the sections list");
291             }
292         }
293     }
294
295     /**
296      * Retrieves the implementation of the named evaluator
297      *
298      * @param name
299      * Name of the evaluator to retrieve
300      * @return The evaluator, null if it doesn't exist
301      */

302     protected Evaluator getEvaluator(String JavaDoc name)
303     {
304         return (Evaluator) this.evaluators.get(name);
305     }
306
307     /**
308      * Adds the evaluator with the given name and class to the config service
309      *
310      * @param name
311      * Name of the evaluator
312      * @param className
313      * Class name of the evaluator
314      */

315     protected void addEvaluator(String JavaDoc name, String JavaDoc className)
316     {
317         Evaluator evaluator = null;
318
319         try
320         {
321             Class JavaDoc clazz = Class.forName(className);
322             evaluator = (Evaluator) clazz.newInstance();
323         }
324         catch (Throwable JavaDoc e)
325         {
326             throw new ConfigException("Could not instantiate evaluator for '" + name + "' with class: " + className, e);
327         }
328
329         this.evaluators.put(name, evaluator);
330
331         if (logger.isDebugEnabled())
332             logger.debug("Added evaluator '" + name + "': " + className);
333     }
334     
335     /**
336      * Determines whether the given section applies for the given object, if it
337      * does, the section is added to given results object.
338      *
339      * @param section
340      * The section to process
341      * @param object
342      * The object to retrieve config for
343      * @param context
344      * The context to use for the lookup
345      * @param results
346      * The resulting config object for the search
347      */

348     protected void processSection(ConfigSection section, Object JavaDoc object, ConfigLookupContext context,
349                                   ConfigImpl results)
350     {
351         String JavaDoc evaluatorName = section.getEvaluator();
352         Evaluator evaluator = getEvaluator(evaluatorName);
353
354         if (evaluator == null)
355         {
356             throw new ConfigException("Unable to locate evaluator implementation for '" + evaluatorName +
357                                       "' for " + section);
358         }
359
360         context.getAlgorithm().process(section, evaluator, object, results);
361     }
362 }
363
Popular Tags