1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kns.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.kns.bo.BusinessObject;
29 import org.kuali.rice.kns.bo.BusinessObjectRelationship;
30 import org.kuali.rice.kns.bo.ExternalizableBusinessObject;
31 import org.kuali.rice.kns.bo.ModuleConfiguration;
32 import org.kuali.rice.kns.datadictionary.BusinessObjectEntry;
33 import org.kuali.rice.kns.datadictionary.PrimitiveAttributeDefinition;
34 import org.kuali.rice.kns.datadictionary.RelationshipDefinition;
35 import org.kuali.rice.kns.service.BusinessObjectDictionaryService;
36 import org.kuali.rice.kns.service.BusinessObjectNotLookupableException;
37 import org.kuali.rice.kns.service.BusinessObjectService;
38 import org.kuali.rice.kns.service.KNSServiceLocator;
39 import org.kuali.rice.kns.service.KNSServiceLocatorWeb;
40 import org.kuali.rice.kns.service.KualiModuleService;
41 import org.kuali.rice.kns.service.LookupService;
42 import org.kuali.rice.kns.service.ModuleService;
43 import org.kuali.rice.kns.util.ExternalizableBusinessObjectUtils;
44 import org.kuali.rice.kns.util.KNSConstants;
45 import org.kuali.rice.kns.util.ObjectUtils;
46 import org.kuali.rice.kns.util.UrlFactory;
47 import org.springframework.beans.BeansException;
48 import org.springframework.beans.factory.NoSuchBeanDefinitionException;
49 import org.springframework.context.ApplicationContext;
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 KNSServiceLocator.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 KNSServiceLocatorWeb.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 KNSConstants.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(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObjectClassAttribute);
198 urlParameters.put(KNSConstants.DISPATCH_REQUEST_PARAMETER, KNSConstants.CONTINUE_WITH_INQUIRY_METHOD_TO_CALL);
199 return urlParameters;
200 }
201
202 protected String getInquiryUrl(Class inquiryBusinessObjectClass){
203 String riceBaseUrl = KNSServiceLocator.getKualiConfigurationService().getPropertyString(KNSConstants.APPLICATION_URL_KEY);
204 String inquiryUrl = riceBaseUrl;
205 if (!inquiryUrl.endsWith("/")) {
206 inquiryUrl = inquiryUrl + "/";
207 }
208 return inquiryUrl + "kr/" + KNSConstants.INQUIRY_ACTION;
209 }
210
211
212
213
214
215
216 public String getExternalizableBusinessObjectLookupUrl(Class inquiryBusinessObjectClass, Map<String, String> parameters) {
217 Properties urlParameters = new Properties();
218
219 String riceBaseUrl = KNSServiceLocator.getKualiConfigurationService().getPropertyString(KNSConstants.APPLICATION_URL_KEY);
220 String lookupUrl = riceBaseUrl;
221 if (!lookupUrl.endsWith("/")) {
222 lookupUrl = lookupUrl + "/";
223 }
224 if (parameters.containsKey(KNSConstants.MULTIPLE_VALUE)) {
225 lookupUrl = lookupUrl + "kr/" + KNSConstants.MULTIPLE_VALUE_LOOKUP_ACTION;
226 }
227 else {
228 lookupUrl = lookupUrl + "kr/" + KNSConstants.LOOKUP_ACTION;
229 }
230 for (String paramName : parameters.keySet()) {
231 urlParameters.put(paramName, parameters.get(paramName));
232 }
233
234 Class clazz = getExternalizableBusinessObjectImplementation(inquiryBusinessObjectClass);
235 urlParameters.put(KNSConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, clazz==null?"":clazz.getName());
236
237 return UrlFactory.parameterizeUrl(lookupUrl, urlParameters);
238 }
239
240
241
242
243
244
245
246
247 public <T extends ExternalizableBusinessObject> T retrieveExternalizableBusinessObjectIfNecessary(
248 BusinessObject businessObject, T currentInstanceExternalizableBO, String externalizableRelationshipName) {
249
250 if(businessObject==null) return null;
251 Class clazz;
252 try{
253 clazz = getExternalizableBusinessObjectImplementation(
254 PropertyUtils.getPropertyType(businessObject, externalizableRelationshipName));
255 } catch(Exception iex){
256 LOG.warn("Exception:"+iex+" thrown while trying to get property type for property:"+externalizableRelationshipName+
257 " from business object:"+businessObject);
258 return null;
259 }
260
261
262
263 BusinessObjectEntry entry =
264 KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(
265 businessObject.getClass().getSimpleName());
266 RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
267 List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions = relationshipDefinition.getPrimitiveAttributes();
268
269 Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
270 Object sourcePropertyValue;
271 Object targetPropertyValue = null;
272 boolean sourceTargetPropertyValuesSame = true;
273 for(PrimitiveAttributeDefinition primitiveAttributeDefinition: primitiveAttributeDefinitions){
274 sourcePropertyValue = ObjectUtils.getPropertyValue(
275 businessObject, primitiveAttributeDefinition.getSourceName());
276 if(currentInstanceExternalizableBO!=null)
277 targetPropertyValue = ObjectUtils.getPropertyValue(currentInstanceExternalizableBO, primitiveAttributeDefinition.getTargetName());
278 if(sourcePropertyValue==null){
279 return null;
280 } else if(targetPropertyValue==null || (targetPropertyValue!=null && !targetPropertyValue.equals(sourcePropertyValue))){
281 sourceTargetPropertyValuesSame = false;
282 }
283 fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
284 }
285
286 if(!sourceTargetPropertyValuesSame)
287 return (T) getExternalizableBusinessObject(clazz, fieldValuesInEBO);
288 return currentInstanceExternalizableBO;
289 }
290
291
292
293
294
295
296
297
298 public List<? extends ExternalizableBusinessObject> retrieveExternalizableBusinessObjectsList(
299 BusinessObject businessObject, String externalizableRelationshipName, Class externalizableClazz) {
300
301 if(businessObject==null) return null;
302
303
304 String className = businessObject.getClass().getName();
305 String key = className.substring(className.lastIndexOf(".")+1);
306 BusinessObjectEntry entry =
307 KNSServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getBusinessObjectEntries().get(key);
308 RelationshipDefinition relationshipDefinition = entry.getRelationshipDefinition(externalizableRelationshipName);
309 List<PrimitiveAttributeDefinition> primitiveAttributeDefinitions = relationshipDefinition.getPrimitiveAttributes();
310 Map<String, Object> fieldValuesInEBO = new HashMap<String, Object>();
311 Object sourcePropertyValue;
312 for(PrimitiveAttributeDefinition primitiveAttributeDefinition: primitiveAttributeDefinitions){
313 sourcePropertyValue = ObjectUtils.getPropertyValue(
314 businessObject, primitiveAttributeDefinition.getSourceName());
315 if(sourcePropertyValue==null){
316 return null;
317 }
318 fieldValuesInEBO.put(primitiveAttributeDefinition.getTargetName(), sourcePropertyValue);
319 }
320 return getExternalizableBusinessObjectsList(
321 getExternalizableBusinessObjectImplementation(externalizableClazz), fieldValuesInEBO);
322 }
323
324
325
326
327 public <E extends ExternalizableBusinessObject> Class<E> getExternalizableBusinessObjectImplementation(Class<E> externalizableBusinessObjectInterface) {
328 if (getModuleConfiguration() == null) {
329 throw new IllegalStateException("Module configuration has not been initialized for the module service.");
330 }
331 int classModifiers = externalizableBusinessObjectInterface.getModifiers();
332 if (!Modifier.isInterface(classModifiers) && !Modifier.isAbstract(classModifiers)) {
333
334 return externalizableBusinessObjectInterface;
335 }
336 if (getModuleConfiguration().getExternalizableBusinessObjectImplementations() == null) {
337 return null;
338 }
339 else {
340 Class<E> implementationClass = getModuleConfiguration().getExternalizableBusinessObjectImplementations().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 = KNSServiceLocatorWeb.getKualiModuleService();
358 if ( kualiModuleService == null ) {
359 kualiModuleService = ((KualiModuleService)applicationContext.getBean( KNSServiceLocatorWeb.KUALI_MODULE_SERVICE ));
360 }
361 } catch ( NoSuchBeanDefinitionException ex ) {
362 kualiModuleService = ((KualiModuleService)applicationContext.getBean( KNSServiceLocatorWeb.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 BusinessObjectRelationship getBusinessObjectRelationship(Class boClass, String attributeName, String attributePrefix){
406 return null;
407 }
408
409
410
411 public BusinessObjectDictionaryService getBusinessObjectDictionaryService () {
412 if ( businessObjectDictionaryService == null ) {
413 businessObjectDictionaryService = KNSServiceLocatorWeb.getBusinessObjectDictionaryService();
414 }
415 return businessObjectDictionaryService;
416 }
417
418
419
420
421 public BusinessObjectService getBusinessObjectService() {
422 if ( businessObjectService == null ) {
423 businessObjectService = KNSServiceLocator.getBusinessObjectService();
424 }
425 return businessObjectService;
426 }
427
428
429
430
431
432 protected LookupService getLookupService() {
433 return lookupService != null ? lookupService : KNSServiceLocatorWeb.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