1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  package org.kuali.rice.ksb.api.bus.support;
17  
18  import org.apache.commons.lang.ArrayUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
21  import org.kuali.rice.core.api.resourceloader.ResourceLoaderException;
22  import org.kuali.rice.ksb.api.KsbApiServiceLocator;
23  import org.springframework.beans.factory.FactoryBean;
24  import org.springframework.beans.factory.FactoryBeanNotInitializedException;
25  import org.springframework.beans.factory.InitializingBean;
26  
27  import javax.xml.namespace.QName;
28  import java.lang.reflect.InvocationHandler;
29  import java.lang.reflect.InvocationTargetException;
30  import java.lang.reflect.Method;
31  import java.lang.reflect.Proxy;
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  public class LazyServiceFactoryBean implements FactoryBean<Object>, InitializingBean {
50  
51      private String serviceNamespace;
52  	private String serviceName;
53      private String applicationId;
54      private Class<?> objectType;
55      private Class<?>[] proxyInterfaces;
56      private Object proxyObject;
57  
58  	public LazyServiceFactoryBean() {
59          this.objectType = Object.class;
60          this.proxyInterfaces = null;
61  	}
62  
63      public void afterPropertiesSet() throws Exception {
64          if (ArrayUtils.isEmpty(getProxyInterfaces())) {
65              setProxyInterfaces(detectProxyInterfaces());
66              if (ArrayUtils.isEmpty(getProxyInterfaces())) {
67                  throw new FactoryBeanNotInitializedException("Failed to initialize factory bean because " +
68                          "proxyInterfaces were not injected or could not be derived from object type.");
69              }
70          }
71          this.proxyObject = Proxy.newProxyInstance(getClass().getClassLoader(), getProxyInterfaces(),
72                  new LazyInvocationHandler());
73  	}
74  
75      protected Class<?>[] detectProxyInterfaces() {
76          Class<?> type = getObjectType();
77          if (type != null && type.isInterface()) {
78              return new Class<?>[] {type};
79          } else if (type != null) {
80              return type.getInterfaces();
81          } else {
82              return null;
83          }
84      }
85  
86      @Override
87      public Object getObject() throws Exception {
88          return this.proxyObject;
89      }
90  
91      @Override
92      public Class<?> getObjectType() {
93          return this.objectType;
94      }
95  
96      public void setObjectType(Class<?> objectType) {
97          this.objectType = objectType;
98      }
99  
100     @Override
101     public boolean isSingleton() {
102         return true;
103     }
104 
105     public String getServiceNamespace() {
106         return serviceNamespace;
107     }
108 
109     public void setServiceNamespace(String serviceNamespace) {
110         this.serviceNamespace = serviceNamespace;
111     }
112 
113     public String getServiceName() {
114         return serviceName;
115     }
116 
117     public void setServiceName(String serviceName) {
118         this.serviceName = serviceName;
119     }
120 
121     public String getApplicationId() {
122         return applicationId;
123     }
124 
125     public void setApplicationId(String applicationId) {
126         this.applicationId = applicationId;
127     }
128 
129     public Class<?>[] getProxyInterfaces() {
130         return proxyInterfaces;
131     }
132 
133     public void setProxyInterfaces(Class<?>[] proxyInterfaces) {
134         this.proxyInterfaces = proxyInterfaces;
135     }
136 
137     private class LazyInvocationHandler implements InvocationHandler {
138         private volatile Object service = null;
139         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
140             try {
141                 if (service == null) {
142                     QName name = new QName(getServiceNamespace(), getServiceName());
143                     if (StringUtils.isNotBlank(getApplicationId())) {
144                         service = KsbApiServiceLocator.getServiceBus().getService(name, getApplicationId());
145                     } else {
146                         service = KsbApiServiceLocator.getServiceBus().getService(name);
147                     }
148                     if (service == null) {
149                         throw new ResourceLoaderException("Failed to locate resource with name: " + name);
150                     }
151                 }
152                 return method.invoke(service, args);
153             } catch (InvocationTargetException e) {
154                 throw e.getTargetException();
155             }
156         }
157 
158     }
159 
160 }