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