Coverage Report - org.kuali.rice.kim.service.impl.GroupUpdateServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
GroupUpdateServiceImpl
4%
6/125
3%
2/64
4.917
GroupUpdateServiceImpl$1
0%
0/3
0%
0/4
4.917
 
 1  
 /*
 2  
  * Copyright 2007-2010 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.service.impl;
 17  
 
 18  
 import org.apache.commons.collections.CollectionUtils;
 19  
 import org.apache.commons.collections.Predicate;
 20  
 import org.apache.commons.lang.StringUtils;
 21  
 import org.apache.log4j.Logger;
 22  
 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
 23  
 import org.kuali.rice.core.api.exception.RiceIllegalStateException;
 24  
 import org.kuali.rice.core.api.exception.RiceRuntimeException;
 25  
 import org.kuali.rice.kim.api.group.Group;
 26  
 import org.kuali.rice.kim.api.group.GroupService;
 27  
 import org.kuali.rice.kim.api.group.GroupUpdateService;
 28  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 29  
 import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
 30  
 import org.kuali.rice.kim.impl.group.GroupAttributeBo;
 31  
 import org.kuali.rice.kim.impl.group.GroupBo;
 32  
 import org.kuali.rice.kim.impl.group.GroupMemberBo;
 33  
 import org.kuali.rice.kim.impl.group.GroupServiceBase;
 34  
 import org.kuali.rice.kim.service.IdentityManagementNotificationService;
 35  
 import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
 36  
 import org.kuali.rice.kim.util.KIMPropertyConstants;
 37  
 import org.kuali.rice.kim.util.KIMWebServiceConstants;
 38  
 import org.kuali.rice.kim.util.KimConstants.KimGroupMemberTypes;
 39  
 import org.kuali.rice.krad.service.KRADServiceLocator;
 40  
 import org.kuali.rice.krad.service.SequenceAccessorService;
 41  
 import org.kuali.rice.ksb.api.KsbApiServiceLocator;
 42  
 
 43  
 import javax.jws.WebService;
 44  
 import javax.xml.namespace.QName;
 45  
 import java.util.ArrayList;
 46  
 import java.util.Collection;
 47  
 import java.util.HashMap;
 48  
 import java.util.List;
 49  
 import java.util.Map;
 50  
 
 51  
 /**
 52  
  * This is the default implementation for the {@link GroupUpdateService}, where the write methods for KIM groups are located.
 53  
  *
 54  
  * @author Kuali Rice Team (rice.collab@kuali.org)
 55  
  *
 56  
  */
 57  
 @WebService(endpointInterface = KIMWebServiceConstants.GroupUpdateService.INTERFACE_CLASS, serviceName = KIMWebServiceConstants.GroupUpdateService.WEB_SERVICE_NAME, portName = KIMWebServiceConstants.GroupUpdateService.WEB_SERVICE_PORT, targetNamespace = KIMWebServiceConstants.MODULE_TARGET_NAMESPACE)
 58  2
 public class GroupUpdateServiceImpl extends GroupServiceBase implements GroupUpdateService {
 59  
         
 60  1
         private static final Logger LOG = Logger.getLogger(GroupUpdateServiceImpl.class);
 61  
 
 62  
         /**
 63  
      * @see org.kuali.rice.kim.api.group.GroupUpdateService#addGroupToGroup(java.lang.String, java.lang.String)
 64  
      */
 65  
     public boolean addGroupToGroup(String childId, String parentId) {
 66  0
         if(childId.equals(parentId)) {
 67  0
             throw new RiceIllegalArgumentException("Can't add group to itself.");
 68  
         }
 69  
 
 70  0
         if(isGroupMemberOfGroup(parentId, childId)) {
 71  0
             throw new RiceIllegalArgumentException("Circular group reference.");
 72  
         }
 73  
 
 74  0
         GroupMemberBo groupMember = new GroupMemberBo();
 75  0
         groupMember.setGroupId(parentId);
 76  0
         groupMember.setTypeCode(KimGroupMemberTypes.GROUP_MEMBER_TYPE);
 77  0
         groupMember.setMemberId(childId);
 78  
 
 79  0
         this.businessObjectService.save(groupMember);
 80  0
         getIdentityManagementNotificationService().groupUpdated();
 81  
 
 82  0
         return true;
 83  
     }
 84  
 
 85  
     /**
 86  
      * @see org.kuali.rice.kim.api.group.GroupUpdateService#addPrincipalToGroup(java.lang.String, java.lang.String)
 87  
      */
 88  
     public boolean addPrincipalToGroup(String principalId, String groupId) {
 89  0
         GroupMemberBo groupMember = new GroupMemberBo();
 90  0
         groupMember.setGroupId(groupId);
 91  0
         groupMember.setTypeCode(KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
 92  0
         groupMember.setMemberId(principalId);
 93  
 
 94  0
         groupMember = (GroupMemberBo)this.businessObjectService.save(groupMember);
 95  0
         KIMServiceLocatorInternal.getGroupInternalService().updateForUserAddedToGroup(groupMember.getMemberId(), groupMember.getGroupId());
 96  0
         getIdentityManagementNotificationService().groupUpdated();
 97  0
         return true;
 98  
     }
 99  
 
 100  
     public Group createGroup(Group group) {
 101  1
         if (group == null) {
 102  1
             throw new RiceIllegalArgumentException(("group is null"));
 103  
         }
 104  0
         if (StringUtils.isNotBlank(group.getId()) && getGroup(group.getId()) != null) {
 105  0
             throw new RiceIllegalStateException("the group to create already exists: " + group);
 106  
         }
 107  0
         List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
 108  0
         if (StringUtils.isNotEmpty(group.getId())) {
 109  0
             for (GroupAttributeBo attr : attrBos) {
 110  0
                 attr.setAssignedToId(group.getId());
 111  
             }
 112  
         }
 113  0
         GroupBo bo = GroupBo.from(group);
 114  0
         bo.setAttributeDetails(attrBos);
 115  
 
 116  0
         bo = saveGroup(bo);
 117  
 
 118  0
         return GroupBo.to(bo);
 119  
     }
 120  
 
 121  
     public Group updateGroup(Group group) {
 122  0
         if (group == null) {
 123  0
             throw new RiceIllegalArgumentException(("group is null"));
 124  
         }
 125  0
         GroupBo origGroup = getGroupBo(group.getId());
 126  0
         if (StringUtils.isBlank(group.getId()) || origGroup == null) {
 127  0
             throw new RiceIllegalStateException("the group does not exist: " + group);
 128  
         }
 129  0
         List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
 130  0
         GroupBo bo = GroupBo.from(group);
 131  0
         bo.setMembers(origGroup.getMembers());
 132  0
         bo.setAttributeDetails(attrBos);
 133  
 
 134  0
         bo = saveGroup(bo);
 135  
 
 136  0
         return GroupBo.to(bo);
 137  
     }
 138  
 
 139  
             /**
 140  
          *
 141  
          * @see org.kuali.rice.kim.api.group.GroupUpdateService#updateGroup(java.lang.String, org.kuali.rice.kim.api.group.Group)
 142  
          */
 143  
         public Group updateGroup(String groupId, Group group) {
 144  1
         if (group == null) {
 145  1
             throw new RiceIllegalArgumentException(("group is null"));
 146  
         }
 147  0
         if (StringUtils.isEmpty(groupId)) {
 148  0
             throw new RiceIllegalArgumentException(("groupId is empty"));
 149  
         }
 150  
 
 151  0
         if (StringUtils.equals(groupId, group.getId())) {
 152  0
             return updateGroup(group);
 153  
         }
 154  
 
 155  
         //if group Ids are different, inactivate old group, and create new with new id based off old
 156  0
         GroupBo groupBo = getGroupBo(groupId);
 157  
 
 158  0
         if (StringUtils.isBlank(group.getId()) || groupBo == null) {
 159  0
             throw new RiceIllegalStateException("the group does not exist: " + group);
 160  
         }
 161  
 
 162  
         //create and save new group
 163  0
         GroupBo newGroup = GroupBo.from(group);
 164  0
         newGroup.setMembers(groupBo.getMembers());
 165  0
         List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
 166  0
         newGroup.setAttributeDetails(attrBos);
 167  0
         newGroup = saveGroup(newGroup);
 168  
 
 169  
         //inactivate and save old group
 170  0
         groupBo.setActive(false);
 171  0
         saveGroup(groupBo);
 172  
 
 173  0
         return GroupBo.to(newGroup);
 174  
     }
 175  
 
 176  
     /**
 177  
     *
 178  
     * @see org.kuali.rice.kim.api.group.GroupUpdateService#removeAllMembers(java.lang.String)
 179  
     */
 180  
    public void removeAllMembers(String groupId) {
 181  0
            GroupService groupService = KimApiServiceLocator.getGroupService();
 182  0
        List<String> memberPrincipalsBefore = groupService.getMemberPrincipalIds(groupId);
 183  
 
 184  0
        Collection<GroupMemberBo> toDeactivate = getActiveGroupMembers(groupId, null, null);
 185  0
        java.sql.Timestamp today = new java.sql.Timestamp(System.currentTimeMillis());
 186  
 
 187  
        // Set principals as inactive
 188  0
         for (GroupMemberBo aToDeactivate : toDeactivate) {
 189  0
             aToDeactivate.setActiveToDate(today);
 190  
         }
 191  
 
 192  
        // Save
 193  0
        this.businessObjectService.save(new ArrayList<GroupMemberBo>(toDeactivate));
 194  0
        List<String> memberPrincipalsAfter = groupService.getMemberPrincipalIds(groupId);
 195  
 
 196  0
        if (!CollectionUtils.isEmpty(memberPrincipalsAfter)) {
 197  
                // should never happen!
 198  0
                LOG.warn("after attempting removal of all members, group with id '" + groupId + "' still has principal members");
 199  
        }
 200  
 
 201  
        // do updates
 202  0
        KIMServiceLocatorInternal.getGroupInternalService().updateForWorkgroupChange(groupId, memberPrincipalsBefore, memberPrincipalsAfter);
 203  0
        getIdentityManagementNotificationService().groupUpdated();
 204  0
    }
 205  
 
 206  
         /**
 207  
      * @see org.kuali.rice.kim.api.group.GroupUpdateService#removeGroupFromGroup(java.lang.String, java.lang.String)
 208  
      */
 209  
     public boolean removeGroupFromGroup(String childId, String parentId) {
 210  0
             java.sql.Timestamp today = new java.sql.Timestamp(System.currentTimeMillis());
 211  
 
 212  0
             List<GroupMemberBo> groupMembers =
 213  
                     getActiveGroupMembers(parentId, childId, KimGroupMemberTypes.GROUP_MEMBER_TYPE);
 214  
 
 215  0
         if(groupMembers.size() == 1) {
 216  0
                 GroupMemberBo groupMember = groupMembers.get(0);
 217  0
                 groupMember.setActiveToDate(today);
 218  0
             this.businessObjectService.save(groupMember);
 219  0
             getIdentityManagementNotificationService().groupUpdated();
 220  0
             return true;
 221  
         }
 222  
 
 223  0
         return false;
 224  
     }
 225  
 
 226  
         /**
 227  
      * @see org.kuali.rice.kim.api.group.GroupUpdateService#removePrincipalFromGroup(java.lang.String, java.lang.String)
 228  
      */
 229  
     @SuppressWarnings("unchecked")
 230  
     public boolean removePrincipalFromGroup(String principalId, String groupId) {
 231  0
             List<GroupMemberBo> groupMembers =
 232  
                     getActiveGroupMembers(groupId, principalId, KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
 233  
 
 234  0
         if(groupMembers.size() == 1) {
 235  0
                 GroupMemberBo member = groupMembers.iterator().next();
 236  0
                 member.setActiveToDate(new java.sql.Timestamp(System.currentTimeMillis()));
 237  0
                 this.businessObjectService.save(member);
 238  0
             KIMServiceLocatorInternal.getGroupInternalService().updateForUserRemovedFromGroup(member.getMemberId(), member.getGroupId());
 239  0
             getIdentityManagementNotificationService().groupUpdated();
 240  0
             return true;
 241  
         }
 242  
 
 243  0
         return false;
 244  
     }
 245  
 
 246  
         protected GroupBo saveGroup(GroupBo group) {
 247  0
                 if ( group == null ) {
 248  0
                         return null;
 249  0
                 } else if (group.getId() != null) {
 250  
                         // Get the version of the group that is in the DB
 251  0
                         GroupBo oldGroup = getGroupBo(group.getId());
 252  
 
 253  0
                         if (oldGroup != null) {
 254  
                                 // Inactivate and re-add members no longer in the group (in order to preserve history).
 255  0
                                 java.sql.Timestamp activeTo = new java.sql.Timestamp(System.currentTimeMillis());
 256  0
                                 List<GroupMemberBo> toReAdd = null;
 257  
 
 258  0
                                 if (oldGroup.getMembers() != null) {
 259  0
                     for (GroupMemberBo member : oldGroup.getMembers()) {
 260  
                         // if the old member isn't in the new group
 261  0
                         if (group.getMembers() == null || !group.getMembers().contains(member)) {
 262  
                             // inactivate the member
 263  0
                             member.setActiveToDate(activeTo);
 264  0
                             if (toReAdd == null) {
 265  0
                                 toReAdd = new ArrayList<GroupMemberBo>();
 266  
                             }
 267  
                             // queue it up for re-adding
 268  0
                             toReAdd.add(member);
 269  
                         }
 270  
                     }
 271  
                                 }
 272  
 
 273  
                                 // do the re-adding
 274  0
                                 if (toReAdd != null) {
 275  0
                                         List<GroupMemberBo> groupMembers = group.getMembers();
 276  0
                                         if (groupMembers == null) {
 277  0
                         groupMembers = new ArrayList<GroupMemberBo>(toReAdd.size());
 278  
                     }
 279  0
                                         group.setMembers(groupMembers);
 280  
                                 }
 281  
                         }
 282  
                 }
 283  
 
 284  0
                 GroupBo savedGroup = KIMServiceLocatorInternal.getGroupInternalService().saveWorkgroup(group);
 285  0
                 getIdentityManagementNotificationService().groupUpdated();
 286  0
                 return savedGroup;
 287  
         }
 288  
 
 289  
 
 290  
         /**
 291  
          * This helper method gets the active group members of the specified type (see {@link KimGroupMemberTypes}).
 292  
          * If the optional params are null, it will return all active members for the specified group regardless
 293  
          * of type.
 294  
          *
 295  
          * @param parentId
 296  
          * @param childId optional, but if provided then memberType must be too
 297  
          * @param memberType optional, but must be provided if childId is
 298  
      * @return a list of group members
 299  
          */
 300  
         private List<GroupMemberBo> getActiveGroupMembers(String parentId,
 301  
                         String childId, String memberType) {
 302  0
             final java.sql.Date today = new java.sql.Date(System.currentTimeMillis());
 303  
 
 304  0
             if (childId != null && memberType == null) throw new RiceRuntimeException("memberType must be non-null if childId is non-null");
 305  
 
 306  0
                 Map<String,Object> criteria = new HashMap<String,Object>(4);
 307  0
         criteria.put(KIMPropertyConstants.GroupMember.GROUP_ID, parentId);
 308  
 
 309  0
         if (childId != null) {
 310  0
                 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, childId);
 311  0
                 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, memberType);
 312  
         }
 313  
 
 314  0
         Collection<GroupMemberBo> groupMembers = this.businessObjectService.findMatching(GroupMemberBo.class, criteria);
 315  
 
 316  0
         CollectionUtils.filter(groupMembers, new Predicate() {
 317  
                         public boolean evaluate(Object object) {
 318  0
                                 GroupMemberBo member = (GroupMemberBo) object;
 319  
                                 // keep in the collection (return true) if the activeToDate is null, or if it is set to a future date
 320  0
                                 return member.getActiveToDate() == null || today.before(member.getActiveToDate());
 321  
                         }
 322  
                 });
 323  
 
 324  0
         return new ArrayList<GroupMemberBo>(groupMembers);
 325  
         }
 326  
 
 327  
     protected IdentityManagementNotificationService getIdentityManagementNotificationService() {
 328  0
         return (IdentityManagementNotificationService) KsbApiServiceLocator.getMessageHelper().getServiceAsynchronously(new QName("KIM", "kimIdentityManagementNotificationService"));
 329  
     }
 330  
         
 331  
 }