/* * Copyright 2008 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.rioproject.impl.associations; import org.rioproject.associations.Association; import org.rioproject.associations.AssociationDescriptor; import org.rioproject.associations.AssociationProxy; import org.rioproject.associations.ServiceSelectionStrategy; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; /** * Factory for dynamic proxies to manage a collection of associated services. * * @author Dennis Reedy */ public class AssociationProxyFactory { /** * Create a proxy for associated services * * @param proxyClassName The classname of the proxy to create. This class must * be an instance of {@link org.rioproject.associations.AssociationProxy} * @param strategyClassName The classname of the * {@link org.rioproject.associations.ServiceSelectionStrategy} to create. If this parameter is null, * the AssociationProxy instance will not have a * <tt>ServiceSelectionStrategy</tt> set * @param association The association for the proxy to use * @param loader The class loader to create the proxy with * @return A generated proxy * * @throws ClassNotFoundException If the interfaces cannot be loaded * @throws IllegalAccessException if the proxy class cannot be created * @throws InstantiationException if the proxy class cannot be created */ @SuppressWarnings("unchecked") public static Object createProxy(String proxyClassName, String strategyClassName, Association association, ClassLoader loader) throws ClassNotFoundException, IllegalAccessException,InstantiationException { if(proxyClassName==null) throw new IllegalArgumentException("proxyClassName is null"); if(loader==null) throw new IllegalArgumentException("classloader is null"); if(association==null) throw new IllegalArgumentException("association is null"); Object proxy; final ClassLoader currentCL = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(loader); Class aProxyClass = loader.loadClass(proxyClassName); AssociationProxy aProxy = (AssociationProxy)aProxyClass.newInstance(); List<Class> list = loadAssociatedInterfaces(association.getAssociationDescriptor(), loader); aProxy.setProxyInterfaces(list.toArray(new Class[list.size()])); list.add(AssociationProxy.class); if(strategyClassName!=null) { ServiceSelectionStrategy strategy = (ServiceSelectionStrategy)loader.loadClass(strategyClassName).newInstance(); strategy.setAssociation(association); aProxy.setServiceSelectionStrategy(strategy); } Class[] interfaces = list.toArray(new Class[list.size()]); proxy = Proxy.newProxyInstance(loader, interfaces, aProxy.getInvocationHandler(association)); } finally { Thread.currentThread().setContextClassLoader(currentCL); } return proxy; } /* * Load interfaces from an AssociationDescriptor */ private static List<Class> loadAssociatedInterfaces(AssociationDescriptor a, ClassLoader cl) throws ClassNotFoundException { List<Class> l = new ArrayList<Class>(); String[] iNames = a.getInterfaceNames(); for(String iName : iNames) { l.add(Class.forName(iName, false, cl)); } return (l); } }