KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > config > xml > XMLConfigService


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.xml;
18
19 import java.io.InputStream JavaDoc;
20 import java.util.HashMap JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.alfresco.config.BaseConfigService;
25 import org.alfresco.config.ConfigElement;
26 import org.alfresco.config.ConfigException;
27 import org.alfresco.config.ConfigSectionImpl;
28 import org.alfresco.config.ConfigSource;
29 import org.alfresco.config.xml.elementreader.ConfigElementReader;
30 import org.alfresco.config.xml.elementreader.GenericElementReader;
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33 import org.dom4j.Document;
34 import org.dom4j.Element;
35 import org.dom4j.io.SAXReader;
36
37 /**
38  * XML based configuration service
39  *
40  * @author gavinc
41  */

42 public class XMLConfigService extends BaseConfigService implements XMLConfigConstants
43 {
44     private static final Log logger = LogFactory.getLog(XMLConfigService.class);
45
46     private Map JavaDoc<String JavaDoc, ConfigElementReader> elementReaders;
47     private String JavaDoc currentArea;
48
49     /**
50      * Constructs an XMLConfigService using the given config source
51      *
52      * @param configSource
53      * A ConfigSource
54      */

55     public XMLConfigService(ConfigSource configSource)
56     {
57         super(configSource);
58     }
59
60     /**
61      * @see org.alfresco.web.config.BaseConfigService#init()
62      */

63     public void init()
64     {
65         if (logger.isDebugEnabled())
66             logger.debug("Commencing initialisation");
67
68         super.init();
69
70         // initialise the element readers map with built-in readers
71
this.elementReaders = new HashMap JavaDoc<String JavaDoc, ConfigElementReader>();
72
73         parse();
74
75         if (logger.isDebugEnabled())
76             logger.debug("Completed initialisation");
77     }
78     
79     /**
80      * @see org.alfresco.config.BaseConfigService#destroy()
81      */

82     public void destroy()
83     {
84        this.elementReaders.clear();
85        this.elementReaders = null;
86        this.currentArea = null;
87        
88        super.destroy();
89     }
90
91     /**
92      * @see org.alfresco.web.config.BaseConfigService#parse(java.io.InputStream)
93      */

94     protected void parse(InputStream JavaDoc stream)
95     {
96         try
97         {
98             // get the root element
99
SAXReader reader = new SAXReader();
100             Document document = reader.read(stream);
101             Element rootElement = document.getRootElement();
102
103             // see if there is an area defined
104
this.currentArea = rootElement.attributeValue("area");
105
106             // parse the plug-ins section first
107
Element pluginsConfig = rootElement.element(ELEMENT_PLUG_INS);
108             parsePluginsElement(pluginsConfig);
109
110             // parse each config section in turn
111
Iterator JavaDoc configElements = rootElement.elementIterator(ELEMENT_CONFIG);
112             while (configElements.hasNext())
113             {
114                 Element configElement = (Element) configElements.next();
115                 parseConfigElement(configElement);
116             }
117         }
118         catch (Throwable JavaDoc e)
119         {
120             if (e instanceof ConfigException)
121             {
122                throw (ConfigException)e;
123             }
124             else
125             {
126                throw new ConfigException("Failed to parse config stream", e);
127             }
128         }
129     }
130
131     /**
132      * Parses the plug-ins section of a config file
133      *
134      * @param pluginsElement
135      * The plug-ins element
136      */

137     private void parsePluginsElement(Element pluginsElement)
138     {
139         if (pluginsElement != null)
140         {
141             // parese the evaluators section
142
parseEvaluatorsElement(pluginsElement.element(ELEMENT_EVALUATORS));
143
144             // parse the element readers section
145
parseElementReadersElement(pluginsElement.element(ELEMENT_ELEMENT_READERS));
146         }
147     }
148
149     /**
150      * Parses the evaluators element
151      *
152      * @param evaluatorsElement
153      */

154     private void parseEvaluatorsElement(Element evaluatorsElement)
155     {
156         if (evaluatorsElement != null)
157         {
158             Iterator JavaDoc evaluators = evaluatorsElement.elementIterator();
159             while (evaluators.hasNext())
160             {
161                 Element evaluatorElement = (Element) evaluators.next();
162                 String JavaDoc evaluatorName = evaluatorElement.attributeValue(ATTR_ID);
163                 String JavaDoc evaluatorClass = evaluatorElement.attributeValue(ATTR_CLASS);
164
165                 // TODO: Can these checks be removed if we use a DTD and/or
166
// schema??
167
if (evaluatorName == null || evaluatorName.length() == 0)
168                 {
169                     throw new ConfigException("All evaluator elements must define an id attribute");
170                 }
171
172                 if (evaluatorClass == null || evaluatorClass.length() == 0)
173                 {
174                     throw new ConfigException("Evaluator '" + evaluatorName + "' must define a class attribute");
175                 }
176
177                 // add the evaluator
178
this.addEvaluator(evaluatorName, evaluatorClass);
179             }
180         }
181     }
182
183     /**
184      * Parses the element-readers element
185      *
186      * @param readersElement
187      */

188     private void parseElementReadersElement(Element readersElement)
189     {
190         if (readersElement != null)
191         {
192             Iterator JavaDoc readers = readersElement.elementIterator();
193             while (readers.hasNext())
194             {
195                 Element readerElement = (Element) readers.next();
196                 String JavaDoc readerElementName = readerElement.attributeValue(ATTR_ELEMENT_NAME);
197                 String JavaDoc readerElementClass = readerElement.attributeValue(ATTR_CLASS);
198
199                 if (readerElementName == null || readerElementName.length() == 0)
200                 {
201                     throw new ConfigException("All element-reader elements must define an element-name attribute");
202                 }
203
204                 if (readerElementClass == null || readerElementClass.length() == 0)
205                 {
206                     throw new ConfigException("Element-reader '" + readerElementName
207                             + "' must define a class attribute");
208                 }
209
210                 // add the evaluator
211
addConfigElementReader(readerElementName, readerElementClass);
212             }
213         }
214     }
215
216     /**
217      * Parses a config element of a config file
218      *
219      * @param configElement
220      * The config element
221      */

222     private void parseConfigElement(Element configElement)
223     {
224         if (configElement != null)
225         {
226             boolean replace = false;
227             String JavaDoc evaluatorName = configElement.attributeValue(ATTR_EVALUATOR);
228             String JavaDoc condition = configElement.attributeValue(ATTR_CONDITION);
229             String JavaDoc replaceValue = configElement.attributeValue(ATTR_REPLACE);
230             if (replaceValue != null && replaceValue.equalsIgnoreCase("true"))
231             {
232                replace = true;
233             }
234
235             // create the section object
236
ConfigSectionImpl section = new ConfigSectionImpl(evaluatorName, condition, replace);
237
238             // retrieve the config elements for the section
239
Iterator JavaDoc children = configElement.elementIterator();
240             while (children.hasNext())
241             {
242                 Element child = (Element) children.next();
243                 String JavaDoc elementName = child.getName();
244
245                 // get the element reader for the child
246
ConfigElementReader elementReader = getConfigElementReader(elementName);
247                 if (logger.isDebugEnabled())
248                     logger.debug("Retrieved element reader " + elementReader + " for element named '" + elementName
249                             + "'");
250
251                 if (elementReader == null)
252                 {
253                     elementReader = new GenericElementReader();
254
255                     if (logger.isDebugEnabled())
256                         logger.debug("Defaulting to " + elementReader + " as there wasn't an element "
257                                 + "reader registered for element '" + elementName + "'");
258                 }
259
260                 ConfigElement cfgElement = elementReader.parse(child);
261                 section.addConfigElement(cfgElement);
262
263                 if (logger.isDebugEnabled())
264                     logger.debug("Added " + cfgElement + " to " + section);
265             }
266
267             // now all the config elements are added, add the section to the
268
// config service
269
addConfigSection(section, this.currentArea);
270         }
271     }
272
273     /**
274      * Adds the config element reader with the given name and class name
275      *
276      * @param elementName
277      * Name of the element the reader is for
278      * @param className
279      * Class name of element reader implementation
280      */

281     private void addConfigElementReader(String JavaDoc elementName, String JavaDoc className)
282     {
283         ConfigElementReader elementReader = null;
284
285         try
286         {
287             Class JavaDoc clazz = Class.forName(className);
288             elementReader = (ConfigElementReader) clazz.newInstance();
289         }
290         catch (Throwable JavaDoc e)
291         {
292             throw new ConfigException("Could not instantiate element reader for '" + elementName + "' with class: "
293                     + className, e);
294
295         }
296
297         this.elementReaders.put(elementName, elementReader);
298
299         if (logger.isDebugEnabled())
300             logger.debug("Added element reader '" + elementName + "': " + className);
301     }
302
303     /**
304      * Retrieves the element reader for the given element name
305      *
306      * @param elementName
307      * Name of the element to get the reader for
308      * @return ConfigElementReader object or null if it doesn't exist
309      */

310     private ConfigElementReader getConfigElementReader(String JavaDoc elementName)
311     {
312         return (ConfigElementReader) this.elementReaders.get(elementName);
313     }
314 }
315
Popular Tags