View Javadoc

1   /*
2    * Copyright 2006-2011 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  
17  package org.kuali.rice.kim.impl.group;
18  
19  
20  import org.apache.commons.lang.StringUtils;
21  import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
22  import org.kuali.rice.kim.api.group.Group;
23  import org.kuali.rice.kim.api.group.GroupMember;
24  import org.kuali.rice.kim.util.KIMPropertyConstants;
25  import org.kuali.rice.kim.util.KimConstants;
26  import org.kuali.rice.kns.service.BusinessObjectService;
27  
28  import java.util.ArrayList;
29  import java.util.Collection;
30  import java.util.Collections;
31  import java.util.HashMap;
32  import java.util.HashSet;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  
37  public abstract class GroupServiceBase {
38      protected BusinessObjectService businessObjectService;
39  
40      //@Override
41      public Group getGroup(String groupId) {
42  		return GroupBo.to(getGroupBo(groupId));
43      }
44  
45      protected GroupBo getGroupBo(String groupId) {
46          if ( StringUtils.isEmpty(groupId) ) {
47  			 throw new RiceIllegalArgumentException("groupId is blank");
48  		}
49          return (GroupBo)businessObjectService.findBySinglePrimaryKey(GroupBo.class, groupId);
50  
51      }
52  
53      //@Override
54  	public boolean isGroupMemberOfGroup(String groupMemberId, String groupId) {
55          if ( StringUtils.isEmpty(groupId) || StringUtils.isEmpty(groupMemberId) ) {
56  			 throw new RiceIllegalArgumentException("groupMemberId or groupId is blank");
57  		}
58  
59          Set<String> visitedGroupIds = new HashSet<String>();
60  		return isMemberOfGroupInternal(groupMemberId, groupId, visitedGroupIds, KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE);
61  	}
62  
63      //@Override
64      public boolean isMemberOfGroup(String principalId, String groupId) {
65          if ( principalId == null || groupId == null ) {
66  			return false;
67  		}
68  		Set<String> visitedGroupIds = new HashSet<String>();
69  		return isMemberOfGroupInternal(principalId, groupId, visitedGroupIds, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE);
70      }
71  
72      /**
73       * @see org.kuali.rice.kim.api.group.GroupService#getGroups(java.util.Collection)
74       */
75      //@Override
76      public Map<String, Group> getGroups(Collection<String> groupIds) {
77          //todo: This is a prime candidate for the new criteria builder
78          //CriteriaBuilder<GroupBo> criteriaBuilder = CriteriaBuilder.newCriteriaBuilder(GroupBo.class);
79          //criteriaBuilder.in("id", new ArrayList(groupIds));
80          //QueryByCriteria.Builder<GroupBo> qbcBuilder = QueryByCriteria.Builder.create(GroupBo.class);
81          //qbcBuilder.set
82  
83          Map<String, Group> result = new HashMap<String, Group>();
84  
85          //todo: hopefully there is an efficient orm way to do this
86          for (String s : groupIds) {
87              Group group = getGroup(s);
88              if (group != null) {
89                  result.put(s, group);
90              }
91          }
92  
93          return result;
94      }
95  
96      //@Override
97      public Group getGroupByName(String namespaceCode, String groupName) {
98          if ( namespaceCode == null || groupName == null ) {
99  			return null;
100 		}
101 		Map<String,String> criteria = new HashMap<String,String>();
102 		criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
103 		criteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, groupName);
104 		Collection<GroupBo> groups = businessObjectService.findMatching(GroupBo.class, criteria);
105 		if ( groups.size() > 0 ) {
106 			return GroupBo.to(groups.iterator().next());
107 		}
108 		return null;
109     }
110 
111     public boolean isMemberOfGroupInternal(String memberId, String groupId, Set<String> visitedGroupIds, String memberType) {
112 		if ( memberId == null || groupId == null ) {
113 			return false;
114 		}
115 
116 		// when group traversal is not needed
117 		Group group = getGroup(groupId);
118 		if ( group == null || !group.isActive() ) {
119 			return false;
120 		}
121 
122         List<GroupMember> members = getMembersOfGroup(group.getId());
123 		// check the immediate group
124 		for (String groupMemberId : getMemberIdsByType(members, memberType)) {
125 			if (groupMemberId.equals(memberId)) {
126 				return true;
127 			}
128 		}
129 
130 		// check each contained group, returning as soon as a match is found
131 		for ( String memberGroupId : getMemberIdsByType(members, KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE) ) {
132 			if (!visitedGroupIds.contains(memberGroupId)){
133 				visitedGroupIds.add(memberGroupId);
134 				if ( isMemberOfGroupInternal( memberId, memberGroupId, visitedGroupIds, memberType ) ) {
135 					return true;
136 				}
137 			}
138 		}
139 
140 		// no match found, return false
141 		return false;
142 	}
143 
144     protected void getParentGroupsInternal( String groupId, Set<Group> groups ) {
145 		Map<String,Group> parentGroups = getDirectParentGroups( groupId );
146 		for ( Group group : parentGroups.values() ) {
147 			if ( !groups.contains( group ) ) {
148 				groups.add( group );
149 				getParentGroupsInternal( group.getId(), groups );
150 			}
151 		}
152 	}
153 
154     protected Map<String,Group> getDirectParentGroups(String groupId) {
155 		if ( groupId == null ) {
156 			return Collections.emptyMap();
157 		}
158 		Map<String,String> criteria = new HashMap<String,String>();
159 		criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, groupId);
160 		criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, KimConstants.KimGroupMemberTypes.GROUP_MEMBER_TYPE);
161 
162 		List<GroupMemberBo> groupMembers = (List<GroupMemberBo>)businessObjectService.findMatching(GroupMemberBo.class, criteria);
163 		Set<String> matchingGroupIds = new HashSet<String>();
164 		// filter to active groups
165 		for ( GroupMemberBo gm : groupMembers ) {
166 			if ( gm.isActive() ) {
167 				matchingGroupIds.add(gm.getGroupId());
168 			}
169 		}
170 		return getGroups(matchingGroupIds);
171 	}
172 
173     public List<GroupMember> getMembersOfGroup(String groupId) {
174         if (groupId == null) {
175             throw new RiceIllegalArgumentException("groupId is blank");
176 		}
177         Map<String,String> criteria = new HashMap<String,String>();
178 		criteria.put(KIMPropertyConstants.GroupMember.GROUP_ID, groupId);
179 
180 		Collection<GroupMemberBo> groupMembersBos = businessObjectService.findMatching(GroupMemberBo.class, criteria);
181         List<GroupMember> groupMembers = new ArrayList<GroupMember>();
182         for (GroupMemberBo groupBo : groupMembersBos) {
183             if (groupBo.isActive()){
184                 groupMembers.add(GroupMemberBo.to(groupBo));
185             }
186         }
187         return groupMembers;
188     }
189 
190     /**
191      * Sets the businessObjectService attribute value.
192      *
193      * @param businessObjectService The businessObjectService to set.
194      */
195     public void setBusinessObjectService(final BusinessObjectService businessObjectService) {
196         this.businessObjectService = businessObjectService;
197     }
198 
199     protected List<Group> toGroupList(List<GroupBo> groupBos) {
200         if (groupBos == null) {
201             return null;
202         }
203         List<Group> groups = new ArrayList<Group>();
204         for (GroupBo bo : groupBos) {
205             groups.add(GroupBo.to(bo));
206         }
207         return groups;
208     }
209 
210     /*protected List<String> getMemberIdsByType(Group group, String memberType) {
211         List<String> principalIds = new ArrayList<String>();
212         if (group != null) {
213             for (GroupMember member : getMembersOfGroup(group.getId())) {
214                 if (member.getTypeCode().equals(memberType)) {
215                     principalIds.add(member.getMemberId());
216                 }
217             }
218         }
219         return principalIds;
220     }*/
221 
222     protected List<GroupMember> getMembersByType(Collection<GroupMember> members, String memberType) {
223         List<GroupMember> membersByType = new ArrayList<GroupMember>();
224         if (members != null) {
225             for (GroupMember member : members) {
226                 if (member.getTypeCode().equals(memberType)) {
227                     membersByType.add(member);
228                 }
229             }
230         }
231         return membersByType;
232     }
233 
234     protected List<String> getMemberIdsByType(Collection<GroupMember> members, String memberType) {
235         List<String> membersIds = new ArrayList<String>();
236         if (members != null) {
237             for (GroupMember member : members) {
238                 if (member.getTypeCode().equals(memberType)) {
239                     membersIds.add(member.getMemberId());
240                 }
241             }
242         }
243         return membersIds;
244     }
245 }