View Javadoc

1   /**
2    * Copyright 2004-2014 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.kpme.core.service.role;
17  
18  import static org.kuali.rice.core.api.criteria.PredicateFactory.and;
19  import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
20  import static org.kuali.rice.core.api.criteria.PredicateFactory.greaterThan;
21  import static org.kuali.rice.core.api.criteria.PredicateFactory.in;
22  import static org.kuali.rice.core.api.criteria.PredicateFactory.isNull;
23  import static org.kuali.rice.core.api.criteria.PredicateFactory.lessThanOrEqual;
24  import static org.kuali.rice.core.api.criteria.PredicateFactory.or;
25  
26  import java.util.ArrayList;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  
34  import javax.xml.namespace.QName;
35  
36  import org.apache.commons.collections.CollectionUtils;
37  import org.apache.commons.collections.MapUtils;
38  import org.apache.commons.lang.StringUtils;
39  import org.apache.log4j.Logger;
40  import org.aspectj.weaver.MemberImpl;
41  import org.joda.time.DateTime;
42  import org.joda.time.LocalDate;
43  import org.kuali.kpme.core.KPMENamespace;
44  import org.kuali.kpme.core.api.job.JobContract;
45  import org.kuali.kpme.core.department.service.DepartmentService;
46  import org.kuali.kpme.core.role.KPMERole;
47  import org.kuali.kpme.core.role.KPMERoleMemberAttribute;
48  import org.kuali.kpme.core.service.HrServiceLocator;
49  import org.kuali.kpme.core.workarea.service.WorkAreaService;
50  import org.kuali.rice.core.api.criteria.LookupCustomizer;
51  import org.kuali.rice.core.api.criteria.Predicate;
52  import org.kuali.rice.core.api.criteria.QueryByCriteria;
53  import org.kuali.rice.core.api.membership.MemberType;
54  import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
55  import org.kuali.rice.kim.api.KimConstants;
56  import org.kuali.rice.kim.api.group.GroupService;
57  import org.kuali.rice.kim.api.role.Role;
58  import org.kuali.rice.kim.api.role.RoleMember;
59  import org.kuali.rice.kim.api.role.RoleMembership;
60  import org.kuali.rice.kim.api.role.RoleService;
61  import org.kuali.rice.kim.api.type.KimType;
62  import org.kuali.rice.kim.api.type.KimTypeInfoService;
63  import org.kuali.rice.kim.framework.role.RoleTypeService;
64  import org.kuali.rice.kim.framework.type.KimTypeService;
65  import org.kuali.rice.kim.impl.KIMPropertyConstants;
66  import org.kuali.rice.kim.impl.common.attribute.AttributeTransform;
67  import org.kuali.rice.kim.impl.role.RoleMemberBo;
68  
69  public class KPMERoleServiceImpl implements KPMERoleService {
70  	
71      private static final Logger LOG = Logger.getLogger(KPMERoleServiceImpl.class);
72      
73      private DepartmentService departmentService;
74      private GroupService groupService;
75  	private KimTypeInfoService kimTypeInfoService;
76  	private RoleService roleService;
77  	private WorkAreaService workAreaService;
78  
79  	public boolean principalHasRole(String principalId, String namespaceCode, String roleName, DateTime asOfDate) {
80  		Map<String, String> qualification = new HashMap<String, String>();
81  		
82  		return principalHasRole(principalId, namespaceCode, roleName, qualification, asOfDate);
83  	}
84  
85  	public boolean principalHasRole(String principalId, String namespaceCode, String roleName, Map<String, String> qualification, DateTime asOfDate) {
86  		boolean principalHasRole = false;
87  		
88  		String roleId = getRoleService().getRoleIdByNamespaceCodeAndName(namespaceCode, roleName);
89  
90  		if(roleId == null)
91  			return false;
92  		
93          if (asOfDate.equals(LocalDate.now().toDateTimeAtStartOfDay())) {
94              principalHasRole = getRoleService().principalHasRole(principalId, Collections.singletonList(roleId), qualification);
95          } else {
96  
97              List<Predicate> predicates = new ArrayList<Predicate>();
98              predicates.add(equal(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleId));
99              predicates.add(or(isNull("activeFromDateValue"), lessThanOrEqual("activeFromDateValue", asOfDate)));
100             predicates.add(or(isNull("activeToDateValue"), greaterThan("activeToDateValue", asOfDate)));
101 
102             LookupCustomizer.Builder<RoleMemberBo> builder = LookupCustomizer.Builder.create();
103             builder.setPredicateTransform(AttributeTransform.getInstance());
104             LookupCustomizer<RoleMemberBo> lookupCustomizer = builder.build();
105             for (Map.Entry<String, String> qualificationEntry : qualification.entrySet()) {
106                 Predicate predicate = equal("attributes[" + qualificationEntry.getKey() + "]", qualificationEntry.getValue());
107                 predicates.add(lookupCustomizer.getPredicateTransform().apply(predicate));
108             }
109 
110             List<RoleMember> roleMembers = getRoleMembers(namespaceCode, roleName, qualification, asOfDate, true);
111 
112             for (RoleMember roleMember : roleMembers) {
113                 if (MemberType.PRINCIPAL.equals(roleMember.getType())) {
114                     if (StringUtils.equals(roleMember.getMemberId(), principalId)) {
115                         principalHasRole = true;
116                         break;
117                     }
118                 } else if (MemberType.GROUP.equals(roleMember.getType())) {
119                     if (getGroupService().isMemberOfGroup(principalId, roleMember.getMemberId())) {
120                         principalHasRole = true;
121                         break;
122                     }
123                 } else if (MemberType.ROLE.equals(roleMember.getType())) {
124                 	Role derivedRole = getRoleService().getRoleByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.DERIVED_ROLE_POSITION.getRoleName());
125                 	// check if the member represents the (nested) derived role 'position'
126                 	if(derivedRole != null && roleMember.getMemberId().equals(derivedRole.getId())) {
127                 		// return true if the principal id is a member of the (nested) derived role 'position'
128                 		RoleTypeService roleTypeService = getRoleTypeService(derivedRole);
129                 		if(roleTypeService.hasDerivedRole(principalId, new ArrayList<String>(), derivedRole.getNamespaceCode(), derivedRole.getName(), qualification)) {
130 	                		principalHasRole = true;
131 	                		break;
132                 		}
133                 	}
134                 }
135             }
136         }
137 				
138 		return principalHasRole;
139 	}
140 
141 	public boolean principalHasRoleInWorkArea(String principalId, String namespaceCode, String roleName, Long workArea, DateTime asOfDate) {
142 		Map<String, String> qualification = new HashMap<String, String>();
143 		qualification.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), String.valueOf(workArea));
144 		//JobContract jobObj = HrServiceLocator.getJobService().getPrimaryJob(principalId, LocalDate.now());
145         //if(jobObj != null) {
146         //	qualification.put(KPMERoleMemberAttribute.POSITION.getRoleMemberAttributeName(), jobObj.getPositionNumber());
147         //}
148 		return principalHasRole(principalId, namespaceCode, roleName, qualification, asOfDate);
149 	}
150 
151 	public boolean principalHasRoleInDepartment(String principalId, String namespaceCode, String roleName, String department, DateTime asOfDate) {
152 		Map<String, String> qualification = new HashMap<String, String>();
153 		qualification.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), department);
154 		
155 		return principalHasRole(principalId, namespaceCode, roleName, qualification, asOfDate);
156 	}
157 
158 	public boolean principalHasRoleInLocation(String principalId, String namespaceCode, String roleName, String location, DateTime asOfDate) {
159 		Map<String, String> qualification = new HashMap<String, String>();
160 		qualification.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), location);
161 		
162 		return principalHasRole(principalId, namespaceCode, roleName, qualification, asOfDate);
163 	}
164 
165 	public List<RoleMember> getRoleMembers(String namespaceCode, String roleName, DateTime asOfDate, boolean isActiveOnly) {
166 		Map<String, String> qualification = new HashMap<String, String>();
167 		
168 		return getRoleMembers(namespaceCode, roleName, qualification, asOfDate, isActiveOnly);
169 	}
170 
171 	public List<RoleMember> getRoleMembers(String namespaceCode, String roleName, Map<String, String> qualification, DateTime asOfDate, boolean isActiveOnly) {
172 		Role role = getRoleService().getRoleByNamespaceCodeAndName(namespaceCode, roleName);
173 		
174 		return getRoleMembers(role, qualification, asOfDate, isActiveOnly);
175 	}
176 	
177 	/**
178 	 * Helper method to recursively search for role members.
179 	 * 
180 	 * @param role The role
181 	 * @param qualification The map of role qualifiers
182 	 * @param asOfDate The effective date of the role
183 	 * @param  activeOnly or not to get only active role members
184 	 * 
185 	 * @return the list of role members in {@code role}.
186 	 */
187 	private List<RoleMember> getRoleMembers(Role role, Map<String, String> qualification, DateTime asOfDate, boolean activeOnly) {
188 		List<RoleMember> roleMembers = new ArrayList<RoleMember>();
189 		
190 		if (role != null) {
191 			RoleTypeService roleTypeService = getRoleTypeService(role);
192 			
193 			if (roleTypeService == null || !roleTypeService.isDerivedRoleType()) {
194                 if (asOfDate.equals(LocalDate.now().toDateTimeAtStartOfDay())) {
195                     List<RoleMembership> memberships = getRoleService().getRoleMembers(Collections.singletonList(role.getId()), qualification);
196                     for (RoleMembership membership : memberships) {
197                         RoleMember roleMember = RoleMember.Builder.create(membership.getRoleId(), membership.getId(), membership.getMemberId(),
198                                 membership.getType(), null, null, membership.getQualifier(), role.getName(), role.getNamespaceCode()).build();
199 
200                         roleMembers.add(roleMember);
201                     }
202                 } else {
203                     List<Predicate> predicates = new ArrayList<Predicate>();
204                     predicates.add(equal(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, role.getId()));
205                     if (activeOnly) {
206                         predicates.add(or(isNull("activeFromDateValue"), lessThanOrEqual("activeFromDateValue", asOfDate)));
207                         predicates.add(or(isNull("activeToDateValue"), greaterThan("activeToDateValue", asOfDate)));
208                     }
209 
210                     LookupCustomizer.Builder<RoleMemberBo> builder = LookupCustomizer.Builder.create();
211                     builder.setPredicateTransform(AttributeTransform.getInstance());
212                     LookupCustomizer<RoleMemberBo> lookupCustomizer = builder.build();
213                     for (Map.Entry<String, String> qualificationEntry : qualification.entrySet()) {
214                         Predicate predicate = equal("attributes[" + qualificationEntry.getKey() + "]", qualificationEntry.getValue());
215                         predicates.add(lookupCustomizer.getPredicateTransform().apply(predicate));
216                     }
217 
218                     List<RoleMember> primaryRoleMembers = getRoleService().findRoleMembers(QueryByCriteria.Builder.fromPredicates(predicates.toArray(new Predicate[] {}))).getResults();
219 
220                     Role positionRole = getRoleService().getRoleByNamespaceCodeAndName(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.DERIVED_ROLE_POSITION.getRoleName());
221                     for (RoleMember primaryRoleMember : primaryRoleMembers) {
222                         if (MemberType.PRINCIPAL.equals(primaryRoleMember.getType())) {
223                             roleMembers.add(primaryRoleMember);
224                         } else if (MemberType.ROLE.equals(primaryRoleMember.getType())) {
225                             // position role memeber has "Derived Role : Position"'s id as the member id
226                             if(positionRole != null && primaryRoleMember.getMemberId().equals(positionRole.getId())) {
227                                 roleMembers.add(primaryRoleMember);
228                             } else {
229                                 Role nestedRole = getRoleService().getRole(primaryRoleMember.getMemberId());
230                                 roleMembers.addAll(getRoleMembers(nestedRole, primaryRoleMember.getAttributes(), asOfDate, activeOnly));
231                             }
232                         }
233                     }
234                 }
235 			} else {
236 				List<RoleMembership> derivedRoleMembers = roleTypeService.getRoleMembersFromDerivedRole(role.getNamespaceCode(), role.getName(), qualification);
237 				
238 				for (RoleMembership derivedRoleMember : derivedRoleMembers) {
239 					RoleMember roleMember = RoleMember.Builder.create(derivedRoleMember.getRoleId(), derivedRoleMember.getId(), derivedRoleMember.getMemberId(), 
240 							derivedRoleMember.getType(), null, null, derivedRoleMember.getQualifier(), role.getName(), role.getNamespaceCode()).build();
241 				                        
242 					roleMembers.add(roleMember);
243 				}
244 			}
245 		}
246 		
247 		return roleMembers;
248 	}
249 
250 	public List<RoleMember> getRoleMembersInPosition(String namespaceCode, String roleName, String position, DateTime asOfDate, boolean isActiveOnly) {
251 		Map<String, String> qualification = new HashMap<String, String>();
252 		qualification.put(KPMERoleMemberAttribute.POSITION.getRoleMemberAttributeName(), String.valueOf(position));
253 		return getRoleMembers(namespaceCode, roleName, qualification, asOfDate, isActiveOnly);
254 	}
255 	
256 	public List<RoleMember> getRoleMembersInWorkArea(String namespaceCode, String roleName, Long workArea, DateTime asOfDate, boolean isActiveOnly) {
257 		Map<String, String> qualification = new HashMap<String, String>();
258 		qualification.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), String.valueOf(workArea));
259 		
260 		return getRoleMembers(namespaceCode, roleName, qualification, asOfDate, isActiveOnly);
261 	}
262 
263 	public List<RoleMember> getRoleMembersInDepartment(String namespaceCode, String roleName, String department, DateTime asOfDate, boolean isActiveOnly) {
264 		Map<String, String> qualification = new HashMap<String, String>();
265 		qualification.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), department);
266 		
267 		return getRoleMembers(namespaceCode, roleName, qualification, asOfDate, isActiveOnly);
268 	}
269 
270 	public List<RoleMember> getRoleMembersInLocation(String namespaceCode, String roleName, String location, DateTime asOfDate, boolean isActiveOnly) {
271 		Map<String, String> qualification = new HashMap<String, String>();
272 		qualification.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), location);
273 		
274 		return getRoleMembers(namespaceCode, roleName, qualification, asOfDate, isActiveOnly);
275 	}
276 
277     @Override
278     public List<Long> getWorkAreasForPrincipalInRoles(String principalId, List<String> roleIds, DateTime asOfDate, boolean isActiveOnly) {
279         Set<Long> workAreas = new HashSet<Long>();
280 
281         Map<String, String> qualifiers = new HashMap<String, String>();
282         qualifiers.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), "%");
283         qualifiers.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), "%");
284         qualifiers.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), "%");
285         JobContract jobObj = HrServiceLocator.getJobService().getPrimaryJob(principalId, LocalDate.now());
286         if(jobObj != null) {
287         	qualifiers.put(KPMERoleMemberAttribute.POSITION.getRoleMemberAttributeName(), jobObj.getPositionNumber());
288         }
289         
290         List<Map<String, String>> roleQualifiers = getRoleQualifiers(principalId, roleIds, qualifiers, asOfDate, isActiveOnly);
291 		for (Map<String, String> roleQualifier : roleQualifiers) {
292 			Long workArea = MapUtils.getLong(roleQualifier, KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName());
293 			if(workArea != null) {
294 				workAreas.add(workArea);
295 			}
296 		}
297 
298         List<String> departments = getDepartmentsForPrincipalInRoles(principalId, roleIds, asOfDate, isActiveOnly);
299         workAreas.addAll(getWorkAreaService().getWorkAreasForDepartments(departments, asOfDate.toLocalDate()));
300 
301         return new ArrayList<Long>(workAreas);
302     }
303 
304     public List<Long> getWorkAreasForPrincipalInRole(String principalId, String namespaceCode, String roleName, DateTime asOfDate, boolean isActiveOnly) {
305 		Set<Long> workAreas = new HashSet<Long>();
306 		
307 		Role role = getRoleService().getRoleByNamespaceCodeAndName(namespaceCode, roleName);
308 
309         Map<String, String> qualifiers = new HashMap<String, String>();
310         qualifiers.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), "%");
311         qualifiers.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), "%");
312         qualifiers.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), "%");
313         JobContract jobObj = HrServiceLocator.getJobService().getPrimaryJob(principalId, LocalDate.now());
314         if(jobObj != null) {
315         	qualifiers.put(KPMERoleMemberAttribute.POSITION.getRoleMemberAttributeName(), jobObj.getPositionNumber());
316         }
317         
318 		List<Map<String, String>> roleQualifiers = getRoleQualifiers(principalId, role, qualifiers, asOfDate, isActiveOnly);
319 		for (Map<String, String> roleQualifier : roleQualifiers) {
320 			Long workArea = MapUtils.getLong(roleQualifier, KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName());
321 			if(workArea != null) {
322 				workAreas.add(workArea);
323 			}
324 		}
325 		
326 		List<String> departments = getDepartmentsForPrincipalInRole(principalId, namespaceCode, roleName, asOfDate, isActiveOnly);
327 		workAreas.addAll(getWorkAreaService().getWorkAreasForDepartments(departments, asOfDate.toLocalDate()));
328 
329 		return new ArrayList<Long>(workAreas);
330 	}
331 
332     public List<String> getDepartmentsForPrincipalInRoles(String principalId, List<String> roleIds, DateTime asOfDate, boolean isActiveOnly) {
333         Set<String> departments = new HashSet<String>();
334 
335         //Role role = getRoleService().getRoleByNamespaceCodeAndName(namespaceCode, roleName);
336 
337         Map<String, String> qualifiers = new HashMap<String, String>();
338         qualifiers.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), "%");
339         qualifiers.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), "%");
340         qualifiers.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), "%");
341         List<Map<String, String>> roleQualifiers = getRoleQualifiers(principalId, roleIds, qualifiers, asOfDate, isActiveOnly);
342 
343         for (Map<String, String> roleQualifier : roleQualifiers) {
344             String department = MapUtils.getString(roleQualifier, KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName());
345             if (department != null) {
346                 departments.add(department);
347             }
348         }
349 
350         List<String> locations = getLocationsForPrincipalInRoles(principalId, roleIds, asOfDate, isActiveOnly);
351         departments.addAll(getDepartmentService().getDepartmentsForLocations(locations, asOfDate.toLocalDate()));
352 
353         return new ArrayList<String>(departments);
354     }
355 
356 	public List<String> getDepartmentsForPrincipalInRole(String principalId, String namespaceCode, String roleName, DateTime asOfDate, boolean isActiveOnly) {
357 		Set<String> departments = new HashSet<String>();
358 		
359 		Role role = getRoleService().getRoleByNamespaceCodeAndName(namespaceCode, roleName);
360 
361         Map<String, String> qualifiers = new HashMap<String, String>();
362         qualifiers.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), "%");
363         qualifiers.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), "%");
364         qualifiers.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), "%");
365         List<Map<String, String>> roleQualifiers = getRoleQualifiers(principalId, role, qualifiers, asOfDate, isActiveOnly);
366 		
367 		for (Map<String, String> roleQualifier : roleQualifiers) {
368 			String department = MapUtils.getString(roleQualifier, KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName());
369 			if (department != null) {
370 				departments.add(department);
371 			}
372 		}
373 		
374 		List<String> locations = getLocationsForPrincipalInRole(principalId, namespaceCode, roleName, asOfDate, isActiveOnly);
375 		departments.addAll(getDepartmentService().getDepartmentsForLocations(locations, asOfDate.toLocalDate()));
376 
377 		return new ArrayList<String>(departments);
378 	}
379 
380     public List<String> getLocationsForPrincipalInRoles(String principalId, List<String> roleIds, DateTime asOfDate, boolean isActiveOnly) {
381         Set<String> locations = new HashSet<String>();
382 
383         Map<String, String> qualifiers = new HashMap<String, String>();
384         qualifiers.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), "%");
385         qualifiers.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), "%");
386         qualifiers.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), "%");
387         List<Map<String, String>> roleQualifiers = getRoleQualifiers(principalId, roleIds, qualifiers, asOfDate, isActiveOnly);
388 
389         for (Map<String, String> roleQualifier : roleQualifiers) {
390             String location = MapUtils.getString(roleQualifier, KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName());
391 
392             if (location != null) {
393                 locations.add(location);
394             }
395         }
396 
397         return new ArrayList<String>(locations);
398     }
399 
400 	public List<String> getLocationsForPrincipalInRole(String principalId, String namespaceCode, String roleName, DateTime asOfDate, boolean isActiveOnly) {
401 		Set<String> locations = new HashSet<String>();
402 		
403 		Role role = getRoleService().getRoleByNamespaceCodeAndName(namespaceCode, roleName);
404 
405         Map<String, String> qualifiers = new HashMap<String, String>();
406         qualifiers.put(KPMERoleMemberAttribute.WORK_AREA.getRoleMemberAttributeName(), "%");
407         qualifiers.put(KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName(), "%");
408         qualifiers.put(KPMERoleMemberAttribute.DEPARTMENT.getRoleMemberAttributeName(), "%");
409 		List<Map<String, String>> roleQualifiers = getRoleQualifiers(principalId, role, qualifiers, asOfDate, isActiveOnly);
410 		
411 		for (Map<String, String> roleQualifier : roleQualifiers) {
412 			String location = MapUtils.getString(roleQualifier, KPMERoleMemberAttribute.LOCATION.getRoleMemberAttributeName());
413 			
414 			if (location != null) {
415 				locations.add(location);
416 			}
417 		}
418 		
419 		return new ArrayList<String>(locations);
420 	}
421 	
422 	/**
423 	 * Helper method to gather up all qualifiers for the given {@code principalId} in {@code role}.
424 	 *
425 	 * @param principalId The person get the role qualifiers for
426 	 * @param role The role
427 	 * @param asOfDate The effective date of the role
428 	 * @param activeOnly Whether or not to consider only active role members
429 	 * 
430 	 * @return the map of qualifiers for the given {@code principalId} in {@code role}.
431 	 */
432 	private List<Map<String, String>> getRoleQualifiers(String principalId, Role role, Map<String, String> qualifiers, DateTime asOfDate, boolean activeOnly) {
433 		List<Map<String, String>> roleQualifiers = new ArrayList<Map<String, String>>();
434         if (asOfDate.equals(LocalDate.now().toDateTimeAtStartOfDay()) && activeOnly) {
435         	List<RoleMembership> principalIdRoleMembers = getRoleService().getRoleMembers(Collections.singletonList(role.getId()), qualifiers);
436         	for(RoleMembership rm : principalIdRoleMembers){
437         		if(rm.getMemberId().equals(principalId)) {
438         			roleQualifiers.add(rm.getQualifier());
439         		}
440         	}
441             return roleQualifiers;
442         }
443 		if (role != null) {
444 			List<RoleMember> principalIdRoleMembers = getPrincipalIdRoleMembers(principalId, role, asOfDate, activeOnly);
445 			
446 	        for (RoleMember principalIdRoleMember : principalIdRoleMembers) {
447 	        	roleQualifiers.add(principalIdRoleMember.getAttributes());
448 	        }
449 		}
450         
451         return roleQualifiers;
452 	}
453 
454     /**
455      * Helper method to gather up all qualifiers for the given {@code principalId} in {@code role}.
456      *
457      * @param principalId The person get the role qualifiers for
458      * @param roleIds The roleIds
459      * @param asOfDate The effective date of the role
460      * @param activeOnly Whether or not to consider only active role members
461      *
462      * @return the map of qualifiers for the given {@code principalId} in {@code role}.
463      */
464     private List<Map<String, String>> getRoleQualifiers(String principalId, List<String> roleIds, Map<String, String> qualifiers, DateTime asOfDate, boolean activeOnly) {
465         List<Map<String, String>> roleQualifiers = new ArrayList<Map<String, String>>();
466 
467         if (asOfDate.equals(LocalDate.now().toDateTimeAtStartOfDay()) && activeOnly) {
468         	List<RoleMembership> principalIdRoleMembers = getRoleService().getRoleMembers(roleIds, qualifiers);
469         	for(RoleMembership rm : principalIdRoleMembers){
470         		if(rm.getMemberId().equals(principalId)) {
471         			roleQualifiers.add(rm.getQualifier());
472         		}
473         	}
474         	return roleQualifiers;
475         }
476         if (CollectionUtils.isNotEmpty(roleIds)) {
477             List<RoleMember> principalIdRoleMembers = getPrincipalIdRoleMembers(principalId, roleIds, asOfDate, activeOnly);
478 
479             for (RoleMember principalIdRoleMember : principalIdRoleMembers) {
480                 roleQualifiers.add(principalIdRoleMember.getAttributes());
481             }
482         }
483 
484         return roleQualifiers;
485     }
486 
487 
488     /**
489      * Helper method to get the role member objects.
490      *
491      * @param principalId The person to get the role for
492      * @param roleIds The role
493      * @param asOfDate The effective date of the role
494      * @param activeOnly Whether or not to consider only active role members
495      *
496      * @return the list of role member objects
497      */
498     private List<RoleMember> getPrincipalIdRoleMembers(String principalId, List<String> roleIds, DateTime asOfDate, boolean activeOnly) {
499         List<String> groupIds = getGroupService().getGroupIdsByPrincipalId(principalId);
500 
501         List<Predicate> predicates = new ArrayList<Predicate>();
502         predicates.add(in(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleIds.toArray(new String[roleIds.size()])));
503 
504         List<Predicate> principalPredicates = new ArrayList<Predicate>();
505         principalPredicates.add(equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode()));
506         if (principalId != null) {
507             principalPredicates.add(equal(KIMPropertyConstants.RoleMember.MEMBER_ID, principalId));
508         }
509         Predicate principalPredicate = and(principalPredicates.toArray(new Predicate[] {}));
510 
511         Predicate rolePredicate = equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.ROLE.getCode());
512 
513         List<Predicate> groupPredicates = new ArrayList<Predicate>();
514         groupPredicates.add(equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode()));
515         if (CollectionUtils.isNotEmpty(groupIds)) {
516             groupPredicates.add(in(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds.toArray(new String[] {})));
517         }
518         Predicate groupPredicate = and(groupPredicates.toArray(new Predicate[] {}));
519 
520         predicates.add(or(principalPredicate, rolePredicate, groupPredicate));
521 
522         if (activeOnly) {
523             predicates.add(or(isNull("activeFromDateValue"), lessThanOrEqual("activeFromDateValue", asOfDate)));
524             predicates.add(or(isNull("activeToDateValue"), greaterThan("activeToDateValue", asOfDate)));
525         }
526 
527         return getRoleService().findRoleMembers(QueryByCriteria.Builder.fromPredicates(predicates.toArray(new Predicate[] {}))).getResults();
528     }
529 	/**
530 	 * Helper method to get the role member objects.
531 	 * 
532 	 * @param principalId The person to get the role for
533 	 * @param role The role
534 	 * @param asOfDate The effective date of the role
535 	 * @param activeOnly Whether or not to consider only active role members
536 	 * 
537 	 * @return the list of role member objects
538 	 */
539 	private List<RoleMember> getPrincipalIdRoleMembers(String principalId, Role role, DateTime asOfDate, boolean activeOnly) {
540 		List<String> groupIds = getGroupService().getGroupIdsByPrincipalId(principalId);
541 
542 		List<Predicate> predicates = new ArrayList<Predicate>();
543 		predicates.add(equal(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, role.getId()));
544 		
545 		List<Predicate> principalPredicates = new ArrayList<Predicate>();
546 		principalPredicates.add(equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode()));
547 		if (principalId != null) {
548 			principalPredicates.add(equal(KIMPropertyConstants.RoleMember.MEMBER_ID, principalId));
549 		}
550 		Predicate principalPredicate = and(principalPredicates.toArray(new Predicate[] {}));
551 		
552 		Predicate rolePredicate = equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.ROLE.getCode());
553 		
554 		List<Predicate> groupPredicates = new ArrayList<Predicate>();
555 		groupPredicates.add(equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode()));
556 		if (CollectionUtils.isNotEmpty(groupIds)) {
557 			groupPredicates.add(in(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds.toArray(new String[] {})));
558 		}
559 		Predicate groupPredicate = and(groupPredicates.toArray(new Predicate[] {}));
560 		
561 		predicates.add(or(principalPredicate, rolePredicate, groupPredicate));
562 		
563 		if (activeOnly) {
564 			predicates.add(or(isNull("activeFromDateValue"), lessThanOrEqual("activeFromDateValue", asOfDate)));
565 			predicates.add(or(isNull("activeToDateValue"), greaterThan("activeToDateValue", asOfDate)));
566 		}
567 		
568 		return getRoleService().findRoleMembers(QueryByCriteria.Builder.fromPredicates(predicates.toArray(new Predicate[] {}))).getResults();
569 	}
570 	
571 	/**
572 	 * Gets the derived role service for {@code role}.
573 	 * 
574 	 * @param role the role
575 	 * 
576 	 * @return the derived role service name for {@code role}.
577 	 */
578     protected RoleTypeService getRoleTypeService(Role role) {
579     	RoleTypeService roleTypeService = null;
580     	
581         if (role != null) {
582         	String serviceName = getDerivedRoleServiceName(role.getKimTypeId());
583         	
584         	if (serviceName != null) {
585                 try {
586                     KimTypeService service = (KimTypeService) GlobalResourceLoader.getService(QName.valueOf(serviceName));
587                     if (service != null && service instanceof RoleTypeService) {
588                         return (RoleTypeService) service;
589                     }
590                 } catch (Exception ex) {
591                     LOG.error("Unable to find role type service with name: " + serviceName, ex);
592                 }
593             }
594         }
595         
596         return roleTypeService;
597     }
598 
599 	/**
600 	 * Gets the derived role service name for {@code kimTypeId}.
601 	 * 
602 	 * @param kimTypeId the KIM type id
603 	 * 
604 	 * @return the derived role service name for {@code kimTypeId}.
605 	 */
606 	protected String getDerivedRoleServiceName(String kimTypeId) {
607 		KimType kimType = getKimTypeInfoService().getKimType(kimTypeId);
608 		
609 		return kimType != null ? kimType.getServiceName() : null;
610 	}
611     
612     public DepartmentService getDepartmentService() {
613     	return departmentService;
614     }
615     
616     public void setDepartmentService(DepartmentService departmentService) {
617     	this.departmentService = departmentService;
618     }
619 
620 	public GroupService getGroupService() {
621 		return groupService;
622 	}
623 
624 	public void setGroupService(GroupService groupService) {
625 		this.groupService = groupService;
626 	}
627 
628 	public KimTypeInfoService getKimTypeInfoService() {
629 		return kimTypeInfoService;
630 	}
631 
632 	public void setKimTypeInfoService(KimTypeInfoService kimTypeInfoService) {
633 		this.kimTypeInfoService = kimTypeInfoService;
634 	}
635 
636 	public RoleService getRoleService() {
637 		return roleService;
638 	}
639 
640 	public void setRoleService(RoleService roleService) {
641 		this.roleService = roleService;
642 	}
643 	
644     public WorkAreaService getWorkAreaService() {
645     	return workAreaService;
646     }
647     
648     public void setWorkAreaService(WorkAreaService workAreaService) {
649     	this.workAreaService = workAreaService;
650     }
651 
652 }