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 java.util.ArrayList;
019import java.util.Collections;
020import java.util.HashSet;
021import java.util.List;
022import java.util.Map;
023import java.util.Set;
024
025import org.apache.commons.lang.StringUtils;
026import org.kuali.rice.core.api.criteria.PredicateFactory;
027import org.kuali.rice.core.api.criteria.QueryByCriteria;
028import org.kuali.rice.core.api.datetime.DateTimeService;
029import org.kuali.rice.core.api.util.Truth;
030import org.kuali.rice.kew.api.KewApiServiceLocator;
031import org.kuali.rice.kim.api.KimConstants;
032import org.kuali.rice.kim.api.responsibility.Responsibility;
033import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
034import org.kuali.rice.kim.api.role.RoleResponsibility;
035import org.kuali.rice.kim.api.services.KimApiServiceLocator;
036import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
037import org.kuali.rice.kim.impl.role.RoleMemberBo;
038import org.kuali.rice.kim.impl.role.RoleResponsibilityBo;
039import org.kuali.rice.krad.data.DataObjectService;
040import org.kuali.rice.krad.data.PersistenceOption;
041import org.kuali.rice.krad.util.KRADPropertyConstants;
042
043public class ResponsibilityInternalServiceImpl implements ResponsibilityInternalService {
044
045    protected DataObjectService dataObjectService;
046    protected ResponsibilityService responsibilityService;
047    protected DateTimeService dateTimeService;
048
049    @Override
050        public RoleMemberBo saveRoleMember(RoleMemberBo roleMember){
051
052                //need to find what responsibilities changed so we can notify interested clients.  Like workflow.
053        List<RoleResponsibility> oldRoleResp = getRoleResponsibilities(roleMember.getRoleId());
054
055        // add row to member table
056        RoleMemberBo member = dataObjectService.save( roleMember, PersistenceOption.FLUSH );
057
058        //need to find what responsibilities changed so we can notify interested clients.  Like workflow.
059        // the new member has been added
060        List<RoleResponsibility> newRoleResp = getRoleResponsibilities(roleMember.getRoleId());
061
062        updateActionRequestsForResponsibilityChange(getChangedRoleResponsibilityIds(oldRoleResp, newRoleResp));
063
064        return member;
065        }
066
067    @Override
068    public DelegateMemberBo saveDelegateMember(DelegateMemberBo delegateMember) {
069
070        // add row to member table
071        DelegateMemberBo member = dataObjectService.save(delegateMember, PersistenceOption.FLUSH);
072
073        return member;
074    }
075
076    @Override
077        public void removeRoleMember(RoleMemberBo roleMember){
078                //need to find what responsibilities changed so we can notify interested clients.  Like workflow.
079        List<RoleResponsibility> oldRoleResp = getRoleResponsibilities(roleMember.getRoleId());
080
081        // need to set end date to inactivate, not delete
082        roleMember.setActiveToDateValue(dateTimeService.getCurrentTimestamp());
083        roleMember = dataObjectService.save( roleMember, PersistenceOption.FLUSH );
084
085        // Notify the RoleTypeService for this role that the member was removed
086        KimApiServiceLocator.getRoleService().notifyOnMemberRemoval(RoleMemberBo.to(roleMember));
087
088        //need to find what responsibilities changed so we can notify interested clients.  Like workflow.
089        // the new member has been added
090        List<RoleResponsibility> newRoleResp = getRoleResponsibilities(roleMember.getRoleId());
091
092        updateActionRequestsForResponsibilityChange(getChangedRoleResponsibilityIds(oldRoleResp, newRoleResp));
093        }
094
095    @Override
096        @SuppressWarnings("unchecked")
097        public void updateActionRequestsForRoleChange(String roleId) {
098        List<RoleResponsibility> newRoleResp = getRoleResponsibilities(roleId);
099
100        updateActionRequestsForResponsibilityChange(getChangedRoleResponsibilityIds(Collections.EMPTY_LIST, newRoleResp));
101        }
102
103
104    @Override
105        public void updateActionRequestsForResponsibilityChange(Set<String> responsibilityIds) {
106        KewApiServiceLocator.getResponsibilityChangeQueue().responsibilitiesChanged(responsibilityIds);
107        }
108
109        @Override
110    public List<RoleResponsibility> getRoleResponsibilities(String roleId){
111                List<RoleResponsibilityBo> rrBoList = dataObjectService.findMatching( RoleResponsibilityBo.class, QueryByCriteria.Builder.fromPredicates(
112                            PredicateFactory.equal(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId),
113                            PredicateFactory.equal(KRADPropertyConstants.ACTIVE,Boolean.TRUE) ) ).getResults();
114                List<RoleResponsibility> result = new ArrayList<RoleResponsibility>( rrBoList.size() );
115                for ( RoleResponsibilityBo bo : rrBoList ) {
116                        result.add( RoleResponsibilityBo.to(bo) );
117                }
118                return result;
119    }
120
121    /**
122     *
123     * This method compares the two lists of responsibility IDs and does a union. returns a unique
124     * list of responsibility ids.
125     *
126     * @param oldRespList
127     * @param newRespList
128     * @return
129     */
130    protected Set<String> getChangedRoleResponsibilityIds(
131                        List<RoleResponsibility> oldRespList,
132                        List<RoleResponsibility> newRespList) {
133                Set<String> lRet = new HashSet<String>();
134
135                for (RoleResponsibility resp : oldRespList) {
136                        lRet.add(resp.getResponsibilityId());
137                }
138                for (RoleResponsibility resp : newRespList) {
139                        lRet.add(resp.getResponsibilityId());
140                }
141
142                return lRet;
143        }
144
145    @Override
146    public boolean areActionsAtAssignmentLevel(Responsibility responsibility ) {
147        Map<String, String> details = responsibility.getAttributes();
148        if ( details == null ) {
149                return false;
150        }
151        String actionDetailsAtRoleMemberLevel = StringUtils.trimToEmpty( details.get( KimConstants.AttributeConstants.ACTION_DETAILS_AT_ROLE_MEMBER_LEVEL ) );
152        return Truth.strToBooleanIgnoreCase(actionDetailsAtRoleMemberLevel, Boolean.FALSE);
153    }
154
155    @Override
156    public boolean areActionsAtAssignmentLevelById( String responsibilityId ) {
157        Responsibility responsibility = responsibilityService.getResponsibility(responsibilityId);
158        if ( responsibility == null ) {
159                return false;
160        }
161        return areActionsAtAssignmentLevel(responsibility);
162    }
163
164    public void setResponsibilityService(ResponsibilityService responsibilityService) {
165        this.responsibilityService = responsibilityService;
166    }
167
168    public void setDataObjectService(DataObjectService dataObjectService) {
169        this.dataObjectService = dataObjectService;
170    }
171
172    public void setDateTimeService(DateTimeService dateTimeService) {
173        this.dateTimeService = dateTimeService;
174    }
175
176}