001 /** 002 * 003 * Copyright 2004 The Apache Software Foundation 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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: 406445 $ $Date: 2006-05-14 15:03:56 -0700 (Sun, 14 May 2006) $ 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()); 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 }