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    
018    package org.apache.geronimo.naming.reference;
019    
020    import org.apache.geronimo.gbean.AbstractName;
021    import org.apache.geronimo.gbean.AbstractNameQuery;
022    import org.apache.geronimo.kernel.GBeanNotFoundException;
023    import org.apache.geronimo.kernel.Kernel;
024    import org.apache.geronimo.kernel.repository.Artifact;
025    
026    import javax.naming.NameNotFoundException;
027    
028    /**
029     * @version $Rev: 534748 $ $Date: 2007-05-03 04:07:09 -0400 (Thu, 03 May 2007) $
030     */
031    public class ResourceReference extends ConfigurationAwareReference {
032        private final Class iface;
033    
034        /**
035         *
036         * @param configId the configId of the configuration that holds the reference, not the resource adapter.
037         * @param abstractNameQuery query for name of the resource adapter.
038         * @param iface
039         */
040        public ResourceReference(Artifact[] configId, AbstractNameQuery abstractNameQuery, Class iface) {
041            super(configId, abstractNameQuery);
042            this.iface = iface;
043        }
044    
045        public String getClassName() {
046            return iface.getName();
047        }
048    
049        public Object getContent() throws NameNotFoundException {
050            Kernel kernel = getKernel();
051    
052            AbstractName target;
053            try {
054                target = resolveTargetName();
055            } catch (GBeanNotFoundException e) {
056                throw (NameNotFoundException) new NameNotFoundException("Could not resolve name query: " + abstractNameQueries).initCause(e);
057            }
058    
059            Object proxy;
060            try {
061                proxy = kernel.invoke(target, "$getResource");
062            } catch (Exception e) {
063                throw (IllegalStateException) new IllegalStateException("Could not get proxy").initCause(e);
064            }
065            if (proxy == null) {
066                throw new IllegalStateException("Proxy not returned. Target " + target + " not started");
067            }
068            if (!iface.isAssignableFrom(proxy.getClass())) {
069                Class proxyClass = proxy.getClass();
070                Class[] interfaces = proxyClass.getInterfaces();
071                StringBuffer message = new StringBuffer();
072                boolean namesMatch = false;
073                for (int i = 0; i < interfaces.length; i++) {
074                    Class anInterface = interfaces[i];
075                    if (iface.getName().equals(anInterface.getName())) {
076                        namesMatch = true;
077                        message.append("Proxy implements correct interface: ").append(iface.getName()).append(", but classloaders differ\n");
078                        message.append("lookup interface classloader: ").append(iface.getClassLoader().toString()).append("\n");
079                        message.append("target interface classloader: ").append(anInterface.getClassLoader().toString()).append("\n");
080                        message.append("target proxy classloader: ").append(proxy.getClass().getClassLoader());
081                        break;
082                    }
083                }
084                if (!namesMatch) {
085                    message.append("Proxy does not implement an interface named: ").append(iface.getName());
086                }
087                throw new ClassCastException(message.toString());
088            }
089            return proxy;
090    
091        }
092    }