1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.api;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.kuali.rice.core.api.config.ConfigurationException;
20 import org.kuali.rice.core.api.util.ClassLoaderUtils;
21 import org.kuali.rice.kew.api.action.InvalidActionTakenException;
22 import org.kuali.rice.kew.api.doctype.IllegalDocumentTypeException;
23 import org.kuali.rice.kew.api.document.DocumentContentUpdate;
24 import org.kuali.rice.kew.api.document.DocumentUpdate;
25
26 import java.io.BufferedReader;
27 import java.io.IOException;
28 import java.io.InputStream;
29 import java.io.InputStreamReader;
30 import java.lang.reflect.InvocationTargetException;
31 import java.lang.reflect.Method;
32
33
34
35
36
37
38
39
40
41
42
43 public final class WorkflowDocumentFactory {
44
45 private static final String CREATE_METHOD_NAME = "createDocument";
46 private static final String LOAD_METHOD_NAME = "loadDocument";
47
48
49
50
51
52
53
54
55
56 private static final class ProviderHolder {
57 static final Object provider;
58 static final Method createMethod;
59 static final Method loadMethod;
60 static {
61 provider = loadProvider();
62 createMethod = locateCreateMethod(provider);
63 loadMethod = locateLoadMethod(provider);
64 }
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public static WorkflowDocument createDocument(String principalId, String documentTypeName) {
82 return createDocument(principalId, documentTypeName, null, null);
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 public static WorkflowDocument createDocument(String principalId, String documentTypeName, String title) {
99 DocumentUpdate.Builder builder = DocumentUpdate.Builder.create();
100 builder.setTitle(title);
101 return createDocument(principalId, documentTypeName, builder.build(), null);
102 }
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119 public static WorkflowDocument createDocument(String principalId, String documentTypeName, DocumentUpdate documentUpdate, DocumentContentUpdate documentContentUpdate) {
120 if (StringUtils.isBlank(principalId)) {
121 throw new IllegalArgumentException("principalId was null or blank");
122 }
123 if (StringUtils.isBlank(documentTypeName)) {
124 throw new IllegalArgumentException("documentTypeName was null or blank");
125 }
126
127 Object workflowDocument = null;
128
129 try {
130 workflowDocument = ProviderHolder.createMethod.invoke(ProviderHolder.provider, principalId, documentTypeName, documentUpdate, documentContentUpdate);
131 } catch (IllegalAccessException e) {
132 throw new ConfigurationException("Failed to invoke " + CREATE_METHOD_NAME, e);
133 } catch (InvocationTargetException e) {
134 if (e.getCause() instanceof RuntimeException) {
135 throw (RuntimeException)e.getCause();
136 }
137 throw new ConfigurationException("Failed to invoke " + CREATE_METHOD_NAME, e);
138 }
139
140 if (!(workflowDocument instanceof WorkflowDocument)) {
141 throw new ConfigurationException("Created document is not a proper instance of " + WorkflowDocument.class + ", was instead " + workflowDocument.getClass());
142 }
143 return (WorkflowDocument)workflowDocument;
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 public static WorkflowDocument loadDocument(String principalId, String documentId) {
163 if (StringUtils.isBlank(principalId)) {
164 throw new IllegalArgumentException("principalId was null or blank");
165 }
166 if (StringUtils.isBlank(documentId)) {
167 throw new IllegalArgumentException("documentId was null or blank");
168 }
169
170 Object workflowDocument = null;
171
172 try {
173 workflowDocument = ProviderHolder.loadMethod.invoke(ProviderHolder.provider, principalId, documentId);
174 } catch (IllegalAccessException e) {
175 throw new ConfigurationException("Failed to invoke " + LOAD_METHOD_NAME, e);
176 } catch (InvocationTargetException e) {
177 if (e.getCause() instanceof RuntimeException) {
178 throw (RuntimeException)e.getCause();
179 }
180 throw new ConfigurationException("Failed to invoke " + LOAD_METHOD_NAME, e);
181 }
182
183 if (!(workflowDocument instanceof WorkflowDocument)) {
184 throw new ConfigurationException("Loaded document is not a proper instance of " + WorkflowDocument.class + ", was instead " + workflowDocument.getClass());
185 }
186 return (WorkflowDocument)workflowDocument;
187 }
188
189
190
191
192
193 private static Object loadProvider() {
194 String providerClassName = null;
195 String resource = null;
196 try {
197 resource = new StringBuilder().append("META-INF/services/").append(WorkflowDocument.class.getName()).toString();
198 final InputStream resourceStream = ClassLoaderUtils.getDefaultClassLoader().getResourceAsStream(resource.toString());
199 if (resourceStream != null) {
200 BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream, "UTF-8"));
201 providerClassName = reader.readLine().trim();
202 reader.close();
203 Class<?> providerClass = Class.forName(providerClassName);
204 return newInstance(providerClass);
205 } else {
206 throw new ConfigurationException("Failed to locate a services definition file at " + resource);
207 }
208 } catch (IOException e) {
209 throw new ConfigurationException("Failure processing services definition file at " + resource, e);
210 } catch (ClassNotFoundException e) {
211 throw new ConfigurationException("Failed to load provider class: " + providerClassName, e);
212 }
213 }
214
215 private static Object newInstance(Class<?> providerClass) {
216 try {
217 return providerClass.newInstance();
218 } catch (InstantiationException e) {
219 throw new ConfigurationException("Failed to instantiate provider class: " + providerClass.getName(), e);
220 } catch (IllegalAccessException e) {
221 throw new ConfigurationException("Failed to instantiate provider class: " + providerClass.getName(), e);
222 }
223 }
224
225 private static Method locateCreateMethod(Object provider) {
226 try {
227 return provider.getClass().getMethod(CREATE_METHOD_NAME, String.class, String.class, DocumentUpdate.class, DocumentContentUpdate.class);
228 } catch (NoSuchMethodException e) {
229 throw new ConfigurationException("Failed to locate valid createDocument method signature on provider class: " + provider.getClass().getName(), e);
230 } catch (SecurityException e) {
231 throw new ConfigurationException("Encountered security issue when attempting to access createDocument method on provider class: " + provider.getClass().getName(), e);
232 }
233 }
234
235 private static Method locateLoadMethod(Object provider) {
236 try {
237 return provider.getClass().getMethod(LOAD_METHOD_NAME, String.class, String.class);
238 } catch (NoSuchMethodException e) {
239 throw new ConfigurationException("Failed to locate valid createDocument method signature on provider class: " + provider.getClass().getName(), e);
240 } catch (SecurityException e) {
241 throw new ConfigurationException("Encountered security issue when attempting to access createDocument method on provider class: " + provider.getClass().getName(), e);
242 }
243 }
244
245 }