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
174 return false;
175 } catch (Exception e) {
176
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
190 if (setInvoker != null && hasTargets) {
191 setInvoker.invoke(target, new Object[]{getProxy()});
192 }
193 }
194 }