001/*
002 * Copyright 2009 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.ole.coa.identity;
017
018import java.util.ArrayList;
019import java.util.Collection;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.Iterator;
023import java.util.List;
024import java.util.Map;
025import java.util.Properties;
026
027import org.apache.commons.lang.StringUtils;
028import org.kuali.ole.coa.service.OrgReviewRoleService;
029import org.kuali.ole.sys.OLEConstants;
030import org.kuali.ole.sys.OLEPropertyConstants;
031import org.kuali.ole.sys.identity.OleKimAttributes;
032import org.kuali.rice.core.api.criteria.PredicateUtils;
033import org.kuali.rice.core.api.criteria.QueryByCriteria;
034import org.kuali.rice.core.api.delegation.DelegationType;
035import org.kuali.rice.kim.api.KimConstants;
036import org.kuali.rice.kim.api.common.delegate.DelegateMember;
037import org.kuali.rice.kim.api.common.delegate.DelegateType;
038import org.kuali.rice.kim.api.identity.principal.Principal;
039import org.kuali.rice.kim.api.identity.principal.PrincipalQueryResults;
040import org.kuali.rice.kim.api.role.DelegateMemberQueryResults;
041import org.kuali.rice.kim.api.role.Role;
042import org.kuali.rice.kim.api.role.RoleMember;
043import org.kuali.rice.kim.api.role.RoleMemberQueryResults;
044import org.kuali.rice.kim.api.role.RoleQueryResults;
045import org.kuali.rice.kim.api.services.KimApiServiceLocator;
046import org.kuali.rice.kns.document.authorization.BusinessObjectRestrictions;
047import org.kuali.rice.kns.lookup.HtmlData;
048import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
049import org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl;
050import org.kuali.rice.kns.web.struts.form.LookupForm;
051import org.kuali.rice.krad.bo.BusinessObject;
052import org.kuali.rice.krad.util.KRADConstants;
053import org.kuali.rice.krad.util.UrlFactory;
054public class OrgReviewRoleLookupableHelperServiceImpl extends KualiLookupableHelperServiceImpl {
055    private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(OrgReviewRoleLookupableHelperServiceImpl.class);
056
057    protected OrgReviewRoleService orgReviewRoleService;
058
059    protected static final String MEMBER_ID = "memberId";
060    protected static final String MEMBER_ATTRIBUTE_NAME_KEY = "attributeDetails.kimAttribute.attributeName";
061    protected static final String MEMBER_ATTRIBUTE_VALUE_KEY = "attributeDetails.attributeValue";
062
063    protected static final Map<String,Map<DelegationType,String>> DELEGATION_ID_CACHE = new HashMap<String, Map<DelegationType,String>>(2);
064
065    protected static final String DELEGATE_SEARCH_IND = "delegate";
066
067    @Override
068    public Collection performLookup(LookupForm lookupForm, Collection resultTable, boolean bounded) {
069        lookupForm.setShowMaintenanceLinks(true);
070        lookupForm.setSuppressActions(false);
071        lookupForm.setHideReturnLink(true);
072        return super.performLookup(lookupForm, resultTable, bounded);
073    }
074
075    @Override
076    public List<HtmlData> getCustomActionUrls(BusinessObject businessObject, List pkNames){
077        OrgReviewRole orr = (OrgReviewRole)businessObject;
078        List<HtmlData> htmlDataList = super.getCustomActionUrls(businessObject, pkNames);
079        if(StringUtils.isNotBlank(getMaintenanceDocumentTypeName()) && allowsMaintenanceEditAction(businessObject) && !orr.isDelegate()) {
080            HtmlData createDelegationUrl = getCreateDelegationUrl(businessObject, pkNames);
081            //createDelegationUrl.setDisplayText(OLEConstants.COAConstants.ORG_REVIEW_ROLE_CREATE_DELEGATION_DISPLAY_TEXT);
082            htmlDataList.add(createDelegationUrl);
083        }
084        return htmlDataList;
085    }
086
087    protected AnchorHtmlData getCreateDelegationUrl(BusinessObject businessObject, List pkNames){
088        OrgReviewRole orr = (OrgReviewRole)businessObject;
089        Properties parameters = new Properties();
090        parameters.put(OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY, OrgReviewRole.NEW_DELEGATION_ID_KEY_VALUE);
091        parameters.put(OLEConstants.DISPATCH_REQUEST_PARAMETER, KRADConstants.MAINTENANCE_EDIT_METHOD_TO_CALL);
092        parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, businessObject.getClass().getName());
093        parameters.put(KRADConstants.COPY_KEYS, OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY+","+OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY+","+KRADConstants.DISPATCH_REQUEST_PARAMETER);
094        parameters.put(OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY, orr.getRoleMemberId());
095        String href = UrlFactory.parameterizeUrl(KRADConstants.MAINTENANCE_ACTION, parameters);
096
097        return new AnchorHtmlData(href, KRADConstants.DOC_HANDLER_METHOD, OLEConstants.COAConstants.ORG_REVIEW_ROLE_CREATE_DELEGATION_DISPLAY_TEXT);
098    }
099
100    @Override
101    protected String getActionUrlHref(BusinessObject businessObject, String methodToCall, List pkNames){
102        OrgReviewRole orr = (OrgReviewRole)businessObject;
103        Properties parameters = new Properties();
104        parameters.put(KRADConstants.DISPATCH_REQUEST_PARAMETER, methodToCall);
105        parameters.put(KRADConstants.BUSINESS_OBJECT_CLASS_ATTRIBUTE, OrgReviewRole.class.getName());
106
107        if(orr.isDelegate()){
108            parameters.put(KRADConstants.COPY_KEYS, OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY+","+KRADConstants.DISPATCH_REQUEST_PARAMETER);
109            parameters.put(OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY, orr.getDelegationMemberId());
110        } else {
111            parameters.put(KRADConstants.COPY_KEYS, OrgReviewRole.ORIGINAL_DELEGATION_MEMBER_ID_TO_MODIFY+","+OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY+","+KRADConstants.DISPATCH_REQUEST_PARAMETER);
112            parameters.put(OrgReviewRole.ORIGINAL_ROLE_MEMBER_ID_TO_MODIFY, orr.getRoleMemberId());
113        }
114        return UrlFactory.parameterizeUrl(KRADConstants.MAINTENANCE_ACTION, parameters);
115    }
116
117    protected List<String> getOverridePKNamesForActionLinks(OrgReviewRole orr){
118        List overridePKNames = new ArrayList<String>();
119        if(orr.isDelegate()) {
120            overridePKNames.add(KimConstants.PrimaryKeyConstants.DELEGATION_MEMBER_ID);
121        } else {
122            overridePKNames.add(KimConstants.PrimaryKeyConstants.ROLE_MEMBER_ID);
123        }
124        return overridePKNames;
125    }
126
127    @Override
128    protected String getActionUrlTitleText(BusinessObject businessObject, String displayText, List pkNames, BusinessObjectRestrictions businessObjectRestrictions){
129        OrgReviewRole orr = (OrgReviewRole)businessObject;
130        return super.getActionUrlTitleText(businessObject, displayText, getOverridePKNamesForActionLinks(orr), businessObjectRestrictions);
131    }
132
133    @Override
134    public List<? extends BusinessObject> getSearchResults(Map<String,String> fieldValues) {
135        return getMemberSearchResults(fieldValues);
136    }
137
138    /**
139     * @see org.kuali.rice.kns.lookup.KualiLookupableHelperServiceImpl#getSearchResultsUnbounded(java.util.Map)
140     */
141    @Override
142    public List<? extends BusinessObject> getSearchResultsUnbounded(
143            Map<String, String> fieldValues) {
144        return getMemberSearchResults(fieldValues);
145    }
146
147    protected List<? extends BusinessObject> getMemberSearchResults(Map<String, String> fieldValues){
148        String delegateSearchIndicator = fieldValues.get(DELEGATE_SEARCH_IND);
149        String documentTypeName = fieldValues.get(OleKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE);
150        List<OleKimDocDelegateMember> searchResultsDelegationMembers = new ArrayList<OleKimDocDelegateMember>();
151        List<RoleMember> searchResultsRoleMembers = new ArrayList<RoleMember>();
152
153        boolean delegateBoolean = getBooleanValueForString(delegateSearchIndicator, false);
154
155        if(StringUtils.isBlank(delegateSearchIndicator) || delegateBoolean ) {
156            Map<String, String> searchCriteriaDelegations = buildOrgReviewRoleSearchCriteriaForDelegations(documentTypeName, fieldValues);
157            if ( searchCriteriaDelegations != null ) {
158                searchResultsDelegationMembers.addAll(searchDelegations(searchCriteriaDelegations));
159            }
160        }
161        if(StringUtils.isBlank(delegateSearchIndicator) || !delegateBoolean ) {
162            Map<String, String> searchCriteriaRoleMembers = buildOrgReviewRoleSearchCriteria(documentTypeName, fieldValues);
163            if ( searchCriteriaRoleMembers != null ) {
164                searchResultsRoleMembers.addAll(searchRoleMembers(searchCriteriaRoleMembers));
165            }
166        }
167        List<OrgReviewRole> flattenedSearchResults = new ArrayList<OrgReviewRole>();
168        flattenedSearchResults.addAll(flattenToOrgReviewMembers(fieldValues.get(OLEPropertyConstants.ACTIVE), documentTypeName, searchResultsRoleMembers));
169        flattenedSearchResults.addAll(flattenToOrgReviewDelegationMembers(fieldValues.get(OLEPropertyConstants.ACTIVE), documentTypeName, searchResultsDelegationMembers));
170        filterOrgReview(fieldValues, flattenedSearchResults);
171
172        return flattenedSearchResults;
173    }
174
175    protected List<String> getPrincipalIdsForWildcardedPrincipalName( String principalName ) {
176        if(StringUtils.isNotBlank(principalName)){
177            PrincipalQueryResults results =  KimApiServiceLocator.getIdentityService().findPrincipals(QueryByCriteria.Builder.fromPredicates(PredicateUtils.convertMapToPredicate(Collections.singletonMap(KimConstants.UniqueKeyConstants.PRINCIPAL_NAME, getQueryString(principalName))) ));
178            List<String> principalIds = new ArrayList<String>(results.getResults().size());
179            for ( Principal principals : results.getResults() ) {
180                principalIds.add( principals.getPrincipalId() );
181            }
182            return principalIds;
183        }
184        return Collections.emptyList();
185    }
186
187    protected List<String> getGroupIdsForWildcardedGroupName( String namespaceCode, String groupName ) {
188        Map<String, String> searchCriteria = new HashMap<String, String>(2);
189        if( StringUtils.isNotBlank(namespaceCode) ) {
190            searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
191        }
192        if( StringUtils.isNotBlank(groupName) ) {
193            searchCriteria.put(KimConstants.UniqueKeyConstants.GROUP_NAME, getQueryString(groupName));
194        }
195        if ( searchCriteria.isEmpty() ) {
196            return Collections.emptyList();
197        }
198        return KimApiServiceLocator.getGroupService().findGroupIds( QueryByCriteria.Builder.fromPredicates(PredicateUtils.convertMapToPredicate(searchCriteria) ) );
199    }
200
201    protected List<String> getRoleIdsForWildcardedRoleName( String namespaceCode, String roleName ) {
202        Map<String, String> searchCriteria = new HashMap<String, String>(2);
203        if( StringUtils.isNotBlank(namespaceCode) ) {
204            searchCriteria.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, namespaceCode);
205        }
206        if( StringUtils.isNotBlank(roleName) ) {
207            searchCriteria.put(KimConstants.UniqueKeyConstants.NAME, getQueryString(roleName));
208        }
209        if ( searchCriteria.isEmpty() ) {
210            return Collections.emptyList();
211        }
212        RoleQueryResults results = KimApiServiceLocator.getRoleService().findRoles( QueryByCriteria.Builder.fromPredicates(PredicateUtils.convertMapToPredicate(searchCriteria) ) );
213        List<String> roleIds = new ArrayList<String>(results.getResults().size());
214        for ( Role role : results.getResults() ) {
215            roleIds.add( role.getId() );
216        }
217        return roleIds;
218    }
219
220    protected void filterOrgReview(Map<String, String> fieldValues, List<OrgReviewRole> searchResults){
221        if ( LOG.isDebugEnabled() ) {
222            LOG.debug( "Performing local filtering of search results" );
223            LOG.debug( "Criteria: " + fieldValues );
224            LOG.debug( "Initial Results: " + searchResults );
225        }
226
227        List<String> principalIds = null;
228        List<String> groupIds = null;
229        List<String> roleIds = null;
230
231        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.PRINCIPAL_NAME_FIELD_NAME)) ) {
232            principalIds = getPrincipalIdsForWildcardedPrincipalName(fieldValues.get(OrgReviewRole.PRINCIPAL_NAME_FIELD_NAME));
233        }
234
235        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAMESPACE_CODE))
236                || StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAME)) ) {
237            groupIds = getGroupIdsForWildcardedGroupName(
238                    fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAMESPACE_CODE),
239                    fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAME));
240        }
241
242        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAMESPACE_CODE))
243                || StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAME)) ) {
244            roleIds = getRoleIdsForWildcardedRoleName(
245                    fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAMESPACE_CODE),
246                    fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAME));
247        }
248
249        String financialSystemDocumentTypeCode = fieldValues.get(OleKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE);
250        String chartOfAccountsCode = fieldValues.get(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE);
251        String organizationCode = fieldValues.get(OLEPropertyConstants.ORGANIZATION_CODE);
252
253        //Loop through org review roles and remove rows where necessary
254        Iterator<OrgReviewRole> it = searchResults.iterator();
255
256        while ( it.hasNext() ) {
257            OrgReviewRole orgReviewRole = it.next();
258            boolean remove = false;
259
260            //check member attribute parameters
261            if(StringUtils.isNotBlank(organizationCode)){
262                //filter by chart/document type if they exist
263                if(StringUtils.isNotBlank(chartOfAccountsCode)){
264                    if(!chartOfAccountsCode.equals(orgReviewRole.getChartOfAccountsCode())){
265                        LOG.debug( "Removing RoleMember because chart does not match" );
266                        remove = true;
267                    }
268                }
269
270                if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
271                    if(!financialSystemDocumentTypeCode.equals(orgReviewRole.getFinancialSystemDocumentTypeCode())){
272                        LOG.debug( "Removing RoleMember because document type does not match" );
273                        remove = true;
274                    }
275                }
276            }else if(StringUtils.isNotBlank(chartOfAccountsCode)){
277                //filter by document type if it exists
278                if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
279                    if(!financialSystemDocumentTypeCode.equals(orgReviewRole.getFinancialSystemDocumentTypeCode())){
280                        LOG.debug( "Removing RoleMember because document type does not match" );
281                        remove = true;
282                    }
283                }
284            }
285
286            List<String> items = new ArrayList<String>();
287
288            //check member id parameters, and only if it hasn't already been marked for removal.
289            if(!remove){
290                if(roleIds!=null){
291                    if(groupIds!=null){
292                        items.addAll( groupIds );
293                        if(!items.contains(orgReviewRole.getGroupMemberGroupId())){
294                            LOG.debug( "Removing RoleMember because group member id does not match" );
295                            remove = true;
296                        }
297                    }
298                    if(principalIds!=null){
299                        items.addAll( principalIds );
300                        if(!items.contains(orgReviewRole.getPrincipalMemberPrincipalId())){
301                            LOG.debug( "Removing RoleMember because principal id does not match" );
302                            remove = true;
303                        }
304                    }
305
306                }else if(groupIds!=null){
307                    if(principalIds!=null){
308                        items.addAll( principalIds );
309                        if(!items.contains(orgReviewRole.getPrincipalMemberPrincipalId())){
310                            LOG.debug( "Removing RoleMember because principal id does not match" );
311                            remove = true;
312                        }
313                    }
314                }
315            }
316
317            //remove if necessary
318            if(remove){
319                it.remove();
320            }
321        }
322    }
323
324    protected String getDelegationIdByRoleAndDelegationType( String roleId, DelegationType type ) {
325        if ( StringUtils.isBlank( roleId ) || type == null ) {
326            return null;
327        }
328        Map<DelegationType,String> tempCache = DELEGATION_ID_CACHE.get(roleId);
329        if ( tempCache == null ) {
330            tempCache = new HashMap<DelegationType, String>(2);
331            DelegateType dt = KimApiServiceLocator.getRoleService().getDelegateTypeByRoleIdAndDelegateTypeCode(roleId, type);
332            if ( dt != null ) {
333                tempCache.put(type, dt.getDelegationId() );
334            }
335            synchronized (DELEGATION_ID_CACHE) {
336                DELEGATION_ID_CACHE.put(roleId, tempCache);
337            }
338        } else {
339            if ( !tempCache.containsKey(type) ) {
340                DelegateType dt = KimApiServiceLocator.getRoleService().getDelegateTypeByRoleIdAndDelegateTypeCode(roleId, type);
341                if ( dt != null ) {
342                    synchronized (DELEGATION_ID_CACHE) {
343                        tempCache.put(type, dt.getDelegationId() );
344                    }
345                }
346            }
347        }
348        return tempCache.get(type);
349    }
350
351    protected void addDelegationsToDelegationMemberSearchCriteria(String documentTypeName, Map<String, String> searchCriteria){
352        List<String> roleNamesToSearchInto = orgReviewRoleService.getRolesToConsider(documentTypeName);
353        if(roleNamesToSearchInto!=null){
354            StringBuilder rolesQueryString = new StringBuilder();
355            boolean firstItem = true;
356            for( String roleName : roleNamesToSearchInto ) {
357                String roleId = KimApiServiceLocator.getRoleService().getRoleIdByNamespaceCodeAndName(OLEConstants.SysKimApiConstants.ORGANIZATION_REVIEWER_ROLE_NAMESPACECODE, roleName);
358                if ( roleId != null ) {
359                    for ( DelegationType type : DelegationType.values() ) {
360                        String delegationId = getDelegationIdByRoleAndDelegationType(roleId, type);
361                        if ( delegationId != null ) {
362                            if ( !firstItem ) {
363                                rolesQueryString.append( KimConstants.KimUIConstants.OR_OPERATOR );
364                            } else {
365                                firstItem = false;
366                            }
367                            rolesQueryString.append( delegationId );
368                        }
369                    }
370                }
371            }
372            if ( rolesQueryString.length() > 0 ) {
373                searchCriteria.put("delegationId", rolesQueryString.toString());
374            }
375        }
376    }
377
378    protected void addRolesToRoleMemberSearchCriteria(String documentTypeName, Map<String, String> searchCriteria){
379        List<String> roleNamesToSearchInto = orgReviewRoleService.getRolesToConsider(documentTypeName);
380        if( roleNamesToSearchInto != null) {
381            StringBuilder rolesQueryString = new StringBuilder();
382            boolean firstItem = true;
383            for ( String roleName : roleNamesToSearchInto ) {
384                String roleId = KimApiServiceLocator.getRoleService().getRoleIdByNamespaceCodeAndName(OLEConstants.SysKimApiConstants.ORGANIZATION_REVIEWER_ROLE_NAMESPACECODE, roleName);
385                if ( roleId != null ) {
386                    if ( !firstItem ) {
387                        rolesQueryString.append( KimConstants.KimUIConstants.OR_OPERATOR );
388                    } else {
389                        firstItem = false;
390                    }
391                    rolesQueryString.append( roleId );
392                }
393            }
394            if ( rolesQueryString.length() > 0 ) {
395                searchCriteria.put("roleId", rolesQueryString.toString());
396            }
397        }
398    }
399
400    protected List<RoleMember> searchRoleMembers(Map<String, String> searchCriteriaRoleMembers){
401        if ( searchCriteriaRoleMembers == null ) {
402            return Collections.emptyList();
403        }
404        if ( LOG.isDebugEnabled() ) {
405            LOG.debug("About to perform Role lookup.  Criteria: " + searchCriteriaRoleMembers);
406        }
407        RoleMemberQueryResults results = KimApiServiceLocator.getRoleService().findRoleMembers( QueryByCriteria.Builder.fromPredicates( PredicateUtils.convertMapToPredicate(searchCriteriaRoleMembers)));
408        if ( LOG.isDebugEnabled() ) {
409            LOG.debug( "Role Member Lookup Results from KIM: " + results );
410        }
411        if ( results == null ) {
412            return Collections.emptyList();
413        }
414        return results.getResults();
415    }
416
417    protected List<OleKimDocDelegateMember> searchDelegations(Map<String, String> searchCriteriaDelegateMembers){
418        DelegateMemberQueryResults queryResults = KimApiServiceLocator.getRoleService().findDelegateMembers(QueryByCriteria.Builder.fromPredicates( PredicateUtils.convertMapToPredicate(searchCriteriaDelegateMembers)));
419        List<DelegateMember> tmpResults = queryResults.getResults();
420        Integer totalRowCount = tmpResults.size();
421        ArrayList<OleKimDocDelegateMember> results = new ArrayList<OleKimDocDelegateMember>(totalRowCount);
422        if ( totalRowCount > 0 ) {
423            for ( DelegateMember dm : tmpResults ) {
424                results.add( new OleKimDocDelegateMember( dm ) );
425            }
426        }
427        return results;
428    }
429
430
431
432
433    private static final String[] TRUE_VALUES = new String[] { "true", "yes", "t", "y" };
434    public static boolean getBooleanValueForString(String value, boolean defaultValue) {
435        if (!StringUtils.isBlank(value)) {
436            for (String trueValue : TRUE_VALUES) {
437                if (value.equalsIgnoreCase(trueValue)) {
438                    return true;
439                }
440            }
441            return false;
442        }
443        return defaultValue;
444    }
445
446    protected List<OrgReviewRole> flattenToOrgReviewMembers(String active, String documentTypeName, List<RoleMember> members){
447        LOG.debug( "\"flattening\" RoleMember objects to OrgReviewRole object" );
448        if(members==null || members.isEmpty() ) {
449            return Collections.emptyList();
450        }
451
452        boolean activeInd = getBooleanValueForString(active, true);
453        List<OrgReviewRole> orgReviewRoles = new ArrayList<OrgReviewRole>();
454        for(RoleMember member: members){
455            if ( LOG.isDebugEnabled() ) {
456                LOG.debug( "Converting Role Member: " + member );
457            }
458            if(StringUtils.isBlank(active) || activeInd == member.isActive() ) {
459                OrgReviewRole orgReviewRole = new OrgReviewRole();
460                orgReviewRole.setRoleMember(member);
461
462                if ( LOG.isDebugEnabled() ) {
463                    LOG.debug( "Converted To OrgReviewRole: " + orgReviewRole );
464                }
465                orgReviewRoles.add(orgReviewRole);
466            } else {
467                LOG.debug( "RoleMember skipped because it did not match the active flag on the lookup" );
468            }
469        }
470        return orgReviewRoles;
471    }
472
473    protected List<OrgReviewRole> flattenToOrgReviewDelegationMembers(String active, String documentTypeName, List<OleKimDocDelegateMember> delegationMembers){
474        if( delegationMembers == null ) {
475            return Collections.emptyList();
476        }
477
478        List<OrgReviewRole> orgReviewRoles = new ArrayList<OrgReviewRole>();
479        boolean activeInd = getBooleanValueForString(active, true);
480        for(OleKimDocDelegateMember member: delegationMembers){
481            if ( LOG.isDebugEnabled() ) {
482                LOG.debug( "Converting Delegation Member: " + member );
483            }
484            if( StringUtils.isBlank(active) || activeInd == member.isActive() ) {
485                OrgReviewRole orr = new OrgReviewRole();
486                orgReviewRoleService.populateOrgReviewRoleFromDelegationMember(orr, member.getRoleMemberId(),
487                        member.getDelegationMemberId());
488                if ( LOG.isDebugEnabled() ) {
489                    LOG.debug("Converted To OrgReviewRole: " + orr);
490                }
491                orgReviewRoles.add(orr);
492            }
493        }
494        return orgReviewRoles;
495    }
496
497    protected String getQueryString(String parameter){
498        if(StringUtils.isBlank(parameter)) {
499            return OLEConstants.WILDCARD_CHARACTER;
500        } else {
501            return OLEConstants.WILDCARD_CHARACTER+parameter+OLEConstants.WILDCARD_CHARACTER;
502        }
503    }
504
505    protected Map<String, String> buildOrgReviewRoleSearchCriteria(String documentTypeName, Map<String, String> fieldValues){
506        List<String> principalIds = null;
507        List<String> groupIds = null;
508        List<String> roleIds = null;
509
510        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.PRINCIPAL_NAME_FIELD_NAME)) ) {
511            principalIds = getPrincipalIdsForWildcardedPrincipalName(fieldValues.get(OrgReviewRole.PRINCIPAL_NAME_FIELD_NAME));
512            if( principalIds.isEmpty() ) {
513                return null;
514            }
515        }
516
517        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAMESPACE_CODE))
518                || StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAME)) ) {
519            groupIds = getGroupIdsForWildcardedGroupName(
520                    fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAMESPACE_CODE),
521                    fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAME));
522            if( groupIds.isEmpty() ) {
523                return null;
524            }
525        }
526
527        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAMESPACE_CODE))
528                || StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAME)) ) {
529            roleIds = getRoleIdsForWildcardedRoleName(
530                    fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAMESPACE_CODE),
531                    fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAME));
532            if( roleIds.isEmpty() ) {
533                return null;
534            }
535        }
536
537        String financialSystemDocumentTypeCode = fieldValues.get(OleKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE);
538        String chartOfAccountsCode = fieldValues.get(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE);
539        String organizationCode = fieldValues.get(OLEPropertyConstants.ORGANIZATION_CODE);
540
541        Map<String, String> searchCriteriaMain = new HashMap<String, String>();
542
543        // Yes, the lines below overwrite each other.  We are essentially attempting to use the most-selective one present.
544        // Complete filtering will be performed later, after the results are retrieved
545        if(StringUtils.isNotBlank(chartOfAccountsCode)){
546            searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, OleKimAttributes.CHART_OF_ACCOUNTS_CODE);
547            searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, chartOfAccountsCode);
548        }
549        if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
550            searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME);
551            searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, financialSystemDocumentTypeCode);
552        }
553        if(StringUtils.isNotBlank(organizationCode)){
554            searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, OleKimAttributes.ORGANIZATION_CODE);
555            searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, organizationCode);
556        }
557
558        String memberIdString = buildMemberIdLookupString(principalIds, groupIds, roleIds);
559        if ( StringUtils.isNotBlank(memberIdString) ) {
560            searchCriteriaMain.put(MEMBER_ID, memberIdString );
561        }
562        addRolesToRoleMemberSearchCriteria(documentTypeName, searchCriteriaMain);
563        return searchCriteriaMain;
564    }
565
566    protected String buildMemberIdLookupString( List<String> principalIds, List<String> groupIds, List<String> roleIds ) {
567        Collection<String> allMemberIds = new ArrayList<String>();
568        if(principalIds!=null){
569            allMemberIds.addAll(principalIds);
570        }
571        if(groupIds!=null){
572            allMemberIds.addAll(groupIds);
573        }
574        if(roleIds!=null){
575            allMemberIds.addAll(roleIds);
576        }
577        return StringUtils.join(allMemberIds, KimConstants.KimUIConstants.OR_OPERATOR);
578    }
579
580    protected Map<String, String> buildOrgReviewRoleSearchCriteriaForDelegations(String documentTypeName, Map<String, String> fieldValues){
581        List<String> principalIds = null;
582        List<String> groupIds = null;
583        List<String> roleIds = null;
584
585        String principalName = fieldValues.get(OrgReviewRole.PRINCIPAL_NAME_FIELD_NAME);
586        if ( StringUtils.isNotBlank(principalName) ) {
587            principalIds = getPrincipalIdsForWildcardedPrincipalName(principalName);
588            if( principalIds.isEmpty() ) {
589                return null;
590            }
591        }
592
593        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAMESPACE_CODE))
594                || StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAME)) ) {
595            groupIds = getGroupIdsForWildcardedGroupName(
596                    fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAMESPACE_CODE),
597                    fieldValues.get(OrgReviewRole.GROUP_NAME_FIELD_NAME));
598            if( groupIds.isEmpty() ) {
599                return null;
600            }
601        }
602
603        if ( StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAMESPACE_CODE))
604                || StringUtils.isNotBlank(fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAME)) ) {
605            roleIds = getRoleIdsForWildcardedRoleName(
606                    fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAMESPACE_CODE),
607                    fieldValues.get(OrgReviewRole.ROLE_NAME_FIELD_NAME));
608            if( roleIds.isEmpty() ) {
609                return null;
610            }
611        }
612
613        // pull the other main three search criteria
614        String financialSystemDocumentTypeCode = fieldValues.get(OleKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE);
615        String chartOfAccountsCode = fieldValues.get(OLEPropertyConstants.CHART_OF_ACCOUNTS_CODE);
616        String organizationCode = fieldValues.get(OLEPropertyConstants.ORGANIZATION_CODE);
617
618        // Yes, the lines below overwrite each other.  We are essentially attempting to use the most-selective one present.
619        // Complete filtering will be performed later, after the results are retrieved
620        Map<String, String> searchCriteriaMain = new HashMap<String, String>();
621        if(StringUtils.isNotBlank(chartOfAccountsCode)){
622            searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, OleKimAttributes.CHART_OF_ACCOUNTS_CODE);
623            searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, chartOfAccountsCode);
624        }
625        if(StringUtils.isNotBlank(financialSystemDocumentTypeCode)){
626            searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME);
627            searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, financialSystemDocumentTypeCode);
628        }
629        if(StringUtils.isNotBlank(organizationCode)){
630            searchCriteriaMain.put(MEMBER_ATTRIBUTE_NAME_KEY, OleKimAttributes.ORGANIZATION_CODE);
631            searchCriteriaMain.put(MEMBER_ATTRIBUTE_VALUE_KEY, organizationCode);
632        }
633
634        String memberIdString = buildMemberIdLookupString(principalIds, groupIds, roleIds);
635        if ( StringUtils.isNotBlank(memberIdString) ) {
636            searchCriteriaMain.put(MEMBER_ID, memberIdString );
637        }
638        addDelegationsToDelegationMemberSearchCriteria(documentTypeName, searchCriteriaMain);
639        return searchCriteriaMain;
640    }
641
642    @Override
643    public void validateSearchParameters(Map fieldValues) {
644        if ( fieldValues != null ) {
645            orgReviewRoleService.validateDocumentType((String)fieldValues.get(OleKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE));
646        }
647        super.validateSearchParameters(fieldValues);
648    }
649
650    public void setOrgReviewRoleService(OrgReviewRoleService orgReviewRoleService) {
651        this.orgReviewRoleService = orgReviewRoleService;
652    }
653
654
655}