1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.service.impl;
17
18 import java.util.ArrayList;
19 import java.util.Collection;
20 import java.util.HashMap;
21 import java.util.Iterator;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Map.Entry;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.log4j.Logger;
28 import org.kuali.rice.core.util.RiceDebugUtils;
29 import org.kuali.rice.kew.service.KEWServiceLocator;
30 import org.kuali.rice.kim.bo.Role;
31 import org.kuali.rice.kim.bo.impl.KimAttributes;
32 import org.kuali.rice.kim.bo.impl.ResponsibilityImpl;
33 import org.kuali.rice.kim.bo.role.dto.KimResponsibilityInfo;
34 import org.kuali.rice.kim.bo.role.dto.KimResponsibilityTemplateInfo;
35 import org.kuali.rice.kim.bo.role.dto.ResponsibilityActionInfo;
36 import org.kuali.rice.kim.bo.role.dto.RoleMembershipInfo;
37 import org.kuali.rice.kim.bo.role.impl.KimResponsibilityImpl;
38 import org.kuali.rice.kim.bo.role.impl.KimResponsibilityTemplateImpl;
39 import org.kuali.rice.kim.bo.role.impl.ResponsibilityAttributeDataImpl;
40 import org.kuali.rice.kim.bo.role.impl.RoleMemberAttributeDataImpl;
41 import org.kuali.rice.kim.bo.role.impl.RoleResponsibilityActionImpl;
42 import org.kuali.rice.kim.bo.role.impl.RoleResponsibilityImpl;
43 import org.kuali.rice.kim.bo.types.dto.AttributeSet;
44 import org.kuali.rice.kim.bo.types.dto.KimTypeAttributeInfo;
45 import org.kuali.rice.kim.dao.KimResponsibilityDao;
46 import org.kuali.rice.kim.service.KIMServiceLocator;
47 import org.kuali.rice.kim.service.ResponsibilityService;
48 import org.kuali.rice.kim.service.ResponsibilityUpdateService;
49 import org.kuali.rice.kim.service.RoleService;
50 import org.kuali.rice.kim.service.support.KimResponsibilityTypeService;
51 import org.kuali.rice.kim.util.KimConstants;
52 import org.kuali.rice.kns.lookup.CollectionIncomplete;
53 import org.kuali.rice.kns.lookup.Lookupable;
54 import org.kuali.rice.kns.service.BusinessObjectService;
55 import org.kuali.rice.kns.service.KNSServiceLocator;
56 import org.kuali.rice.kns.service.SequenceAccessorService;
57 import org.kuali.rice.kns.util.KNSPropertyConstants;
58 import org.kuali.rice.ksb.cache.RiceCacheAdministrator;
59
60
61
62
63
64
65
66 public class ResponsibilityServiceImpl extends ResponsibilityServiceBase implements ResponsibilityService {
67 private static final Logger LOG = Logger.getLogger( ResponsibilityServiceImpl.class );
68 private RoleService roleService;
69 private KimResponsibilityDao responsibilityDao;
70 private KimResponsibilityTypeService responsibilityTypeService;
71
72
73
74
75
76
77
78
79
80 public KimResponsibilityInfo getResponsibility(String responsibilityId) {
81 KimResponsibilityImpl impl = getResponsibilityImpl( responsibilityId );
82 if ( impl != null ) {
83 return impl.toSimpleInfo();
84 }
85 return null;
86 }
87
88
89
90
91 public List<KimResponsibilityInfo> getResponsibilitiesByName( String namespaceCode, String responsibilityName) {
92 List<KimResponsibilityImpl> impls = getResponsibilityImplsByName( namespaceCode, responsibilityName );
93 List<KimResponsibilityInfo> results = new ArrayList<KimResponsibilityInfo>( impls.size() );
94 for ( KimResponsibilityImpl impl : impls ) {
95 results.add( impl.toSimpleInfo() );
96 }
97 return results;
98 }
99
100 public KimResponsibilityImpl getResponsibilityImpl(String responsibilityId) {
101 if ( StringUtils.isBlank( responsibilityId ) ) {
102 return null;
103 }
104 HashMap<String,Object> pk = new HashMap<String,Object>( 1 );
105 pk.put( KimConstants.PrimaryKeyConstants.RESPONSIBILITY_ID, responsibilityId );
106 return (KimResponsibilityImpl)getBusinessObjectService().findByPrimaryKey( KimResponsibilityImpl.class, pk );
107 }
108
109 public KimResponsibilityTemplateInfo getResponsibilityTemplate(
110 String responsibilityTemplateId) {
111 KimResponsibilityTemplateImpl impl = getResponsibilityTemplateImpl(responsibilityTemplateId);
112 if ( impl != null ) {
113 return impl.toInfo();
114 }
115 return null;
116 }
117
118 public KimResponsibilityTemplateInfo getResponsibilityTemplateByName(
119 String namespaceCode, String responsibilityTemplateName) {
120 KimResponsibilityTemplateImpl impl = getResponsibilityTemplateImplsByName(namespaceCode, responsibilityTemplateName);
121 if ( impl != null ) {
122 return impl.toInfo();
123 }
124 return null;
125 }
126
127 public KimResponsibilityTemplateImpl getResponsibilityTemplateImpl(
128 String responsibilityTemplateId) {
129 return (KimResponsibilityTemplateImpl)getBusinessObjectService().findBySinglePrimaryKey(KimResponsibilityTemplateImpl.class, responsibilityTemplateId);
130 }
131
132 public KimResponsibilityTemplateImpl getResponsibilityTemplateImplsByName(
133 String namespaceCode, String responsibilityTemplateName) {
134 HashMap<String,Object> pk = new HashMap<String,Object>( 3 );
135 pk.put( KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
136 pk.put( KimConstants.UniqueKeyConstants.RESPONSIBILITY_TEMPLATE_NAME, responsibilityTemplateName );
137 pk.put( KNSPropertyConstants.ACTIVE, "Y");
138 return (KimResponsibilityTemplateImpl)getBusinessObjectService().findByPrimaryKey( KimResponsibilityTemplateImpl.class, pk );
139 }
140
141 public RoleResponsibilityImpl getRoleResponsibilityImpl(String roleResponsibilityId) {
142 if ( StringUtils.isBlank( roleResponsibilityId ) ) {
143 return null;
144 }
145 HashMap<String,Object> pk = new HashMap<String,Object>( 1 );
146 pk.put( KimConstants.PrimaryKeyConstants.ROLE_RESPONSIBILITY_ID, roleResponsibilityId );
147 return (RoleResponsibilityImpl)getBusinessObjectService().findByPrimaryKey( RoleResponsibilityImpl.class, pk );
148 }
149
150
151 @SuppressWarnings("unchecked")
152 protected List<KimResponsibilityImpl> getResponsibilityImplsByName( String namespaceCode, String responsibilityName ) {
153 HashMap<String,Object> pk = new HashMap<String,Object>( 3 );
154 pk.put( KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
155 pk.put( KimConstants.UniqueKeyConstants.RESPONSIBILITY_NAME, responsibilityName );
156 pk.put( KNSPropertyConstants.ACTIVE, "Y");
157 return (List<KimResponsibilityImpl>)getBusinessObjectService().findMatching( KimResponsibilityImpl.class, pk );
158 }
159
160 @SuppressWarnings("unchecked")
161 protected List<KimResponsibilityImpl> getResponsibilityImplsByTemplateName( String namespaceCode, String responsibilityTemplateName ) {
162 String cacheKey = getResponsibilityImplByTemplateNameCacheKey(namespaceCode, responsibilityTemplateName);
163 List<KimResponsibilityImpl> result = (List<KimResponsibilityImpl>)getCacheAdministrator().getFromCache(cacheKey);
164 if ( result == null ) {
165 HashMap<String,Object> pk = new HashMap<String,Object>( 4 );
166 pk.put( "template."+KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode );
167 pk.put( "template."+KimConstants.UniqueKeyConstants.RESPONSIBILITY_TEMPLATE_NAME, responsibilityTemplateName );
168 pk.put( "template."+KNSPropertyConstants.ACTIVE, "Y");
169 pk.put( KNSPropertyConstants.ACTIVE, "Y");
170 result = (List<KimResponsibilityImpl>)getBusinessObjectService().findMatching( KimResponsibilityImpl.class, pk );
171 getCacheAdministrator().putInCache(cacheKey, result, RESPONSIBILITY_IMPL_CACHE_GROUP);
172 }
173 return result;
174 }
175
176
177
178
179
180
181 public boolean hasResponsibility(String principalId, String namespaceCode,
182 String responsibilityName, AttributeSet qualification,
183 AttributeSet responsibilityDetails) {
184
185 List<KimResponsibilityImpl> responsibilities = getResponsibilityImplsByName( namespaceCode, responsibilityName );
186
187 List<KimResponsibilityInfo> applicableResponsibilities = getMatchingResponsibilities( responsibilities, responsibilityDetails );
188 List<String> roleIds = getRoleIdsForResponsibilities( applicableResponsibilities, qualification );
189 return getRoleService().principalHasRole( principalId, roleIds, qualification );
190 }
191
192
193
194
195
196
197 public boolean hasResponsibilityByTemplateName(String principalId,
198 String namespaceCode, String responsibilityTemplateName,
199 AttributeSet qualification, AttributeSet responsibilityDetails) {
200
201 List<KimResponsibilityImpl> responsibilities = getResponsibilityImplsByTemplateName( namespaceCode, responsibilityTemplateName );
202
203 List<KimResponsibilityInfo> applicableResponsibilities = getMatchingResponsibilities( responsibilities, responsibilityDetails );
204 List<String> roleIds = getRoleIdsForResponsibilities( applicableResponsibilities, qualification );
205 return getRoleService().principalHasRole( principalId, roleIds, qualification );
206 }
207
208
209
210
211 public List<ResponsibilityActionInfo> getResponsibilityActions( String namespaceCode, String responsibilityName,
212 AttributeSet qualification, AttributeSet responsibilityDetails) {
213
214 List<KimResponsibilityImpl> responsibilities = getResponsibilityImplsByName( namespaceCode, responsibilityName );
215
216 List<KimResponsibilityInfo> applicableResponsibilities = getMatchingResponsibilities( responsibilities, responsibilityDetails );
217 List<ResponsibilityActionInfo> results = new ArrayList<ResponsibilityActionInfo>();
218 for ( KimResponsibilityInfo r : applicableResponsibilities ) {
219 List<String> roleIds = getRoleIdsForResponsibility( r, qualification );
220 results.addAll( getActionsForResponsibilityRoles( r, roleIds, qualification) );
221 }
222 return results;
223 }
224
225 protected void logResponsibilityCheck(String namespaceCode, String responsibilityName, AttributeSet responsibilityDetails, AttributeSet qualification ) {
226 StringBuilder sb = new StringBuilder();
227 sb.append( '\n' );
228 sb.append( "Get Resp Actions: " ).append( namespaceCode ).append( "/" ).append( responsibilityName ).append( '\n' );
229 sb.append( " Details:\n" );
230 if ( responsibilityDetails != null ) {
231 sb.append( responsibilityDetails.formattedDump( 25 ) );
232 } else {
233 sb.append( " [null]\n" );
234 }
235 sb.append( " Qualifiers:\n" );
236 if ( qualification != null ) {
237 sb.append( qualification.formattedDump( 25 ) );
238 } else {
239 sb.append( " [null]\n" );
240 }
241 if (LOG.isTraceEnabled()) {
242 LOG.trace( sb.append( RiceDebugUtils.getTruncatedStackTrace(true)).toString() );
243 } else {
244 LOG.debug(sb.toString());
245 }
246 }
247
248
249
250
251 public List<ResponsibilityActionInfo> getResponsibilityActionsByTemplateName( String namespaceCode, String responsibilityTemplateName,
252 AttributeSet qualification, AttributeSet responsibilityDetails) {
253 if ( LOG.isDebugEnabled() ) {
254 logResponsibilityCheck( namespaceCode, responsibilityTemplateName, responsibilityDetails, qualification );
255 }
256
257 List<KimResponsibilityImpl> responsibilities = getResponsibilityImplsByTemplateName( namespaceCode, responsibilityTemplateName );
258
259 List<KimResponsibilityInfo> applicableResponsibilities = getMatchingResponsibilities( responsibilities, responsibilityDetails );
260 List<ResponsibilityActionInfo> results = new ArrayList<ResponsibilityActionInfo>();
261 for ( KimResponsibilityInfo r : applicableResponsibilities ) {
262 List<String> roleIds = getRoleIdsForResponsibility( r, qualification );
263 results.addAll( getActionsForResponsibilityRoles( r, roleIds, qualification) );
264 }
265 if ( LOG.isDebugEnabled() ) {
266 LOG.debug("Found " + results.size() + " matching ResponsibilityActionInfo objects");
267 if ( LOG.isTraceEnabled() ) {
268 LOG.trace( results );
269 }
270 }
271 return results;
272 }
273
274 protected List<ResponsibilityActionInfo> getActionsForResponsibilityRoles( KimResponsibilityInfo responsibility, List<String> roleIds, AttributeSet qualification ) {
275 List<ResponsibilityActionInfo> results = new ArrayList<ResponsibilityActionInfo>();
276 Collection<RoleMembershipInfo> roleMembers = getRoleService().getRoleMembers( roleIds, qualification );
277 for ( RoleMembershipInfo rm : roleMembers ) {
278
279 if ( StringUtils.isNotBlank( rm.getMemberId() ) ) {
280 ResponsibilityActionInfo rai;
281 if ( rm.getMemberTypeCode().equals( Role.PRINCIPAL_MEMBER_TYPE ) ) {
282 rai = new ResponsibilityActionInfo( rm.getMemberId(), null, rm.getEmbeddedRoleId(), responsibility, rm.getRoleId(), rm.getQualifier(), rm.getDelegates() );
283 } else {
284 rai = new ResponsibilityActionInfo( null, rm.getMemberId(), rm.getEmbeddedRoleId(), responsibility, rm.getRoleId(), rm.getQualifier(), rm.getDelegates() );
285 }
286
287 RoleResponsibilityActionImpl action = responsibilityDao.getResponsibilityAction( rm.getRoleId(), responsibility.getResponsibilityId(), rm.getRoleMemberId() );
288 if ( action == null ) {
289 LOG.error( "Unable to get responsibility action record for role/responsibility/roleMember: "
290 + rm.getRoleId() + "/" + responsibility.getResponsibilityId() + "/" + rm.getRoleMemberId() );
291 LOG.error( "Skipping this role member in getActionsForResponsibilityRoles()");
292 continue;
293 }
294
295 rai.setActionTypeCode( action.getActionTypeCode() );
296 rai.setActionPolicyCode( action.getActionPolicyCode() );
297 rai.setPriorityNumber(action.getPriorityNumber() == null ? DEFAULT_PRIORITY_NUMBER : action.getPriorityNumber());
298 rai.setForceAction( action.isForceAction() );
299 rai.setParallelRoutingGroupingCode( (rm.getRoleSortingCode()==null)?"":rm.getRoleSortingCode() );
300 rai.setRoleResponsibilityActionId( action.getRoleResponsibilityActionId() );
301 results.add( rai );
302 }
303 }
304 return results;
305 }
306
307
308 protected Map<String,KimResponsibilityTypeService> getResponsibilityTypeServicesByTemplateId(Collection<KimResponsibilityImpl> responsibilities) {
309 Map<String,KimResponsibilityTypeService> responsibilityTypeServices = new HashMap<String, KimResponsibilityTypeService>(responsibilities.size());
310 for ( KimResponsibilityImpl responsibility : responsibilities ) {
311 String serviceName = responsibility.getTemplate().getKimType().getKimTypeServiceName();
312 if ( serviceName != null ) {
313 KimResponsibilityTypeService responsibiltyTypeService = (KimResponsibilityTypeService)KIMServiceLocator.getService(serviceName);
314 if ( responsibiltyTypeService != null ) {
315 responsibilityTypeServices.put(responsibility.getTemplateId(), responsibiltyTypeService);
316 } else {
317 responsibilityTypeServices.put(responsibility.getTemplateId(), getDefaultResponsibilityTypeService());
318 }
319 }
320 }
321 return responsibilityTypeServices;
322 }
323
324 protected Map<String,List<KimResponsibilityInfo>> groupResponsibilitiesByTemplate(Collection<KimResponsibilityImpl> responsibilities) {
325 Map<String,List<KimResponsibilityInfo>> results = new HashMap<String,List<KimResponsibilityInfo>>();
326 for (KimResponsibilityImpl responsibility : responsibilities) {
327 List<KimResponsibilityInfo> responsibilityInfos = results.get( responsibility.getTemplateId() );
328 if ( responsibilityInfos == null ) {
329 responsibilityInfos = new ArrayList<KimResponsibilityInfo>();
330 results.put( responsibility.getTemplateId(), responsibilityInfos );
331 }
332 responsibilityInfos.add(responsibility.toSimpleInfo());
333 }
334 return results;
335 }
336
337
338
339
340
341 protected List<KimResponsibilityInfo> getMatchingResponsibilities( List<KimResponsibilityImpl> responsibilities, AttributeSet responsibilityDetails ) {
342 List<KimResponsibilityInfo> applicableResponsibilities = new ArrayList<KimResponsibilityInfo>();
343 if ( responsibilityDetails == null || responsibilityDetails.isEmpty() ) {
344
345 for ( KimResponsibilityImpl responsibility : responsibilities ) {
346 applicableResponsibilities.add(responsibility.toSimpleInfo());
347 }
348 } else {
349
350
351 Map<String,KimResponsibilityTypeService> responsibilityTypeServices = getResponsibilityTypeServicesByTemplateId(responsibilities);
352
353 Map<String,List<KimResponsibilityInfo>> responsibilityMap = groupResponsibilitiesByTemplate(responsibilities);
354
355
356 for ( Entry<String,List<KimResponsibilityInfo>> respEntry : responsibilityMap.entrySet() ) {
357 KimResponsibilityTypeService responsibilityTypeService = responsibilityTypeServices.get( respEntry.getKey() );
358 List<KimResponsibilityInfo> responsibilityInfos = respEntry.getValue();
359 if (responsibilityTypeService == null) {
360 responsibilityTypeService = getDefaultResponsibilityTypeService();
361 }
362 applicableResponsibilities.addAll(responsibilityTypeService.getMatchingResponsibilities(responsibilityDetails, responsibilityInfos));
363 }
364 }
365 return applicableResponsibilities;
366 }
367
368 protected List<String> getRoleIdsForResponsibilities( List<KimResponsibilityInfo> responsibilities, AttributeSet qualification ) {
369
370 return responsibilityDao.getRoleIdsForResponsibilities( responsibilities );
371 }
372
373 public List<String> getRoleIdsForResponsibility( KimResponsibilityInfo responsibility, AttributeSet qualification ) {
374
375 return responsibilityDao.getRoleIdsForResponsibility( responsibility );
376 }
377
378 protected boolean areActionsAtAssignmentLevel( KimResponsibilityImpl responsibility ) {
379 AttributeSet details = responsibility.getDetails();
380 if ( details == null ) {
381 return false;
382 }
383 String actionDetailsAtRoleMemberLevel = details.get( KimAttributes.ACTION_DETAILS_AT_ROLE_MEMBER_LEVEL );
384 return Boolean.valueOf(actionDetailsAtRoleMemberLevel);
385 }
386
387
388
389
390 public boolean areActionsAtAssignmentLevel( KimResponsibilityInfo responsibility ) {
391 AttributeSet details = responsibility.getDetails();
392 if ( details == null ) {
393 return false;
394 }
395 String actionDetailsAtRoleMemberLevel = details.get( KimAttributes.ACTION_DETAILS_AT_ROLE_MEMBER_LEVEL );
396 return Boolean.valueOf(actionDetailsAtRoleMemberLevel);
397 }
398
399
400
401
402 public boolean areActionsAtAssignmentLevelById( String responsibilityId ) {
403 KimResponsibilityImpl responsibility = getResponsibilityImpl(responsibilityId);
404 if ( responsibility == null ) {
405 return false;
406 }
407 return areActionsAtAssignmentLevel(responsibility);
408 }
409
410 @SuppressWarnings("unchecked")
411 public List<? extends KimResponsibilityInfo> lookupResponsibilityInfo( Map<String,String> searchCriteria, boolean unbounded ) {
412 Collection baseResults = null;
413 Lookupable responsibilityLookupable = KNSServiceLocator.getLookupable(
414 KNSServiceLocator.getBusinessObjectDictionaryService().getLookupableID(ResponsibilityImpl.class)
415 );
416 responsibilityLookupable.setBusinessObjectClass(ResponsibilityImpl.class);
417 if ( unbounded ) {
418 baseResults = responsibilityLookupable.getSearchResultsUnbounded( searchCriteria );
419 } else {
420 baseResults = responsibilityLookupable.getSearchResults(searchCriteria);
421 }
422 List<KimResponsibilityInfo> results = new ArrayList<KimResponsibilityInfo>( baseResults.size() );
423 for ( ResponsibilityImpl resp : (Collection<ResponsibilityImpl>)baseResults ) {
424 results.add( resp.toSimpleInfo() );
425 }
426 if ( baseResults instanceof CollectionIncomplete ) {
427 results = new CollectionIncomplete<KimResponsibilityInfo>( results, ((CollectionIncomplete<KimResponsibilityInfo>)baseResults).getActualSizeIfTruncated() );
428 }
429 return results;
430
431 }
432
433
434
435
436
437
438
439
440
441
442
443
444
445 protected RoleService getRoleService() {
446 if ( roleService == null ) {
447 roleService = KIMServiceLocator.getRoleManagementService();
448 }
449
450 return roleService;
451 }
452
453 public void setRoleService(RoleService roleService) {
454 this.roleService = roleService;
455 }
456
457 public KimResponsibilityDao getResponsibilityDao() {
458 return this.responsibilityDao;
459 }
460
461 public void setResponsibilityDao(KimResponsibilityDao responsibilityDao) {
462 this.responsibilityDao = responsibilityDao;
463 }
464
465 protected KimResponsibilityTypeService getDefaultResponsibilityTypeService() {
466 if (responsibilityTypeService == null) {
467 responsibilityTypeService = (KimResponsibilityTypeService)KIMServiceLocator.getBean(DEFAULT_RESPONSIBILITY_TYPE_SERVICE);
468 }
469 return responsibilityTypeService;
470 }
471
472
473
474
475 }