View Javadoc
1   /**
2    * Copyright 2005-2016 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kim.impl.responsibility;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.apache.commons.lang.exception.ExceptionUtils;
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.kuali.rice.core.api.criteria.CriteriaLookupService;
23  import org.kuali.rice.core.api.criteria.GenericQueryResults;
24  import org.kuali.rice.core.api.criteria.LookupCustomizer;
25  import org.kuali.rice.core.api.criteria.Predicate;
26  import org.kuali.rice.core.api.criteria.QueryByCriteria;
27  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
28  import org.kuali.rice.core.api.exception.RiceIllegalStateException;
29  import org.kuali.rice.core.api.membership.MemberType;
30  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
31  import org.kuali.rice.kim.api.common.delegate.DelegateType;
32  import org.kuali.rice.kim.api.common.template.Template;
33  import org.kuali.rice.kim.api.common.template.TemplateQueryResults;
34  import org.kuali.rice.kim.api.responsibility.Responsibility;
35  import org.kuali.rice.kim.api.responsibility.ResponsibilityAction;
36  import org.kuali.rice.kim.api.responsibility.ResponsibilityQueryResults;
37  import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
38  import org.kuali.rice.kim.api.role.RoleMembership;
39  import org.kuali.rice.kim.api.role.RoleResponsibilityAction;
40  import org.kuali.rice.kim.api.role.RoleService;
41  import org.kuali.rice.kim.api.type.KimType;
42  import org.kuali.rice.kim.api.type.KimTypeInfoService;
43  import org.kuali.rice.kim.framework.responsibility.ResponsibilityTypeService;
44  import org.kuali.rice.kim.impl.KIMPropertyConstants;
45  import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
46  import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
47  import org.kuali.rice.kim.impl.role.RoleResponsibilityActionBo;
48  import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
49  import org.kuali.rice.krad.service.BusinessObjectService;
50  import org.springframework.util.CollectionUtils;
51  
52  import javax.xml.namespace.QName;
53  import java.util.ArrayList;
54  import java.util.Collection;
55  import java.util.Collections;
56  import java.util.HashMap;
57  import java.util.Iterator;
58  import java.util.List;
59  import java.util.Map;
60  
61  import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
62  
63  public class ResponsibilityServiceImpl implements ResponsibilityService {
64  
65      private static final Integer DEFAULT_PRIORITY_NUMBER = Integer.valueOf(1);
66      private static final Log LOG = LogFactory.getLog(ResponsibilityServiceImpl.class);
67  
68      private BusinessObjectService businessObjectService;
69      private CriteriaLookupService criteriaLookupService;
70      private ResponsibilityTypeService defaultResponsibilityTypeService;
71      private KimTypeInfoService kimTypeInfoService;
72      private RoleService roleService;
73  
74      @Override
75      public Responsibility createResponsibility(final Responsibility responsibility)
76              throws RiceIllegalArgumentException, RiceIllegalStateException {
77          incomingParamCheck(responsibility, "responsibility");
78  
79          if (StringUtils.isNotBlank(responsibility.getId()) && getResponsibility(responsibility.getId()) != null) {
80              throw new RiceIllegalStateException("the responsibility to create already exists: " + responsibility);
81          }
82          List<ResponsibilityAttributeBo> attrBos = Collections.emptyList();
83          if (responsibility.getTemplate() != null) {
84              attrBos = KimAttributeDataBo.createFrom(ResponsibilityAttributeBo.class, responsibility.getAttributes(), responsibility.getTemplate().getKimTypeId());
85          }
86          ResponsibilityBo bo = ResponsibilityBo.from(responsibility);
87          bo.setAttributeDetails(attrBos);
88          return ResponsibilityBo.to(businessObjectService.save(bo));
89      }
90  
91      @Override
92      public Responsibility updateResponsibility(final Responsibility responsibility)
93              throws RiceIllegalArgumentException, RiceIllegalStateException {
94          incomingParamCheck(responsibility, "responsibility");
95  
96          if (StringUtils.isBlank(responsibility.getId()) || getResponsibility(responsibility.getId()) == null) {
97              throw new RiceIllegalStateException("the responsibility does not exist: " + responsibility);
98          }
99  
100        List<ResponsibilityAttributeBo> attrBos = Collections.emptyList();
101         if (responsibility.getTemplate() != null) {
102             attrBos = KimAttributeDataBo.createFrom(ResponsibilityAttributeBo.class, responsibility.getAttributes(), responsibility.getTemplate().getKimTypeId());
103         }
104         ResponsibilityBo bo = ResponsibilityBo.from(responsibility);
105 
106         if (bo.getAttributeDetails() != null) {
107             bo.getAttributeDetails().clear();
108             bo.setAttributeDetails(attrBos);
109         }
110 
111         return ResponsibilityBo.to(businessObjectService.save(bo));
112     }
113 
114     @Override
115     public Responsibility getResponsibility(final String id) throws RiceIllegalArgumentException {
116         incomingParamCheck(id, "id");
117 
118         return ResponsibilityBo.to(businessObjectService.findBySinglePrimaryKey(ResponsibilityBo.class, id));
119     }
120 
121     @Override
122     public Responsibility findRespByNamespaceCodeAndName(final String namespaceCode, final String name)
123             throws RiceIllegalArgumentException {
124         incomingParamCheck(namespaceCode, "namespaceCode");
125         incomingParamCheck(name, "name");
126 
127         final Map<String, String> crit = new HashMap<String, String>();
128         crit.put("namespaceCode", namespaceCode);
129         crit.put("name", name);
130         crit.put("active", "Y");
131 
132         final Collection<ResponsibilityBo> bos = businessObjectService.findMatching(ResponsibilityBo.class, Collections.unmodifiableMap(crit));
133 
134         if (bos != null) {
135             if (bos.size() > 1) {
136                 throw new RiceIllegalStateException("more than one Responsibility found with namespace code: " + namespaceCode + " and name: " + name);
137             }
138 
139             final Iterator<ResponsibilityBo> i = bos.iterator();
140             return i.hasNext() ? ResponsibilityBo.to(i.next()) : null;
141         }
142         return null;
143     }
144 
145     @Override
146     public Template getResponsibilityTemplate(final String id) throws RiceIllegalArgumentException {
147         incomingParamCheck(id, "id");
148 
149         return ResponsibilityTemplateBo.to(businessObjectService.findBySinglePrimaryKey(ResponsibilityTemplateBo.class, id));
150     }
151 
152     @Override
153     public Template findRespTemplateByNamespaceCodeAndName(final String namespaceCode, final String name) throws RiceIllegalArgumentException {
154         incomingParamCheck(namespaceCode, "namespaceCode");
155         incomingParamCheck(name, "name");
156 
157         final Map<String, String> crit = new HashMap<String, String>();
158         crit.put("namespaceCode", namespaceCode);
159         crit.put("name", name);
160         crit.put("active", "Y");
161 
162         final Collection<ResponsibilityTemplateBo> bos = businessObjectService.findMatching(ResponsibilityTemplateBo.class, Collections.unmodifiableMap(crit));
163         if (bos != null) {
164             if (bos.size() > 1) {
165                 throw new RiceIllegalStateException("more than one Responsibility Template found with namespace code: " + namespaceCode + " and name: " + name);
166             }
167 
168             final Iterator<ResponsibilityTemplateBo> i = bos.iterator();
169             return i.hasNext() ? ResponsibilityTemplateBo.to(i.next()) : null;
170         }
171         return null;
172     }
173 
174     @Override
175     public boolean hasResponsibility(final String principalId, final String namespaceCode,
176             final String respName, final Map<String, String> qualification) throws RiceIllegalArgumentException {
177         incomingParamCheck(principalId, "principalId");
178         incomingParamCheck(namespaceCode, "namespaceCode");
179         incomingParamCheck(respName, "respName");
180         incomingParamCheck(qualification, "qualification");
181 
182         // get all the responsibility objects whose name match that requested
183         final List<Responsibility> responsibilities = Collections.singletonList(findRespByNamespaceCodeAndName(namespaceCode, respName));
184         return hasResp(principalId, namespaceCode, responsibilities, qualification, null);
185     }
186 
187     @Override
188     public boolean hasResponsibilityByTemplate(final String principalId, final String namespaceCode,
189             final String respTemplateName, final Map<String, String> qualification,
190             final Map<String, String> responsibilityDetails) throws RiceIllegalArgumentException {
191         incomingParamCheck(principalId, "principalId");
192         incomingParamCheck(namespaceCode, "namespaceCode");
193         incomingParamCheck(respTemplateName, "respTemplateName");
194         incomingParamCheck(qualification, "qualification");
195         incomingParamCheck(responsibilityDetails, "responsibilityDetails");
196 
197 
198         // get all the responsibility objects whose name match that requested
199         final List<Responsibility> responsibilities = findResponsibilitiesByTemplate(namespaceCode, respTemplateName);
200         return hasResp(principalId, namespaceCode, responsibilities, qualification, responsibilityDetails);
201     }
202 
203     private boolean hasResp(final String principalId, final String namespaceCode,
204             final List<Responsibility> responsibilities,
205             final Map<String, String> qualification,
206             final Map<String, String> responsibilityDetails) throws RiceIllegalArgumentException {
207         // now, filter the full list by the detail passed
208         final List<String> ids = new ArrayList<String>();
209         for (Responsibility r : getMatchingResponsibilities(responsibilities, responsibilityDetails)) {
210             ids.add(r.getId());
211         }
212         final List<String> roleIds = getRoleIdsForResponsibilities(ids);
213         return roleService.principalHasRole(principalId, roleIds, qualification);
214     }
215 
216     @Override
217     public List<ResponsibilityAction> getResponsibilityActions(final String namespaceCode,
218             final String responsibilityName, final Map<String, String> qualification) throws RiceIllegalArgumentException {
219         incomingParamCheck(namespaceCode, "namespaceCode");
220         incomingParamCheck(responsibilityName, "responsibilityName");
221         incomingParamCheck(qualification, "qualification");
222         
223         if ( LOG.isDebugEnabled() ) {
224             logResponsibilityCheck( namespaceCode, responsibilityName, qualification, Collections.<String, String>emptyMap() );
225         }
226 
227         // get all the responsibility objects whose name match that requested
228         List<Responsibility> responsibilities = Collections.singletonList(findRespByNamespaceCodeAndName(namespaceCode, responsibilityName));
229         return getRespActions(namespaceCode, responsibilities, qualification, null);
230     }
231 
232     @Override
233     public List<ResponsibilityAction> getResponsibilityActionsByTemplate(final String namespaceCode,
234             final String respTemplateName, final Map<String, String> qualification,
235             final Map<String, String> responsibilityDetails) throws RiceIllegalArgumentException {
236         incomingParamCheck(namespaceCode, "namespaceCode");
237         incomingParamCheck(respTemplateName, "respTemplateName");
238         incomingParamCheck(qualification, "qualification");
239         
240         if ( LOG.isDebugEnabled() ) {
241             logResponsibilityCheck( namespaceCode, respTemplateName, qualification, responsibilityDetails );
242         }
243 
244         // get all the responsibility objects whose name match that requested
245         List<Responsibility> responsibilities = findResponsibilitiesByTemplate(namespaceCode, respTemplateName);
246         return getRespActions(namespaceCode, responsibilities, qualification, responsibilityDetails);
247     }
248 
249     private List<ResponsibilityAction> getRespActions(final String namespaceCode,
250             final List<Responsibility> responsibilities,
251             final Map<String, String> qualification,
252             final Map<String, String> responsibilityDetails) {
253         // now, filter the full list by the detail passed
254         List<Responsibility> applicableResponsibilities = getMatchingResponsibilities(responsibilities, responsibilityDetails);
255         List<ResponsibilityAction> results = new ArrayList<ResponsibilityAction>();
256         for (Responsibility r : applicableResponsibilities) {
257             List<String> roleIds = getRoleIdsForResponsibility(r.getId());
258             results.addAll(getActionsForResponsibilityRoles(r, roleIds, qualification));
259         }
260         if ( LOG.isDebugEnabled() ) {
261             LOG.debug("Found " + results.size() + " matching ResponsibilityAction objects");
262             if ( LOG.isTraceEnabled() ) {
263                 LOG.trace( results );
264             }
265         }
266         return results;
267     }
268 
269     private List<ResponsibilityAction> getActionsForResponsibilityRoles(Responsibility responsibility, List<String> roleIds, Map<String, String> qualification) {
270         List<ResponsibilityAction> results = new ArrayList<ResponsibilityAction>();
271         Collection<RoleMembership> roleMembers = roleService.getRoleMembers(roleIds,qualification);
272         for (RoleMembership rm : roleMembers) {
273             // only add them to the list if the member ID has been populated
274             if (StringUtils.isNotBlank(rm.getMemberId())) {
275                 List<RoleResponsibilityAction> roleResponsibilityActions
276                         = getResponsibilityActions(rm.getRoleId(), responsibility.getId(), rm.getId());
277                 for (RoleResponsibilityAction roleResponsibilityAction : roleResponsibilityActions) {
278                     final ResponsibilityAction.Builder rai = ResponsibilityAction.Builder.create();
279                     rai.setMemberRoleId((rm.getEmbeddedRoleId() == null) ? rm.getRoleId() : rm.getEmbeddedRoleId());
280                     rai.setRoleId(rm.getRoleId());
281                     rai.setQualifier(rm.getQualifier());
282                     final List<DelegateType.Builder> bs = new ArrayList<DelegateType.Builder>();
283                     for (DelegateType d : rm.getDelegates()) {
284                         bs.add(DelegateType.Builder.create(d));
285                     }
286                     rai.setDelegates(bs);
287                     rai.setResponsibilityId(responsibility.getId());
288                     rai.setResponsibilityName(responsibility.getName());
289                     rai.setResponsibilityNamespaceCode(responsibility.getNamespaceCode());
290 
291                     if (MemberType.PRINCIPAL.equals(rm.getType())) {
292                         rai.setPrincipalId(rm.getMemberId());
293                     } else {
294                         rai.setGroupId(rm.getMemberId());
295                     }
296                     // add the data to the ResponsibilityActionInfo objects
297                     rai.setActionTypeCode(roleResponsibilityAction.getActionTypeCode());
298                     rai.setActionPolicyCode(roleResponsibilityAction.getActionPolicyCode());
299                     rai.setPriorityNumber(roleResponsibilityAction.getPriorityNumber() == null ? DEFAULT_PRIORITY_NUMBER : roleResponsibilityAction.getPriorityNumber());
300                     rai.setForceAction(roleResponsibilityAction.isForceAction());
301                     rai.setParallelRoutingGroupingCode((rm.getRoleSortingCode() == null) ? "" : rm.getRoleSortingCode());
302                     rai.setRoleResponsibilityActionId(roleResponsibilityAction.getId());
303                     results.add(rai.build());
304                 }
305             }
306         }
307         return Collections.unmodifiableList(results);
308     }
309 
310     private List<RoleResponsibilityAction> getResponsibilityActions(String roleId, String responsibilityId, String roleMemberId) {
311         List<RoleResponsibilityAction> responsibilityActions = new ArrayList<RoleResponsibilityAction>();
312 
313         // KULRICE-7459: Requisition, PO and its subtype documents are going to final status where they should not.
314         //
315         // need to do in 2 steps due to "*" wildcard convention in column data for role member id and role
316         // responsibility id.  Well, we could do in 1 step w/ straight SQL, but not w/ Criteria API due to the
317         // INNER JOIN automatically created between RoleResponsibility and RoleResponsibilityAction tables.
318 
319         final Predicate roleResponsibilityPredicate =
320                 and(
321                         equal("responsibilityId", responsibilityId),
322                         equal("roleId", roleId),
323                         equal("active", "Y")
324                 );
325 
326         // First get RoleResponsibilityBos
327         final QueryByCriteria.Builder roleResponsibilityQueryBuilder = QueryByCriteria.Builder.create();
328         roleResponsibilityQueryBuilder.setPredicates(roleResponsibilityPredicate);
329         final GenericQueryResults<RoleResponsibilityBo> roleResponsibilityResults =
330                 criteriaLookupService.lookup(RoleResponsibilityBo.class, roleResponsibilityQueryBuilder.build());
331         final List<RoleResponsibilityBo> roleResponsibilityBos = roleResponsibilityResults.getResults();
332 
333         if (!CollectionUtils.isEmpty(roleResponsibilityBos)) { // if there are any...
334             // Then query RoleResponsibilityActionBos based on them
335 
336             List<String> roleResponsibilityIds = new ArrayList<String>(roleResponsibilityBos.size());
337             for (RoleResponsibilityBo roleResponsibilityBo : roleResponsibilityBos) {
338                 roleResponsibilityIds.add(roleResponsibilityBo.getRoleResponsibilityId());
339             }
340 
341             final Predicate roleResponsibilityActionPredicate =
342                     or(
343                             and(
344                                     in("roleResponsibilityId", roleResponsibilityIds.toArray()),
345                                     or(
346                                             equal(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId),
347                                             equal(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, "*")
348                                     )
349                             ),
350                             and(
351                                     equal("roleResponsibilityId", "*"),
352                                     equal(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId)
353                             )
354                     );
355 
356             final QueryByCriteria.Builder roleResponsibilityActionQueryBuilder = QueryByCriteria.Builder.create();
357             roleResponsibilityActionQueryBuilder.setPredicates(roleResponsibilityActionPredicate);
358 
359             final GenericQueryResults<RoleResponsibilityActionBo> roleResponsibilityActionResults =
360                     criteriaLookupService.lookup(
361                             RoleResponsibilityActionBo.class, roleResponsibilityActionQueryBuilder.build()
362                     );
363 
364             final List<RoleResponsibilityActionBo> roleResponsibilityActionBos = roleResponsibilityActionResults.getResults();
365             for (RoleResponsibilityActionBo roleResponsibilityActionBo : roleResponsibilityActionBos) {
366                 responsibilityActions.add(RoleResponsibilityActionBo.to(roleResponsibilityActionBo));
367             };
368         }
369 
370         return Collections.unmodifiableList(responsibilityActions);
371     }
372 
373     @Override
374     public List<String> getRoleIdsForResponsibility(String id) throws RiceIllegalArgumentException {
375         incomingParamCheck(id, "id");
376 
377         final List<String> roleIds = getRoleIdsForPredicate(and(equal("responsibilityId", id), equal("active", "Y")));
378 
379         return Collections.unmodifiableList(roleIds);
380     }
381 
382     @Override
383     public ResponsibilityQueryResults findResponsibilities(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
384         incomingParamCheck(queryByCriteria, "queryByCriteria");
385 
386         LookupCustomizer.Builder<ResponsibilityBo> lc = LookupCustomizer.Builder.create();
387         lc.setPredicateTransform(AttributeTransform.getInstance());
388 
389         GenericQueryResults<ResponsibilityBo> results = criteriaLookupService.lookup(ResponsibilityBo.class, queryByCriteria, lc.build());
390 
391         ResponsibilityQueryResults.Builder builder = ResponsibilityQueryResults.Builder.create();
392         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
393         builder.setTotalRowCount(results.getTotalRowCount());
394 
395         final List<Responsibility.Builder> ims = new ArrayList<Responsibility.Builder>();
396         for (ResponsibilityBo bo : results.getResults()) {
397             ims.add(Responsibility.Builder.create(bo));
398         }
399 
400         builder.setResults(ims);
401         return builder.build();
402     }
403 
404     @Override
405     public TemplateQueryResults findResponsibilityTemplates(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
406         incomingParamCheck(queryByCriteria, "queryByCriteria");
407 
408         GenericQueryResults<ResponsibilityTemplateBo> results = criteriaLookupService.lookup(ResponsibilityTemplateBo.class, queryByCriteria);
409 
410         TemplateQueryResults.Builder builder = TemplateQueryResults.Builder.create();
411         builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
412         builder.setTotalRowCount(results.getTotalRowCount());
413 
414         final List<Template.Builder> ims = new ArrayList<Template.Builder>();
415         for (ResponsibilityTemplateBo bo : results.getResults()) {
416             ims.add(Template.Builder.create(bo));
417         }
418 
419         builder.setResults(ims);
420         return builder.build();
421     }
422 
423     /**
424      * Compare each of the passed in responsibilities with the given responsibilityDetails.  Those that
425      * match are added to the result list.
426      */
427     private List<Responsibility> getMatchingResponsibilities(List<Responsibility> responsibilities, Map<String, String> responsibilityDetails) {
428         // if no details passed, assume that all match
429         if (responsibilityDetails == null || responsibilityDetails.isEmpty()) {
430             return responsibilities;
431         }
432 
433         final List<Responsibility> applicableResponsibilities = new ArrayList<Responsibility>();
434         // otherwise, attempt to match the permission details
435         // build a map of the template IDs to the type services
436         Map<String, ResponsibilityTypeService> responsibilityTypeServices = getResponsibilityTypeServicesByTemplateId(responsibilities);
437         // build a map of permissions by template ID
438         Map<String, List<Responsibility>> responsibilityMap = groupResponsibilitiesByTemplate(responsibilities);
439         // loop over the different templates, matching all of the same template against the type
440         // service at once
441         for (Map.Entry<String, List<Responsibility>> respEntry : responsibilityMap.entrySet()) {
442             ResponsibilityTypeService responsibilityTypeService = responsibilityTypeServices.get(respEntry.getKey());
443             List<Responsibility> responsibilityInfos = respEntry.getValue();
444             if (responsibilityTypeService == null) {
445                 responsibilityTypeService = defaultResponsibilityTypeService;
446             }
447             applicableResponsibilities.addAll(responsibilityTypeService.getMatchingResponsibilities(responsibilityDetails, responsibilityInfos));
448         }
449         return Collections.unmodifiableList(applicableResponsibilities);
450     }
451 
452     private Map<String, ResponsibilityTypeService> getResponsibilityTypeServicesByTemplateId(Collection<Responsibility> responsibilities) {
453         Map<String, ResponsibilityTypeService> responsibilityTypeServices = new HashMap<String, ResponsibilityTypeService>(responsibilities.size());
454         for (Responsibility responsibility : responsibilities) {
455             final Template t = responsibility.getTemplate();
456             final KimType type = kimTypeInfoService.getKimType(t.getKimTypeId());
457 
458             final String serviceName = type.getServiceName();
459             if (serviceName != null) {
460                 ResponsibilityTypeService responsibiltyTypeService = GlobalResourceLoader.getService(QName.valueOf(serviceName));
461                 if (responsibiltyTypeService != null) {
462                     responsibilityTypeServices.put(responsibility.getTemplate().getId(), responsibiltyTypeService);
463                 } else {
464                     responsibilityTypeServices.put(responsibility.getTemplate().getId(), defaultResponsibilityTypeService);
465                 }
466             }
467         }
468         return Collections.unmodifiableMap(responsibilityTypeServices);
469     }
470 
471     private Map<String, List<Responsibility>> groupResponsibilitiesByTemplate(Collection<Responsibility> responsibilities) {
472         final Map<String, List<Responsibility>> results = new HashMap<String, List<Responsibility>>();
473         for (Responsibility responsibility : responsibilities) {
474             List<Responsibility> responsibilityInfos = results.get(responsibility.getTemplate().getId());
475             if (responsibilityInfos == null) {
476                 responsibilityInfos = new ArrayList<Responsibility>();
477                 results.put(responsibility.getTemplate().getId(), responsibilityInfos);
478             }
479             responsibilityInfos.add(responsibility);
480         }
481         return Collections.unmodifiableMap(results);
482     }
483 
484     private List<String> getRoleIdsForResponsibilities(Collection<String> ids) {
485         final List<String> roleIds = getRoleIdsForPredicate(and(in("responsibilityId", ids.toArray()), equal("active", "Y")));
486 
487         return Collections.unmodifiableList(roleIds);
488     }
489 
490     private List<String> getRoleIdsForPredicate(Predicate p) {
491         final QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
492         builder.setPredicates(p);
493         final GenericQueryResults<RoleResponsibilityBo> qr = criteriaLookupService.lookup(RoleResponsibilityBo.class, builder.build());
494 
495         final List<String> roleIds = new ArrayList<String>();
496         for (RoleResponsibilityBo bo : qr.getResults()) {
497             roleIds.add(bo.getRoleId());
498         }
499         return Collections.unmodifiableList(roleIds);
500     }
501 
502 
503     @Override
504     public List<Responsibility> findResponsibilitiesByTemplate(String namespaceCode, String templateName) {
505 
506         final Map<String, String> crit = new HashMap<String, String>();
507         crit.put("template.namespaceCode", namespaceCode); 
508         crit.put("template.name", templateName); 
509         crit.put("active", "Y"); 
510 
511         final Collection<ResponsibilityBo> bos = businessObjectService.findMatching(ResponsibilityBo.class, Collections.unmodifiableMap(crit));
512         final List<Responsibility> ims = new ArrayList<Responsibility>();
513         if (bos != null) {
514             for (ResponsibilityBo bo : bos) {
515                 if (bo != null) {
516                     ims.add(ResponsibilityBo.to(bo));
517                 }
518             }
519         }
520 
521         return Collections.unmodifiableList(ims);
522     }
523 
524     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
525         this.businessObjectService = businessObjectService;
526     }
527 
528     public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
529         this.criteriaLookupService = criteriaLookupService;
530     }
531 
532     public void setDefaultResponsibilityTypeService(final ResponsibilityTypeService defaultResponsibilityTypeService) {
533         this.defaultResponsibilityTypeService = defaultResponsibilityTypeService;
534     }
535 
536     public void setKimTypeInfoService(final KimTypeInfoService kimTypeInfoService) {
537         this.kimTypeInfoService = kimTypeInfoService;
538     }
539 
540     public void setRoleService(final RoleService roleService) {
541         this.roleService = roleService;
542     }
543 
544     protected void logResponsibilityCheck(String namespaceCode, String responsibilityName, 
545                          Map<String, String> responsibilityDetails, Map<String, String> qualification ) {
546         StringBuilder sb = new StringBuilder();
547         sb.append(  '\n' );
548         sb.append( "Get Resp Actions: " ).append( namespaceCode ).append( "/" ).append( responsibilityName ).append( '\n' );
549         sb.append( "             Details:\n" );
550         if ( responsibilityDetails != null ) {
551             sb.append( responsibilityDetails );
552         } else {
553             sb.append( "                         [null]\n" );
554         }
555         sb.append( "             Qualifiers:\n" );
556         if ( qualification != null ) {
557             sb.append( qualification );
558         } else {
559             sb.append( "                         [null]\n" );
560         }
561         if (LOG.isTraceEnabled()) { 
562             LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable())));
563         } else {
564             LOG.debug(sb.toString());
565         }
566     }
567     
568     private void incomingParamCheck(Object object, String name) {
569         if (object == null) {
570             throw new RiceIllegalArgumentException(name + " was null");
571         } else if (object instanceof String
572                 && StringUtils.isBlank((String) object)) {
573             throw new RiceIllegalArgumentException(name + " was blank");
574         }
575     }
576 }