1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.service.impl;
17
18 import org.apache.commons.beanutils.PropertyUtils;
19 import org.apache.commons.lang.StringUtils;
20 import org.apache.log4j.Logger;
21 import org.kuali.rice.krad.bo.BusinessObject;
22 import org.kuali.rice.krad.bo.DataObjectRelationship;
23 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
24 import org.kuali.rice.krad.bo.ModuleConfiguration;
25 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
26 import org.kuali.rice.krad.datadictionary.PrimitiveAttributeDefinition;
27 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
28 import org.kuali.rice.krad.service.BusinessObjectDictionaryService;
29 import org.kuali.rice.krad.service.BusinessObjectNotLookupableException;
30 import org.kuali.rice.krad.service.BusinessObjectService;
31 import org.kuali.rice.krad.service.KRADServiceLocator;
32 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
33 import org.kuali.rice.krad.service.KualiModuleService;
34 import org.kuali.rice.krad.service.LookupService;
35 import org.kuali.rice.krad.service.ModuleService;
36 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
37 import org.kuali.rice.krad.util.KRADConstants;
38 import org.kuali.rice.krad.util.ObjectUtils;
39 import org.kuali.rice.krad.util.UrlFactory;
40 import org.springframework.beans.BeansException;
41 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
42 import org.springframework.context.ApplicationContext;
43
44 import java.lang.reflect.Modifier;
45 import java.util.HashMap;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Map.Entry;
49 import java.util.Properties;
50
51
52
53
54
55
56 public class ModuleServiceBase implements ModuleService {
57
58 protected static final Logger LOG = Logger.getLogger(ModuleServiceBase.class);
59
60 protected ModuleConfiguration moduleConfiguration;
61 protected BusinessObjectService businessObjectService;
62 protected LookupService lookupService;
63 protected BusinessObjectDictionaryService businessObjectDictionaryService;
64 protected KualiModuleService kualiModuleService;
65 protected ApplicationContext applicationContext;
66
67
68
69
70 public boolean isResponsibleFor(Class businessObjectClass) {
71 if(getModuleConfiguration() == null)
72 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
73
74 if (getModuleConfiguration().getPackagePrefixes() == null || businessObjectClass == null) {
75 return false;
76 }
77 for (String prefix : getModuleConfiguration().getPackagePrefixes()) {
78 if (businessObjectClass.getPackage().getName().startsWith(prefix)) {
79 return true;
80 }
81 }
82 if (ExternalizableBusinessObject.class.isAssignableFrom(businessObjectClass)) {
83 Class externalizableBusinessObjectInterface = ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(businessObjectClass);
84 if (externalizableBusinessObjectInterface != null) {
85 for (String prefix : getModuleConfiguration().getPackagePrefixes()) {
86 if (externalizableBusinessObjectInterface.getPackage().getName().startsWith(prefix)) {
87 return true;
88 }
89 }
90 }
91 }
92 return false;
93 }
94
95
96
97
98
99
100 public boolean isResponsibleForJob(String jobName) {
101 if(getModuleConfiguration() == null)
102 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
103
104 if (getModuleConfiguration().getJobNames() == null || StringUtils.isEmpty(jobName))
105 return false;
106
107 return getModuleConfiguration().getJobNames().contains(jobName);
108 }
109
110
111
112
113 public <T extends ExternalizableBusinessObject> T getExternalizableBusinessObject(Class<T> businessObjectClass, Map<String, Object> fieldValues) {
114 Class<? extends ExternalizableBusinessObject> implementationClass = getExternalizableBusinessObjectImplementation(businessObjectClass);
115 ExternalizableBusinessObject businessObject = (ExternalizableBusinessObject)
116 getBusinessObjectService().findByPrimaryKey(implementationClass, fieldValues);
117 return (T) businessObject;
118 }
119
120
121
122
123 public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsList(
124 Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues) {
125 Class<? extends ExternalizableBusinessObject> implementationClass = getExternalizableBusinessObjectImplementation(externalizableBusinessObjectClass);
126 return (List<T>) getBusinessObjectService().findMatching(implementationClass, fieldValues);
127 }
128
129
130
131
132 public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsListForLookup(
133 Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues, boolean unbounded) {
134 Class<? extends ExternalizableBusinessObject> implementationClass = getExternalizableBusinessObjectImplementation(externalizableBusinessObjectClass);
135 if (isExternalizableBusinessObjectLookupable(implementationClass)) {
136 Map<String, String> searchCriteria = new HashMap<String, String>();
137 for (Entry<String, Object> fieldValue : fieldValues.entrySet()) {
138 if (fieldValue.getValue() != null) {
139 searchCriteria.put(fieldValue.getKey(), fieldValue.getValue().toString());
140 }
141 else {
142 searchCriteria.put(fieldValue.getKey(), null);
143 }
144 }
145 return (List<T>) getLookupService().findCollectionBySearchHelper(implementationClass, searchCriteria, unbounded);
146 } else {
147 throw new BusinessObjectNotLookupableException("External business object is not a Lookupable: " + implementationClass);
148 }
149 }
150
151 public List listPrimaryKeyFieldNames(Class businessObjectInterfaceClass){
152 Class clazz = getExternalizableBusinessObjectImplementation(businessObjectInterfaceClass);
153 return KRADServiceLocator.getPersistenceStructureService().listPrimaryKeyFieldNames(clazz);
154 }
155
156
157
158
159 public BusinessObjectEntry getExternalizableBusinessObjectDictionaryEntry(
160 Class businessObjectInterfaceClass) {
161 Class boClass = businessObjectInterfaceClass;
162 if(businessObjectInterfaceClass.isInterface())
163 boClass = getExternalizableBusinessObjectImplementation(businessObjectInterfaceClass);
164 return boClass==null?null:
165 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntryForConcreteClass(boClass.getName());
166 }
167
168 public String getExternalizableBusinessObjectInquiryUrl(Class inquiryBusinessObjectClass, Map<String, String[]> parameters) {
169 if(!ExternalizableBusinessObject.class.isAssignableFrom(inquiryBusinessObjectClass)) {
170 return KRADConstants.EMPTY_STRING;
171 }
172 String businessObjectClassAttribute;
173 if(inquiryBusinessObjectClass.isInterface()){
174 Class implementationClass = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
175 if (implementationClass == null) {
176 LOG.error("Can't find ExternalizableBusinessObject implementation class for interface " + inquiryBusinessObjectClass.getName());
177 throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for interface " + inquiryBusinessObjectClass.getName());
178 }
179 businessObjectClassAttribute = implementationClass.getName();
180 }else{
181 LOG.warn("Inquiry was invoked with a non-interface class object " + inquiryBusinessObjectClass.getName());
182 businessObjectClassAttribute = inquiryBusinessObjectClass.getName();
183 }
184 return UrlFactory.parameterizeUrl(
185 getInquiryUrl(inquiryBusinessObjectClass),
186 getUrlParameters(businessObjectClassAttribute, parameters));
187 }
188
189 protected Properties getUrlParameters(String businessObjectClassAttribute, Map<String, String[]> parameters){
190 Properties urlParameters = new Properties();
191 for (String paramName : parameters.keySet()) {
192 String[] parameterValues = parameters.get(paramName);
193 if (parameterValues.length > 0) {
194 urlParameters.put(paramName, parameterValues[0]);
195 }
196 }
197 urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObjectClassAttribute);
198 urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
199 return urlParameters;
200 }
201
202 protected String getInquiryUrl(Class inquiryBusinessObjectClass){
203 String riceBaseUrl = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
204 KRADConstants.APPLICATION_URL_KEY);
205 String inquiryUrl = riceBaseUrl;
206 if (!inquiryUrl.endsWith("/")) {
207 inquiryUrl = inquiryUrl + "/";
208 }
209 return inquiryUrl + "kr/" + KRADConstants.INQUIRY_ACTION;
210 }
211
212
213
214
215
216
217 public String getExternalizableBusinessObjectLookupUrl(Class inquiryBusinessObjectClass, Map<String, String> parameters) {
218 Properties urlParameters = new Properties();
219
220 String riceBaseUrl = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
221 KRADConstants.APPLICATION_URL_KEY);
222 String lookupUrl = riceBaseUrl;
223 if (!lookupUrl.endsWith("/")) {
224 lookupUrl = lookupUrl + "/";
225 }
226 if (parameters.containsKey(KRADConstants.MULTIPLE_VALUE)) {
227 lookupUrl = lookupUrl + "kr/" + KRADConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
228 }
229 else {
230 lookupUrl = lookupUrl + "kr/" + KRADConstants.LOOKUP_ACTION;
231 }
232 for (String paramName : parameters.keySet()) {
233 urlParameters.put(paramName, parameters.get(paramName));
234 }
235
236 Class clazz = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
237 urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz==null?"":clazz.getName());
238
239 return UrlFactory.parameterizeUrl(lookupUrl, urlParameters);
240 }
241
242
243
244
245
246
247
248
249 public <T extends ExternalizableBusinessObject> T retrieveExternalizableBusinessObjectIfNecessary(
250 BusinessObject businessObject, T currentInstanceExternalizableBO, String externalizableRelationshipName) {
251
252 if(businessObject==null) return null;
253 Class clazz;
254 try{
255 clazz = getExternalizableBusinessObjectImplementation(
256 PropertyUtils.getPropertyType(businessObject, externalizableRelationshipName));
257 } catch(Exception iex){
258 LOG.warn("Exception:"+iex+" thrown while trying to get property type for property:"+externalizableRelationshipName+
259 " from business object:"+businessObject);
260 return null;
261 }
262
263
264
265 BusinessObjectEntry entry =
266 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(
267 businessObject.getClass().getSimpleName());
268 RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
269 List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions = relationshipDefinition.getPrimitiveAttributes();
270
271 Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
272 Object sourcePropertyValue;
273 Object targetPropertyValue = null;
274 boolean sourceTargetPropertyValuesSame = true;
275 for(PrimitiveAttributeDefinition primitiveAttributeDefinition: primitiveAttributeDefinitions){
276 sourcePropertyValue = ObjectUtils.getPropertyValue(
277 businessObject, primitiveAttributeDefinition.getSourceName());
278 if(currentInstanceExternalizableBO!=null)
279 targetPropertyValue = ObjectUtils.getPropertyValue(currentInstanceExternalizableBO, primitiveAttributeDefinition.getTargetName());
280 if(sourcePropertyValue==null){
281 return null;
282 } else if(targetPropertyValue==null || (targetPropertyValue!=null && !targetPropertyValue.equals(sourcePropertyValue))){
283 sourceTargetPropertyValuesSame = false;
284 }
285 fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
286 }
287
288 if(!sourceTargetPropertyValuesSame)
289 return (T) getExternalizableBusinessObject(clazz, fieldValuesInEBO);
290 return currentInstanceExternalizableBO;
291 }
292
293
294
295
296
297
298
299
300 public List<? extends ExternalizableBusinessObject> retrieveExternalizableBusinessObjectsList(
301 BusinessObject businessObject, String externalizableRelationshipName, Class externalizableClazz) {
302
303 if(businessObject==null) return null;
304
305
306 String className = businessObject.getClass().getName();
307 String key = className.substring(className.lastIndexOf(".")+1);
308 BusinessObjectEntry entry =
309 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(key);
310 RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
311 List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions = relationshipDefinition.getPrimitiveAttributes();
312 Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
313 Object sourcePropertyValue;
314 for(PrimitiveAttributeDefinition primitiveAttributeDefinition: primitiveAttributeDefinitions){
315 sourcePropertyValue = ObjectUtils.getPropertyValue(
316 businessObject, primitiveAttributeDefinition.getSourceName());
317 if(sourcePropertyValue==null){
318 return null;
319 }
320 fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
321 }
322 return getExternalizableBusinessObjectsList(
323 getExternalizableBusinessObjectImplementation(externalizableClazz), fieldValuesInEBO);
324 }
325
326
327
328
329 public <E extends ExternalizableBusinessObject> Class<E> getExternalizableBusinessObjectImplementation(Class<E> externalizableBusinessObjectInterface) {
330 if (getModuleConfiguration() == null) {
331 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
332 }
333 int classModifiers = externalizableBusinessObjectInterface.getModifiers();
334 if (!Modifier.isInterface(classModifiers) && !Modifier.isAbstract(classModifiers)) {
335
336 return externalizableBusinessObjectInterface;
337 }
338 if (getModuleConfiguration().getExternalizableBusinessObjectImplementations() == null) {
339 return null;
340 }
341 else {
342 Class<E> implementationClass = getModuleConfiguration().getExternalizableBusinessObjectImplementations().get(externalizableBusinessObjectInterface);
343 int implClassModifiers = implementationClass.getModifiers();
344 if (Modifier.isInterface(implClassModifiers) || Modifier.isAbstract(implClassModifiers)) {
345 throw new RuntimeException("Implementation class must be non-abstract class: ebo interface: " + externalizableBusinessObjectInterface.getName() + " impl class: "
346 + implementationClass.getName() + " module: " + getModuleConfiguration().getNamespaceCode());
347 }
348 return implementationClass;
349 }
350
351 }
352
353
354
355
356 public void afterPropertiesSet() throws Exception {
357 KualiModuleService kualiModuleService = null;
358 try {
359 kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
360 if ( kualiModuleService == null ) {
361 kualiModuleService = ((KualiModuleService)applicationContext.getBean( KRADServiceLocatorWeb.KUALI_MODULE_SERVICE ));
362 }
363 } catch ( NoSuchBeanDefinitionException ex ) {
364 kualiModuleService = ((KualiModuleService)applicationContext.getBean( KRADServiceLocatorWeb.KUALI_MODULE_SERVICE ));
365 }
366 kualiModuleService.getInstalledModuleServices().add( this );
367 }
368
369
370
371
372 public ModuleConfiguration getModuleConfiguration() {
373 return this.moduleConfiguration;
374 }
375
376
377
378
379 public void setModuleConfiguration(ModuleConfiguration moduleConfiguration) {
380 this.moduleConfiguration = moduleConfiguration;
381 }
382
383
384
385
386 public boolean isExternalizable(Class boClazz){
387 if(boClazz==null) return false;
388 return ExternalizableBusinessObject.class.isAssignableFrom(boClazz);
389 }
390
391 public boolean isExternalizableBusinessObjectLookupable(Class boClass) {
392 return getBusinessObjectDictionaryService().isLookupable(boClass);
393 }
394
395 public boolean isExternalizableBusinessObjectInquirable(Class boClass) {
396 return getBusinessObjectDictionaryService().isInquirable(boClass);
397 }
398
399 public <T extends ExternalizableBusinessObject> T createNewObjectFromExternalizableClass(Class<T> boClass) {
400 try {
401 return (T) getExternalizableBusinessObjectImplementation(boClass).newInstance();
402 } catch (Exception e) {
403 throw new RuntimeException("Unable to create externalizable business object class", e);
404 }
405 }
406
407 public DataObjectRelationship getBusinessObjectRelationship(Class boClass, String attributeName, String attributePrefix){
408 return null;
409 }
410
411
412
413 public BusinessObjectDictionaryService getBusinessObjectDictionaryService () {
414 if ( businessObjectDictionaryService == null ) {
415 businessObjectDictionaryService = KRADServiceLocatorWeb.getBusinessObjectDictionaryService();
416 }
417 return businessObjectDictionaryService;
418 }
419
420
421
422
423 public BusinessObjectService getBusinessObjectService() {
424 if ( businessObjectService == null ) {
425 businessObjectService = KRADServiceLocator.getBusinessObjectService();
426 }
427 return businessObjectService;
428 }
429
430
431
432
433
434 protected LookupService getLookupService() {
435 return lookupService != null ? lookupService : KRADServiceLocatorWeb.getLookupService();
436 }
437
438
439
440
441 public KualiModuleService getKualiModuleService() {
442 return this.kualiModuleService;
443 }
444
445
446
447
448 public void setKualiModuleService(KualiModuleService kualiModuleService) {
449 this.kualiModuleService = kualiModuleService;
450 }
451
452
453
454
455 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
456 this.applicationContext = applicationContext;
457 }
458
459
460
461
462
463
464
465
466 public List<List<String>> listAlternatePrimaryKeyFieldNames(
467 Class businessObjectInterfaceClass) {
468 return null;
469 }
470
471 }
472