View Javadoc
1   package org.apache.fulcrum.yaafi.framework.interceptor;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.reflect.InvocationHandler;
23  import java.lang.reflect.Proxy;
24  import java.util.List;
25  
26  import org.apache.avalon.framework.service.ServiceException;
27  import org.apache.avalon.framework.service.ServiceManager;
28  import org.apache.fulcrum.yaafi.framework.constant.AvalonYaafiConstants;
29  import org.apache.fulcrum.yaafi.framework.reflection.Clazz;
30  import org.apache.fulcrum.yaafi.framework.util.Validate;
31  
32  
33  /**
34   * A factory for creating dynamic proxies for Avalon services.
35   *
36   * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
37   */
38  
39  public class AvalonInterceptorFactory
40  {
41      /**
42       * Creates a dynamic proxy wrapping a service instance.
43       *
44       * @param serviceName the name of the service
45       * @param serviceShorthand the shorthand of the service being intercepted
46       * @param serviceManager the corresponding service manager
47       * @param serviceInterceptorList the list of interceptors to be installed
48       * @param serviceDelegate the service implementation
49       * @return a dynamic proxy
50       * @throws ServiceException an interceptor was not found
51       */
52      public static Object create(
53          String serviceName,
54          String serviceShorthand,
55          ServiceManager serviceManager,
56          String[] serviceInterceptorList,
57          Object serviceDelegate )
58          throws ServiceException
59      {
60          Validate.notEmpty(serviceName,"serviceName");
61          Validate.notEmpty(serviceShorthand,"serviceShorthand");
62          Validate.notNull(serviceManager,"serviceManager");
63          Validate.notNull(serviceInterceptorList,"serviceInterceptorList");
64          Validate.notNull(serviceDelegate,"serviceDelegate");
65  
66          Object result;
67  
68          Class<? extends Object> clazz = serviceDelegate.getClass();
69          ClassLoader classLoader = clazz.getClassLoader();
70          List<?> interfaceList = Clazz.getAllInterfaces(clazz);
71  
72          // get the service interfaces to avoid look-ups
73  
74          AvalonInterceptorService[] avalonInterceptorServices = resolve(
75              serviceManager,
76              serviceInterceptorList
77              );
78  
79          InvocationHandler invocationHandler = new AvalonInterceptorInvocationHandler(
80              serviceName,
81              serviceShorthand,
82              serviceDelegate,
83              avalonInterceptorServices
84              );
85  
86          result = Proxy.newProxyInstance(
87              classLoader,
88              (Class[]) interfaceList.toArray(new Class[interfaceList.size()]),
89              invocationHandler
90              );
91  
92          return result;
93      }
94  
95      /**
96       * Resolve all interceptor service names to service interfaces.
97       *
98       * @param serviceManager to lookup the services
99       * @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;
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 }