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