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 }