View Javadoc
1   /**
2    * Copyright 2005-2015 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.ksb.messaging;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.lang.exception.ExceptionUtils;
20  import org.apache.log4j.Logger;
21  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
22  
23  import javax.xml.namespace.QName;
24  import java.lang.reflect.InvocationHandler;
25  import java.lang.reflect.InvocationTargetException;
26  import java.lang.reflect.Method;
27  import java.lang.reflect.Proxy;
28  
29  /**
30   * This class creates a proxy for services deployed on KSB. A 
31   * reference to the service is obtained only upon the first method
32   * invocation.
33   * 
34   * @author Kuali Rice Team (rice.collab@kuali.org)
35   *
36   */
37  public class KSBClientProxy implements InvocationHandler {
38  
39  private static final Logger LOG = Logger.getLogger(KSBClientProxy.class);
40      
41      private QName serviceName;
42      private volatile Object service;
43  
44  
45      public static <T> T newInstance(String serviceQName, Class<T> interfaceClass) throws InstantiationException, IllegalAccessException {
46          if (StringUtils.isBlank(serviceQName)) {
47              throw new IllegalArgumentException("the qname was blank");
48          }
49  
50          if (interfaceClass == null) {
51              throw new IllegalArgumentException("the interfaceClass was null");
52          }
53  
54          @SuppressWarnings("unchecked")
55          final T t = (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[] { interfaceClass }, new KSBClientProxy(serviceQName));
56          return t;
57      }
58  
59      public KSBClientProxy(String serviceQName){
60          if (StringUtils.isBlank(serviceQName)) {
61              throw new IllegalArgumentException("the qname was blank");
62          }
63  
64          this.serviceName = QName.valueOf(serviceQName);
65      }
66      
67      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
68          //using DCL idiom
69          //see effective java 2nd ed. pg. 71
70          Object s = service;
71          if (s == null) {
72              synchronized (this) {
73                  s = service;
74                  if (s == null) {
75                      service = s = GlobalResourceLoader.getService(serviceName);
76                  }
77              }
78          }
79  
80          if (s != null) {
81              try {
82                  return method.invoke(s, args);
83              } catch (InvocationTargetException e) {
84                  throw ExceptionUtils.getRootCause(e);
85              }
86          }
87  
88          LOG.warn("serviceName: " + serviceName + " was not found");
89          return null;
90      }
91  }