View Javadoc
1   /**
2    * Copyright 2005-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.rice.kim.lookup;
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.in;
21  import static org.kuali.rice.core.api.criteria.PredicateFactory.like;
22  import static org.kuali.rice.core.api.criteria.PredicateFactory.likeIgnoreCase;
23  import static org.kuali.rice.core.api.criteria.PredicateFactory.or;
24  
25  import java.util.ArrayList;
26  import java.util.Collection;
27  import java.util.Collections;
28  import java.util.Comparator;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.Map.Entry;
34  import java.util.Properties;
35  import java.util.Set;
36  
37  import org.apache.commons.lang.StringUtils;
38  import org.joda.time.DateTime;
39  import org.kuali.rice.core.api.CoreApiServiceLocator;
40  import org.kuali.rice.core.api.criteria.Predicate;
41  import org.kuali.rice.core.api.criteria.QueryByCriteria;
42  import org.kuali.rice.core.api.membership.MemberType;
43  import org.kuali.rice.core.api.util.ConcreteKeyValue;
44  import org.kuali.rice.core.api.util.KeyValue;
45  import org.kuali.rice.core.api.util.Truth;
46  import org.kuali.rice.kew.api.KewApiConstants;
47  import org.kuali.rice.kim.api.KimConstants;
48  import org.kuali.rice.kim.api.identity.principal.Principal;
49  import org.kuali.rice.kim.api.permission.Permission;
50  import org.kuali.rice.kim.api.responsibility.Responsibility;
51  import org.kuali.rice.kim.api.responsibility.ResponsibilityQueryResults;
52  import org.kuali.rice.kim.api.role.Role;
53  import org.kuali.rice.kim.api.role.RoleMember;
54  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
55  import org.kuali.rice.kim.api.type.KimAttributeField;
56  import org.kuali.rice.kim.api.type.KimType;
57  import org.kuali.rice.kim.impl.KIMPropertyConstants;
58  import org.kuali.rice.kim.impl.role.RoleBo;
59  import org.kuali.rice.kim.impl.type.KimTypeBo;
60  import org.kuali.rice.kim.impl.type.KimTypeLookupableHelperServiceImpl;
61  import org.kuali.rice.kim.util.KimCommonUtilsInternal;
62  import org.kuali.rice.kim.web.struts.form.IdentityManagementRoleDocumentForm;
63  import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions;
64  import org.kuali.rice.kns.lookup.HtmlData;
65  import org.kuali.rice.kns.web.struts.form.KualiForm;
66  import org.kuali.rice.kns.web.struts.form.LookupForm;
67  import org.kuali.rice.kns.web.ui.Field;
68  import org.kuali.rice.kns.web.ui.Row;
69  import org.kuali.rice.krad.bo.BusinessObject;
70  import org.kuali.rice.krad.datadictionary.BusinessObjectEntry;
71  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
72  import org.kuali.rice.krad.service.ModuleService;
73  import org.kuali.rice.krad.util.BeanPropertyComparator;
74  import org.kuali.rice.krad.util.GlobalVariables;
75  import org.kuali.rice.krad.util.KRADConstants;
76  import org.kuali.rice.krad.util.UrlFactory;
77  
78  /**
79   * This is a description of what this class does - shyu don't forget to fill this in.
80   *
81   * @author Kuali Rice Team (rice.collab@kuali.org)
82   *
83   */
84  public class RoleLookupableHelperServiceImpl extends KimLookupableHelperServiceImpl {
85      private static final long serialVersionUID = 1L;
86  
87      protected static final String GROUP_CRITERIA = "group";
88      protected static final String RESPONSIBILITY_CRITERIA = "resp";
89      protected static final String PERMISSION_CRITERIA = "perm";
90      protected static final String ROLE_MEMBER_ATTRIBUTE_CRITERIA = "attr";
91      protected static final String OTHER_CRITERIA = "lookupNames";
92  
93      protected static final String LOOKUP_PARM_PERMISSION_TEMPLATE_NAMESPACE = "permTmplNamespaceCode";
94      protected static final String LOOKUP_PARM_PERMISSION_TEMPLATE_NAME = "permTmplName";
95      protected static final String LOOKUP_PARM_PERMISSION_NAMESPACE = "permNamespaceCode";
96      protected static final String LOOKUP_PARM_PERMISSION_NAME = "permName";
97  
98      protected static final String LOOKUP_PARM_RESP_TEMPLATE_NAMESPACE = "respTmplNamespaceCode";
99      protected static final String LOOKUP_PARM_RESP_TEMPLATE_NAME = "respTmplName";
100     protected static final String LOOKUP_PARM_RESP_NAMESPACE = "respNamespaceCode";
101     protected static final String LOOKUP_PARM_RESP_NAME = "respName";
102 
103 	// need this so kimtypeId value can be retained in 'rows'
104 	// 1st pass populate the grprows
105 	// 2nd pass for jsp, no populate, so return the existing one.
106 	private List<Row> roleRows = new ArrayList<Row>();
107 	private List<Row> attrRows = new ArrayList<Row>();
108 	private String typeId;
109 	private List<KimAttributeField> attrDefinitions;
110 
111 	/**
112 	 * This overridden method ...
113 	 *
114 	 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#allowsMaintenanceNewOrCopyAction()
115 	 */
116 	@Override
117 	public boolean allowsMaintenanceNewOrCopyAction() {
118         Map<String, String> permissionDetails = new HashMap<String, String>();
119         permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME,KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_TYPE_NAME);
120         permissionDetails.put(KRADConstants.MAINTENANCE_ACTN, KRADConstants.MAINTENANCE_NEW_ACTION);
121 
122         return !KimApiServiceLocator.getPermissionService().isPermissionDefinedByTemplate(KRADConstants.KNS_NAMESPACE,
123                 KimConstants.PermissionTemplateNames.CREATE_MAINTAIN_RECORDS, permissionDetails)
124                 || KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(GlobalVariables.getUserSession().getPrincipalId(), KRADConstants.KNS_NAMESPACE,
125                 KimConstants.PermissionTemplateNames.CREATE_MAINTAIN_RECORDS, permissionDetails,
126                 new HashMap<String, String>());
127 	}
128 
129 	/**
130 	 * This overridden method ...
131 	 *
132 	 * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#allowsMaintenanceEditAction(org.kuali.rice.krad.bo.BusinessObject)
133 	 */
134 	@Override
135 	protected boolean allowsMaintenanceEditAction(BusinessObject businessObject) {
136         Map<String, String> permissionDetails = new HashMap<String, String>(2);
137         permissionDetails.put(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME,KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_TYPE_NAME);
138         permissionDetails.put(KRADConstants.MAINTENANCE_ACTN, KRADConstants.MAINTENANCE_EDIT_ACTION);
139 
140         return !KimApiServiceLocator.getPermissionService().isPermissionDefinedByTemplate(KRADConstants.KNS_NAMESPACE,
141                 KimConstants.PermissionTemplateNames.CREATE_MAINTAIN_RECORDS, permissionDetails)
142                 || KimApiServiceLocator.getPermissionService().isAuthorizedByTemplate(GlobalVariables.getUserSession().getPrincipalId(), KRADConstants.KNS_NAMESPACE,
143                 KimConstants.PermissionTemplateNames.CREATE_MAINTAIN_RECORDS, permissionDetails,
144                 new HashMap<String, String>());
145 	}
146 
147     @Override
148     public List<HtmlData> getCustomActionUrls(BusinessObject bo, List pkNames) {
149     	RoleBo roleBo = (RoleBo) bo;
150         List<HtmlData> anchorHtmlDataList = new ArrayList<HtmlData>();
151     	if(allowsNewOrCopyAction(KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_TYPE_NAME)){
152     		anchorHtmlDataList.add(getEditRoleUrl(roleBo));
153     	}
154     	return anchorHtmlDataList;
155     }
156 
157     protected HtmlData getEditRoleUrl(RoleBo roleBo) {
158         Properties parameters = new Properties();
159         parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.DOC_HANDLER_METHOD);
160         parameters.put(KRADConstants.PARAMETER_COMMAND, KewApiConstants.INITIATE_COMMAND);
161         parameters.put(KRADConstants.DOCUMENT_TYPE_NAME, KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_TYPE_NAME);
162         parameters.put(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID, roleBo.getId());
163         if (StringUtils.isNotBlank(getReturnLocation())) {
164         	parameters.put(KRADConstants.RETURN_LOCATION_PARAMETER, getReturnLocation());
165 		}
166         String href = UrlFactory.parameterizeUrl(KimCommonUtilsInternal.getKimBasePath()+KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_ACTION, parameters);
167 
168         HtmlData.AnchorHtmlData anchorHtmlData = new HtmlData.AnchorHtmlData(href,
169         		KRADConstants.DOC_HANDLER_METHOD, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL);
170         return anchorHtmlData;
171     }
172 
173     @Override
174 	protected HtmlData getReturnAnchorHtmlData(BusinessObject businessObject, Properties parameters, LookupForm lookupForm, List returnKeys, BusinessObjectRestrictions businessObjectRestrictions){
175     	RoleBo roleBo = (RoleBo) businessObject;
176     	HtmlData anchorHtmlData = super.getReturnAnchorHtmlData(businessObject, parameters, lookupForm, returnKeys, businessObjectRestrictions);
177 
178     	// prevent derived roles from being selectable (except for identityManagementRoleDocuments)
179     	KualiForm myForm = (KualiForm) GlobalVariables.getUserSession().retrieveObject(getDocFormKey());
180     	if (myForm == null || !(myForm instanceof IdentityManagementRoleDocumentForm)){
181     		if(KimTypeLookupableHelperServiceImpl.hasDerivedRoleTypeService(KimTypeBo.to(roleBo.getKimRoleType()))){
182     			((HtmlData.AnchorHtmlData)anchorHtmlData).setHref("");
183     		}
184     	}
185     	return anchorHtmlData;
186     }
187 
188     @Override
189     public List<? extends BusinessObject> getSearchResults(java.util.Map<String,String> fieldValues) {
190         fieldValues.remove(KRADConstants.BACK_LOCATION);
191         fieldValues.remove(KRADConstants.DOC_FORM_KEY);
192         fieldValues.remove(KRADConstants.DOC_NUM);
193 
194         QueryByCriteria criteria = getRoleCriteria(fieldValues);
195 
196         List<Role> results = KimApiServiceLocator.getRoleService().findRoles(criteria).getResults();
197         List<RoleBo> roles = new ArrayList<RoleBo>(results.size());
198         for ( Role role : results ) {
199             roles.add( RoleBo.from(role) );
200         }
201 
202         return roles;
203     }
204 
205 	private List<KeyValue> getRoleTypeOptions() {
206 		List<KeyValue> options = new ArrayList<KeyValue>();
207 		options.add(new ConcreteKeyValue("", ""));
208 
209 		Collection<KimType> kimGroupTypes = KimApiServiceLocator.getKimTypeInfoService().findAllKimTypes();
210 		// get the distinct list of type IDs from all roles in the system
211         for (KimType kimType : kimGroupTypes) {
212             if (KimTypeLookupableHelperServiceImpl.hasRoleTypeService(kimType)) {
213                 String value = kimType.getNamespaceCode().trim() + KRADConstants.FIELD_CONVERSION_PAIR_SEPARATOR + kimType.getName().trim();
214                 options.add(new ConcreteKeyValue(kimType.getId(), value));
215             }
216         }
217         Collections.sort(options, new Comparator<KeyValue>() {
218            @Override
219 		public int compare(KeyValue k1, KeyValue k2) {
220                return k1.getValue().compareTo(k2.getValue());
221            }
222         });
223 		return options;
224 	}
225 
226 	public List<Row> getRoleRows() {
227 		return this.roleRows;
228 	}
229 
230 	public void setRoleRows(List<Row> roleRows) {
231 		this.roleRows = roleRows;
232 	}
233 
234 	public List<KimAttributeField> getAttrDefinitions() {
235 		return this.attrDefinitions;
236 	}
237 
238 	public void setAttrDefinitions(List<KimAttributeField> attrDefinitions) {
239 		this.attrDefinitions = attrDefinitions;
240 	}
241 
242 	public List<Row> getAttrRows() {
243 		return this.attrRows;
244 	}
245 
246 	public void setAttrRows(List<Row> attrRows) {
247 		this.attrRows = attrRows;
248 	}
249 
250 	public String getTypeId() {
251 		return this.typeId;
252 	}
253 
254 	public void setTypeId(String typeId) {
255 		this.typeId = typeId;
256 	}
257 
258 	@Override
259 	public List<Row> getRows() {
260 		new ArrayList<Row>();
261 		if (getRoleRows().isEmpty()) {
262 			List<Row> rows = super.getRows();
263 			List<Row> returnRows = new ArrayList<Row>();
264 			for (Row row : rows) {
265 				for (int i = row.getFields().size() - 1; i >= 0; i--) {
266 					Field field = row.getFields().get(i);
267 					if (field.getPropertyName().equals("kimTypeId")) {
268 						Field typeField = new Field();
269 						typeField.setFieldLabel("Type");
270 						typeField.setPropertyName("kimTypeId");
271 						typeField.setFieldValidValues(getRoleTypeOptions());
272 						typeField.setFieldType(Field.DROPDOWN);
273 						typeField.setMaxLength(100);
274 						typeField.setSize(40);
275 						// row.getFields().set(i, new Field("Type", "", Field.DROPDOWN_REFRESH,
276 						// false, "kimTypeId", "", getGroupTypeOptions(), null));
277 						row.getFields().set(i, typeField);
278 					}
279 				}
280 				returnRows.add(row);
281 			}
282 			setRoleRows(returnRows);
283 			//setAttrRows(setupAttributeRows());
284 		}
285 		if (getAttrRows().isEmpty()) {
286 			//setAttrDefinitions(new AttributeDefinitionMap());
287 			return getRoleRows();
288 		} else {
289 			List<Row> fullRows = new ArrayList<Row>();
290 			fullRows.addAll(getRoleRows());
291 			//fullRows.addAll(getAttrRows());
292 			return fullRows;
293 		}
294 
295 	}
296 
297 	@Override
298 	protected List<? extends BusinessObject> getSearchResultsHelper(
299 			Map<String, String> fieldValues, boolean unbounded) {
300         List searchResults;
301     	Map<String,String> nonBlankFieldValues = new HashMap<String, String>();
302     	boolean includeAttr = false;
303     	for (String fieldName : fieldValues.keySet()) {
304     		if (StringUtils.isNotBlank(fieldValues.get(fieldName)) ) {
305     			nonBlankFieldValues.put(fieldName, fieldValues.get(fieldName));
306     			if (fieldName.contains(".")) {
307     				includeAttr = true;
308     			}
309     		}
310     	}
311 
312     	if (includeAttr) {
313         	ModuleService eboModuleService = KRADServiceLocatorWeb.getKualiModuleService().getResponsibleModuleService( getBusinessObjectClass() );
314         	BusinessObjectEntry ddEntry = eboModuleService.getExternalizableBusinessObjectDictionaryEntry(getBusinessObjectClass());
315         	Map<String,String> filteredFieldValues = new HashMap<String, String>();
316         	for (String fieldName : nonBlankFieldValues.keySet()) {
317         		if (ddEntry.getAttributeNames().contains(fieldName) || fieldName.contains(".")) {
318         			filteredFieldValues.put(fieldName, nonBlankFieldValues.get(fieldName));
319         		}
320         	}
321         	searchResults = eboModuleService.getExternalizableBusinessObjectsListForLookup(getBusinessObjectClass(), (Map)filteredFieldValues, unbounded);
322 
323     	} else {
324     		searchResults = super.getSearchResultsHelper(fieldValues, unbounded);
325     	}
326         List defaultSortColumns = getDefaultSortColumns();
327         if (defaultSortColumns.size() > 0) {
328             Collections.sort(searchResults, new BeanPropertyComparator(defaultSortColumns, true));
329         }
330         return searchResults;
331 
332 	}
333 
334 	private static final String ROLE_ID_URL_KEY = "&"+KimConstants.PrimaryKeyConstants.ROLE_ID+"=";
335 
336 	public static String getCustomRoleInquiryHref(String href){
337 		return getCustomRoleInquiryHref("", href);
338 	}
339 
340 	static String getCustomRoleInquiryHref(String backLocation, String href){
341         Properties parameters = new Properties();
342         String hrefPart = "";
343     	String docTypeAction = "";
344     	if(StringUtils.isBlank(backLocation) || backLocation.contains(KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_ACTION)
345     			|| !backLocation.contains(KimConstants.KimUIConstants.KIM_GROUP_DOCUMENT_ACTION)){
346     		docTypeAction = KimConstants.KimUIConstants.KIM_ROLE_INQUIRY_ACTION;
347     	} else{
348     		docTypeAction = KimConstants.KimUIConstants.KIM_GROUP_DOCUMENT_ACTION;
349     	}
350 		if (StringUtils.isNotBlank(href) && href.contains(ROLE_ID_URL_KEY)) {
351 			int idx1 = href.indexOf("&"+ KimConstants.PrimaryKeyConstants.ROLE_ID+"=");
352 		    int idx2 = href.indexOf("&", idx1+1);
353 		    if (idx2 < 0) {
354 		    	idx2 = href.length();
355 		    }
356 	        parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.PARAM_MAINTENANCE_VIEW_MODE_INQUIRY);
357 	        hrefPart = href.substring(idx1, idx2);
358 	    }
359 		return UrlFactory.parameterizeUrl(KimCommonUtilsInternal.getKimBasePath()+docTypeAction, parameters)+hrefPart;
360 	}
361 
362     public QueryByCriteria getRoleCriteria(Map<String, String> fieldValues) {
363         List<Predicate> criteria = new ArrayList<Predicate>();
364 
365         Map<String, Map<String, String>> criteriaMap = setupCritMaps(fieldValues);
366 
367         Map<String, String> lookupNames = criteriaMap.get(OTHER_CRITERIA);
368         for (Map.Entry<String, String> entry : lookupNames.entrySet()) {
369             String propertyName = entry.getKey();
370             String lookupValue = entry.getValue();
371             if (StringUtils.isNotBlank(lookupValue)) {
372                 if (!propertyName.equals(KIMPropertyConstants.Principal.PRINCIPAL_NAME)) {
373                     if (propertyName.equals(KIMPropertyConstants.Principal.ACTIVE)) {
374                         criteria.add( equal( propertyName, Truth.strToBooleanIgnoreCase(lookupValue) ) );
375                     } else {
376                         criteria.add( likeIgnoreCase(propertyName, lookupValue));
377                     }
378                 } else {
379                     Collection<String> roleIds = getRoleIdsForPrincipalName(lookupValue);
380                     criteria.add( in(KimConstants.PrimaryKeyConstants.ID, roleIds) );
381                 }
382             }
383         }
384 
385 //        if (!criteriaMap.get(ROLE_MEMBER_ATTRIBUTE_CRITERIA).isEmpty()) {
386 //            String kimTypeId = null;
387 //            for (Map.Entry<String, String> entry : fieldValues.entrySet()) {
388 //                if (entry.getKey().equals(KIMPropertyConstants.KimType.KIM_TYPE_ID)) {
389 //                    kimTypeId = entry.getValue();
390 //                    break;
391 //                }
392 //            }
393 //            setupAttrCriteria(criteria, criteriaMap.get(ROLE_MEMBER_ATTRIBUTE_CRITERIA), kimTypeId);
394 //        }
395         if (!criteriaMap.get(PERMISSION_CRITERIA).isEmpty()) {
396             criteria.add( in(KimConstants.PrimaryKeyConstants.ID, getPermissionRoleIds(criteriaMap.get(PERMISSION_CRITERIA))) );
397         }
398         if (!criteriaMap.get(RESPONSIBILITY_CRITERIA).isEmpty()) {
399             criteria.add( in(KimConstants.PrimaryKeyConstants.ID, getResponsibilityRoleIds(criteriaMap.get(RESPONSIBILITY_CRITERIA))) );
400         }
401         if (!criteriaMap.get(GROUP_CRITERIA).isEmpty()) {
402             criteria.add( in(KimConstants.PrimaryKeyConstants.ID, getGroupCriteriaRoleIds(criteriaMap.get(GROUP_CRITERIA))) );
403         }
404 
405         return QueryByCriteria.Builder.fromPredicates(criteria);
406     }
407 
408     protected Collection<String> getRoleIdsForPrincipalName(String principalName) {
409         principalName = principalName.replace('*', '%');
410 
411         QueryByCriteria principalCriteria = QueryByCriteria.Builder.fromPredicates(
412                 likeIgnoreCase(KIMPropertyConstants.Principal.PRINCIPAL_NAME, principalName)
413                 , equal(KIMPropertyConstants.Principal.ACTIVE, Boolean.TRUE)
414                 );
415         List<Principal> principals = KimApiServiceLocator.getIdentityService().findPrincipals(principalCriteria).getResults();
416 
417         if (principals.isEmpty()) {
418             return Collections.singletonList("NOTFOUND");  // this forces a blank return.
419         }
420         Set<String> roleIds = new HashSet<String>();
421 
422         // Get matching principal IDs
423         List<String> principalIds = new ArrayList<String>(principals.size());
424         for (Principal principal : principals) {
425             principalIds.add(principal.getPrincipalId());
426         }
427 
428         // Get groups which the principals belong to
429         Set<String> groupIds = new HashSet<String>();
430         for (String principalId : principalIds) {
431             List<String> principalGroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId);
432             if ( principalGroupIds.isEmpty() ) {
433                 groupIds.add( "NOTFOUND" );
434             } else {
435                 groupIds.addAll(principalGroupIds);
436             }
437         }
438 
439         // Get roles to which this person has been added directly or via a group
440         QueryByCriteria roleMemberCriteria = QueryByCriteria.Builder.fromPredicates(
441                 or(
442                     and(
443                             equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode())
444                             , in(KIMPropertyConstants.RoleMember.MEMBER_ID, principalIds)
445                         ),
446                     and(
447                         equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode())
448                         , in(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds)
449                         )
450                     )
451                 );
452 
453         List<RoleMember> roleMembers = KimApiServiceLocator.getRoleService().findRoleMembers(roleMemberCriteria).getResults();
454 
455         DateTime now = new DateTime( CoreApiServiceLocator.getDateTimeService().getCurrentDate().getTime() );
456         for (RoleMember roleMbr : roleMembers ) {
457             if (roleMbr.isActive( now ) ) {
458                 roleIds.add(roleMbr.getRoleId());
459             }
460         }
461         if (roleIds.isEmpty()) {
462             return Collections.singletonList("NOTFOUND");  // this forces a blank return.
463         }
464 
465         return roleIds;
466     }
467 
468     protected static List<String> PERM_FIELD_NAMES;
469     protected static List<String> RESP_FIELD_NAMES;
470     static {
471         PERM_FIELD_NAMES = new ArrayList<String>(4);
472         PERM_FIELD_NAMES.add(LOOKUP_PARM_PERMISSION_NAME);
473         PERM_FIELD_NAMES.add(LOOKUP_PARM_PERMISSION_NAMESPACE);
474         PERM_FIELD_NAMES.add(LOOKUP_PARM_PERMISSION_TEMPLATE_NAME);
475         PERM_FIELD_NAMES.add(LOOKUP_PARM_PERMISSION_TEMPLATE_NAMESPACE);
476 
477         RESP_FIELD_NAMES = new ArrayList<String>(4);
478         RESP_FIELD_NAMES.add(LOOKUP_PARM_RESP_NAME);
479         RESP_FIELD_NAMES.add(LOOKUP_PARM_RESP_NAMESPACE);
480         RESP_FIELD_NAMES.add(LOOKUP_PARM_RESP_TEMPLATE_NAME);
481         RESP_FIELD_NAMES.add(LOOKUP_PARM_RESP_TEMPLATE_NAMESPACE);
482     }
483 
484     private Map<String, Map<String, String>> setupCritMaps(Map<String, String> fieldValues) {
485         Map<String, Map<String, String>> critMapMap = new HashMap<String, Map<String, String>>();
486 
487         Map<String, String> permFieldMap = new HashMap<String, String>();
488         Map<String, String> respFieldMap = new HashMap<String, String>();
489 //        Map<String, String> attrFieldMap = new HashMap<String, String>();
490         Map<String, String> groupFieldMap = new HashMap<String, String>();
491         Map<String, String> lookupNamesMap = new HashMap<String, String>();
492 
493         for (Map.Entry<String, String> entry : fieldValues.entrySet()) {
494             String nameValue = entry.getValue();
495             String propertyName = entry.getKey();
496             if (StringUtils.isNotBlank(nameValue)) {
497                 if (PERM_FIELD_NAMES.contains(propertyName)) {
498                     permFieldMap.put(propertyName, nameValue);
499                 } else if (RESP_FIELD_NAMES.contains(propertyName)) {
500                     respFieldMap.put(propertyName, nameValue);
501                 } else if (propertyName.startsWith(KimConstants.AttributeConstants.GROUP_NAME)) {
502                     groupFieldMap.put(propertyName, nameValue);
503 //                } else if (entry.getKey().contains(".")) {
504 //                    attrFieldMap.put(entry.getKey(), nameValue).replace('*', '%');
505                 } else {
506                     lookupNamesMap.put(propertyName, nameValue);
507                 }
508             }
509         }
510 
511         critMapMap.put(PERMISSION_CRITERIA, permFieldMap);
512         critMapMap.put(RESPONSIBILITY_CRITERIA, respFieldMap);
513         critMapMap.put(GROUP_CRITERIA, groupFieldMap);
514 //        critMap.put(ROLE_MEMBER_ATTRIBUTE_CRITERIA, attrFieldMap);
515         critMapMap.put(OTHER_CRITERIA, lookupNamesMap);
516 
517         return critMapMap;
518     }
519 
520 //    private void setupAttrCriteria(Criteria crit, Map<String, String> attrCrit, String kimTypeId) {
521 //        for (Map.Entry<String, String> entry : attrCrit.entrySet()) {
522 //            Criteria subCrit = new Criteria();
523 //            addLikeToCriteria(subCrit, "attributes.attributeValue", entry.getValue());
524 //            addEqualToCriteria(subCrit, "attributes.kimAttributeId", entry.getKey().substring(entry.getKey().indexOf(".") + 1, entry.getKey().length()));
525 //            addEqualToCriteria(subCrit, "attributes.kimTypeId", kimTypeId);
526 //            subCrit.addEqualToField("roleId", Criteria.PARENT_QUERY_PREFIX + "id");
527 //            crit.addExists(QueryFactory.newReportQuery(RoleMemberBo.class, subCrit));
528 //        }
529 //    }
530 
531     protected Collection<String> getPermissionRoleIds(Map<String, String> permCrit) {
532         List<Predicate> criteria = new ArrayList<Predicate>();
533 
534         for (Map.Entry<String, String> entry : permCrit.entrySet()) {
535             if ( StringUtils.isNotBlank(entry.getValue()) ) {
536                 String propertyName = entry.getKey();
537                 String lookupValue = entry.getValue().replace('*', '%');
538                 if ( propertyName.equals(LOOKUP_PARM_PERMISSION_NAME) ) {
539                     criteria.add( likeIgnoreCase(KimConstants.UniqueKeyConstants.PERMISSION_NAME, lookupValue) );
540                 } else if ( propertyName.equals(LOOKUP_PARM_PERMISSION_NAMESPACE) ) {
541                     criteria.add( like(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, lookupValue) );
542                 } else if ( propertyName.equals(LOOKUP_PARM_PERMISSION_TEMPLATE_NAME) ) {
543                     criteria.add( likeIgnoreCase("template." + KimConstants.UniqueKeyConstants.PERMISSION_TEMPLATE_NAME, lookupValue) );
544                 } else if ( propertyName.equals(LOOKUP_PARM_PERMISSION_TEMPLATE_NAMESPACE) ){
545                     criteria.add( like("template." + KimConstants.UniqueKeyConstants.NAMESPACE_CODE, lookupValue) );
546                 }
547             }
548         }
549         if(criteria.isEmpty()){
550             return Collections.singletonList("NOTFOUND");  // this forces a blank return.
551         }
552 
553         List<Permission> permissions = KimApiServiceLocator.getPermissionService().findPermissions( QueryByCriteria.Builder.fromPredicates(criteria) ).getResults();
554         Set<String> roleIds = new HashSet<String>();
555 
556         for ( Permission permission : permissions ) {
557             roleIds.addAll( KimApiServiceLocator.getPermissionService().getRoleIdsForPermission(permission.getNamespaceCode(), permission.getName()) );
558         }
559 
560         if (roleIds.isEmpty()) {
561             roleIds.add("NOTFOUND"); // this forces a blank return.
562         }
563 
564         return roleIds;
565     }
566 
567     protected Collection<String> getResponsibilityRoleIds(Map<String, String> respCrit) {
568         List<Predicate> criteria = new ArrayList<Predicate>();
569 
570         for (Map.Entry<String, String> entry : respCrit.entrySet()) {
571             if ( StringUtils.isNotBlank(entry.getValue()) ) {
572                 String propertyName = entry.getKey();
573                 String lookupValue = entry.getValue().replace('*', '%');
574                 if (propertyName.equals(LOOKUP_PARM_RESP_NAME) ) {
575                     criteria.add( likeIgnoreCase(KimConstants.UniqueKeyConstants.RESPONSIBILITY_NAME, lookupValue));
576                 } else if ( propertyName.equals(LOOKUP_PARM_RESP_NAMESPACE) ) {
577                     criteria.add( like(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, lookupValue));
578                 } else if (propertyName.equals(LOOKUP_PARM_RESP_TEMPLATE_NAME)) {
579                     criteria.add( likeIgnoreCase("template." + KimConstants.UniqueKeyConstants.RESPONSIBILITY_TEMPLATE_NAME, lookupValue));
580                 } else if ( propertyName.equals(LOOKUP_PARM_RESP_TEMPLATE_NAMESPACE) ){
581                     criteria.add( like("template." + KimConstants.UniqueKeyConstants.NAMESPACE_CODE, lookupValue));
582                 }
583             }
584         }
585         if(criteria.isEmpty()){
586             return Collections.singletonList("NOTFOUND");  // this forces a blank return.
587         }
588 
589         ResponsibilityQueryResults results = KimApiServiceLocator.getResponsibilityService().findResponsibilities(QueryByCriteria.Builder.fromPredicates(criteria) );
590         List<Responsibility> responsibilities = results.getResults();
591 
592         Set<String> roleIds = new HashSet<String>();
593         for (Responsibility responsibility : responsibilities) {
594             roleIds.addAll(KimApiServiceLocator.getResponsibilityService().getRoleIdsForResponsibility(responsibility.getId()));
595         }
596 
597         if (roleIds.isEmpty()) {
598             roleIds.add("NOTFOUND"); // this forces a blank return.
599         }
600 
601         return roleIds;
602     }
603 
604     protected Collection<String> getGroupCriteriaRoleIds(Map<String,String> groupCrit) {
605         List<Predicate> criteria = new ArrayList<Predicate>();
606 
607         for (Entry<String, String> entry : groupCrit.entrySet()) {
608             if ( StringUtils.isNotBlank(entry.getValue()) ) {
609                 String propertyName = entry.getKey();
610                 String lookupValue = entry.getValue().replace('*', '%');
611                 if (propertyName.equals(KimConstants.AttributeConstants.GROUP_NAME)) {
612                     criteria.add( likeIgnoreCase(KimConstants.AttributeConstants.NAME, lookupValue));
613                 } else { // the namespace code for the group field is named something besides the default. Set it to the default.
614                     criteria.add( like(KimConstants.AttributeConstants.NAMESPACE_CODE, lookupValue));
615                 }
616             }
617        }
618         if(criteria.isEmpty()){
619             return Collections.singletonList("NOTFOUND");  // this forces a blank return.
620         }
621 
622        List<String> groupIds = KimApiServiceLocator.getGroupService().findGroupIds(QueryByCriteria.Builder.fromPredicates(criteria));
623 
624        if(groupIds.isEmpty()){
625            return Collections.singletonList("NOTFOUND");  // this forces a blank return.
626        }
627 
628        // Get roles to which this person has been added directly or via a group
629        QueryByCriteria roleMemberCriteria = QueryByCriteria.Builder.fromPredicates(
630                equal(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode())
631                , in(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds)
632                );
633 
634        List<RoleMember> roleMembers = KimApiServiceLocator.getRoleService().findRoleMembers(roleMemberCriteria).getResults();
635 
636        Set<String> roleIds = new HashSet<String>();
637        DateTime now = new DateTime( CoreApiServiceLocator.getDateTimeService().getCurrentDate().getTime() );
638        for (RoleMember roleMbr : roleMembers ) {
639            if (roleMbr.isActive( now ) ) {
640                roleIds.add(roleMbr.getRoleId());
641            }
642        }
643 
644        return roleIds;
645     }
646 
647     /**
648      * This overridden method ...
649      *
650      * @see org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl#getMaintenanceDocumentTypeName()
651      */
652     @Override
653     protected String getMaintenanceDocumentTypeName() {
654         return KimConstants.KimUIConstants.KIM_ROLE_DOCUMENT_TYPE_NAME;
655     }
656 }