001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019 020 021 package org.apache.geronimo.naming.reference; 022 023 import java.util.List; 024 import java.util.Set; 025 import java.util.Collections; 026 027 import javax.naming.NamingException; 028 import javax.naming.NameNotFoundException; 029 030 import org.apache.geronimo.kernel.Kernel; 031 import org.apache.geronimo.kernel.GBeanNotFoundException; 032 import org.apache.geronimo.kernel.repository.Artifact; 033 import org.apache.geronimo.kernel.config.Configuration; 034 import org.apache.geronimo.kernel.config.ConfigurationManager; 035 import org.apache.geronimo.kernel.config.ConfigurationUtil; 036 import org.apache.geronimo.gbean.AbstractName; 037 import org.apache.geronimo.gbean.AbstractNameQuery; 038 039 /** 040 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 041 */ 042 public abstract class AbstractEntryFactory<T, S> implements EntryFactory<T> { 043 private static final long serialVersionUID = 7642216668523441421L; 044 private final Artifact[] configId; 045 private final Set<AbstractNameQuery> abstractNameQueries; 046 private final Class<S> gbeanClass; 047 048 protected AbstractEntryFactory(Artifact[] configId, AbstractNameQuery abstractNameQuery, Class<S> gbeanClass) { 049 this(configId, Collections.singleton(abstractNameQuery), gbeanClass); 050 } 051 052 protected AbstractEntryFactory(Artifact[] configId, Set<AbstractNameQuery> abstractNameQueries, Class<S> gbeanClass) { 053 if (configId == null || configId.length == 0) { 054 throw new NullPointerException("No configId"); 055 } 056 this.configId = configId; 057 this.abstractNameQueries = abstractNameQueries; 058 this.gbeanClass = gbeanClass; 059 } 060 061 protected S getGBean(Kernel kernel) throws NamingException { 062 AbstractName target; 063 try { 064 target = resolveTargetName(kernel); 065 } catch (GBeanNotFoundException e) { 066 throw (NameNotFoundException) new NameNotFoundException("Could not resolve name query: " + abstractNameQueries).initCause(e); 067 } 068 069 Object proxy; 070 try { 071 proxy = kernel.getGBean(target); 072 } catch (Exception e) { 073 throw (IllegalStateException) new IllegalStateException("Could not get proxy").initCause(e); 074 } 075 if (proxy == null) { 076 throw new IllegalStateException("Proxy not returned. Target " + target + " not started"); 077 } 078 checkClass(proxy, gbeanClass); 079 return (S)proxy; 080 081 } 082 083 protected void checkClass(Object proxy, Class clazz) { 084 if (!clazz.isAssignableFrom(proxy.getClass())) { 085 Class proxyClass = proxy.getClass(); 086 Class[] interfaces = proxyClass.getInterfaces(); 087 StringBuffer message = new StringBuffer(); 088 boolean namesMatch = false; 089 for (Class anInterface : interfaces) { 090 if (clazz.getName().equals(anInterface.getName())) { 091 namesMatch = true; 092 message.append("Proxy implements correct interface: ").append(clazz.getName()).append(", but classloaders differ\n"); 093 message.append("lookup interface classloader: ").append(clazz.getClassLoader().toString()).append("\n"); 094 message.append("target interface classloader: ").append(anInterface.getClassLoader().toString()).append("\n"); 095 message.append("target proxy classloader: ").append(proxy.getClass().getClassLoader()); 096 break; 097 } 098 } 099 if (!namesMatch) { 100 message.append("Proxy does not implement an interface named: ").append(clazz.getName()); 101 } 102 throw new ClassCastException(message.toString()); 103 } 104 } 105 106 public Configuration getConfiguration(Kernel kernel) { 107 ConfigurationManager configurationManager = ConfigurationUtil.getConfigurationManager(kernel); 108 Configuration configuration = configurationManager.getConfiguration(configId[0]); 109 if (configuration == null) { 110 throw new IllegalStateException("No configuration found for id: " + configId[0]); 111 } 112 next: for (int i = 1; i < configId.length; i++) { 113 List<Configuration> children = configuration.getChildren(); 114 for (Configuration child: children) { 115 if (child.getId().equals(configId[i])) { 116 configuration = child; 117 break next; 118 } 119 } 120 throw new IllegalStateException("No configuration found for id: " + configId[i]); 121 } 122 return configuration; 123 } 124 125 public AbstractName resolveTargetName(Kernel kernel) throws GBeanNotFoundException { 126 Configuration configuration = getConfiguration(kernel); 127 try { 128 return configuration.findGBean(abstractNameQueries); 129 } catch (GBeanNotFoundException e) { 130 Set results = kernel.listGBeans(abstractNameQueries); 131 if (results.size() == 1) { 132 return (AbstractName) results.iterator().next(); 133 } 134 throw new GBeanNotFoundException("Name query " + abstractNameQueries + " not satisfied in kernel, matches: " + results, e); 135 } 136 } 137 138 139 }