001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.geronimo.gbean.runtime;
018
019 import org.apache.geronimo.gbean.AbstractName;
020 import org.apache.geronimo.gbean.GReferenceInfo;
021 import org.apache.geronimo.gbean.InvalidConfigurationException;
022 import org.apache.geronimo.kernel.ClassLoading;
023 import org.apache.geronimo.kernel.GBeanNotFoundException;
024 import org.apache.geronimo.kernel.Kernel;
025 import org.apache.geronimo.kernel.management.State;
026 import org.apache.commons.logging.Log;
027 import org.apache.commons.logging.LogFactory;
028
029 import java.lang.reflect.Method;
030 import java.lang.reflect.Modifier;
031
032 /**
033 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
034 */
035 public abstract class AbstractGBeanReference implements GBeanReference {
036 /**
037 * Should we proxy references.
038 */
039 protected static final boolean NO_PROXY;
040 static {
041 Log log = LogFactory.getLog(AbstractGBeanReference.class);
042 String no_proxy = System.getProperty("Xorg.apache.geronimo.gbean.NoProxy", "true");
043 NO_PROXY = no_proxy.equalsIgnoreCase("true");
044 if (NO_PROXY) {
045 log.info("GBean references are not using proxies");
046 } else {
047 log.info("GBean references are using proxies");
048 }
049 }
050
051 /**
052 * Name of this reference.
053 */
054 private final String name;
055
056 /**
057 * Interface this GBeanInstance uses to refer to the other.
058 */
059 private final Class referenceType;
060
061 /**
062 * Proxy type which is injected into the GBeanInstance.
063 */
064 private final Class proxyType;
065
066 /**
067 * The GBeanInstance to which this reference belongs.
068 */
069 private final GBeanInstance gbeanInstance;
070
071 /**
072 * The method that will be called to set the attribute value. If null, the value will be set with
073 * a constructor argument
074 */
075 private final MethodInvoker setInvoker;
076
077 private final boolean hasTargets;
078
079 /**
080 * The metadata for this reference
081 */
082 private final GReferenceInfo referenceInfo;
083
084 /**
085 * The kernel to which the reference is bound.
086 */
087 private final Kernel kernel;
088
089 /**
090 * Proxy for this reference
091 */
092 private Object proxy;
093
094
095 public AbstractGBeanReference(GBeanInstance gbeanInstance, GReferenceInfo referenceInfo, Kernel kernel, boolean hasTargets) throws InvalidConfigurationException {
096 this.gbeanInstance = gbeanInstance;
097 this.referenceInfo = referenceInfo;
098 this.kernel = kernel;
099 this.hasTargets = hasTargets;
100
101 this.name = referenceInfo.getName();
102 try {
103 this.referenceType = ClassLoading.loadClass(referenceInfo.getReferenceType(), gbeanInstance.getType().getClassLoader());
104 } catch (ClassNotFoundException e) {
105 throw new InvalidConfigurationException("Could not load Reference Type: " + getDescription(), e);
106 }
107 if (Modifier.isFinal(referenceType.getModifiers())) {
108 throw new IllegalArgumentException("Proxy interface cannot be a final class: " + referenceType.getName());
109 }
110 try {
111 this.proxyType = ClassLoading.loadClass(referenceInfo.getProxyType(), gbeanInstance.getType().getClassLoader());
112 } catch (ClassNotFoundException e) {
113 throw new InvalidConfigurationException("Could not load Proxy Type:" + getDescription(), e);
114 }
115
116 if (referenceInfo.getSetterName() != null) {
117 try {
118 String setterName = referenceInfo.getSetterName();
119 Method setterMethod = gbeanInstance.getType().getMethod(setterName, new Class[] {proxyType});
120 if (NO_PROXY) {
121 setInvoker = new ReflectionMethodInvoker(setterMethod);
122 } else {
123 setInvoker = new FastMethodInvoker(setterMethod);
124 }
125 } catch (NoSuchMethodException e) {
126 throw new InvalidConfigurationException("Setter method not found " + getDescription(), e);
127 }
128 } else {
129 setInvoker = null;
130 }
131
132 }
133
134 protected final Kernel getKernel() {
135 return kernel;
136 }
137
138 public final GBeanInstance getGBeanInstance() {
139 return gbeanInstance;
140 }
141
142 public final String getName() {
143 return name;
144 }
145
146 public final GReferenceInfo getReferenceInfo() {
147 return referenceInfo;
148 }
149
150 public final Class getReferenceType() {
151 return referenceType;
152 }
153
154 public final Class getProxyType() {
155 return proxyType;
156 }
157
158 public final Object getProxy() {
159 return proxy;
160 }
161
162 protected final void setProxy(Object proxy) {
163 this.proxy = proxy;
164 }
165
166 /**
167 * Is the component in the Running state
168 *
169 * @param abstractName name of the component to check
170 * @return true if the component is running; false otherwise
171 */
172 protected boolean isRunning(Kernel kernel, AbstractName abstractName) {
173 try {
174 final int state = kernel.getGBeanState(abstractName);
175 return state == State.RUNNING_INDEX;
176 } catch (GBeanNotFoundException e) {
177 // mbean is no longer registerd
178 return false;
179 } catch (Exception e) {
180 // problem getting the attribute, mbean has most likely failed
181 return false;
182 }
183 }
184
185 protected final String getDescription() {
186 return "\n GBeanInstance: " + gbeanInstance.getName() +
187 "\n Reference Name: " + getName() +
188 "\n Reference Type: " + referenceInfo.getReferenceType() +
189 "\n Proxy Type: " + referenceInfo.getProxyType();
190 }
191
192 public final synchronized void inject(Object target) throws Exception {
193 // set the proxy into the instance
194 if (setInvoker != null && hasTargets) {
195 setInvoker.invoke(target, new Object[]{getProxy()});
196 }
197 }
198 }