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