KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > gjndi > KernelContextGBean


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

17 package org.apache.geronimo.gjndi;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.apache.geronimo.gbean.AbstractName;
22 import org.apache.geronimo.gbean.AbstractNameQuery;
23 import org.apache.geronimo.gbean.GBeanInfo;
24 import org.apache.geronimo.gbean.GBeanInfoBuilder;
25 import org.apache.geronimo.gbean.GBeanLifecycle;
26 import org.apache.geronimo.kernel.GBeanNotFoundException;
27 import org.apache.geronimo.kernel.Kernel;
28 import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter;
29 import org.apache.geronimo.kernel.lifecycle.LifecycleListener;
30 import org.apache.xbean.naming.context.ContextAccess;
31 import org.apache.xbean.naming.context.WritableContext;
32
33 import javax.naming.Name JavaDoc;
34 import javax.naming.NamingException JavaDoc;
35 import java.util.Collections JavaDoc;
36 import java.util.HashMap JavaDoc;
37 import java.util.HashSet JavaDoc;
38 import java.util.Iterator JavaDoc;
39 import java.util.LinkedHashMap JavaDoc;
40 import java.util.Map JavaDoc;
41 import java.util.Set JavaDoc;
42
43 /**
44  * @version $Rev$ $Date$
45  */

