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.ReadWriteLock;
31  import org.apache.fulcrum.yaafi.framework.util.Validate;
32  
33  
34  /**
35   * A factory for creating dynamic proxies for Avalon services.
36   *
37   * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
38   */
39  
40  public class AvalonInterceptorFactory
41  {
42      /**
43       * Creates a dynamic proxy wrapping a service instance.
44       *
45       * @param serviceName the name of the service
46       * @param serviceShorthand the shorthand of the service being intercepted
47       * @param serviceManager the corresponding service manager
48       * @param serviceInterceptorList the list of interceptors to be installed
49       * @param serviceDelegate the service implementation
50       * @param readWriteLock the YAAFI kernel lock
51       * @return a dynamic proxy
52       * @throws ServiceException an interceptor was not found
53       */
54      public static Object create(
55          String serviceName,
56          String serviceShorthand,
57          ServiceManager serviceManager,
58          String[] serviceInterceptorList,
59          Object serviceDelegate,
60          ReadWriteLock readWriteLock )
61          throws ServiceException
62      {
63          Validate.notEmpty(serviceName,"serviceName");
64          Validate.notEmpty(serviceShorthand,"serviceShorthand");
65          Validate.notNull(serviceManager,"serviceManager");
66          Validate.notNull(serviceInterceptorList,"serviceInterceptorList");
67          Validate.notNull(serviceDelegate,"serviceDelegate");
68          Validate.notNull(readWriteLock,"readWriteLock");
69  
70          Object result = null;
71  
72          Class clazz = serviceDelegate.getClass();
73          ClassLoader classLoader = clazz.getClassLoader();
74          List interfaceList = Clazz.getAllInterfaces(clazz);
75  
76          // get the service interfaces to avoid lookups
77  
78          AvalonInterceptorService[] avalonInterceptorServices = resolve(
79              serviceManager,
80              serviceInterceptorList
81              );
82  
83          InvocationHandler invocationHandler = new AvalonInterceptorInvocationHandler(
84              serviceName,
85              serviceShorthand,
86              serviceDelegate,
87              avalonInterceptorServices,
88              readWriteLock
89              );
90  
91          result = Proxy.newProxyInstance(
92              classLoader,
93              (Class[]) interfaceList.toArray(new Class[interfaceList.size()]),
94              invocationHandler
95              );
96  
97          return result;
98      }
99  
100     /**
101      * Resolve all interceptor service names to service interfaces.
102      *
103      * @param serviceManager to lookup the services
104      * @param interceptorList the list of service names
105      * @return a list of interceptor services
106      * @throws ServiceException an interceptor service was not found
107      */
108     private static AvalonInterceptorService[] resolve( ServiceManager serviceManager, String[] interceptorList )
109         throws ServiceException
110     {
111         String interceptorServiceName = null;
112         AvalonInterceptorService[] result = new AvalonInterceptorService[interceptorList.length];
113 
114         for( int i=0; i<interceptorList.length; i++ )
115         {
116             interceptorServiceName = interceptorList[i];
117             Object currService = serviceManager.lookup(interceptorServiceName);
118 
119             if (currService instanceof AvalonInterceptorService)
120             {
121                 result[i] = (AvalonInterceptorService) currService;
122             }
123             else
124             {
125                 String msg = "The following service is not an AvalonInterceptorService : " + interceptorServiceName;
126                 throw new ServiceException(AvalonYaafiConstants.AVALON_CONTAINER_YAAFI,msg);
127             }
128         }
129 
130         return result;
131     }
132 }