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 java.lang.reflect.Modifier;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22 import java.util.Map.Entry;
23 import java.util.Properties;
24
25 import org.apache.commons.beanutils.PropertyUtils;
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.log4j.Logger;
28 import org.kuali.rice.core.api.config.property.ConfigurationService;
29 import org.kuali.rice.coreservice.framework.parameter.ParameterService;
30 import org.kuali.rice.coreservice.framework.CoreFrameworkServiceLocator;
31 import org.kuali.rice.kns.service.KNSServiceLocator;
32 import org.kuali.rice.krad.bo.BusinessObject;
33 import org.kuali.rice.krad.bo.DataObjectRelationship;
34 import org.kuali.rice.krad.bo.ExternalizableBusinessObject;
35 import org.kuali.rice.krad.bo.ModuleConfiguration;
36 import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
37 import org.kuali.rice.krad.datadictionary.PrimitiveAttributeDefinition;
38 import org.kuali.rice.krad.datadictionary.RelationshipDefinition;
39 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
40 import org.kuali.rice.krad.service.BusinessObjectNotLookupableException;
41 import org.kuali.rice.krad.service.BusinessObjectService;
42 import org.kuali.rice.krad.service.KRADServiceLocator;
43 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
44 import org.kuali.rice.krad.service.KualiModuleService;
45 import org.kuali.rice.krad.service.LookupService;
46 import org.kuali.rice.krad.service.ModuleService;
47 import org.kuali.rice.krad.uif.UifConstants;
48 import org.kuali.rice.krad.uif.UifParameters;
49 import org.kuali.rice.krad.util.ExternalizableBusinessObjectUtils;
50 import org.kuali.rice.krad.util.KRADConstants;
51 import org.kuali.rice.krad.util.ObjectUtils;
52 import org.kuali.rice.krad.util.UrlFactory;
53 import org.springframework.beans.BeansException;
54 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
55 import org.springframework.context.ApplicationContext;
56
57
58
59
60
61
62 public class ModuleServiceBase implements ModuleService {
63
64 protected static final Logger LOG = Logger.getLogger(ModuleServiceBase.class);
65
66 protected ModuleConfiguration moduleConfiguration;
67 protected BusinessObjectService businessObjectService;
68 protected LookupService lookupService;
69 protected BusinessObjectDictionaryService businessObjectDictionaryService;
70 protected KualiModuleService kualiModuleService;
71 protected ApplicationContext applicationContext;
72 protected ConfigurationService kualiConfigurationService;
73
74
75
76
77 public boolean isResponsibleFor(Class businessObjectClass) {
78 if (getModuleConfiguration() == null) {
79 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
80 }
81
82 if (getModuleConfiguration().getPackagePrefixes() == null || businessObjectClass == null) {
83 return false;
84 }
85 for (String prefix : getModuleConfiguration().getPackagePrefixes()) {
86 if (businessObjectClass.getPackage().getName().startsWith(prefix)) {
87 return true;
88 }
89 }
90 if (ExternalizableBusinessObject.class.isAssignableFrom(businessObjectClass)) {
91 Class externalizableBusinessObjectInterface =
92 ExternalizableBusinessObjectUtils.determineExternalizableBusinessObjectSubInterface(
93 businessObjectClass);
94 if (externalizableBusinessObjectInterface != null) {
95 for (String prefix : getModuleConfiguration().getPackagePrefixes()) {
96 if (externalizableBusinessObjectInterface.getPackage().getName().startsWith(prefix)) {
97 return true;
98 }
99 }
100 }
101 }
102 return false;
103 }
104
105
106
107
108 public boolean isResponsibleForJob(String jobName) {
109 if (getModuleConfiguration() == null) {
110 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
111 }
112
113 if (getModuleConfiguration().getJobNames() == null || StringUtils.isEmpty(jobName)) {
114 return false;
115 }
116
117 return getModuleConfiguration().getJobNames().contains(jobName);
118 }
119
120
121
122
123 public <T extends ExternalizableBusinessObject> T getExternalizableBusinessObject(Class<T> businessObjectClass,
124 Map<String, Object> fieldValues) {
125 Class<? extends ExternalizableBusinessObject> implementationClass =
126 getExternalizableBusinessObjectImplementation(businessObjectClass);
127 ExternalizableBusinessObject businessObject =
128 (ExternalizableBusinessObject) getBusinessObjectService().findByPrimaryKey(implementationClass,
129 fieldValues);
130 return (T) businessObject;
131 }
132
133
134
135
136 public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsList(
137 Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues) {
138 Class<? extends ExternalizableBusinessObject> implementationClass =
139 getExternalizableBusinessObjectImplementation(externalizableBusinessObjectClass);
140 return (List<T>) getBusinessObjectService().findMatching(implementationClass, fieldValues);
141 }
142
143
144
145
146
147 public <T extends ExternalizableBusinessObject> List<T> getExternalizableBusinessObjectsListForLookup(
148 Class<T> externalizableBusinessObjectClass, Map<String, Object> fieldValues, boolean unbounded) {
149 Class<? extends ExternalizableBusinessObject> implementationClass =
150 getExternalizableBusinessObjectImplementation(externalizableBusinessObjectClass);
151 if (isExternalizableBusinessObjectLookupable(implementationClass)) {
152 Map<String, String> searchCriteria = new HashMap<String, String>();
153 for (Entry<String, Object> fieldValue : fieldValues.entrySet()) {
154 if (fieldValue.getValue() != null) {
155 searchCriteria.put(fieldValue.getKey(), fieldValue.getValue().toString());
156 } else {
157 searchCriteria.put(fieldValue.getKey(), null);
158 }
159 }
160 return (List<T>) getLookupService().findCollectionBySearchHelper(implementationClass, searchCriteria,
161 unbounded);
162 } else {
163 throw new BusinessObjectNotLookupableException(
164 "External business object is not a Lookupable: " + implementationClass);
165 }
166 }
167
168 public List listPrimaryKeyFieldNames(Class businessObjectInterfaceClass) {
169 Class clazz = getExternalizableBusinessObjectImplementation(businessObjectInterfaceClass);
170 return KRADServiceLocator.getPersistenceStructureService().listPrimaryKeyFieldNames(clazz);
171 }
172
173
174
175
176 public BusinessObjectEntry getExternalizableBusinessObjectDictionaryEntry(Class businessObjectInterfaceClass) {
177 Class boClass = getExternalizableBusinessObjectImplementation(businessObjectInterfaceClass);
178
179 return boClass == null ? null : KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary()
180 .getBusinessObjectEntryForConcreteClass(boClass.getName());
181 }
182
183
184
185
186
187 public String getExternalizableDataObjectInquiryUrl(Class<?> inquiryDataObjectClass, Properties parameters) {
188 String baseUrl = getBaseInquiryUrl();
189
190
191 if (ExternalizableBusinessObject.class.isAssignableFrom(inquiryDataObjectClass)) {
192 Class implementationClass = getExternalizableBusinessObjectImplementation(inquiryDataObjectClass.asSubclass(
193 ExternalizableBusinessObject.class));
194 if (implementationClass == null) {
195 throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for "
196 + inquiryDataObjectClass.getName());
197 }
198
199 parameters.put(UifParameters.DATA_OBJECT_CLASS_NAME, implementationClass.getName());
200 }
201
202 return UrlFactory.parameterizeUrl(baseUrl, parameters);
203 }
204
205
206
207
208
209
210 protected String getBaseInquiryUrl() {
211 return getKualiConfigurationService().getPropertyValueAsString(KRADConstants.KRAD_INQUIRY_URL_KEY);
212 }
213
214
215
216
217
218 public String getExternalizableDataObjectLookupUrl(Class<?> lookupDataObjectClass, Properties parameters) {
219 String baseUrl = getBaseLookupUrl();
220
221
222 if (ExternalizableBusinessObject.class.isAssignableFrom(lookupDataObjectClass)) {
223 Class implementationClass = getExternalizableBusinessObjectImplementation(lookupDataObjectClass.asSubclass(
224 ExternalizableBusinessObject.class));
225 if (implementationClass == null) {
226 throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for "
227 + lookupDataObjectClass.getName());
228 }
229
230 parameters.put(UifParameters.DATA_OBJECT_CLASS_NAME, implementationClass.getName());
231 }
232
233 return UrlFactory.parameterizeUrl(baseUrl, parameters);
234 }
235
236
237
238
239
240
241 protected String getBaseLookupUrl() {
242 return getKualiConfigurationService().getPropertyValueAsString(KRADConstants.KRAD_LOOKUP_URL_KEY);
243 }
244
245 @Deprecated
246 public String getExternalizableBusinessObjectInquiryUrl(Class inquiryBusinessObjectClass,
247 Map<String, String[]> parameters) {
248 if (!ExternalizableBusinessObject.class.isAssignableFrom(inquiryBusinessObjectClass)) {
249 return KRADConstants.EMPTY_STRING;
250 }
251 String businessObjectClassAttribute;
252
253 Class implementationClass = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
254 if (implementationClass == null) {
255 LOG.error("Can't find ExternalizableBusinessObject implementation class for " + inquiryBusinessObjectClass
256 .getName());
257 throw new RuntimeException("Can't find ExternalizableBusinessObject implementation class for interface "
258 + inquiryBusinessObjectClass.getName());
259 }
260 businessObjectClassAttribute = implementationClass.getName();
261 return UrlFactory.parameterizeUrl(getInquiryUrl(inquiryBusinessObjectClass), getUrlParameters(
262 businessObjectClassAttribute, parameters));
263 }
264
265 @Deprecated
266 protected Properties getUrlParameters(String businessObjectClassAttribute, Map<String, String[]> parameters) {
267 Properties urlParameters = new Properties();
268 for (String paramName : parameters.keySet()) {
269 String[] parameterValues = parameters.get(paramName);
270 if (parameterValues.length > 0) {
271 urlParameters.put(paramName, parameterValues[0]);
272 }
273 }
274 urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObjectClassAttribute);
275 urlParameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
276 return urlParameters;
277 }
278
279 @Deprecated
280 protected String getInquiryUrl(Class inquiryBusinessObjectClass) {
281 String riceBaseUrl = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
282 KRADConstants.APPLICATION_URL_KEY);
283 String inquiryUrl = riceBaseUrl;
284 if (!inquiryUrl.endsWith("/")) {
285 inquiryUrl = inquiryUrl + "/";
286 }
287 return inquiryUrl + "kr/" + KRADConstants.INQUIRY_ACTION;
288 }
289
290
291
292
293
294
295
296 @Deprecated
297 public String getExternalizableBusinessObjectLookupUrl(Class inquiryBusinessObjectClass,
298 Map<String, String> parameters) {
299 Properties urlParameters = new Properties();
300
301 String riceBaseUrl = KRADServiceLocator.getKualiConfigurationService().getPropertyValueAsString(
302 KRADConstants.APPLICATION_URL_KEY);
303 String lookupUrl = riceBaseUrl;
304 if (!lookupUrl.endsWith("/")) {
305 lookupUrl = lookupUrl + "/";
306 }
307 if (parameters.containsKey(KRADConstants.MULTIPLE_VALUE)) {
308 lookupUrl = lookupUrl + "kr/" + KRADConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
309 } else {
310 lookupUrl = lookupUrl + "kr/" + KRADConstants.LOOKUP_ACTION;
311 }
312 for (String paramName : parameters.keySet()) {
313 urlParameters.put(paramName, parameters.get(paramName));
314 }
315
316 Class clazz = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
317 urlParameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz == null ? "" : clazz.getName());
318
319 return UrlFactory.parameterizeUrl(lookupUrl, urlParameters);
320 }
321
322
323
324
325
326
327
328
329 public <T extends ExternalizableBusinessObject> T retrieveExternalizableBusinessObjectIfNecessary(
330 BusinessObject businessObject, T currentInstanceExternalizableBO, String externalizableRelationshipName) {
331
332 if (businessObject == null) {
333 return null;
334 }
335 Class clazz;
336 try {
337 clazz = getExternalizableBusinessObjectImplementation(PropertyUtils.getPropertyType(businessObject,
338 externalizableRelationshipName));
339 } catch (Exception iex) {
340 LOG.warn("Exception:"
341 + iex
342 + " thrown while trying to get property type for property:"
343 + externalizableRelationshipName
344 + " from business object:"
345 + businessObject);
346 return null;
347 }
348
349
350
351 BusinessObjectEntry entry =
352 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(
353 businessObject.getClass().getSimpleName());
354 RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
355 List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions =
356 relationshipDefinition.getPrimitiveAttributes();
357
358 Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
359 Object sourcePropertyValue;
360 Object targetPropertyValue = null;
361 boolean sourceTargetPropertyValuesSame = true;
362 for (PrimitiveAttributeDefinition primitiveAttributeDefinition : primitiveAttributeDefinitions) {
363 sourcePropertyValue = ObjectUtils.getPropertyValue(businessObject,
364 primitiveAttributeDefinition.getSourceName());
365 if (currentInstanceExternalizableBO != null) {
366 targetPropertyValue = ObjectUtils.getPropertyValue(currentInstanceExternalizableBO,
367 primitiveAttributeDefinition.getTargetName());
368 }
369 if (sourcePropertyValue == null) {
370 return null;
371 } else if (targetPropertyValue == null || (targetPropertyValue != null && !targetPropertyValue.equals(
372 sourcePropertyValue))) {
373 sourceTargetPropertyValuesSame = false;
374 }
375 fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
376 }
377
378 if (!sourceTargetPropertyValuesSame) {
379 return (T) getExternalizableBusinessObject(clazz, fieldValuesInEBO);
380 }
381 return currentInstanceExternalizableBO;
382 }
383
384
385
386
387
388
389
390
391 public List<? extends ExternalizableBusinessObject> retrieveExternalizableBusinessObjectsList(
392 BusinessObject businessObject, String externalizableRelationshipName, Class externalizableClazz) {
393
394 if (businessObject == null) {
395 return null;
396 }
397
398
399 String className = businessObject.getClass().getName();
400 String key = className.substring(className.lastIndexOf(".") + 1);
401 BusinessObjectEntry entry =
402 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(
403 key);
404 RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
405 List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions =
406 relationshipDefinition.getPrimitiveAttributes();
407 Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
408 Object sourcePropertyValue;
409 for (PrimitiveAttributeDefinition primitiveAttributeDefinition : primitiveAttributeDefinitions) {
410 sourcePropertyValue = ObjectUtils.getPropertyValue(businessObject,
411 primitiveAttributeDefinition.getSourceName());
412 if (sourcePropertyValue == null) {
413 return null;
414 }
415 fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
416 }
417 return getExternalizableBusinessObjectsList(getExternalizableBusinessObjectImplementation(externalizableClazz),
418 fieldValuesInEBO);
419 }
420
421
422
423
424 public <E extends ExternalizableBusinessObject> Class<E> getExternalizableBusinessObjectImplementation(
425 Class<E> externalizableBusinessObjectInterface) {
426 if (getModuleConfiguration() == null) {
427 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
428 }
429 int classModifiers = externalizableBusinessObjectInterface.getModifiers();
430 Map<Class, Class> ebos = getModuleConfiguration().getExternalizableBusinessObjectImplementations();
431
432 if (ebos.containsValue(externalizableBusinessObjectInterface)) {
433 return externalizableBusinessObjectInterface;
434 }
435 if (getModuleConfiguration().getExternalizableBusinessObjectImplementations() == null) {
436 return null;
437 } else {
438 Class<E> implementationClass = ebos.get(externalizableBusinessObjectInterface);
439 int implClassModifiers = implementationClass.getModifiers();
440 if (Modifier.isInterface(implClassModifiers) || Modifier.isAbstract(implClassModifiers)) {
441 throw new RuntimeException("Implementation class must be non-abstract class: ebo interface: "
442 + externalizableBusinessObjectInterface.getName()
443 + " impl class: "
444 + implementationClass.getName()
445 + " module: "
446 + getModuleConfiguration().getNamespaceCode());
447 }
448 return implementationClass;
449 }
450
451 }
452
453
454
455
456 public void afterPropertiesSet() throws Exception {
457 KualiModuleService kualiModuleService = null;
458 try {
459 kualiModuleService = KRADServiceLocatorWeb.getKualiModuleService();
460 if (kualiModuleService == null) {
461 kualiModuleService = ((KualiModuleService) applicationContext.getBean(
462 KRADServiceLocatorWeb.KUALI_MODULE_SERVICE));
463 }
464 } catch (NoSuchBeanDefinitionException ex) {
465 kualiModuleService = ((KualiModuleService) applicationContext.getBean(
466 KRADServiceLocatorWeb.KUALI_MODULE_SERVICE));
467 }
468 kualiModuleService.getInstalledModuleServices().add(this);
469 }
470
471
472
473
474 public ModuleConfiguration getModuleConfiguration() {
475 return this.moduleConfiguration;
476 }
477
478
479
480
481 public void setModuleConfiguration(ModuleConfiguration moduleConfiguration) {
482 this.moduleConfiguration = moduleConfiguration;
483 }
484
485
486
487
488 public boolean isExternalizable(Class boClazz) {
489 if (boClazz == null) {
490 return false;
491 }
492 return ExternalizableBusinessObject.class.isAssignableFrom(boClazz);
493 }
494
495 public boolean isExternalizableBusinessObjectLookupable(Class boClass) {
496 return getBusinessObjectDictionaryService().isLookupable(boClass);
497 }
498
499 public boolean isExternalizableBusinessObjectInquirable(Class boClass) {
500 return getBusinessObjectDictionaryService().isInquirable(boClass);
501 }
502
503 public <T extends ExternalizableBusinessObject> T createNewObjectFromExternalizableClass(Class<T> boClass) {
504 try {
505 return (T) getExternalizableBusinessObjectImplementation(boClass).newInstance();
506 } catch (Exception e) {
507 throw new RuntimeException("Unable to create externalizable business object class", e);
508 }
509 }
510
511 public DataObjectRelationship getBusinessObjectRelationship(Class boClass, String attributeName,
512 String attributePrefix) {
513 return null;
514 }
515
516 public BusinessObjectDictionaryService getBusinessObjectDictionaryService() {
517 if (businessObjectDictionaryService == null) {
518 businessObjectDictionaryService = KNSServiceLocator.getBusinessObjectDictionaryService();
519 }
520 return businessObjectDictionaryService;
521 }
522
523
524
525
526 public BusinessObjectService getBusinessObjectService() {
527 if (businessObjectService == null) {
528 businessObjectService = KRADServiceLocator.getBusinessObjectService();
529 }
530 return businessObjectService;
531 }
532
533
534
535
536
537
538 protected LookupService getLookupService() {
539 return lookupService != null ? lookupService : KRADServiceLocatorWeb.getLookupService();
540 }
541
542
543
544
545 public KualiModuleService getKualiModuleService() {
546 return this.kualiModuleService;
547 }
548
549
550
551
552 public void setKualiModuleService(KualiModuleService kualiModuleService) {
553 this.kualiModuleService = kualiModuleService;
554 }
555
556 protected ConfigurationService getKualiConfigurationService() {
557 if (this.kualiConfigurationService == null) {
558 this.kualiConfigurationService = KRADServiceLocator.getKualiConfigurationService();
559 }
560
561 return this.kualiConfigurationService;
562 }
563
564 public void setKualiConfigurationService(ConfigurationService kualiConfigurationService) {
565 this.kualiConfigurationService = kualiConfigurationService;
566 }
567
568
569
570
571 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
572 this.applicationContext = applicationContext;
573 }
574
575
576
577
578
579
580 public List<List<String>> listAlternatePrimaryKeyFieldNames(Class businessObjectInterfaceClass) {
581 return null;
582 }
583
584
585
586
587
588
589 @Override
590 public boolean isLocked() {
591 ModuleConfiguration configuration = this.getModuleConfiguration();
592 if (configuration != null) {
593 String namespaceCode = configuration.getNamespaceCode();
594 String componentCode = KRADConstants.DetailTypes.ALL_DETAIL_TYPE;
595 String parameterName = KRADConstants.SystemGroupParameterNames.OLTP_LOCKOUT_ACTIVE_IND;
596 ParameterService parameterService = CoreFrameworkServiceLocator.getParameterService();
597 String shouldLockout = parameterService.getParameterValueAsString(namespaceCode, componentCode,
598 parameterName);
599 if (StringUtils.isNotBlank(shouldLockout)) {
600 return parameterService.getParameterValueAsBoolean(namespaceCode, componentCode, parameterName);
601 }
602 }
603 return false;
604 }
605 }
606