View Javadoc

1   /**
2    *
3    * Copyright 2004 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  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.gbean.runtime;
18  
19  import org.apache.geronimo.gbean.AbstractName;
20  import org.apache.geronimo.gbean.GReferenceInfo;
21  import org.apache.geronimo.gbean.InvalidConfigurationException;
22  import org.apache.geronimo.kernel.ClassLoading;
23  import org.apache.geronimo.kernel.GBeanNotFoundException;
24  import org.apache.geronimo.kernel.Kernel;
25  import org.apache.geronimo.kernel.management.State;
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  
29  import java.lang.reflect.Method;
30  import java.lang.reflect.Modifier;
31  
32  /**
33   * @version $Rev: 406445 $ $Date: 2006-05-14 15:03:56 -0700 (Sun, 14 May 2006) $
34   */
35  public abstract class AbstractGBeanReference implements GBeanReference {
36      /**
37       * Should we proxy references.
38       */
39      protected static final boolean NO_PROXY = Boolean.getBoolean("Xorg.apache.geronimo.gbean.NoProxy");
40      static {
41          if (NO_PROXY) {
42              Log log = LogFactory.getLog(AbstractGBeanReference.class);
43              log.warn("GBean reference proxies has been disabled:  This is an experimental and untested operating mode");
44          }
45      }
46  
47      /**
48       * Name of this reference.
49       */
50      private final String name;
51  
52      /**
53       * Interface this GBeanInstance uses to refer to the other.
54       */
55      private final Class referenceType;
56  
57      /**
58       * Proxy type which is injected into the GBeanInstance.
59       */
60      private final Class proxyType;
61  
62      /**
63       * The GBeanInstance to which this reference belongs.
64       */
65      private final GBeanInstance gbeanInstance;
66  
67      /**
68       * The method that will be called to set the attribute value.  If null, the value will be set with
69       * a constructor argument
70       */
71      private final MethodInvoker setInvoker;
72  
73      private final boolean hasTargets;
74  
75      /**
76       * The metadata for this reference
77       */
78      private final GReferenceInfo referenceInfo;
79  
80      /**
81       * The kernel to which the reference is bound.
82       */
83      private final Kernel kernel;
84  
85      /**
86       * Proxy for this reference
87       */
88      private Object proxy;
89  
90  
91      public AbstractGBeanReference(GBeanInstance gbeanInstance, GReferenceInfo referenceInfo, Kernel kernel, boolean hasTargets) throws InvalidConfigurationException {
92          this.gbeanInstance = gbeanInstance;
93          this.referenceInfo = referenceInfo;
94          this.kernel = kernel;
95          this.hasTargets = hasTargets;
96  
97          this.name = referenceInfo.getName();
98          try {
99              this.referenceType = ClassLoading.loadClass(referenceInfo.getReferenceType(), gbeanInstance.getType().getClassLoader());
100         } catch (ClassNotFoundException e) {
101             throw new InvalidConfigurationException("Could not load Reference Type: " + getDescription());
102         }
103         if (Modifier.isFinal(referenceType.getModifiers())) {
104             throw new IllegalArgumentException("Proxy interface cannot be a final class: " + referenceType.getName());
105         }
106         try {
107             this.proxyType = ClassLoading.loadClass(referenceInfo.getProxyType(), gbeanInstance.getType().getClassLoader());
108         } catch (ClassNotFoundException e) {
109             throw new InvalidConfigurationException("Could not load Proxy Type:" + getDescription());
110         }
111 
112         if (referenceInfo.getSetterName() != null) {
113             try {
114                 String setterName = referenceInfo.getSetterName();
115                 Method setterMethod = gbeanInstance.getType().getMethod(setterName, new Class[] {proxyType});
116                 if (NO_PROXY) {
117                     setInvoker = new ReflectionMethodInvoker(setterMethod);
118                 } else {
119                     setInvoker = new FastMethodInvoker(setterMethod);
120                 }
121             } catch (NoSuchMethodException e) {
122                 throw new InvalidConfigurationException("Setter method not found " + getDescription());
123             }
124         } else {
125             setInvoker = null;
126         }
127 
128     }
129 
130     protected final Kernel getKernel() {
131         return kernel;
132     }
133 
134     public final GBeanInstance getGBeanInstance() {
135         return gbeanInstance;
136     }
137 
138     public final String getName() {
139         return name;
140     }
141 
142     public final GReferenceInfo getReferenceInfo() {
143         return referenceInfo;
144     }
145 
146     public final Class getReferenceType() {
147         return referenceType;
148     }
149 
150     public final Class getProxyType() {
151         return proxyType;
152     }
153 
154     public final Object getProxy() {
155         return proxy;
156     }
157 
158     protected final void setProxy(Object proxy) {
159         this.proxy = proxy;
160     }
161 
162     /**
163      * Is the component in the Running state
164      *
165      * @param abstractName name of the component to check
166      * @return true if the component is running; false otherwise
167      */
168     protected boolean isRunning(Kernel kernel, AbstractName abstractName) {
169         try {
170             final int state = kernel.getGBeanState(abstractName);
171             return state == State.RUNNING_INDEX;
172         } catch (GBeanNotFoundException e) {
173             // mbean is no longer registerd
174             return false;
175         } catch (Exception e) {
176             // problem getting the attribute, mbean has most likely failed
177             return false;
178         }
179     }
180 
181     protected final String getDescription() {
182         return "\n    GBeanInstance: " + gbeanInstance.getName() +
183                 "\n    Reference Name: " + getName() +
184                 "\n    Reference Type: " + referenceInfo.getReferenceType() +
185                 "\n    Proxy Type: " + referenceInfo.getProxyType();
186     }
187 
188     public final synchronized void inject(Object target) throws Exception {
189         // set the proxy into the instance
190         if (setInvoker != null && hasTargets) {
191             setInvoker.invoke(target, new Object[]{getProxy()});
192         }
193     }
194 }