1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
53
54
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 public class GroupUpdateServiceImpl extends GroupServiceBase implements GroupUpdateService {
59
60 private static final Logger LOG = Logger.getLogger(GroupUpdateServiceImpl.class);
61
62
63
64
65 public boolean addGroupToGroup(String childId, String parentId) {
66 if(childId.equals(parentId)) {
67 throw new RiceIllegalArgumentException("Can't add group to itself.");
68 }
69
70 if(isGroupMemberOfGroup(parentId, childId)) {
71 throw new RiceIllegalArgumentException("Circular group reference.");
72 }
73
74 GroupMemberBo groupMember = new GroupMemberBo();
75 groupMember.setGroupId(parentId);
76 groupMember.setTypeCode(KimGroupMemberTypes.GROUP_MEMBER_TYPE);
77 groupMember.setMemberId(childId);
78
79 this.businessObjectService.save(groupMember);
80 getIdentityManagementNotificationService().groupUpdated();
81
82 return true;
83 }
84
85
86
87
88 public boolean addPrincipalToGroup(String principalId, String groupId) {
89 GroupMemberBo groupMember = new GroupMemberBo();
90 groupMember.setGroupId(groupId);
91 groupMember.setTypeCode(KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
92 groupMember.setMemberId(principalId);
93
94 groupMember = (GroupMemberBo)this.businessObjectService.save(groupMember);
95 KIMServiceLocatorInternal.getGroupInternalService().updateForUserAddedToGroup(groupMember.getMemberId(), groupMember.getGroupId());
96 getIdentityManagementNotificationService().groupUpdated();
97 return true;
98 }
99
100 public Group createGroup(Group group) {
101 if (group == null) {
102 throw new RiceIllegalArgumentException(("group is null"));
103 }
104 if (StringUtils.isNotBlank(group.getId()) && getGroup(group.getId()) != null) {
105 throw new RiceIllegalStateException("the group to create already exists: " + group);
106 }
107 List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
108 if (StringUtils.isNotEmpty(group.getId())) {
109 for (GroupAttributeBo attr : attrBos) {
110 attr.setAssignedToId(group.getId());
111 }
112 }
113 GroupBo bo = GroupBo.from(group);
114 bo.setAttributeDetails(attrBos);
115
116 bo = saveGroup(bo);
117
118 return GroupBo.to(bo);
119 }
120
121 public Group updateGroup(Group group) {
122 if (group == null) {
123 throw new RiceIllegalArgumentException(("group is null"));
124 }
125 GroupBo origGroup = getGroupBo(group.getId());
126 if (StringUtils.isBlank(group.getId()) || origGroup == null) {
127 throw new RiceIllegalStateException("the group does not exist: " + group);
128 }
129 List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
130 GroupBo bo = GroupBo.from(group);
131 bo.setMembers(origGroup.getMembers());
132 bo.setAttributeDetails(attrBos);
133
134 bo = saveGroup(bo);
135
136 return GroupBo.to(bo);
137 }
138
139
140
141
142
143 public Group updateGroup(String groupId, Group group) {
144 if (group == null) {
145 throw new RiceIllegalArgumentException(("group is null"));
146 }
147 if (StringUtils.isEmpty(groupId)) {
148 throw new RiceIllegalArgumentException(("groupId is empty"));
149 }
150
151 if (StringUtils.equals(groupId, group.getId())) {
152 return updateGroup(group);
153 }
154
155
156 GroupBo groupBo = getGroupBo(groupId);
157
158 if (StringUtils.isBlank(group.getId()) || groupBo == null) {
159 throw new RiceIllegalStateException("the group does not exist: " + group);
160 }
161
162
163 GroupBo newGroup = GroupBo.from(group);
164 newGroup.setMembers(groupBo.getMembers());
165 List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
166 newGroup.setAttributeDetails(attrBos);
167 newGroup = saveGroup(newGroup);
168
169
170 groupBo.setActive(false);
171 saveGroup(groupBo);
172
173 return GroupBo.to(newGroup);
174 }
175
176
177
178
179
180 public void removeAllMembers(String groupId) {
181 GroupService groupService = KimApiServiceLocator.getGroupService();
182 List<String> memberPrincipalsBefore = groupService.getMemberPrincipalIds(groupId);
183
184 Collection<GroupMemberBo> toDeactivate = getActiveGroupMembers(groupId, null, null);
185 java.sql.Timestamp today = new java.sql.Timestamp(System.currentTimeMillis());
186
187
188 for (GroupMemberBo aToDeactivate : toDeactivate) {
189 aToDeactivate.setActiveToDate(today);
190 }
191
192
193 this.businessObjectService.save(new ArrayList<GroupMemberBo>(toDeactivate));
194 List<String> memberPrincipalsAfter = groupService.getMemberPrincipalIds(groupId);
195
196 if (!CollectionUtils.isEmpty(memberPrincipalsAfter)) {
197
198 LOG.warn("after attempting removal of all members, group with id '" + groupId + "' still has principal members");
199 }
200
201
202 KIMServiceLocatorInternal.getGroupInternalService().updateForWorkgroupChange(groupId, memberPrincipalsBefore, memberPrincipalsAfter);
203 getIdentityManagementNotificationService().groupUpdated();
204 }
205
206
207
208
209 public boolean removeGroupFromGroup(String childId, String parentId) {
210 java.sql.Timestamp today = new java.sql.Timestamp(System.currentTimeMillis());
211
212 List<GroupMemberBo> groupMembers =
213 getActiveGroupMembers(parentId, childId, KimGroupMemberTypes.GROUP_MEMBER_TYPE);
214
215 if(groupMembers.size() == 1) {
216 GroupMemberBo groupMember = groupMembers.get(0);
217 groupMember.setActiveToDate(today);
218 this.businessObjectService.save(groupMember);
219 getIdentityManagementNotificationService().groupUpdated();
220 return true;
221 }
222
223 return false;
224 }
225
226
227
228
229 @SuppressWarnings("unchecked")
230 public boolean removePrincipalFromGroup(String principalId, String groupId) {
231 List<GroupMemberBo> groupMembers =
232 getActiveGroupMembers(groupId, principalId, KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
233
234 if(groupMembers.size() == 1) {
235 GroupMemberBo member = groupMembers.iterator().next();
236 member.setActiveToDate(new java.sql.Timestamp(System.currentTimeMillis()));
237 this.businessObjectService.save(member);
238 KIMServiceLocatorInternal.getGroupInternalService().updateForUserRemovedFromGroup(member.getMemberId(), member.getGroupId());
239 getIdentityManagementNotificationService().groupUpdated();
240 return true;
241 }
242
243 return false;
244 }
245
246 protected GroupBo saveGroup(GroupBo group) {
247 if ( group == null ) {
248 return null;
249 } else if (group.getId() != null) {
250
251 GroupBo oldGroup = getGroupBo(group.getId());
252
253 if (oldGroup != null) {
254
255 java.sql.Timestamp activeTo = new java.sql.Timestamp(System.currentTimeMillis());
256 List<GroupMemberBo> toReAdd = null;
257
258 if (oldGroup.getMembers() != null) {
259 for (GroupMemberBo member : oldGroup.getMembers()) {
260
261 if (group.getMembers() == null || !group.getMembers().contains(member)) {
262
263 member.setActiveToDate(activeTo);
264 if (toReAdd == null) {
265 toReAdd = new ArrayList<GroupMemberBo>();
266 }
267
268 toReAdd.add(member);
269 }
270 }
271 }
272
273
274 if (toReAdd != null) {
275 List<GroupMemberBo> groupMembers = group.getMembers();
276 if (groupMembers == null) {
277 groupMembers = new ArrayList<GroupMemberBo>(toReAdd.size());
278 }
279 group.setMembers(groupMembers);
280 }
281 }
282 }
283
284 GroupBo savedGroup = KIMServiceLocatorInternal.getGroupInternalService().saveWorkgroup(group);
285 getIdentityManagementNotificationService().groupUpdated();
286 return savedGroup;
287 }
288
289
290
291
292
293
294
295
296
297
298
299
300 private List<GroupMemberBo> getActiveGroupMembers(String parentId,
301 String childId, String memberType) {
302 final java.sql.Date today = new java.sql.Date(System.currentTimeMillis());
303
304 if (childId != null && memberType == null) throw new RiceRuntimeException("memberType must be non-null if childId is non-null");
305
306 Map<String,Object> criteria = new HashMap<String,Object>(4);
307 criteria.put(KIMPropertyConstants.GroupMember.GROUP_ID, parentId);
308
309 if (childId != null) {
310 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, childId);
311 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, memberType);
312 }
313
314 Collection<GroupMemberBo> groupMembers = this.businessObjectService.findMatching(GroupMemberBo.class, criteria);
315
316 CollectionUtils.filter(groupMembers, new Predicate() {
317 public boolean evaluate(Object object) {
318 GroupMemberBo member = (GroupMemberBo) object;
319
320 return member.getActiveToDate() == null || today.before(member.getActiveToDate());
321 }
322 });
323
324 return new ArrayList<GroupMemberBo>(groupMembers);
325 }
326
327 protected IdentityManagementNotificationService getIdentityManagementNotificationService() {
328 return (IdentityManagementNotificationService) KsbApiServiceLocator.getMessageHelper().getServiceAsynchronously(new QName("KIM", "kimIdentityManagementNotificationService"));
329 }
330
331 }