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 public final class WorkflowDocumentFactory {
38
39 private static final String CREATE_METHOD_NAME = "createDocument";
40 private static final String LOAD_METHOD_NAME = "loadDocument";
41
42
43
44
45
46 private static final class ProviderHolder {
47 static final Object provider;
48 static final Method createMethod;
49 static final Method loadMethod;
50 static {
51 provider = loadProvider();
52 createMethod = locateCreateMethod(provider);
53 loadMethod = locateLoadMethod(provider);
54 }
55 }
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 public static WorkflowDocument createDocument(String principalId, String documentTypeName) {
72 return createDocument(principalId, documentTypeName, null, null);
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public static WorkflowDocument createDocument(String principalId, String documentTypeName, String title) {
89 DocumentUpdate.Builder builder = DocumentUpdate.Builder.create();
90 builder.setTitle(title);
91 return createDocument(principalId, documentTypeName, builder.build(), null);
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 public static WorkflowDocument createDocument(String principalId, String documentTypeName, DocumentUpdate documentUpdate, DocumentContentUpdate documentContentUpdate) {
109 if (StringUtils.isBlank(principalId)) {
110 throw new IllegalArgumentException("principalId was null or blank");
111 }
112 if (StringUtils.isBlank(documentTypeName)) {
113 throw new IllegalArgumentException("documentTypeName was null or blank");
114 }
115
116 Object workflowDocument = null;
117
118 try {
119 workflowDocument = ProviderHolder.createMethod.invoke(ProviderHolder.provider, principalId, documentTypeName, documentUpdate, documentContentUpdate);
120 } catch (IllegalAccessException e) {
121 throw new ConfigurationException("Failed to invoke " + CREATE_METHOD_NAME, e);
122 } catch (InvocationTargetException e) {
123 if (e.getCause() instanceof RuntimeException) {
124 throw (RuntimeException)e.getCause();
125 }
126 throw new ConfigurationException("Failed to invoke " + CREATE_METHOD_NAME, e);
127 }
128
129 if (!(workflowDocument instanceof WorkflowDocument)) {
130 throw new ConfigurationException("Created document is not a proper instance of " + WorkflowDocument.class + ", was instead " + workflowDocument.getClass());
131 }
132 return (WorkflowDocument)workflowDocument;
133 }
134
135 public static WorkflowDocument loadDocument(String principalId, String documentId) {
136 if (StringUtils.isBlank(principalId)) {
137 throw new IllegalArgumentException("principalId was null or blank");
138 }
139 if (StringUtils.isBlank(documentId)) {
140 throw new IllegalArgumentException("documentId was null or blank");
141 }
142
143 Object workflowDocument = null;
144
145 try {
146 workflowDocument = ProviderHolder.loadMethod.invoke(ProviderHolder.provider, principalId, documentId);
147 } catch (IllegalAccessException e) {
148 throw new ConfigurationException("Failed to invoke " + LOAD_METHOD_NAME, e);
149 } catch (InvocationTargetException e) {
150 if (e.getCause() instanceof RuntimeException) {
151 throw (RuntimeException)e.getCause();
152 }
153 throw new ConfigurationException("Failed to invoke " + LOAD_METHOD_NAME, e);
154 }
155
156 if (!(workflowDocument instanceof WorkflowDocument)) {
157 throw new ConfigurationException("Loaded document is not a proper instance of " + WorkflowDocument.class + ", was instead " + workflowDocument.getClass());
158 }
159 return (WorkflowDocument)workflowDocument;
160 }
161
162 private static Object loadProvider() {
163 String providerClassName = null;
164 String resource = null;
165 try {
166 resource = new StringBuilder().append("META-INF/services/").append(WorkflowDocument.class.getName()).toString();
167 final InputStream resourceStream = ClassLoaderUtils.getDefaultClassLoader().getResourceAsStream(resource.toString());
168 if (resourceStream != null) {
169 BufferedReader reader = new BufferedReader(new InputStreamReader(resourceStream, "UTF-8"));
170 providerClassName = reader.readLine().trim();
171 reader.close();
172 Class<?> providerClass = Class.forName(providerClassName);
173 return newInstance(providerClass);
174 } else {
175 throw new ConfigurationException("Failed to locate a services definition file at " + resource);
176 }
177 } catch (IOException e) {
178 throw new ConfigurationException("Failure processing services definition file at " + resource, e);
179 } catch (ClassNotFoundException e) {
180 throw new ConfigurationException("Failed to load provider class: " + providerClassName, e);
181 }
182 }
183
184 private static Object newInstance(Class<?> providerClass) {
185 try {
186 return providerClass.newInstance();
187 } catch (InstantiationException e) {
188 throw new ConfigurationException("Failed to instantiate provider class: " + providerClass.getName(), e);
189 } catch (IllegalAccessException e) {
190 throw new ConfigurationException("Failed to instantiate provider class: " + providerClass.getName(), e);
191 }
192 }
193
194 private static Method locateCreateMethod(Object provider) {
195 try {
196 return provider.getClass().getMethod(CREATE_METHOD_NAME, String.class, String.class, DocumentUpdate.class, DocumentContentUpdate.class);
197 } catch (NoSuchMethodException e) {
198 throw new ConfigurationException("Failed to locate valid createDocument method signature on provider class: " + provider.getClass().getName(), e);
199 } catch (SecurityException e) {
200 throw new ConfigurationException("Encountered security issue when attempting to access createDocument method on provider class: " + provider.getClass().getName(), e);
201 }
202 }
203
204 private static Method locateLoadMethod(Object provider) {
205 try {
206 return provider.getClass().getMethod(LOAD_METHOD_NAME, String.class, String.class);
207 } catch (NoSuchMethodException e) {
208 throw new ConfigurationException("Failed to locate valid createDocument method signature on provider class: " + provider.getClass().getName(), e);
209 } catch (SecurityException e) {
210 throw new ConfigurationException("Encountered security issue when attempting to access createDocument method on provider class: " + provider.getClass().getName(), e);
211 }
212 }
213
214 }