1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kim.impl.group;
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.criteria.CriteriaLookupService;
23 import org.kuali.rice.core.api.criteria.GenericQueryResults;
24 import org.kuali.rice.core.api.criteria.LookupCustomizer;
25 import org.kuali.rice.core.api.criteria.QueryByCriteria;
26 import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
27 import org.kuali.rice.core.api.exception.RiceRuntimeException;
28 import org.kuali.rice.core.api.membership.MemberType;
29 import org.kuali.rice.kim.api.KimConstants;
30 import org.kuali.rice.kim.api.group.Group;
31 import org.kuali.rice.kim.api.group.GroupMember;
32 import org.kuali.rice.kim.api.group.GroupMemberQueryResults;
33 import org.kuali.rice.kim.api.group.GroupQueryResults;
34 import org.kuali.rice.kim.api.group.GroupService;
35 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
36 import org.kuali.rice.kim.impl.KIMPropertyConstants;
37 import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
38 import org.kuali.rice.kim.impl.common.attribute.KimAttributeDataBo;
39 import org.kuali.rice.kim.impl.services.KimImplServiceLocator;
40 import org.kuali.rice.krad.service.BusinessObjectService;
41
42 import javax.jws.WebParam;
43 import java.sql.Timestamp;
44 import java.util.ArrayList;
45 import java.util.Collection;
46 import java.util.Collections;
47 import java.util.HashMap;
48 import java.util.HashSet;
49 import java.util.List;
50 import java.util.Map;
51 import java.util.Set;
52
53 import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
54
55 public class GroupServiceImpl extends GroupServiceBase implements GroupService {
56 private static final Logger LOG = Logger.getLogger(GroupServiceImpl.class);
57
58 protected BusinessObjectService businessObjectService;
59 private CriteriaLookupService criteriaLookupService;
60
61 @Override
62 public Group getGroup(String groupId) throws RiceIllegalArgumentException {
63 incomingParamCheck(groupId, "groupId");
64 return GroupBo.to(getGroupBo(groupId));
65 }
66
67 @Override
68 public List<Group> getGroupsByPrincipalId(String principalId) throws RiceIllegalArgumentException {
69 incomingParamCheck(principalId, "principalId");
70 return getGroupsByPrincipalIdAndNamespaceCodeInternal(principalId, null);
71 }
72
73 @Override
74 public List<Group> getGroupsByPrincipalIdAndNamespaceCode(String principalId, String namespaceCode) throws RiceIllegalArgumentException {
75 incomingParamCheck(principalId, "principalId");
76 incomingParamCheck(namespaceCode, "namespaceCode");
77
78 return getGroupsByPrincipalIdAndNamespaceCodeInternal(principalId, namespaceCode);
79 }
80
81 protected List<Group> getGroupsByPrincipalIdAndNamespaceCodeInternal(String principalId, String namespaceCode) throws RiceIllegalArgumentException {
82
83 Collection<Group> directGroups = getDirectGroupsForPrincipal( principalId, namespaceCode );
84 Set<Group> groups = new HashSet<Group>();
85 groups.addAll(directGroups);
86 for ( Group group : directGroups ) {
87 groups.add( group );
88 groups.addAll( getParentGroups( group.getId() ) );
89 }
90 return Collections.unmodifiableList(new ArrayList<Group>( groups ));
91 }
92
93 @Override
94 public List<String> findGroupIds(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
95 incomingParamCheck(queryByCriteria, "queryByCriteria");
96
97 GroupQueryResults results = this.findGroups(queryByCriteria);
98 List<String> result = new ArrayList<String>();
99
100 for (Group group : results.getResults()) {
101 result.add(group.getId());
102 }
103
104 return Collections.unmodifiableList(result);
105 }
106
107 @Override
108 public boolean isDirectMemberOfGroup(String principalId, String groupId) throws RiceIllegalArgumentException {
109 incomingParamCheck(principalId, "principalId");
110 incomingParamCheck(groupId, "groupId");
111
112 Map<String,String> criteria = new HashMap<String,String>();
113 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, principalId);
114 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode());
115 criteria.put(KIMPropertyConstants.GroupMember.GROUP_ID, groupId);
116
117 Collection<GroupMemberBo> groupMembers = businessObjectService.findMatching(GroupMemberBo.class, criteria);
118 for ( GroupMemberBo gm : groupMembers ) {
119 if ( gm.isActive(new Timestamp(System.currentTimeMillis())) ) {
120 return true;
121 }
122 }
123 return false;
124 }
125
126 @Override
127 public List<String> getGroupIdsByPrincipalId(String principalId) throws RiceIllegalArgumentException {
128 incomingParamCheck(principalId, "principalId");
129 return getGroupIdsByPrincipalIdAndNamespaceCodeInternal(principalId, null);
130 }
131
132 @Override
133 public List<String> getGroupIdsByPrincipalIdAndNamespaceCode(String principalId, String namespaceCode) throws RiceIllegalArgumentException {
134 incomingParamCheck(principalId, "principalId");
135 incomingParamCheck(namespaceCode, "namespaceCode");
136
137 List<String> result = new ArrayList<String>();
138
139 if (principalId != null) {
140 List<Group> groupList = getGroupsByPrincipalIdAndNamespaceCode(principalId, namespaceCode);
141
142 for (Group group : groupList) {
143 result.add(group.getId());
144 }
145 }
146
147 return Collections.unmodifiableList(result);
148 }
149
150 protected List<String> getGroupIdsByPrincipalIdAndNamespaceCodeInternal(String principalId, String namespaceCode) throws RiceIllegalArgumentException {
151
152 List<String> result = new ArrayList<String>();
153
154 if (principalId != null) {
155 List<Group> groupList = getGroupsByPrincipalIdAndNamespaceCodeInternal(principalId, namespaceCode);
156
157 for (Group group : groupList) {
158 result.add(group.getId());
159 }
160 }
161
162 return Collections.unmodifiableList(result);
163 }
164
165 @Override
166 public List<String> getDirectGroupIdsByPrincipalId(String principalId) throws RiceIllegalArgumentException {
167 incomingParamCheck(principalId, "principalId");
168
169 List<String> result = new ArrayList<String>();
170
171 if (principalId != null) {
172 Collection<Group> groupList = getDirectGroupsForPrincipal(principalId);
173
174 for (Group g : groupList) {
175 result.add(g.getId());
176 }
177 }
178
179 return Collections.unmodifiableList(result);
180 }
181
182 @Override
183 public List<String> getMemberPrincipalIds(String groupId) throws RiceIllegalArgumentException {
184 incomingParamCheck(groupId, "groupId");
185
186 return getMemberPrincipalIdsInternal(groupId, new HashSet<String>());
187 }
188
189 @Override
190 public List<String> getDirectMemberPrincipalIds(String groupId) throws RiceIllegalArgumentException {
191 incomingParamCheck(groupId, "groupId");
192
193 return this.getMemberIdsByType(getMembersOfGroup(groupId), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
194 }
195
196 @Override
197 public List<String> getMemberGroupIds(String groupId) throws RiceIllegalArgumentException {
198 incomingParamCheck(groupId, "groupId");
199
200 List<GroupBo> groups = getMemberGroupBos( groupId );
201 ArrayList<String> groupIds = new ArrayList<String>( groups.size() );
202 for ( GroupBo group : groups ) {
203 if ( group.isActive() ) {
204 groupIds.add( group.getId() );
205 }
206 }
207 return Collections.unmodifiableList(groupIds);
208 }
209
210
211 protected List<GroupBo> getMemberGroupBos(String groupId) {
212 if ( groupId == null ) {
213 return Collections.emptyList();
214 }
215 Set<GroupBo> groups = new HashSet<GroupBo>();
216
217 GroupBo group = getGroupBo(groupId);
218 getMemberGroupsInternal(group, groups);
219
220 return new ArrayList<GroupBo>(groups);
221 }
222
223 protected void getMemberGroupsInternal( GroupBo group, Set<GroupBo> groups ) {
224 if ( group == null ) {
225 return;
226 }
227 List<String> groupIds = group.getMemberGroupIds();
228
229 for (String id : groupIds) {
230 GroupBo memberGroup = getGroupBo(id);
231
232 if ( memberGroup.isActive() && !groups.contains( memberGroup ) ) {
233 groups.add(memberGroup);
234 getMemberGroupsInternal(memberGroup,groups);
235 }
236 }
237
238 }
239
240 @Override
241 public boolean isGroupMemberOfGroup(String groupMemberId, String groupId) throws RiceIllegalArgumentException {
242 incomingParamCheck(groupMemberId, "groupMemberId");
243 incomingParamCheck(groupId, "groupId");
244
245 return isMemberOfGroupInternal(groupMemberId, groupId, new HashSet<String>(), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE);
246 }
247
248 @Override
249 public boolean isMemberOfGroup(String principalId, String groupId) throws RiceIllegalArgumentException{
250 incomingParamCheck(principalId, "principalId");
251 incomingParamCheck(groupId, "groupId");
252
253 Set<String> visitedGroupIds = new HashSet<String>();
254 return isMemberOfGroupInternal(principalId, groupId, visitedGroupIds, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
255 }
256
257 @Override
258 public List<String> getDirectMemberGroupIds(String groupId) throws RiceIllegalArgumentException{
259 incomingParamCheck(groupId, "groupId");
260
261 return this.getMemberIdsByType(getMembersOfGroup(groupId), KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE);
262 }
263
264 @Override
265 public List<String> getParentGroupIds(String groupId) throws RiceIllegalArgumentException {
266 incomingParamCheck(groupId, "groupId");
267
268 List<String> result = new ArrayList<String>();
269 if (groupId != null) {
270 List<Group> groupList = getParentGroups(groupId);
271
272 for (Group group : groupList) {
273 result.add(group.getId());
274 }
275 }
276
277 return Collections.unmodifiableList(result);
278 }
279
280 @Override
281 public List<String> getDirectParentGroupIds(String groupId) throws RiceIllegalArgumentException {
282 incomingParamCheck(groupId, "groupId");
283
284 List<String> result = new ArrayList<String>();
285 if (groupId != null) {
286 List<Group> groupList = getDirectParentGroups(groupId);
287 for (Group group : groupList) {
288 result.add(group.getId());
289 }
290 }
291
292 return Collections.unmodifiableList(result);
293 }
294
295 @Override
296 public Map<String, String> getAttributes(String groupId) throws RiceIllegalArgumentException {
297 incomingParamCheck(groupId, "groupId");
298
299 Group group = getGroup(groupId);
300 if (group != null) {
301 return group.getAttributes();
302 }
303 return Collections.emptyMap();
304 }
305
306 @Override
307 public List<GroupMember> getMembers(List<String> groupIds) throws RiceIllegalArgumentException{
308 if (CollectionUtils.isEmpty(groupIds)) {
309 throw new RiceIllegalArgumentException("groupIds is empty");
310 }
311
312
313 List<GroupMember> groupMembers = new ArrayList<GroupMember>();
314 for (String groupId : groupIds) {
315 groupMembers.addAll(getMembersOfGroup(groupId));
316 }
317 return Collections.unmodifiableList(groupMembers);
318 }
319
320 @Override
321 public List<Group> getGroups(Collection<String> groupIds) throws RiceIllegalArgumentException {
322 incomingParamCheck(groupIds, "groupIds");
323 if (groupIds.isEmpty()) {
324 return Collections.emptyList();
325 }
326 final QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
327 builder.setPredicates(and(in("id", groupIds.toArray()), equal("active", "Y")));
328 GroupQueryResults qr = findGroups(builder.build());
329
330 return qr.getResults();
331 }
332
333 @Override
334 public Group getGroupByNamespaceCodeAndName(String namespaceCode, String groupName) throws RiceIllegalArgumentException{
335 incomingParamCheck(namespaceCode, "namespaceCode");
336 incomingParamCheck(groupName, "groupName");
337
338 Map<String,String> criteria = new HashMap<String,String>();
339 criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
340 criteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, groupName);
341 Collection<GroupBo> groups = businessObjectService.findMatching(GroupBo.class, criteria);
342 if ( !groups.isEmpty() ) {
343 return GroupBo.to(groups.iterator().next());
344 }
345 return null;
346 }
347
348 @Override
349 public GroupQueryResults findGroups(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
350 incomingParamCheck(queryByCriteria, "queryByCriteria");
351
352 LookupCustomizer.Builder<GroupBo> lc = LookupCustomizer.Builder.create();
353 lc.setPredicateTransform(AttributeTransform.getInstance());
354
355 GenericQueryResults<GroupBo> results = criteriaLookupService.lookup(GroupBo.class, queryByCriteria, lc.build());
356
357 GroupQueryResults.Builder builder = GroupQueryResults.Builder.create();
358 builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
359 builder.setTotalRowCount(results.getTotalRowCount());
360
361 final List<Group.Builder> ims = new ArrayList<Group.Builder>();
362 for (GroupBo bo : results.getResults()) {
363 ims.add(Group.Builder.create(bo));
364 }
365
366 builder.setResults(ims);
367 return builder.build();
368 }
369
370 @Override
371 public GroupMemberQueryResults findGroupMembers(final QueryByCriteria queryByCriteria) throws RiceIllegalArgumentException {
372 incomingParamCheck(queryByCriteria, "queryByCriteria");
373
374 GenericQueryResults<GroupMemberBo> results = criteriaLookupService.lookup(GroupMemberBo.class, queryByCriteria);
375
376 GroupMemberQueryResults.Builder builder = GroupMemberQueryResults.Builder.create();
377 builder.setMoreResultsAvailable(results.isMoreResultsAvailable());
378 builder.setTotalRowCount(results.getTotalRowCount());
379
380 final List<GroupMember.Builder> ims = new ArrayList<GroupMember.Builder>();
381 for (GroupMemberBo bo : results.getResults()) {
382 ims.add(GroupMember.Builder.create(bo));
383 }
384
385 builder.setResults(ims);
386 return builder.build();
387 }
388
389
390 protected boolean isMemberOfGroupInternal(String memberId, String groupId, Set<String> visitedGroupIds, MemberType memberType) {
391 if ( memberId == null || groupId == null ) {
392 return false;
393 }
394
395
396 Group group = getGroup(groupId);
397 if ( group == null || !group.isActive() ) {
398 return false;
399 }
400
401 List<GroupMember> members = getMembersOfGroup(group.getId());
402
403 for (String groupMemberId : getMemberIdsByType(members, memberType)) {
404 if (groupMemberId.equals(memberId)) {
405 return true;
406 }
407 }
408
409
410 for ( String memberGroupId : getMemberIdsByType(members, KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE) ) {
411 if (!visitedGroupIds.contains(memberGroupId)){
412 visitedGroupIds.add(memberGroupId);
413 if ( isMemberOfGroupInternal( memberId, memberGroupId, visitedGroupIds, memberType ) ) {
414 return true;
415 }
416 }
417 }
418
419
420 return false;
421 }
422
423 protected void getParentGroupsInternal( String groupId, Set<Group> groups ) {
424 List<Group> parentGroups = getDirectParentGroups( groupId );
425 for ( Group group : parentGroups ) {
426 if ( !groups.contains( group ) ) {
427 groups.add( group );
428 getParentGroupsInternal( group.getId(), groups );
429 }
430 }
431 }
432
433 protected List<Group> getDirectParentGroups(String groupId) {
434 if ( groupId == null ) {
435 return Collections.emptyList();
436 }
437 Map<String,String> criteria = new HashMap<String,String>();
438 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, groupId);
439 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE.getCode());
440
441 List<GroupMemberBo> groupMembers = (List<GroupMemberBo>)businessObjectService.findMatching(GroupMemberBo.class, criteria);
442 Set<String> matchingGroupIds = new HashSet<String>();
443
444 for ( GroupMemberBo gm : groupMembers ) {
445 if ( gm.isActive(new Timestamp(System.currentTimeMillis())) ) {
446 matchingGroupIds.add(gm.getGroupId());
447 }
448 }
449 if (CollectionUtils.isNotEmpty(matchingGroupIds)) {
450 return getGroups(matchingGroupIds);
451 }
452 return Collections.emptyList();
453 }
454
455 @Override
456 public List<GroupMember> getMembersOfGroup(String groupId) throws RiceIllegalArgumentException {
457 incomingParamCheck(groupId, "groupId");
458 Map<String,String> criteria = new HashMap<String,String>();
459 criteria.put(KIMPropertyConstants.GroupMember.GROUP_ID, groupId);
460
461 Collection<GroupMemberBo> groupMembersBos = businessObjectService.findMatching(GroupMemberBo.class, criteria);
462 List<GroupMember> groupMembers = new ArrayList<GroupMember>();
463 for (GroupMemberBo groupBo : groupMembersBos) {
464 if (groupBo.isActive(new Timestamp(System.currentTimeMillis()))){
465 groupMembers.add(GroupMemberBo.to(groupBo));
466 }
467 }
468 return Collections.unmodifiableList(groupMembers);
469 }
470
471 protected List<String> getMemberIdsByType(Collection<GroupMember> members, MemberType memberType) {
472 List<String> membersIds = new ArrayList<String>();
473 if (members != null) {
474 for (GroupMember member : members) {
475 if (member.getType().equals(memberType)) {
476 membersIds.add(member.getMemberId());
477 }
478 }
479 }
480 return Collections.unmodifiableList(membersIds);
481 }
482
483 protected GroupBo getGroupBo(String groupId) {
484 incomingParamCheck(groupId, "groupId");
485 return businessObjectService.findByPrimaryKey(GroupBo.class, Collections.singletonMap("id", groupId));
486 }
487
488 protected GroupMemberBo getGroupMemberBo(String id) {
489 incomingParamCheck(id, "id");
490 return businessObjectService.findByPrimaryKey(GroupMemberBo.class, Collections.singletonMap("id", id));
491 }
492
493 protected List<Group> getParentGroups(String groupId) throws RiceIllegalArgumentException {
494 if ( StringUtils.isEmpty(groupId) ) {
495 throw new RiceIllegalArgumentException("groupId is blank");
496 }
497 Set<Group> groups = new HashSet<Group>();
498 getParentGroupsInternal( groupId, groups );
499 return new ArrayList<Group>( groups );
500 }
501
502 protected List<String> getMemberPrincipalIdsInternal(String groupId, Set<String> visitedGroupIds) {
503 if ( groupId == null ) {
504 return Collections.emptyList();
505 }
506 Set<String> ids = new HashSet<String>();
507 GroupBo group = getGroupBo(groupId);
508 if ( group == null || !group.isActive()) {
509 return Collections.emptyList();
510 }
511
512
513
514 ids.addAll( group.getMemberPrincipalIds());
515 visitedGroupIds.add(group.getId());
516
517 for (String memberGroupId : group.getMemberGroupIds()) {
518 if (!visitedGroupIds.contains(memberGroupId)){
519 ids.addAll(getMemberPrincipalIdsInternal(memberGroupId, visitedGroupIds));
520 }
521 }
522
523 return Collections.unmodifiableList(new ArrayList<String>(ids));
524 }
525
526 protected Collection<Group> getDirectGroupsForPrincipal( String principalId ) {
527 return getDirectGroupsForPrincipal( principalId, null );
528 }
529
530 protected Collection<Group> getDirectGroupsForPrincipal( String principalId, String namespaceCode ) {
531 if ( principalId == null ) {
532 return Collections.emptyList();
533 }
534 Map<String,Object> criteria = new HashMap<String,Object>();
535 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, principalId);
536 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE.getCode());
537 Collection<GroupMemberBo> groupMembers = businessObjectService.findMatching(GroupMemberBo.class, criteria);
538 Set<String> groupIds = new HashSet<String>( groupMembers.size() );
539
540 for ( GroupMemberBo gm : groupMembers ) {
541 if ( gm.isActive(new Timestamp(System.currentTimeMillis())) ) {
542 groupIds.add( gm.getGroupId() );
543 }
544 }
545
546 List<Group> groups = CollectionUtils.isEmpty(groupIds) ? Collections.<Group>emptyList() : getGroups(groupIds);
547 List<Group> result = new ArrayList<Group>( groups.size() );
548
549 for ( Group group : groups ) {
550 if ( group.isActive() ) {
551 if ( StringUtils.isBlank(namespaceCode) || StringUtils.equals(namespaceCode, group.getNamespaceCode() ) ) {
552 result.add(group);
553 }
554 }
555 }
556 return result;
557 }
558
559 @Override
560 public boolean addGroupToGroup(String childId, String parentId) throws RiceIllegalArgumentException {
561 incomingParamCheck(childId, "childId");
562 incomingParamCheck(parentId, "parentId");
563
564 if(childId.equals(parentId)) {
565 throw new RiceIllegalArgumentException("Can't add group to itself.");
566 }
567 if(isGroupMemberOfGroup(parentId, childId)) {
568 throw new RiceIllegalArgumentException("Circular group reference.");
569 }
570
571 GroupMemberBo groupMember = new GroupMemberBo();
572 groupMember.setGroupId(parentId);
573 groupMember.setType(KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE);
574 groupMember.setMemberId(childId);
575
576 this.businessObjectService.save(groupMember);
577 return true;
578 }
579
580 @Override
581 public boolean addPrincipalToGroup(String principalId, String groupId) throws RiceIllegalArgumentException {
582 incomingParamCheck(principalId, "principalId");
583 incomingParamCheck(groupId, "groupId");
584
585 GroupMemberBo groupMember = new GroupMemberBo();
586 groupMember.setGroupId(groupId);
587 groupMember.setType(KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
588 groupMember.setMemberId(principalId);
589
590 groupMember = this.businessObjectService.save(groupMember);
591 KimImplServiceLocator.getGroupInternalService().updateForUserAddedToGroup(groupMember.getMemberId(),
592 groupMember.getGroupId());
593 return true;
594 }
595
596 @Override
597 public Group createGroup(Group group) throws RiceIllegalArgumentException {
598 incomingParamCheck(group, "group");
599 if (StringUtils.isNotBlank(group.getId()) && getGroup(group.getId()) != null) {
600 throw new RiceIllegalArgumentException("the group to create already exists: " + group);
601 }
602 List<GroupAttributeBo> attrBos = KimAttributeDataBo
603 .createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
604 if (StringUtils.isNotEmpty(group.getId())) {
605 for (GroupAttributeBo attr : attrBos) {
606 attr.setAssignedToId(group.getId());
607 }
608 }
609 GroupBo bo = GroupBo.from(group);
610 bo.setAttributeDetails(attrBos);
611
612 bo = saveGroup(bo);
613
614 return GroupBo.to(bo);
615 }
616
617 @Override
618 public Group updateGroup(Group group) throws RiceIllegalArgumentException{
619 incomingParamCheck(group, "group");
620 GroupBo origGroup = getGroupBo(group.getId());
621 if (StringUtils.isBlank(group.getId()) || origGroup == null) {
622 throw new RiceIllegalArgumentException("the group does not exist: " + group);
623 }
624 List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
625 GroupBo bo = GroupBo.from(group);
626 bo.setMembers(origGroup.getMembers());
627 bo.setAttributeDetails(attrBos);
628
629 bo = saveGroup(bo);
630 if (origGroup.isActive()
631 && !bo.isActive()) {
632 KimImplServiceLocator.getRoleInternalService().groupInactivated(bo.getId());
633 }
634
635 return GroupBo.to(bo);
636 }
637
638 @Override
639 public Group updateGroup(String groupId, Group group) throws RiceIllegalArgumentException{
640 incomingParamCheck(group, "group");
641 incomingParamCheck(groupId, "groupId");
642
643 if (StringUtils.equals(groupId, group.getId())) {
644 return updateGroup(group);
645 }
646
647
648 GroupBo groupBo = getGroupBo(groupId);
649
650 if (StringUtils.isBlank(group.getId()) || groupBo == null) {
651 throw new RiceIllegalArgumentException("the group does not exist: " + group);
652 }
653
654
655 GroupBo newGroup = GroupBo.from(group);
656 newGroup.setMembers(groupBo.getMembers());
657 List<GroupAttributeBo> attrBos = KimAttributeDataBo.createFrom(GroupAttributeBo.class, group.getAttributes(), group.getKimTypeId());
658 newGroup.setAttributeDetails(attrBos);
659 newGroup = saveGroup(newGroup);
660
661
662 groupBo.setActive(false);
663 saveGroup(groupBo);
664
665 return GroupBo.to(newGroup);
666 }
667
668 @Override
669 public GroupMember createGroupMember(GroupMember groupMember) throws RiceIllegalArgumentException {
670 incomingParamCheck(groupMember, "groupMember");
671 if (StringUtils.isNotBlank(groupMember.getId()) && getGroupMemberBo(groupMember.getId()) != null) {
672 throw new RiceIllegalArgumentException("the groupMember to create already exists: " + groupMember);
673 }
674
675 GroupMemberBo bo = GroupMemberBo.from(groupMember);
676 GroupBo groupBo = getGroupBo(groupMember.getGroupId());
677 groupBo.getMembers().add(bo);
678 groupBo = saveGroup(groupBo);
679
680
681 for (GroupMemberBo member : groupBo.getMembers()) {
682 if (member.getMemberId().equals(groupMember.getMemberId())
683 && member.getType().equals(groupMember.getType())
684 && member.getActiveFromDate().equals(groupMember.getActiveFromDate())
685 && member.getActiveToDate().equals(groupMember.getActiveToDate())) {
686 return GroupMemberBo.to(member);
687 }
688 }
689 return GroupMemberBo.to(bo);
690 }
691
692 @Override
693 public GroupMember updateGroupMember(
694 @WebParam(name = "groupMember") GroupMember groupMember) throws RiceIllegalArgumentException {
695 incomingParamCheck(groupMember, "groupMember");
696 if (StringUtils.isBlank(groupMember.getId()) || getGroupMemberBo(groupMember.getId()) == null) {
697 throw new RiceIllegalArgumentException("the groupMember to update does not exist: " + groupMember);
698 }
699
700 GroupMemberBo bo = GroupMemberBo.from(groupMember);
701 GroupBo groupBo = getGroupBo(groupMember.getGroupId());
702
703
704 List<GroupMemberBo> memberList = new ArrayList<GroupMemberBo>();
705 for (GroupMemberBo member : groupBo.getMembers()) {
706 if (member.getId().equals(bo.getId())) {
707 memberList.add(bo);
708 } else {
709 memberList.add(member);
710 }
711
712 }
713 groupBo.setMembers(memberList);
714 groupBo = saveGroup(groupBo);
715
716
717 for (GroupMemberBo member : groupBo.getMembers()) {
718 if (member.getId().equals(groupMember.getId())) {
719 return GroupMemberBo.to(member);
720 }
721 }
722 return GroupMemberBo.to(bo);
723 }
724
725 @Override
726 public void removeAllMembers(String groupId) throws RiceIllegalArgumentException{
727 incomingParamCheck(groupId, "groupId");
728
729
730 GroupService groupService = KimApiServiceLocator.getGroupService();
731 List<String> memberPrincipalsBefore = groupService.getMemberPrincipalIds(groupId);
732
733 Collection<GroupMemberBo> toDeactivate = getActiveGroupMembers(groupId, null, null);
734 java.sql.Timestamp today = new java.sql.Timestamp(System.currentTimeMillis());
735
736
737 for (GroupMemberBo aToDeactivate : toDeactivate) {
738 aToDeactivate.setActiveToDateValue(today);
739 }
740
741
742 this.businessObjectService.save(new ArrayList<GroupMemberBo>(toDeactivate));
743 List<String> memberPrincipalsAfter = groupService.getMemberPrincipalIds(groupId);
744
745 if (!CollectionUtils.isEmpty(memberPrincipalsAfter)) {
746
747 LOG.warn("after attempting removal of all members, group with id '" + groupId + "' still has principal members");
748 }
749
750
751 KimImplServiceLocator.getGroupInternalService().updateForWorkgroupChange(groupId, memberPrincipalsBefore,
752 memberPrincipalsAfter);
753 }
754
755 @Override
756 public boolean removeGroupFromGroup(String childId, String parentId) throws RiceIllegalArgumentException {
757 incomingParamCheck(childId, "childId");
758 incomingParamCheck(parentId, "parentId");
759
760 java.sql.Timestamp today = new java.sql.Timestamp(System.currentTimeMillis());
761
762 List<GroupMemberBo> groupMembers =
763 getActiveGroupMembers(parentId, childId, KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE);
764
765 if(groupMembers.size() == 1) {
766 GroupMemberBo groupMember = groupMembers.get(0);
767 groupMember.setActiveToDateValue(today);
768 this.businessObjectService.save(groupMember);
769 return true;
770 }
771
772 return false;
773 }
774
775 @Override
776 public boolean removePrincipalFromGroup(String principalId, String groupId) throws RiceIllegalArgumentException {
777 incomingParamCheck(principalId, "principalId");
778 incomingParamCheck(groupId, "groupId");
779
780 List<GroupMemberBo> groupMembers =
781 getActiveGroupMembers(groupId, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
782
783 if(groupMembers.size() == 1) {
784 GroupMemberBo member = groupMembers.iterator().next();
785 member.setActiveToDateValue(new java.sql.Timestamp(System.currentTimeMillis()));
786 this.businessObjectService.save(member);
787 KimImplServiceLocator.getGroupInternalService().updateForUserRemovedFromGroup(member.getMemberId(),
788 member.getGroupId());
789 return true;
790 }
791
792 return false;
793 }
794
795 protected GroupBo saveGroup(GroupBo group) {
796 if ( group == null ) {
797 return null;
798 } else if (group.getId() != null) {
799
800 GroupBo oldGroup = getGroupBo(group.getId());
801
802 if (oldGroup != null) {
803
804 java.sql.Timestamp activeTo = new java.sql.Timestamp(System.currentTimeMillis());
805 List<GroupMemberBo> toReAdd = null;
806
807 if (oldGroup.getMembers() != null) {
808 for (GroupMemberBo member : oldGroup.getMembers()) {
809
810 if (group.getMembers() == null || !group.getMembers().contains(member)) {
811
812 member.setActiveToDateValue(activeTo);
813 if (toReAdd == null) {
814 toReAdd = new ArrayList<GroupMemberBo>();
815 }
816
817 toReAdd.add(member);
818 }
819 }
820 }
821
822
823 if (toReAdd != null) {
824 List<GroupMemberBo> groupMembers = group.getMembers();
825 if (groupMembers == null) {
826 groupMembers = new ArrayList<GroupMemberBo>(toReAdd.size());
827 }
828 group.setMembers(groupMembers);
829 }
830 }
831 }
832
833 return KimImplServiceLocator.getGroupInternalService().saveWorkgroup(group);
834 }
835
836
837
838
839
840
841
842
843
844
845
846
847 private List<GroupMemberBo> getActiveGroupMembers(String parentId, String childId, MemberType memberType) {
848 final java.sql.Date today = new java.sql.Date(System.currentTimeMillis());
849
850 if (childId != null && memberType == null) {
851 throw new RiceRuntimeException("memberType must be non-null if childId is non-null");
852 }
853
854 Map<String,Object> criteria = new HashMap<String,Object>(4);
855 criteria.put(KIMPropertyConstants.GroupMember.GROUP_ID, parentId);
856
857 if (childId != null) {
858 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, childId);
859 criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, memberType.getCode());
860 }
861
862 Collection<GroupMemberBo> groupMembers = this.businessObjectService.findMatching(GroupMemberBo.class, criteria);
863
864 CollectionUtils.filter(groupMembers, new Predicate() {
865 @Override public boolean evaluate(Object object) {
866 GroupMemberBo member = (GroupMemberBo) object;
867
868 return member.getActiveToDate() == null || today.before(member.getActiveToDate().toDate());
869 }
870 });
871
872 return new ArrayList<GroupMemberBo>(groupMembers);
873 }
874
875
876
877
878
879
880 public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
881 this.businessObjectService = businessObjectService;
882 }
883
884
885
886
887
888
889 public void setCriteriaLookupService(final CriteriaLookupService criteriaLookupService) {
890 this.criteriaLookupService = criteriaLookupService;
891 }
892
893 private void incomingParamCheck(Object object, String name) {
894 if (object == null) {
895 throw new RiceIllegalArgumentException(name + " was null");
896 } else if (object instanceof String
897 && StringUtils.isBlank((String) object)) {
898 throw new RiceIllegalArgumentException(name + " was blank");
899 }
900 }
901 }