Coverage Report - org.kuali.rice.kim.lookup.RoleMemberLookupableHelperServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RoleMemberLookupableHelperServiceImpl
0%
0/157
0%
0/122
7.182
RoleMemberLookupableHelperServiceImpl$1
0%
0/3
N/A
7.182
 
 1  
 /*
 2  
  * Copyright 2007-2009 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 org.apache.commons.collections.CollectionUtils;
 19  
 import org.apache.commons.collections.Predicate;
 20  
 import org.apache.commons.lang.StringUtils;
 21  
 import org.kuali.rice.core.api.criteria.QueryByCriteria;
 22  
 import org.kuali.rice.kim.api.group.Group;
 23  
 import org.kuali.rice.kim.api.group.GroupQueryResults;
 24  
 import org.kuali.rice.kim.api.identity.entity.Entity;
 25  
 import org.kuali.rice.kim.api.identity.entity.EntityQueryResults;
 26  
 import org.kuali.rice.kim.api.identity.principal.Principal;
 27  
 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
 28  
 import org.kuali.rice.kim.impl.role.RoleBo;
 29  
 import org.kuali.rice.kim.impl.role.RoleMemberBo;
 30  
 import org.kuali.rice.kim.util.KimConstants;
 31  
 import org.kuali.rice.kns.web.ui.Field;
 32  
 import org.kuali.rice.kns.web.ui.Row;
 33  
 import org.kuali.rice.krad.bo.BusinessObject;
 34  
 import org.kuali.rice.krad.lookup.CollectionIncomplete;
 35  
 import org.kuali.rice.krad.util.KRADPropertyConstants;
 36  
 
 37  
 import java.sql.Timestamp;
 38  
 import java.util.ArrayList;
 39  
 import java.util.Arrays;
 40  
 import java.util.HashMap;
 41  
 import java.util.Iterator;
 42  
 import java.util.List;
 43  
 import java.util.Map;
 44  
 
 45  
 import static org.kuali.rice.core.api.criteria.PredicateFactory.and;
 46  
 import static org.kuali.rice.core.api.criteria.PredicateFactory.like;
 47  
 
 48  0
 public abstract class RoleMemberLookupableHelperServiceImpl extends KimLookupableHelperServiceImpl {
 49  
 
 50  
         protected static final String DETAIL_CRITERIA = "detailCriteria";
 51  
         protected static final String WILDCARD = "*";
 52  
     protected static final String TEMPLATE_NAMESPACE_CODE = "template." + KimConstants.UniqueKeyConstants.NAMESPACE_CODE;
 53  
     protected static final String TEMPLATE_NAME = "template.name";
 54  
     protected static final String NAMESPACE_CODE = KimConstants.UniqueKeyConstants.NAMESPACE_CODE;
 55  
     protected static final String NAME = "name";
 56  
     protected static final String GROUP_NAME = KimConstants.UniqueKeyConstants.GROUP_NAME;
 57  
     protected static final String ASSIGNED_TO_PRINCIPAL_NAME = "assignedToPrincipal.principalName";
 58  
     protected static final String ASSIGNED_TO_GROUP_NAMESPACE_CODE = "assignedToGroupNamespaceForLookup";
 59  
     protected static final String ASSIGNED_TO_GROUP_NAME = "assignedToGroup." + KimConstants.UniqueKeyConstants.GROUP_NAME;
 60  
     protected static final String ASSIGNED_TO_NAMESPACE_FOR_LOOKUP = "assignedToRoleNamespaceForLookup";
 61  
     protected static final String ASSIGNED_TO_ROLE_NAME = "assignedToRole." + KimConstants.UniqueKeyConstants.ROLE_NAME;
 62  
     protected static final String ATTRIBUTE_NAME = "attributeName";
 63  
     protected static final String ATTRIBUTE_VALUE = "attributeValue";
 64  
     protected static final String ASSIGNED_TO_ROLE_NAMESPACE_CODE = KimConstants.UniqueKeyConstants.NAMESPACE_CODE;
 65  
     protected static final String ASSIGNED_TO_ROLE_ROLE_NAME = KimConstants.UniqueKeyConstants.ROLE_NAME;
 66  
     protected static final String ASSIGNED_TO_ROLE_MEMBER_ID = "members.memberId";
 67  
     protected static final String DETAIL_OBJECTS_ATTRIBUTE_VALUE = "detailObjects.attributeValue";
 68  
     protected static final String DETAIL_OBJECTS_ATTRIBUTE_NAME = "detailObjects.kimAttribute.attributeName";
 69  
     
 70  
     @Override
 71  
     protected List<? extends BusinessObject> getSearchResultsHelper(Map<String, String> fieldValues, boolean unbounded) {
 72  0
             Map<String, String> searchCriteria = buildRoleSearchCriteria(fieldValues);
 73  0
             if(searchCriteria == null) {
 74  0
                     return new ArrayList<BusinessObject>();
 75  
         }
 76  0
         return getMemberSearchResults(fieldValues, unbounded);
 77  
     }
 78  
 
 79  
     protected abstract List<? extends BusinessObject> getMemberSearchResults(Map<String, String> searchCriteria, boolean unbounded);
 80  
     
 81  
     protected Map<String, String> buildSearchCriteria(Map<String, String> fieldValues){
 82  0
         String templateNamespaceCode = fieldValues.get(TEMPLATE_NAMESPACE_CODE);
 83  0
         String templateName = fieldValues.get(TEMPLATE_NAME);
 84  0
         String namespaceCode = fieldValues.get(NAMESPACE_CODE);
 85  0
         String name = fieldValues.get(NAME);
 86  0
         String attributeDetailValue = fieldValues.get(ATTRIBUTE_VALUE);
 87  0
         String attributeDetailName = fieldValues.get(ATTRIBUTE_NAME);
 88  0
         String detailCriteria = fieldValues.get( DETAIL_CRITERIA );
 89  0
         String active = fieldValues.get( KRADPropertyConstants.ACTIVE );
 90  
 
 91  0
             Map<String,String> searchCriteria = new HashMap<String, String>();
 92  0
             if(StringUtils.isNotEmpty(templateNamespaceCode)) {
 93  0
                     searchCriteria.put(TEMPLATE_NAMESPACE_CODE, WILDCARD+templateNamespaceCode+WILDCARD);
 94  
             }
 95  0
         if(StringUtils.isNotEmpty(templateName)) {
 96  0
                 searchCriteria.put(TEMPLATE_NAME, WILDCARD+templateName+WILDCARD);
 97  
         }
 98  0
         if(StringUtils.isNotEmpty(namespaceCode)) {
 99  0
                 searchCriteria.put(NAMESPACE_CODE, WILDCARD+namespaceCode+WILDCARD);
 100  
         }
 101  0
         if(StringUtils.isNotEmpty(name)) {
 102  0
                 searchCriteria.put(NAME, WILDCARD+name+WILDCARD);
 103  
         }
 104  0
         if(StringUtils.isNotEmpty(attributeDetailValue)) {
 105  0
                 searchCriteria.put(DETAIL_OBJECTS_ATTRIBUTE_VALUE, WILDCARD+attributeDetailValue+WILDCARD);
 106  
         }
 107  0
         if(StringUtils.isNotEmpty(attributeDetailName)) {
 108  0
                 searchCriteria.put(DETAIL_OBJECTS_ATTRIBUTE_NAME, WILDCARD+attributeDetailName+WILDCARD);
 109  
         }
 110  0
         if ( StringUtils.isNotBlank( detailCriteria ) ) {
 111  0
                 searchCriteria.put(DETAIL_CRITERIA, detailCriteria);
 112  
         }
 113  0
         if ( StringUtils.isNotBlank( active ) ) {
 114  0
                 searchCriteria.put(KRADPropertyConstants.ACTIVE, active);
 115  
         }
 116  
 
 117  0
         return searchCriteria;
 118  
     }
 119  
     
 120  
     protected String getQueryString(String parameter){
 121  0
             if(StringUtils.isEmpty(parameter)) {
 122  0
                     return WILDCARD;
 123  
         }
 124  
             else {
 125  0
                     return WILDCARD+parameter+WILDCARD;
 126  
         }
 127  
     }
 128  
     
 129  
     @SuppressWarnings({ "unchecked" })
 130  
         protected Map<String, String> buildRoleSearchCriteria(Map<String, String> fieldValues){
 131  0
                String assignedToPrincipalName = fieldValues.get(ASSIGNED_TO_PRINCIPAL_NAME);
 132  
             Map<String, String> searchCriteria;
 133  0
             List<Principal> principals = new ArrayList<Principal>();
 134  0
         if(StringUtils.isNotEmpty(assignedToPrincipalName)){
 135  0
             QueryByCriteria.Builder query = QueryByCriteria.Builder.create();
 136  0
             query.setPredicates(like("principals.principalName", WILDCARD+assignedToPrincipalName+WILDCARD));
 137  0
                 EntityQueryResults qr = KimApiServiceLocator.getIdentityService().findEntities(query.build());
 138  0
                 if(qr.getResults() == null || qr.getResults().isEmpty()) {
 139  0
                         return null;
 140  
                 }
 141  
                 else {
 142  0
                         for (Entity kimEntityInfo : qr.getResults()) {
 143  0
                                 if(kimEntityInfo.getPrincipals() != null){
 144  0
                                         principals.addAll(kimEntityInfo.getPrincipals());
 145  
                                 }
 146  
                         }
 147  
                 }
 148  
         }
 149  0
         String assignedToGroupNamespaceCode = fieldValues.get(ASSIGNED_TO_GROUP_NAMESPACE_CODE);
 150  0
         String assignedToGroupName = fieldValues.get(ASSIGNED_TO_GROUP_NAME);
 151  0
         List<Group> groups = null;
 152  0
         if(StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isEmpty(assignedToGroupName) ||
 153  
                         StringUtils.isEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName) ||
 154  
                         StringUtils.isNotEmpty(assignedToGroupNamespaceCode) && StringUtils.isNotEmpty(assignedToGroupName)){
 155  0
             QueryByCriteria.Builder builder = QueryByCriteria.Builder.create();
 156  0
                 builder.setPredicates(and(
 157  
                             like(NAMESPACE_CODE, getQueryString(assignedToGroupNamespaceCode)),
 158  
                             like(GROUP_NAME, getQueryString(assignedToGroupName))));
 159  0
                 GroupQueryResults qr = KimApiServiceLocator.getGroupService().findGroups(builder.build());
 160  0
                 if(qr.getTotalRowCount() == 0) {
 161  0
                         return null;
 162  
             }
 163  
         }
 164  
 
 165  0
         String assignedToRoleNamespaceCode = fieldValues.get(ASSIGNED_TO_NAMESPACE_FOR_LOOKUP);
 166  0
         String assignedToRoleName = fieldValues.get(ASSIGNED_TO_ROLE_NAME);
 167  
 
 168  0
             searchCriteria = new HashMap<String, String>();
 169  0
         if (StringUtils.isNotEmpty(assignedToRoleNamespaceCode)) {
 170  0
                 searchCriteria.put(ASSIGNED_TO_ROLE_NAMESPACE_CODE, WILDCARD+assignedToRoleNamespaceCode+WILDCARD);
 171  
         }
 172  0
         if(StringUtils.isNotEmpty(assignedToRoleName)) {
 173  0
                 searchCriteria.put(ASSIGNED_TO_ROLE_ROLE_NAME, WILDCARD+assignedToRoleName+WILDCARD);
 174  
         }
 175  
 
 176  0
             StringBuffer memberQueryString = null;
 177  0
         if(principals!=null) {
 178  0
                 memberQueryString = new StringBuffer();
 179  0
                 for(Principal principal: principals){
 180  0
                         memberQueryString.append(principal.getPrincipalId()+KimConstants.KimUIConstants.OR_OPERATOR);
 181  
                 }
 182  0
             if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR)) {
 183  0
                     memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
 184  
             }
 185  
         }
 186  0
         if(groups!=null){
 187  0
                 if(memberQueryString==null) {
 188  0
                         memberQueryString = new StringBuffer();
 189  
             }
 190  0
                 else if(StringUtils.isNotEmpty(memberQueryString.toString())) {
 191  0
                         memberQueryString.append(KimConstants.KimUIConstants.OR_OPERATOR);
 192  
             }
 193  0
                 for(Group group: groups){
 194  0
                         memberQueryString.append(group.getId()+KimConstants.KimUIConstants.OR_OPERATOR);
 195  
                 }
 196  0
             if(memberQueryString.toString().endsWith(KimConstants.KimUIConstants.OR_OPERATOR)) {
 197  0
                     memberQueryString.delete(memberQueryString.length()-KimConstants.KimUIConstants.OR_OPERATOR.length(), memberQueryString.length());
 198  
             }
 199  0
                 searchCriteria.put(ASSIGNED_TO_ROLE_MEMBER_ID, memberQueryString.toString());
 200  
         }
 201  0
         if (memberQueryString!=null && StringUtils.isNotEmpty(memberQueryString.toString())) {
 202  0
                 searchCriteria.put(ASSIGNED_TO_ROLE_MEMBER_ID, memberQueryString.toString());
 203  
         }
 204  
 
 205  0
         return searchCriteria;
 206  
     }
 207  
 
 208  
     
 209  
     /** Checks whether the 2nd map is a subset of the first. */
 210  
         protected boolean isMapSubset( Map<String, String> mainMap, Map<String, String> subsetMap ) {
 211  0
                 for ( Map.Entry<String, String> keyValue : subsetMap.entrySet() ) {
 212  0
                         if ( !mainMap.containsKey(keyValue.getKey()) 
 213  
                                         || !StringUtils.equals( mainMap.get(keyValue.getKey()), keyValue.getValue() ) ) {
 214  
 //                                if ( LOG.isDebugEnabled() ) {
 215  
 //                                        LOG.debug( "Maps did not match:\n" + mainMap + "\n" + subsetMap );
 216  
 //                                }
 217  0
                                 return false;
 218  
                         }
 219  
                 }
 220  
 //                if ( LOG.isDebugEnabled() ) {
 221  
 //                        LOG.debug( "Maps matched:\n" + mainMap + "\n" + subsetMap );
 222  
 //                }
 223  0
                 return true;
 224  
         }
 225  
 
 226  
         /** Converts a special criteria string that is in the form key=value,key2=value2 into a map */
 227  
         protected Map<String, String> parseDetailCriteria( String detailCritiera ) {
 228  0
             if ( StringUtils.isBlank(detailCritiera) ) {
 229  0
                 return new HashMap<String, String>(0);
 230  
             }
 231  0
                 String[] keyValuePairs = StringUtils.split(detailCritiera, ',');
 232  0
                 if ( keyValuePairs == null || keyValuePairs.length == 0 ) {
 233  0
                     return new HashMap<String, String>(0);
 234  
                 }
 235  0
                 Map<String, String> parsedDetails = new HashMap<String, String>( keyValuePairs.length );
 236  0
                 for ( String keyValueStr : keyValuePairs ) {
 237  0
                         String[] keyValue = StringUtils.split(keyValueStr, '=');
 238  0
                         if ( keyValue.length >= 2 ) {
 239  0
                                 parsedDetails.put(keyValue[0], keyValue[1]);
 240  
                         }
 241  
                 }
 242  0
                 return parsedDetails;
 243  
         }
 244  
         
 245  
         
 246  
         @Override
 247  
         public List<Row> getRows() {
 248  0
                 List<Row> rows = super.getRows();
 249  0
                 Iterator<Row> i = rows.iterator();
 250  0
                 while ( i.hasNext() ) {
 251  0
                         Row row = i.next();
 252  0
                         int numFieldsRemoved = 0;
 253  0
                         boolean rowIsBlank = true;
 254  0
                         for (Iterator<Field> fieldIter = row.getFields().iterator(); fieldIter.hasNext();) {
 255  0
                                 Field field = fieldIter.next();
 256  0
                                 String propertyName = field.getPropertyName();
 257  0
                                 if ( propertyName.equals(DETAIL_CRITERIA) ) {
 258  0
                                         Object val = getParameters().get( propertyName );
 259  0
                                         String propVal = null;
 260  0
                                         if ( val != null ) {
 261  0
                                                 propVal = (val instanceof String)?(String)val:((String[])val)[0];
 262  
                                         }
 263  0
                                         if ( StringUtils.isBlank( propVal ) ) {
 264  0
                                                 fieldIter.remove();
 265  0
                                                 numFieldsRemoved++;
 266  
                                         } else {
 267  0
                                                 field.setReadOnly(true);
 268  0
                                                 rowIsBlank = false;
 269  
                                                 // leaving this in would prevent the "clear" button from resetting this value
 270  
 //                                                field.setDefaultValue( propVal );
 271  
                                         }
 272  0
                                 } else if (!Field.BLANK_SPACE.equals(field.getFieldType())) {
 273  0
                                         rowIsBlank = false;
 274  
                                 }
 275  0
                         }
 276  
                         // Check if any fields were removed from the row.
 277  0
                         if (numFieldsRemoved > 0) {
 278  
                                 // If fields were removed, check whether or not the remainder of the row is empty or only has blank space fields.
 279  0
                                 if (rowIsBlank) {
 280  
                                         // If so, then remove the row entirely.
 281  0
                                         i.remove();
 282  
                                 } else {
 283  
                                         // Otherwise, add one blank space for each field that was removed, using a technique similar to FieldUtils.createBlankSpace.
 284  
                                         // It is safe to just add blank spaces as needed, since the removable field is the last of the visible ones in the list (or
 285  
                                         // at least for the Permission and Responsibility lookups).
 286  0
                                         while (numFieldsRemoved > 0) {
 287  0
                                                 Field blankSpace = new Field();
 288  0
                                                 blankSpace.setFieldType(Field.BLANK_SPACE);
 289  0
                                                 blankSpace.setPropertyName(Field.BLANK_SPACE);
 290  0
                                                 row.getFields().add(blankSpace);
 291  0
                                                 numFieldsRemoved--;
 292  0
                                         }
 293  
                                 }
 294  
                         }
 295  0
                 }
 296  0
                 return rows;
 297  
         }
 298  
     
 299  
         protected Long getActualSizeIfTruncated(List result){
 300  0
                 Long actualSizeIfTruncated = new Long(0); 
 301  0
                 if(result instanceof CollectionIncomplete) {
 302  0
                         actualSizeIfTruncated = ((CollectionIncomplete)result).getActualSizeIfTruncated();
 303  
         }
 304  0
                 return actualSizeIfTruncated;
 305  
         }
 306  
         
 307  
         @SuppressWarnings("unchecked")
 308  
         protected List<RoleBo> searchRoles(Map<String, String> roleSearchCriteria, boolean unbounded){
 309  0
                 List<RoleBo> roles = (List<RoleBo>)getLookupService().findCollectionBySearchHelper(
 310  
                                 RoleBo.class, roleSearchCriteria, unbounded);
 311  0
                 String membersCrt = roleSearchCriteria.get("members.memberId");
 312  0
                 List<RoleBo> roles2Remove = new ArrayList<RoleBo>();
 313  0
                 if(StringUtils.isNotBlank(membersCrt)){
 314  0
                         List<String> memberSearchIds = new ArrayList<String>();
 315  0
                         List<String> memberIds = new ArrayList<String>(); 
 316  0
                         if(membersCrt.contains(KimConstants.KimUIConstants.OR_OPERATOR)) {
 317  0
                                 memberSearchIds = new ArrayList<String>(Arrays.asList(membersCrt.split("\\|")));
 318  
             }
 319  
                         else {
 320  0
                                 memberSearchIds.add(membersCrt);
 321  
             }
 322  0
                         for(RoleBo roleBo : roles){
 323  0
                                 List<RoleMemberBo> roleMembers = roleBo.getMembers();
 324  0
                                 memberIds.clear(); 
 325  0
                         CollectionUtils.filter(roleMembers, new Predicate() {
 326  
                                         public boolean evaluate(Object object) {
 327  0
                                                 RoleMemberBo member = (RoleMemberBo) object;
 328  
                                                 // keep active member
 329  0
                                                 return member.isActive(new Timestamp(System.currentTimeMillis()));
 330  
                                         }
 331  
                                 });
 332  
                        
 333  0
                         if(roleMembers != null && !roleMembers.isEmpty()){
 334  0
                                 for(RoleMemberBo memberImpl : roleMembers) {
 335  0
                                         memberIds.add(memberImpl.getMemberId());
 336  
                     }
 337  0
                                 if(((List<String>)CollectionUtils.intersection(memberSearchIds, memberIds)).isEmpty()) {
 338  0
                                         roles2Remove.add(roleBo);
 339  
                     }
 340  
                         }
 341  
                         else
 342  
                         {
 343  0
                                 roles2Remove.add(roleBo);
 344  
                         }
 345  0
                         }
 346  
                 }
 347  0
                 if(!roles2Remove.isEmpty()) {
 348  0
                         roles.removeAll(roles2Remove);
 349  
         }
 350  0
                 return roles;
 351  
         }
 352  
 
 353  
 
 354  
 }