001 package org.apache.fulcrum.yaafi.framework.interceptor; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 import java.lang.reflect.InvocationHandler; 023 import java.lang.reflect.Proxy; 024 import java.util.List; 025 026 import org.apache.avalon.framework.service.ServiceException; 027 import org.apache.avalon.framework.service.ServiceManager; 028 import org.apache.fulcrum.yaafi.framework.constant.AvalonYaafiConstants; 029 import org.apache.fulcrum.yaafi.framework.reflection.Clazz; 030 import org.apache.fulcrum.yaafi.framework.util.Validate; 031 032 033 /** 034 * A factory for creating dynamic proxies for Avalon services. 035 * 036 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a> 037 */ 038 039 public class AvalonInterceptorFactory 040 { 041 /** 042 * Creates a dynamic proxy wrapping a service instance. 043 * 044 * @param serviceName the name of the service 045 * @param serviceShorthand the shorthand of the service being intercepted 046 * @param serviceManager the corresponding service manager 047 * @param serviceInterceptorList the list of interceptors to be installed 048 * @param serviceDelegate the service implementation 049 * @return a dynamic proxy 050 * @throws ServiceException an interceptor was not found 051 */ 052 public static Object create( 053 String serviceName, 054 String serviceShorthand, 055 ServiceManager serviceManager, 056 String[] serviceInterceptorList, 057 Object serviceDelegate ) 058 throws ServiceException 059 { 060 Validate.notEmpty(serviceName,"serviceName"); 061 Validate.notEmpty(serviceShorthand,"serviceShorthand"); 062 Validate.notNull(serviceManager,"serviceManager"); 063 Validate.notNull(serviceInterceptorList,"serviceInterceptorList"); 064 Validate.notNull(serviceDelegate,"serviceDelegate"); 065 066 Object result = null; 067 068 Class clazz = serviceDelegate.getClass(); 069 ClassLoader classLoader = clazz.getClassLoader(); 070 List interfaceList = Clazz.getAllInterfaces(clazz); 071 072 // get the service interfaces to avoid lookups 073 074 AvalonInterceptorService[] avalonInterceptorServices = resolve( 075 serviceManager, 076 serviceInterceptorList 077 ); 078 079 InvocationHandler invocationHandler = new AvalonInterceptorInvocationHandler( 080 serviceName, 081 serviceShorthand, 082 serviceDelegate, 083 avalonInterceptorServices 084 ); 085 086 result = Proxy.newProxyInstance( 087 classLoader, 088 (Class[]) interfaceList.toArray(new Class[interfaceList.size()]), 089 invocationHandler 090 ); 091 092 return result; 093 } 094 095 /** 096 * Resolve all interceptor service names to service interfaces. 097 * 098 * @param serviceManager to lookup the services 099 * @param interceptorList the list of service names 100 * @return a list of interceptor services 101 * @throws ServiceException an interceptor service was not found 102 */ 103 private static AvalonInterceptorService[] resolve( ServiceManager serviceManager, String[] interceptorList ) 104 throws ServiceException 105 { 106 String interceptorServiceName = null; 107 AvalonInterceptorService[] result = new AvalonInterceptorService[interceptorList.length]; 108 109 for( int i=0; i<interceptorList.length; i++ ) 110 { 111 interceptorServiceName = interceptorList[i]; 112 Object currService = serviceManager.lookup(interceptorServiceName); 113 114 if (currService instanceof AvalonInterceptorService) 115 { 116 result[i] = (AvalonInterceptorService) currService; 117 } 118 else 119 { 120 String msg = "The following service is not an AvalonInterceptorService : " + interceptorServiceName; 121 throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI,msg); 122 } 123 } 124 125 return result; 126 } 127 }