KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > cocoon > woody > binding > JXPathBindingManager


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.apache.cocoon.woody.binding;
17
18 import org.apache.avalon.framework.activity.Disposable;
19 import org.apache.avalon.framework.activity.Initializable;
20 import org.apache.avalon.framework.configuration.Configurable;
21 import org.apache.avalon.framework.configuration.Configuration;
22 import org.apache.avalon.framework.configuration.ConfigurationException;
23 import org.apache.avalon.framework.logger.AbstractLogEnabled;
24 import org.apache.avalon.framework.service.ServiceException;
25 import org.apache.avalon.framework.service.ServiceManager;
26 import org.apache.avalon.framework.service.Serviceable;
27 import org.apache.avalon.framework.thread.ThreadSafe;
28 import org.apache.cocoon.woody.CacheManager;
29 import org.apache.cocoon.woody.datatype.DatatypeManager;
30 import org.apache.cocoon.woody.util.DomHelper;
31 import org.apache.cocoon.woody.util.SimpleServiceSelector;
32 import org.apache.excalibur.source.Source;
33 import org.w3c.dom.Document JavaDoc;
34 import org.w3c.dom.Element JavaDoc;
35 import org.xml.sax.InputSource JavaDoc;
36
37 /**
38  * JXPathBindingManager provides an implementation of {@link BindingManager}by
39  * usage of the <a HREF="http://jakarta.apache.org/commons/jxpath/index.html">
40  * JXPath package </a>.
41  *
42  * @version CVS $Id: JXPathBindingManager.java 36537 2004-08-17 20:36:47Z vgritsenko $
43  */

44 public class JXPathBindingManager extends AbstractLogEnabled implements
45         BindingManager, Serviceable, Disposable, Initializable, Configurable,
46         ThreadSafe {
47
48     private static final String JavaDoc PREFIX = "WoodyBinding:";
49
50     private ServiceManager manager;
51
52     private DatatypeManager datatypeManager;
53
54     private Configuration configuration;
55
56     private SimpleServiceSelector bindingBuilderSelector;
57
58     private CacheManager cacheManager;
59
60     public void service(ServiceManager manager) throws ServiceException {
61         this.manager = manager;
62         this.datatypeManager = (DatatypeManager) manager.lookup(DatatypeManager.ROLE);
63         this.cacheManager = (CacheManager) manager.lookup(CacheManager.ROLE);
64     }
65
66     public void configure(Configuration configuration)
67     throws ConfigurationException {
68         this.configuration = configuration;
69     }
70
71     public void initialize() throws Exception JavaDoc {
72         bindingBuilderSelector = new SimpleServiceSelector("binding",
73                                                            JXPathBindingBuilderBase.class);
74         bindingBuilderSelector.enableLogging(getLogger());
75         bindingBuilderSelector.configure(configuration.getChild("bindings"));
76     }
77
78     public Binding createBinding(Source source) throws BindingException {
79         Binding binding = (Binding) this.cacheManager.get(source, PREFIX);
80         if (binding == null) {
81             try {
82                 InputSource JavaDoc is = new InputSource JavaDoc(source.getInputStream());
83                 is.setSystemId(source.getURI());
84
85                 Document JavaDoc doc = DomHelper.parse(is);
86                 Element JavaDoc rootElm = doc.getDocumentElement();
87                 if (BindingManager.NAMESPACE.equals(rootElm.getNamespaceURI())) {
88                     binding = getBuilderAssistant()
89                             .getBindingForConfigurationElement(rootElm);
90                     ((JXPathBindingBase) binding).enableLogging(getLogger());
91                     if (getLogger().isDebugEnabled()) {
92                         getLogger().debug("Creation of new Binding finished. " +
93                                           binding);
94                     }
95                 } else {
96                     if (getLogger().isDebugEnabled()) {
97                         getLogger().debug("Root Element of said binding file is in wrong namespace.");
98                     }
99                 }
100
101                 this.cacheManager.set(binding, source, PREFIX);
102             } catch (BindingException e) {
103                 throw e;
104             } catch (Exception JavaDoc e) {
105                 throw new BindingException("Error creating binding from " +
106                                            source.getURI(), e);
107             }
108         }
109
110         return binding;
111     }
112
113     private Assistant getBuilderAssistant() {
114         return new Assistant();
115     }
116
117     public void dispose() {
118         if (this.bindingBuilderSelector != null) {
119             this.bindingBuilderSelector.dispose();
120             this.bindingBuilderSelector = null;
121         }
122         this.manager.release(this.datatypeManager);
123         this.datatypeManager = null;
124         this.manager.release(this.cacheManager);
125         this.cacheManager = null;
126         this.manager = null;
127     }
128
129     /**
130      * Assistant Inner class discloses enough features to the created
131      * childBindings to recursively
132      *
133      * This patterns was chosen to prevent Inversion Of Control between this
134      * factory and its builder classes (that could be provided by third
135      * parties.)
136      */

137     /*
138      * NOTE: To get access to the logger in this inner class you must not call
139      * getLogger() as with JDK 1.3 this gives a NoSuchMethod error. You need to
140      * implement an explicit access method for the logger in the outer class.
141      */

142     public class Assistant {
143
144         private JXPathBindingBuilderBase getBindingBuilder(String JavaDoc bindingType)
145                 throws BindingException {
146             try {
147                 return (JXPathBindingBuilderBase) bindingBuilderSelector
148                         .select(bindingType);
149             } catch (ServiceException e) {
150                 throw new BindingException(
151                         "Cannot handle binding element with " + "name \""
152                                 + bindingType + "\".", e);
153             }
154         }
155
156         /**
157          * Creates a {@link Binding}following the specification in the
158          * provided config element.
159          */

160         public JXPathBindingBase getBindingForConfigurationElement(
161                 Element JavaDoc configElm) throws BindingException {
162             String JavaDoc bindingType = configElm.getLocalName();
163             JXPathBindingBuilderBase bindingBuilder = getBindingBuilder(bindingType);
164             JXPathBindingBase childBinding = bindingBuilder.buildBinding(
165                     configElm, this);
166             return childBinding;
167         }
168
169         /**
170          * Makes an array of childBindings for the child-elements of the
171          * provided configuration element.
172          */

173         public JXPathBindingBase[] makeChildBindings(Element JavaDoc parentElement)
174                 throws BindingException {
175             if (parentElement != null) {
176                 Element JavaDoc[] childElements = DomHelper.getChildElements(
177                         parentElement, BindingManager.NAMESPACE);
178                 if (childElements.length > 0) {
179                     JXPathBindingBase[] childBindings = new JXPathBindingBase[childElements.length];
180                     for (int i = 0; i < childElements.length; i++) {
181                         childBindings[i] = getBindingForConfigurationElement(childElements[i]);
182                     }
183                     return childBindings;
184                 }
185             }
186             return null;
187         }
188
189         public DatatypeManager getDatatypeManager() {
190             return datatypeManager;
191         }
192
193         public ServiceManager getServiceManager() {
194             return manager;
195         }
196     }
197 }
198
Popular Tags