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: 549825 $ $Date: 2007-06-22 10:17:31 -0400 (Fri, 22 Jun 2007) $
034 */
035 public abstract class AbstractGBeanReference implements GBeanReference {
036 /**
037 * Should we proxy references.
038 */
039 protected static final boolean NO_PROXY = Boolean.getBoolean("Xorg.apache.geronimo.gbean.NoProxy");
040 static {
041 if (NO_PROXY) {
042 Log log = LogFactory.getLog(AbstractGBeanReference.class);
043 log.warn("GBean reference proxies has been disabled: This is an experimental and untested operating mode");
044 }
045 }
046
047 /**
048 * Name of this reference.
049 */
050 private final String name;
051
052 /**
053 * Interface this GBeanInstance uses to refer to the other.
054 */
055 private final Class referenceType;
056
057 /**
058 * Proxy type which is injected into the GBeanInstance.
059 */
060 private final Class proxyType;
061
062 /**
063 * The GBeanInstance to which this reference belongs.
064 */
065 private final GBeanInstance gbeanInstance;
066
067 /**
068 * The method that will be called to set the attribute value. If null, the value will be set with
069 * a constructor argument
070 */
071 private final MethodInvoker setInvoker;
072
073 private final boolean hasTargets;
074
075 /**
076 * The metadata for this reference
077 */
078 private final GReferenceInfo referenceInfo;
079
080 /**
081 * The kernel to which the reference is bound.
082 */
083 private final Kernel kernel;
084
085 /**
086 * Proxy for this reference
087 */
088 private Object proxy;
089
090
091 public AbstractGBeanReference(GBeanInstance gbeanInstance, GReferenceInfo referenceInfo, Kernel kernel, boolean hasTargets) throws InvalidConfigurationException {
092 this.gbeanInstance = gbeanInstance;
093 this.referenceInfo = referenceInfo;
094 this.kernel = kernel;
095 this.hasTargets = hasTargets;
096
097 this.name = referenceInfo.getName();
098 try {
099 this.referenceType = ClassLoading.loadClass(referenceInfo.getReferenceType(), gbeanInstance.getType().getClassLoader());
100 } catch (ClassNotFoundException e) {
101 throw new InvalidConfigurationException("Could not load Reference Type: " + getDescription(), e);
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(), e);
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(), e);
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 }