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 }