001/**
002 * Copyright 2005-2016 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kim.impl.responsibility;
017
018import org.apache.commons.lang.StringUtils;
019import org.apache.commons.lang.exception.ExceptionUtils;
020import org.apache.commons.logging.Log;
021import org.apache.commons.logging.LogFactory;
022import org.kuali.rice.core.api.criteria.CriteriaLookupService;
023import org.kuali.rice.core.api.criteria.GenericQueryResults;
024import org.kuali.rice.core.api.criteria.LookupCustomizer;
025import org.kuali.rice.core.api.criteria.Predicate;
026import org.kuali.rice.core.api.criteria.QueryByCriteria;
027import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
028import org.kuali.rice.core.api.exception.RiceIllegalStateException;
029import org.kuali.rice.core.api.membership.MemberType;
030import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
031import org.kuali.rice.kim.api.common.delegate.DelegateType;
032import org.kuali.rice.kim.api.common.template.Template;
033import org.kuali.rice.kim.api.common.template.TemplateQueryResults;
034import org.kuali.rice.kim.api.responsibility.Responsibility;
035import org.kuali.rice.kim.api.responsibility.ResponsibilityAction;
036import org.kuali.rice.kim.api.responsibility.ResponsibilityQueryResults;
037import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
038import org.kuali.rice.kim.api.role.RoleMembership;
039import org.kuali.rice.kim.api.role.RoleResponsibilityAction;
040import org.kuali.rice.kim.api.role.RoleService;
041import org.kuali.rice.kim.api.type.KimType;
042import org.kuali.rice.kim.api.type.KimTypeInfoService;
043import org.kuali.rice.kim.framework.responsibility.ResponsibilityTypeService;
044import org.kuali.rice.kim.impl.KIMPropertyConstants;
045import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
046import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
047import org.kuali.rice.kim.impl.role.RoleResponsibilityActionBo;
048import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
049import org.kuali.rice.krad.service.BusinessObjectService;
050import org.springframework.util.CollectionUtils;
051
052import javax.xml.namespace.QName;
053import java.util.ArrayList;
054import java.util.Collection;
055import java.util.Collections;
056import java.util.HashMap;
057import java.util.Iterator;
058import java.util.List;
059import java.util.Map;
060
061import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
062
063public class ResponsibilityServiceImpl implements ResponsibilityService {
064
065    private static final Integer DEFAULT_PRIORITY_NUMBER = Integer.valueOf(1);
066    private static final Log LOG = LogFactory.getLog(ResponsibilityServiceImpl.class);
067
068    private BusinessObjectService businessObjectService;
069    private CriteriaLookupService criteriaLookupService;
070    private ResponsibilityTypeService defaultResponsibilityTypeService;
071    private KimTypeInfoService kimTypeInfoService;
072    private RoleService roleService;
073
074    @Override
075    public Responsibility createResponsibility(final Responsibility responsibility)
076            throws RiceIllegalArgumentException, RiceIllegalStateException {
077        incomingParamCheck(responsibility, "responsibility");
078
079        if (StringUtils.isNotBlank(responsibility.getId()) && getResponsibility(responsibility.getId()) != null) {
080            throw new RiceIllegalStateException("the responsibility to create already exists: " + responsibility);
081        }
082        List<ResponsibilityAttributeBo> attrBos = Collections.emptyList();
083        if (responsibility.getTemplate() != null) {
084            attrBos = KimAttributeDataBo.createFrom(ResponsibilityAttributeBo.class, responsibility.getAttributes(), responsibility.getTemplate().getKimTypeId());
085        }
086        ResponsibilityBo bo = ResponsibilityBo.from(responsibility);
087        bo.setAttributeDetails(attrBos);
088        return ResponsibilityBo.to(businessObjectService.save(bo));
089    }
090
091    @Override
092    public Responsibility updateResponsibility(final Responsibility responsibility)
093            throws RiceIllegalArgumentException, RiceIllegalStateException {
094        incomingParamCheck(responsibility, "responsibility");
095
096        if (StringUtils.isBlank(responsibility.getId()) || getResponsibility(responsibility.getId()) == null) {
097            throw new RiceIllegalStateException("the responsibility does not exist: " + responsibility);
098        }
099
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                final ResponsibilityAction.Builder rai = ResponsibilityAction.Builder.create();
276                rai.setMemberRoleId((rm.getEmbeddedRoleId() == null) ? rm.getRoleId() : rm.getEmbeddedRoleId());
277                rai.setRoleId(rm.getRoleId());
278                rai.setQualifier(rm.getQualifier());
279                final List<DelegateType.Builder> bs = new ArrayList<DelegateType.Builder>();
280                for (DelegateType d : rm.getDelegates()) {
281                    bs.add(DelegateType.Builder.create(d));
282                }
283                rai.setDelegates(bs);
284                rai.setResponsibilityId(responsibility.getId());
285                rai.setResponsibilityName(responsibility.getName());
286                rai.setResponsibilityNamespaceCode(responsibility.getNamespaceCode());
287
288                if (MemberType.PRINCIPAL.equals(rm.getType())) {
289                    rai.setPrincipalId(rm.getMemberId());
290                } else {
291                    rai.setGroupId(rm.getMemberId());
292                }
293                // get associated resp resolution objects
294                RoleResponsibilityAction action = getResponsibilityAction(rm.getRoleId(), responsibility.getId(), rm.getId());
295                if (action == null) {
296                    LOG.error("Unable to get responsibility action record for role/responsibility/roleMember: "
297                            + rm.getRoleId() + "/" + responsibility.getId() + "/" + rm.getId());
298                    LOG.error("Skipping this role member in getActionsForResponsibilityRoles()");
299                    continue;
300                }
301                // add the data to the ResponsibilityActionInfo objects
302                rai.setActionTypeCode(action.getActionTypeCode());
303                rai.setActionPolicyCode(action.getActionPolicyCode());
304                rai.setPriorityNumber(action.getPriorityNumber() == null ? DEFAULT_PRIORITY_NUMBER : action.getPriorityNumber());
305                rai.setForceAction(action.isForceAction());
306                rai.setParallelRoutingGroupingCode((rm.getRoleSortingCode() == null) ? "" : rm.getRoleSortingCode());
307                rai.setRoleResponsibilityActionId(action.getId());
308                results.add(rai.build());
309            }
310        }
311        return Collections.unmodifiableList(results);
312    }
313
314    private RoleResponsibilityAction getResponsibilityAction(String roleId, String responsibilityId, String roleMemberId) {
315        RoleResponsibilityAction result = null;
316
317        // KULRICE-7459: Requisition, PO and its subtype documents are going to final status where they should not.
318        //
319        // need to do in 2 steps due to "*" wildcard convention in column data for role member id and role
320        // responsibility id.  Well, we could do in 1 step w/ straight SQL, but not w/ Criteria API due to the
321        // INNER JOIN automatically created between RoleResponsibility and RoleResponsibilityAction tables.
322
323        final Predicate roleResponsibilityPredicate =
324                and(
325                        equal("responsibilityId", responsibilityId),
326                        equal("roleId", roleId),
327                        equal("active", "Y")
328                );
329
330        // First get RoleResponsibilityBos
331        final QueryByCriteria.Builder roleResponsibilityQueryBuilder = QueryByCriteria.Builder.create();
332        roleResponsibilityQueryBuilder.setPredicates(roleResponsibilityPredicate);
333        final GenericQueryResults<RoleResponsibilityBo> roleResponsibilityResults =
334                criteriaLookupService.lookup(RoleResponsibilityBo.class, roleResponsibilityQueryBuilder.build());
335        final List<RoleResponsibilityBo> roleResponsibilityBos = roleResponsibilityResults.getResults();
336
337        if (!CollectionUtils.isEmpty(roleResponsibilityBos)) { // if there are any...
338            // Then query RoleResponsibilityActionBos based on them
339
340            List<String> roleResponsibilityIds = new ArrayList<String>(roleResponsibilityBos.size());
341            for (RoleResponsibilityBo roleResponsibilityBo : roleResponsibilityBos) {
342                roleResponsibilityIds.add(roleResponsibilityBo.getRoleResponsibilityId());
343            }
344
345            final Predicate roleResponsibilityActionPredicate =
346                    or(
347                            and(
348                                    in("roleResponsibilityId", roleResponsibilityIds.toArray()),
349                                    or(
350                                            equal(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId),
351                                            equal(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, "*")
352                                    )
353                            ),
354                            and(
355                                    equal("roleResponsibilityId", "*"),
356                                    equal(KIMPropertyConstants.RoleMember.ROLE_MEMBER_ID, roleMemberId)
357                            )
358                    );
359
360            final QueryByCriteria.Builder roleResponsibilityActionQueryBuilder = QueryByCriteria.Builder.create();
361            roleResponsibilityActionQueryBuilder.setPredicates(roleResponsibilityActionPredicate);
362
363            final GenericQueryResults<RoleResponsibilityActionBo> roleResponsibilityActionResults =
364                    criteriaLookupService.lookup(
365                            RoleResponsibilityActionBo.class, roleResponsibilityActionQueryBuilder.build()
366                    );
367
368            final List<RoleResponsibilityActionBo> roleResponsibilityActionBos = roleResponsibilityActionResults.getResults();
369            //seems a little dubious that we are just returning the first result...
370            if (!roleResponsibilityActionBos.isEmpty()) {
371                result = RoleResponsibilityActionBo.to(roleResponsibilityActionBos.get(0));
372            };
373        }
374
375        return result;
376    }
377
378    @Override
379    public List<String> getRoleIdsForResponsibility(String id) throws RiceIllegalArgumentException {
380        incomingParamCheck(id, "id");
381
382        final List<String> roleIds = getRoleIdsForPredicate(and(equal("responsibilityId", id), equal("active", "Y")));
383
384        return Collections.unmodifiableList(roleIds);
385    }
386
387    @Override
388    public ResponsibilityQueryResults findResponsibilities(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
389        incomingParamCheck(queryByCriteria, "queryByCriteria");
390
391        LookupCustomizer.Builder<ResponsibilityBo> lc = LookupCustomizer.Builder.create();
392        lc.setPredicateTransform(AttributeTransform.getInstance());
393
394        GenericQueryResults<ResponsibilityBo> results = criteriaLookupService.lookup(ResponsibilityBo.class, queryByCriteria, lc.build());
395
396        ResponsibilityQueryResults.Builder builder = ResponsibilityQueryResults.Builder.create();
397        builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
398        builder.setTotalRowCount(results.getTotalRowCount());
399
400        final List<Responsibility.Builder> ims = new ArrayList<Responsibility.Builder>();
401        for (ResponsibilityBo bo : results.getResults()) {
402            ims.add(Responsibility.Builder.create(bo));
403        }
404
405        builder.setResults(ims);
406        return builder.build();
407    }
408
409    @Override
410    public TemplateQueryResults findResponsibilityTemplates(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
411        incomingParamCheck(queryByCriteria, "queryByCriteria");
412
413        GenericQueryResults<ResponsibilityTemplateBo> results = criteriaLookupService.lookup(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", "Y")));
491
492        return Collections.unmodifiableList(roleIds);
493    }
494
495    private List<String> getRoleIdsForPredicate(Predicate p) {
496        final QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
497        builder.setPredicates(p);
498        final GenericQueryResults<RoleResponsibilityBo> qr = criteriaLookupService.lookup(RoleResponsibilityBo.class, builder.build());
499
500        final List<String> roleIds = new ArrayList<String>();
501        for (RoleResponsibilityBo bo : qr.getResults()) {
502            roleIds.add(bo.getRoleId());
503        }
504        return Collections.unmodifiableList(roleIds);
505    }
506
507
508    @Override
509    public List<Responsibility> findResponsibilitiesByTemplate(String namespaceCode, String templateName) {
510
511        final Map<String, String> crit = new HashMap<String, String>();
512        crit.put("template.namespaceCode", namespaceCode); 
513        crit.put("template.name", templateName); 
514        crit.put("active", "Y"); 
515
516        final Collection<ResponsibilityBo> bos = businessObjectService.findMatching(ResponsibilityBo.class, Collections.unmodifiableMap(crit));
517        final List<Responsibility> ims = new ArrayList<Responsibility>();
518        if (bos != null) {
519            for (ResponsibilityBo bo : bos) {
520                if (bo != null) {
521                    ims.add(ResponsibilityBo.to(bo));
522                }
523            }
524        }
525
526        return Collections.unmodifiableList(ims);
527    }
528
529    public void setBusinessObjectService(BusinessObjectService businessObjectService) {
530        this.businessObjectService = businessObjectService;
531    }
532
533    public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
534        this.criteriaLookupService = criteriaLookupService;
535    }
536
537    public void setDefaultResponsibilityTypeService(final ResponsibilityTypeService defaultResponsibilityTypeService) {
538        this.defaultResponsibilityTypeService = defaultResponsibilityTypeService;
539    }
540
541    public void setKimTypeInfoService(final KimTypeInfoService kimTypeInfoService) {
542        this.kimTypeInfoService = kimTypeInfoService;
543    }
544
545    public void setRoleService(final RoleService roleService) {
546        this.roleService = roleService;
547    }
548
549    protected void logResponsibilityCheck(String namespaceCode, String responsibilityName, 
550                    Map<String, String> responsibilityDetails, Map<String, String> qualification ) {
551        StringBuilder sb = new StringBuilder();
552        sb.append(  '\n' );
553        sb.append( "Get Resp Actions: " ).append( namespaceCode ).append( "/" ).append( responsibilityName ).append( '\n' );
554        sb.append( "             Details:\n" );
555        if ( responsibilityDetails != null ) {
556            sb.append( responsibilityDetails );
557        } else {
558            sb.append( "                         [null]\n" );
559        }
560        sb.append( "             Qualifiers:\n" );
561        if ( qualification != null ) {
562            sb.append( qualification );
563        } else {
564            sb.append( "                         [null]\n" );
565        }
566        if (LOG.isTraceEnabled()) { 
567            LOG.trace( sb.append(ExceptionUtils.getStackTrace(new Throwable())));
568        } else {
569            LOG.debug(sb.toString());
570        }
571    }
572
573    private void incomingParamCheck(Object object, String name) {
574        if (object == null) {
575            throw new RiceIllegalArgumentException(name + " was null");
576        } else if (object instanceof String
577                && StringUtils.isBlank((String) object)) {
578            throw new RiceIllegalArgumentException(name + " was blank");
579        }
580    }
581}