View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.proxy2;
18  
19  import java.util.Arrays;
20  import java.util.ServiceLoader;
21  
22  /**
23   * {@link ProxyFactory} implementation that delegates to the first discovered {@link ProxyFactory} service provider that
24   * {@link #canProxy(Class...)}.
25   */
26  class DefaultProxyFactory implements ProxyFactory
27  {
28      /** Shared instance */
29      static final DefaultProxyFactory INSTANCE = new DefaultProxyFactory();
30  
31      private static final ServiceLoader<ProxyFactory> SERVICES = ServiceLoader.load(ProxyFactory.class);
32  
33      /**
34       * {@inheritDoc}
35       */
36      @Override
37      public boolean canProxy(Class<?>... proxyClasses)
38      {
39          for (ProxyFactory proxyFactory : SERVICES)
40          {
41              if (proxyFactory.canProxy(proxyClasses))
42              {
43                  return true;
44              }
45          }
46          return false;
47      }
48  
49      /**
50       * {@inheritDoc}
51       */
52      @Override
53      public <T> T createDelegatorProxy(ObjectProvider<?> delegateProvider, Class<?>... proxyClasses)
54      {
55          @SuppressWarnings("unchecked") // type inference
56          final T result = (T) getCapableProxyFactory(proxyClasses).createDelegatorProxy(delegateProvider, proxyClasses);
57          return result;
58      }
59  
60      /**
61       * {@inheritDoc}
62       */
63      @Override
64      public <T> T createDelegatorProxy(ClassLoader classLoader, ObjectProvider<?> delegateProvider,
65              Class<?>... proxyClasses)
66      {
67          @SuppressWarnings("unchecked") // type inference
68          final T result = (T) getCapableProxyFactory(proxyClasses).createDelegatorProxy(classLoader, delegateProvider,
69                  proxyClasses);
70          return result;
71      }
72  
73      /**
74       * {@inheritDoc}
75       */
76      @Override
77      public <T> T createInterceptorProxy(Object target, Interceptor interceptor, Class<?>... proxyClasses)
78      {
79          @SuppressWarnings("unchecked") // type inference
80          final T result = (T) getCapableProxyFactory(proxyClasses).createInterceptorProxy(target, interceptor,
81                  proxyClasses);
82          return result;
83      }
84  
85      /**
86       * {@inheritDoc}
87       */
88      @Override
89      public <T> T createInterceptorProxy(ClassLoader classLoader, Object target, Interceptor interceptor,
90              Class<?>... proxyClasses)
91      {
92          @SuppressWarnings("unchecked") // type inference
93          final T result = (T) getCapableProxyFactory(proxyClasses).createInterceptorProxy(classLoader, target,
94                  interceptor, proxyClasses);
95          return result;
96      }
97  
98      /**
99       * {@inheritDoc}
100      */
101     @Override
102     public <T> T createInvokerProxy(Invoker invoker, Class<?>... proxyClasses)
103     {
104         @SuppressWarnings("unchecked") // type inference
105         final T result = (T) getCapableProxyFactory(proxyClasses).createInvokerProxy(invoker, proxyClasses);
106         return result;
107     }
108 
109     /**
110      * {@inheritDoc}
111      */
112     @Override
113     public <T> T createInvokerProxy(ClassLoader classLoader, Invoker invoker, Class<?>... proxyClasses)
114     {
115         @SuppressWarnings("unchecked") // type inference
116         final T result = (T) getCapableProxyFactory(proxyClasses)
117                 .createInvokerProxy(classLoader, invoker, proxyClasses);
118         return result;
119     }
120 
121     private ProxyFactory getCapableProxyFactory(Class<?>... proxyClasses)
122     {
123         for (ProxyFactory proxyFactory : SERVICES)
124         {
125             if (proxyFactory.canProxy(proxyClasses))
126             {
127                 return proxyFactory;
128             }
129         }
130         throw new IllegalArgumentException("Could not proxy " + Arrays.toString(proxyClasses));
131     }
132 }