View Javadoc

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.kuali.rice.kim.bo.group.dto.GroupInfo;
19  import org.kuali.rice.kim.bo.group.impl.GroupMemberImpl;
20  import org.kuali.rice.kim.bo.impl.GroupImpl;
21  import org.kuali.rice.kim.service.IdentityManagementNotificationService;
22  import org.kuali.rice.kim.util.KIMPropertyConstants;
23  import org.kuali.rice.kim.util.KimConstants;
24  import org.kuali.rice.kim.util.KimConstants.KimGroupMemberTypes;
25  import org.kuali.rice.kns.service.BusinessObjectService;
26  import org.kuali.rice.kns.service.KNSServiceLocator;
27  import org.kuali.rice.kns.service.LookupService;
28  import org.kuali.rice.ksb.service.KSBServiceLocator;
29  
30  import javax.xml.namespace.QName;
31  import java.util.*;
32  
33  /**
34   * This is a description of what this class does - jjhanso don't forget to fill this in. 
35   * 
36   * @author Kuali Rice Team (rice.collab@kuali.org)
37   *
38   */
39  public abstract class GroupServiceBase {
40  	private BusinessObjectService businessObjectService;
41  	private LookupService lookupService;
42  	
43  	/**
44       * @see org.kuali.rice.kim.service.GroupService#getGroupInfo(java.lang.String)
45       */
46      public GroupInfo getGroupInfo(String groupId) {
47          GroupImpl group = getGroupImpl(groupId);
48          return toGroupInfo(group);
49      }
50      
51      
52  	/**
53       * @see org.kuali.rice.kim.service.GroupService#isGroupMemberOfGroup(java.lang.String,
54       *      java.lang.String)
55       */
56  	public boolean isGroupMemberOfGroup(String groupMemberId, String groupId) {
57          if( groupId == null || groupMemberId == null) {
58              return false;
59          }
60  
61          // TODO: should it check for valid group ids here?
62  
63          return isGroupMemberOfGroupInternal(groupMemberId, groupId);
64  	}
65  	
66  	/**
67       * @see org.kuali.rice.kim.service.GroupService#getGroupInfoByName(java.lang.String, java.lang.String)
68       */
69      public GroupInfo getGroupInfoByName(String namespaceCode, String groupName) {
70          return toGroupInfo(getGroupByName(namespaceCode, groupName));
71      }
72      
73  	 /**
74       * @see org.kuali.rice.kim.service.GroupService#getGroupInfos(java.util.List)
75       */
76      public Map<String, GroupInfo> getGroupInfos(Collection<String> groupIds) {
77          Map<String, GroupInfo> result = new HashMap<String, GroupInfo>();
78  
79          // hopefully there is an efficient orm way to do this
80          for (String s : groupIds) {
81              GroupImpl group = getGroupImpl(s);
82              if (group != null) {
83                  result.put(s, toGroupInfo(group));
84              }
85          }
86  
87          return result;
88      }
89      
90      protected GroupImpl getGroupImpl(String groupId) {
91  		if ( groupId == null ) {
92  			return null;
93  		}
94  		Map<String,String> criteria = new HashMap<String,String>();
95  		criteria.put(KIMPropertyConstants.Group.GROUP_ID, groupId);
96  		return (GroupImpl) getBusinessObjectService().findByPrimaryKey(GroupImpl.class, criteria);
97  	}
98  
99  	@SuppressWarnings("unchecked")
100 	protected GroupImpl getGroupByName(String namespaceCode, String groupName) {
101 		if ( namespaceCode == null || groupName == null ) {
102 			return null;
103 		}
104 		Map<String,String> criteria = new HashMap<String,String>();
105 		criteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
106 		criteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, groupName);
107 		Collection<GroupImpl> groups = getBusinessObjectService().findMatching(GroupImpl.class, criteria);
108 		if ( groups.size() > 0 ) {
109 			return groups.iterator().next();
110 		}
111 		return null;
112 	}
113 	
114 	protected GroupInfo toGroupInfo(GroupImpl kimGroup) {
115         GroupInfo info = null;
116 
117         if (kimGroup != null) {
118             info = new GroupInfo();
119 
120             info.setActive(kimGroup.isActive());
121             info.setGroupDescription(kimGroup.getGroupDescription());
122             info.setGroupId(kimGroup.getGroupId());
123             info.setGroupName(kimGroup.getGroupName());
124             info.setKimTypeId(kimGroup.getKimTypeId());
125             info.setNamespaceCode(kimGroup.getNamespaceCode());
126 
127             info.setAttributes(kimGroup.getAttributes());
128         }
129 
130         return info;
131     }
132 
133     protected List<GroupInfo> toGroupInfo(List<GroupImpl> kimGroups){
134     	List<GroupInfo> lRet = null;
135 
136     	if(kimGroups != null){
137     		lRet = new ArrayList<GroupInfo>();
138 
139     		for(GroupImpl gi: kimGroups){
140     			lRet.add(this.toGroupInfo(gi));
141     		}
142     	}
143 
144     	return lRet;
145     }
146  
147 	protected boolean isGroupMemberOfGroupInternal(String groupMemberId, String groupId) {
148 
149 	    GroupImpl group = getGroupImpl(groupId);
150 	    if (group == null) {
151 	    	return false;
152 	    }
153 	    if( !group.isActive() ) {
154 	        return false;
155 	    }
156 
157 	    for( String memberGroupId : group.getMemberGroupIds()) {
158 	        if(memberGroupId.equals(groupMemberId)) {
159 	            return true;
160 	        }
161 	        else if(isGroupMemberOfGroup(groupMemberId, memberGroupId)) {
162 	            return true;
163 	        }
164 	    }
165 
166 	    return false;
167 	}
168 
169 	@SuppressWarnings("unchecked")
170 	protected Map<String,GroupInfo> getDirectParentGroups(String groupId) {
171 		if ( groupId == null ) {
172 			return Collections.emptyMap();
173 		}
174 		Map<String,String> criteria = new HashMap<String,String>();
175 		criteria.put(KIMPropertyConstants.GroupMember.MEMBER_ID, groupId);
176 		criteria.put(KIMPropertyConstants.GroupMember.MEMBER_TYPE_CODE, KimGroupMemberTypes.GROUP_MEMBER_TYPE);
177 
178 		List<GroupMemberImpl> groupMembers = (List<GroupMemberImpl>)getBusinessObjectService().findMatching(GroupMemberImpl.class, criteria);
179 		Set<String> matchingGroupIds = new HashSet<String>();
180 		// filter to active groups
181 		for ( GroupMemberImpl gm : groupMembers ) {
182 			if ( gm.isActive() ) {
183 				matchingGroupIds.add(gm.getGroupId());
184 			}
185 		}
186 		return getGroupInfos(matchingGroupIds);
187 	}
188 
189 	/**
190 	 * @see org.kuali.rice.kim.service.GroupService#getParentGroups(java.lang.String)
191 	 */
192 	protected List<GroupInfo> getParentGroups(String groupId) {
193 		if ( groupId == null ) {
194 			return Collections.emptyList();
195 		}
196 		Set<GroupInfo> groups = new HashSet<GroupInfo>();
197 		getParentGroupsInternal( groupId, groups );
198 		return new ArrayList<GroupInfo>( groups );
199 	}
200 
201 	protected void getParentGroupsInternal( String groupId, Set<GroupInfo> groups ) {
202 		Map<String,GroupInfo> parentGroups = getDirectParentGroups( groupId );
203 		for ( GroupInfo group : parentGroups.values() ) {
204 			if ( !groups.contains( group ) ) {
205 				groups.add( group );
206 				getParentGroupsInternal( group.getGroupId(), groups );
207 			}
208 		}
209 	}
210 	
211 	public List<String> getMemberPrincipalIds(String groupId) {
212 		if ( groupId == null ) {
213 			return Collections.emptyList();
214 		}
215 		Set<String> ids = new HashSet<String>();
216 		Set<String> groupIds = new HashSet<String>();
217 		
218 		GroupImpl group = getGroupImpl(groupId);
219 		if ( group == null ) {
220 			return Collections.emptyList();
221 		}
222 
223 		ids.addAll( group.getMemberPrincipalIds() );
224 		groupIds.add(group.getGroupId());
225 
226 		for (String memberGroupId : group.getMemberGroupIds()) {
227 			if (!groupIds.contains(memberGroupId)){
228 				ids.addAll(getMemberPrincipalIds(memberGroupId));
229 			}
230 		}
231 
232 		return new ArrayList<String>(ids);
233 	}
234 
235 	protected List<String> getMemberPrincipalIdsInternal(String groupId, Set<String> visitedGroupIds) {
236 		if ( groupId == null ) {
237 			return Collections.emptyList();
238 		}
239 		Set<String> ids = new HashSet<String>();	
240 		GroupImpl group = getGroupImpl(groupId);
241 		if ( group == null ) {
242 			return Collections.emptyList();
243 		}
244 
245 		ids.addAll( group.getMemberPrincipalIds() );
246 		visitedGroupIds.add(group.getGroupId());
247 
248 		for (String memberGroupId : group.getMemberGroupIds()) {
249 			if (!visitedGroupIds.contains(memberGroupId)){
250 				ids.addAll(getMemberPrincipalIdsInternal(memberGroupId, visitedGroupIds));
251 			}
252 		}
253 
254 		return new ArrayList<String>(ids);
255 	}
256 
257 	public boolean isMemberOfGroupInternal(String principalId, String groupId, Set<String> visitedGroupIds) {
258 		if ( principalId == null || groupId == null ) {
259 			return false;
260 		}
261 		// we could call the getMemberPrincipalIds method, but this will be more efficient
262 		// when group traversal is not needed
263 		GroupImpl group = getGroupImpl(groupId);
264 		if ( group == null || !group.isActive() ) {
265 			return false;
266 		}
267 		// check the immediate group
268 		for (String groupPrincipalId : group.getMemberPrincipalIds() ) {
269 			if (groupPrincipalId.equals(principalId)) {
270 				return true;
271 			}
272 		}
273 
274 		// check each contained group, returning as soon as a match is found
275 		for ( String memberGroupId : group.getMemberGroupIds() ) {
276 			if (!visitedGroupIds.contains(memberGroupId)){
277 				visitedGroupIds.add(memberGroupId);
278 				if ( isMemberOfGroupInternal( principalId, memberGroupId, visitedGroupIds ) ) {
279 					return true;
280 				}
281 			}
282 		}
283 
284 		// no match found, return false
285 		return false;
286 	}
287 
288 	protected IdentityManagementNotificationService getIdentityManagementNotificationService() {
289         return (IdentityManagementNotificationService)KSBServiceLocator.getMessageHelper().getServiceAsynchronously(new QName("KIM", "kimIdentityManagementNotificationService"));
290     }
291 
292 	protected BusinessObjectService getBusinessObjectService() {
293 		if ( businessObjectService == null ) {
294 			businessObjectService = KNSServiceLocator.getBusinessObjectService();
295 		}
296 		return businessObjectService;
297 	}
298 	
299     /**
300 	 * @return the lookupService
301 	 */
302     protected LookupService getLookupService() {
303 		if(lookupService == null) {
304 			lookupService = KNSServiceLocator.getLookupService();
305 		}
306 		return lookupService;
307     }
308 }