46 public class KernelContextGBean extends WritableContext implements GBeanLifecycle {
47     private static final Log log = LogFactory.getLog(KernelContextGBean.class);
48
49     private final Kernel kernel;
50     private final AbstractNameQuery abstractNameQuery;
51     private final LifecycleListener listener = new ContextLifecycleListener();
52     private final Map JavaDoc bindingsByAbstractName = new HashMap JavaDoc();
53
54     public KernelContextGBean(String JavaDoc nameInNamespace, AbstractNameQuery abstractNameQuery, Kernel kernel) throws NamingException JavaDoc {
55         super(nameInNamespace, Collections.EMPTY_MAP, ContextAccess.UNMODIFIABLE, false);
56         this.abstractNameQuery = abstractNameQuery;
57         this.kernel = kernel;
58     }
59
60     public synchronized void doStart() {
61         kernel.getLifecycleMonitor().addLifecycleListener(listener, abstractNameQuery);
62         Set JavaDoc set = kernel.listGBeans(abstractNameQuery);
63         for (Iterator JavaDoc iterator = set.iterator(); iterator.hasNext();) {
64             AbstractName abstractName = (AbstractName) iterator.next();
65             try {
66                 if (kernel.isRunning(abstractName)) {
67                     addBinding(abstractName);
68                 }
69             } catch (NamingException JavaDoc e) {
70                 log.error("Error adding binding for " + abstractName);
71             }
72         }
73
74     }
75
76     public void doStop() {
77         destroy();
78     }
79
80     public void doFail() {
81         destroy();
82     }
83
84     private synchronized void destroy() {
85         kernel.getLifecycleMonitor().removeLifecycleListener(listener);
86         Set JavaDoc abstractNames = new HashSet JavaDoc(bindingsByAbstractName.keySet());
87         for (Iterator JavaDoc iterator = abstractNames.iterator(); iterator.hasNext();) {
88             AbstractName abstractName = (AbstractName) iterator.next();
89             removeBinding(abstractName);
90         }
91         bindingsByAbstractName.clear();
92     }
93
94     private class ContextLifecycleListener extends LifecycleAdapter {
95         public void running(AbstractName abstractName) {
96             try {
97                 addBinding(abstractName);
98             } catch (NamingException JavaDoc e) {
99                 log.error("Error adding binding for " + abstractName);
100             }
101         }
102
103         public void stopping(AbstractName abstractName) {
104             removeBinding(abstractName);
105         }
106
107         public void stopped(AbstractName abstractName) {
108             removeBinding(abstractName);
109         }
110
111         public void failed(AbstractName abstractName) {
112             removeBinding(abstractName);
113         }
114
115         public void unloaded(AbstractName abstractName) {
116             removeBinding(abstractName);
117         }
118     }
119
120     /**
121      * Binds the specified gbean. This method uses createBindingName and preprocessValue before binding the object.
122      *
123      * @param abstractName the abstract name of the gbean to bind
124      * @throws NamingException if an error occurs during binding
125      */

126     protected synchronized void addBinding(AbstractName abstractName) throws NamingException JavaDoc {
127         if (bindingsByAbstractName.containsKey(abstractName)) {
128             // previously bound
129
return;
130         }
131
132         // get the gbean
133
Object JavaDoc instance = null;
134         try {
135             instance = kernel.getGBean(abstractName);
136         } catch (GBeanNotFoundException e) {
137             throw new NamingException JavaDoc("GBean not found: " + abstractName);
138         }
139
140         // create the bindings for this object
141
Map JavaDoc bindings = createBindings(abstractName, instance);
142         if (bindings == null || bindings.isEmpty()) {
143             return;
144         }
145
146         // bind the value
147
for (Iterator JavaDoc iterator = bindings.entrySet().iterator(); iterator.hasNext();) {
148             Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
149             Name name = (Name) entry.getKey();
150             Object JavaDoc value = entry.getValue();
151             addBinding(abstractName, name, value);
152         }
153
154         // remember where we bound this value
155
bindingsByAbstractName.put(abstractName, bindings.keySet());
156     }
157
158     private Map JavaDoc bindingsByName = new HashMap JavaDoc();
159
160     private synchronized void addBinding(AbstractName abstractName, Name name, Object JavaDoc value) throws NamingException JavaDoc {
161         LinkedHashMap JavaDoc bindings = (LinkedHashMap JavaDoc) bindingsByName.get(name);
162         if (bindings == null) {
163             addDeepBinding(name, value, true, true);
164
165             bindings = new LinkedHashMap JavaDoc();
166             bindings.put(abstractName, value);
167             bindingsByName.put(name, bindings);
168         } else {
169             bindings.put(abstractName, value);
170         }
171     }
172
173     /**
174      * Unbinds the specified gbean.
175      *
176      * @param abstractName the abstract name of the gbean to unbind
177      */

178     protected synchronized void removeBinding(AbstractName abstractName) {
179         Set JavaDoc bindingNames = (Set JavaDoc) bindingsByAbstractName.remove(abstractName);
180         if (bindingNames == null) return;
181
182         for (Iterator JavaDoc iterator = bindingNames.iterator(); iterator.hasNext();) {
183             Name name = (Name) iterator.next();
184
185             LinkedHashMap JavaDoc bindings = (LinkedHashMap JavaDoc) bindingsByName.get(name);
186             if (bindings == null) continue;
187
188             if (first(bindings).getKey().equals(abstractName)) {
189                 bindings.remove(abstractName);
190                 Map.Entry JavaDoc newEntry = first(bindings);
191                 if (newEntry != null) {
192                     Object JavaDoc newAbstractName = newEntry.getValue();
193                     Object JavaDoc newValue = newEntry.getValue();
194                     try {
195                         addDeepBinding(name, newValue, true, true);
196                     } catch (NamingException JavaDoc e) {
197                         boolean logged = false;
198                         try {
199                             removeDeepBinding(name, true);
200                         } catch (NamingException JavaDoc e1) {
201                             logged = true;
202                             log.error("Unable to remove binding " + name + " to " + abstractName, e);
203                         }
204                         if (!logged) log.error("Unable to rebind binding " + name + " to " + newAbstractName);
205                     }
206                 } else {
207                     bindingsByName.remove(name);
208                     try {
209                         removeDeepBinding(name, true, true);
210                     } catch (NamingException JavaDoc e) {
211                         log.error("Unable to remove binding " + name + " to " + abstractName, e);
212                     }
213                 }
214             } else {
215                 bindings.remove(abstractName);
216             }
217         }
218     }
219
220     private static Map.Entry JavaDoc first(LinkedHashMap JavaDoc map) {
221         if (map.isEmpty()) return null;
222         return (Map.Entry JavaDoc) map.entrySet().iterator().next();
223     }
224
225     protected Map JavaDoc createBindings(AbstractName abstractName, Object JavaDoc value) throws NamingException JavaDoc {
226         // generate a name for this binding
227
Name name = createBindingName(abstractName, value);
228         if (name == null) return null;
229
230         // give sub classes a chance to preprocess the value
231
value = preprocessVaue(abstractName, name, value);
232         if (value == null) return null;
233
234         Map JavaDoc bindings = Collections.singletonMap(name, value);
235         return bindings;
236     }
237
238     /**
239      * Create a name under which we will bind the specified gbean with the specified value.
240      * By default, this method simply returns the "name" element of the abstract name
241      *
242      * @param abstractName the abstract name of the gbean to bind
243      * @param value the gbean instance
244      * @return the name under which the gbean should be bound
245      */

246     protected Name createBindingName(AbstractName abstractName, Object JavaDoc value) throws NamingException JavaDoc {
247         String JavaDoc shortName = (String JavaDoc) abstractName.getName().get("name");
248         return getNameParser().parse(shortName);
249     }
250
251     /**
252      * Preprocess the value before it is bound. This is usefult for wrapping values with reference objects.
253      * By default, this method simply return the value.
254      *
255      * @param abstractName the abstract name of the gbean to bind
256      * @param name the name under which the gbean will be bound
257      * @param value the gbean instance
258      * @return the value to bind
259      */

260     protected Object JavaDoc preprocessVaue(AbstractName abstractName, Name name, Object JavaDoc value) throws NamingException JavaDoc {
261         return value;
262     }
263
264     public static final GBeanInfo GBEAN_INFO;
265
266     public static GBeanInfo getGBeanInfo() {
267         return GBEAN_INFO;
268     }
269
270     static {
271         GBeanInfoBuilder builder = GBeanInfoBuilder.createStatic(KernelContextGBean.class, "Context");
272         builder.addAttribute("nameInNamespace", String JavaDoc.class, true);
273         builder.addAttribute("abstractNameQuery", AbstractNameQuery.class, true);
274         builder.setConstructor(new String JavaDoc[]{"nameInNamespace", "abstractNameQuery", "kernel"});
275         GBEAN_INFO = builder.getBeanInfo();
276     }
277 }
278
Popular Tags