001    /**
002     * Copyright 2005-2013 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     */
016    package org.kuali.rice.kim.impl.role;
017    
018    import org.apache.commons.collections.CollectionUtils;
019    import org.apache.commons.lang.StringUtils;
020    import org.apache.ojb.broker.query.Criteria;
021    import org.apache.ojb.broker.query.Query;
022    import org.apache.ojb.broker.query.QueryFactory;
023    import org.apache.ojb.broker.query.ReportQueryByCriteria;
024    import org.joda.time.DateTime;
025    import org.kuali.rice.core.api.criteria.Predicate;
026    import org.kuali.rice.core.api.criteria.PredicateFactory;
027    import org.kuali.rice.core.api.criteria.PredicateUtils;
028    import org.kuali.rice.core.api.criteria.QueryByCriteria;
029    import org.kuali.rice.core.api.membership.MemberType;
030    import org.kuali.rice.core.api.util.Truth;
031    import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
032    import org.kuali.rice.kim.api.KimConstants;
033    import org.kuali.rice.kim.api.common.attribute.KimAttribute;
034    import org.kuali.rice.kim.api.group.GroupMember;
035    import org.kuali.rice.kim.api.identity.entity.EntityDefault;
036    import org.kuali.rice.kim.api.identity.principal.Principal;
037    import org.kuali.rice.kim.api.permission.Permission;
038    import org.kuali.rice.kim.api.responsibility.Responsibility;
039    import org.kuali.rice.kim.api.responsibility.ResponsibilityQueryResults;
040    import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
041    import org.kuali.rice.kim.api.role.Role;
042    import org.kuali.rice.kim.api.role.RoleMember;
043    import org.kuali.rice.kim.api.role.RoleMembership;
044    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
045    import org.kuali.rice.kim.api.type.KimType;
046    import org.kuali.rice.kim.impl.KIMPropertyConstants;
047    import org.kuali.rice.kim.impl.common.attribute.KimAttributeBo;
048    import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo;
049    import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
050    import org.kuali.rice.kim.impl.type.KimTypeBo;
051    import org.springframework.dao.DataAccessException;
052    import org.springframework.jdbc.core.JdbcTemplate;
053    import org.springframework.jdbc.core.PreparedStatementCallback;
054    import org.springframework.jdbc.core.PreparedStatementCreator;
055    import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
056    
057    import javax.sql.DataSource;
058    import java.sql.Connection;
059    import java.sql.Date;
060    import java.sql.PreparedStatement;
061    import java.sql.ResultSet;
062    import java.sql.SQLException;
063    import java.sql.Timestamp;
064    import java.util.ArrayList;
065    import java.util.Collection;
066    import java.util.HashMap;
067    import java.util.List;
068    import java.util.Map;
069    import java.util.Map.Entry;
070    
071    import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
072    
073    public class RoleDaoOjb extends PlatformAwareDaoBaseOjb implements RoleDao {
074    
075        private DataSource dataSource;
076    
077        public void setDataSource(DataSource dataSource) {
078            this.dataSource = new TransactionAwareDataSourceProxy(dataSource);
079        }
080    
081        /**
082         * Adds SubCriteria to the Query Criteria using the role qualification passed in
083         *
084         * @param c             The Query Criteria object to be used
085         * @param qualification The role qualification
086         */
087        private void addSubCriteriaBasedOnRoleQualification(Criteria c, Map<String, String> qualification) {
088            if (qualification != null && CollectionUtils.isNotEmpty(qualification.keySet())) {
089                for (Map.Entry<String, String> qualifier : qualification.entrySet()) {
090                    Criteria subCrit = new Criteria();
091                    if (StringUtils.isNotEmpty(qualifier.getValue())) {
092                        String value = (qualifier.getValue()).replace('*', '%');
093                        subCrit.addLike("attributeValue", value);
094                        subCrit.addEqualTo("kimAttributeId", qualifier.getKey());
095                        subCrit.addEqualToField("assignedToId", Criteria.PARENT_QUERY_PREFIX + "id");
096                        ReportQueryByCriteria subQuery = QueryFactory.newReportQuery(RoleMemberAttributeDataBo.class, subCrit);
097                        c.addExists(subQuery);
098                    }
099                }
100            }
101        }
102    
103        public List<RoleMemberBo> getRoleMembersForGroupIds(String roleId, List<String> groupIds) {
104            Criteria crit = new Criteria();
105            crit.addEqualTo(KIMPropertyConstants.RoleMember.ROLE_ID, roleId);
106            crit.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode());
107            crit.addIn(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds);
108            Query query = QueryFactory.newQuery(RoleMemberBo.class, crit);
109            Collection<RoleMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
110            List<RoleMemberBo> results = new ArrayList<RoleMemberBo>(coll.size());
111            for (RoleMemberBo rm : coll) {
112                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
113                    results.add(rm);
114                }
115            }
116            return results;
117        }
118    
119        @SuppressWarnings("unchecked")
120        public List<RoleMemberBo> getRolePrincipalsForPrincipalIdAndRoleIds(Collection<String> roleIds, String principalId, Map<String, String> qualification) {
121    
122            Criteria c = new Criteria();
123    
124            if (CollectionUtils.isNotEmpty(roleIds)) {
125                if (roleIds.size() == 1) {
126                    c.addEqualTo(KIMPropertyConstants.RoleMember.ROLE_ID, roleIds.iterator().next());
127                } else {
128                    c.addIn(KIMPropertyConstants.RoleMember.ROLE_ID, roleIds);
129                }
130            }
131            if (principalId != null) {
132                c.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_ID, principalId);
133            }
134            c.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode());
135            addSubCriteriaBasedOnRoleQualification(c, qualification);
136    
137            Query query = QueryFactory.newQuery(RoleMemberBo.class, c);
138            Collection<RoleMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
139            ArrayList<RoleMemberBo> results = new ArrayList<RoleMemberBo>(coll.size());
140            for (RoleMemberBo rm : coll) {
141                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
142                    results.add(rm);
143                }
144            }
145            return results;
146        }
147    
148        public List<GroupMember> getGroupPrincipalsForPrincipalIdAndGroupIds(Collection<String> groupIds, String principalId) {
149            List<String> groupIdValues = new ArrayList<String>();
150            List<GroupMember> groupPrincipals = new ArrayList<GroupMember>();
151            if (groupIds != null
152                    && principalId == null) {
153                groupIdValues = new ArrayList<String>(groupIds);
154            } else if (principalId != null) {
155                groupIdValues = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(principalId);
156            }
157            if (groupIdValues != null
158                    && groupIdValues.size() > 0) {
159                Collection<GroupMember> groupMembers = KimApiServiceLocator.getGroupService().getMembers(groupIdValues);
160                for (GroupMember groupMembershipInfo : groupMembers) {
161                    if (principalId != null) {
162                        if (MemberType.PRINCIPAL.equals(groupMembershipInfo.getType())
163                                && StringUtils.equals(principalId, groupMembershipInfo.getMemberId())
164                                && groupMembershipInfo.isActive(new DateTime())) {
165                            groupPrincipals.add(groupMembershipInfo);
166                        }
167                    } else {
168                        groupPrincipals.add(groupMembershipInfo);
169                    }
170                }
171            }
172            return groupPrincipals;
173        }
174    
175        public List<GroupMember> getGroupMembers(Collection<String> groupIds) {
176            List<GroupMember> groupMembers = new ArrayList<GroupMember>();
177            if (groupIds != null) {
178                List<String> groupIdValues = new ArrayList<String>(groupIds);
179    
180                if (groupIdValues.size() > 0) {
181    
182                    Collection<GroupMember> groupMemberships = KimApiServiceLocator.getGroupService().getMembers(groupIdValues);
183    
184                    if (!CollectionUtils.isEmpty(groupMemberships)) {
185                        for (GroupMember groupMembershipInfo : groupMemberships) {
186                            if (MemberType.GROUP.equals(groupMembershipInfo.getType())
187                                    && groupMembershipInfo.isActive(new DateTime())) {
188                                groupMembers.add(groupMembershipInfo);
189                            }
190                        }
191                    }
192                }
193            }
194            return groupMembers;
195        }
196    
197        @SuppressWarnings("unchecked")
198        public List<RoleMemberBo> getRoleGroupsForGroupIdsAndRoleIds(Collection<String> roleIds, Collection<String> groupIds, Map<String, String> qualification) {
199            Criteria c = new Criteria();
200            if (roleIds != null && !roleIds.isEmpty()) {
201                c.addIn(KIMPropertyConstants.RoleMember.ROLE_ID, roleIds);
202            }
203            if (groupIds != null && !groupIds.isEmpty()) {
204                c.addIn(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds);
205            }
206            c.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode());
207            addSubCriteriaBasedOnRoleQualification(c, qualification);
208    
209            Query query = QueryFactory.newQuery(RoleMemberBo.class, c);
210            Collection<RoleMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
211            ArrayList<RoleMemberBo> results = new ArrayList<RoleMemberBo>(coll.size());
212            for (RoleMemberBo rm : coll) {
213                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
214                    results.add(rm);
215                }
216            }
217            return results;
218        }
219    
220        @SuppressWarnings("unchecked")
221        public Map<String, DelegateTypeBo> getDelegationImplMapFromRoleIds(Collection<String> roleIds) {
222            Map<String, DelegateTypeBo> results = new HashMap<String, DelegateTypeBo>();
223            if (CollectionUtils.isNotEmpty(roleIds)) {
224                Criteria c = new Criteria();
225                c.addIn(KIMPropertyConstants.Delegation.ROLE_ID, roleIds);
226                c.addEqualTo(KIMPropertyConstants.Delegation.ACTIVE, Boolean.TRUE);
227                Query query = QueryFactory.newQuery(DelegateTypeBo.class, c);
228                Collection<DelegateTypeBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
229                for (DelegateTypeBo delegateBo : coll) {
230                    results.put(delegateBo.getDelegationId(), delegateBo);
231                }
232            }
233            return results;
234        }
235    
236        @SuppressWarnings("unchecked")
237        public List<DelegateTypeBo> getDelegationBosForRoleIds(Collection<String> roleIds) {
238            List<DelegateTypeBo> results = new ArrayList<DelegateTypeBo>();
239            if (roleIds != null && !roleIds.isEmpty()) {
240                Criteria c = new Criteria();
241                c.addIn(KIMPropertyConstants.Delegation.ROLE_ID, roleIds);
242                c.addEqualTo(KIMPropertyConstants.Delegation.ACTIVE, Boolean.TRUE);
243                Query query = QueryFactory.newQuery(DelegateTypeBo.class, c);
244                Collection<DelegateTypeBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
245                for (DelegateTypeBo delegateBo : coll) {
246                    results.add(delegateBo);
247                }
248            }
249            return results;
250        }
251    
252        @SuppressWarnings("unchecked")
253        public List<DelegateMemberBo> getDelegationPrincipalsForPrincipalIdAndDelegationIds(
254                Collection<String> delegationIds, String principalId) {
255            Criteria c = new Criteria();
256    
257            if (principalId != null) {
258                c.addEqualTo(KIMPropertyConstants.DelegationMember.MEMBER_ID, principalId);
259            }
260            c.addEqualTo(KIMPropertyConstants.DelegationMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode());
261            if (delegationIds != null && !delegationIds.isEmpty()) {
262                c.addIn(KIMPropertyConstants.DelegationMember.DELEGATION_ID, delegationIds);
263            }
264            Query query = QueryFactory.newQuery(DelegateMemberBo.class, c);
265            Collection<DelegateMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
266            ArrayList<DelegateMemberBo> results = new ArrayList<DelegateMemberBo>(coll.size());
267            for (DelegateMemberBo rm : coll) {
268                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
269                    results.add(rm);
270                }
271            }
272            return results;
273        }
274    
275        @SuppressWarnings("unchecked")
276        public List<DelegateMemberBo> getDelegationGroupsForGroupIdsAndDelegationIds(Collection<String> delegationIds,
277                List<String> groupIds) {
278            Criteria c = new Criteria();
279            if (delegationIds != null && !delegationIds.isEmpty()) {
280                c.addIn(KIMPropertyConstants.DelegationMember.DELEGATION_ID, delegationIds);
281            }
282            if (groupIds != null && !groupIds.isEmpty()) {
283                c.addIn(KIMPropertyConstants.DelegationMember.MEMBER_ID, groupIds);
284            }
285            c.addEqualTo(KIMPropertyConstants.DelegationMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode());
286            Query query = QueryFactory.newQuery(DelegateMemberBo.class, c);
287            Collection<DelegateMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
288            ArrayList<DelegateMemberBo> results = new ArrayList<DelegateMemberBo>(coll.size());
289            for (DelegateMemberBo rm : coll) {
290                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
291                    results.add(rm);
292                }
293            }
294            return results;
295        }
296    
297        public List<RoleMemberBo> getRoleMembersForRoleIds(Collection<String> roleIds, String memberTypeCode,
298                Map<String, String> qualification) {
299            JdbcTemplate template = new JdbcTemplate(dataSource);
300            final List<String> roleIDs = new ArrayList<String>(roleIds);
301            final String memberTypeCd = memberTypeCode;
302            final Map<String, String> qual = qualification;
303            final List<RoleMemberBo> roleMemberBos = new ArrayList<RoleMemberBo>();
304            List<RoleMemberBo> results = template.execute(new PreparedStatementCreator() {
305    
306                        /*
307                         SAMPLE QUERY
308    
309                        SELECT A0.ROLE_MBR_ID AS ROLE_MBR_ID,A0.ROLE_ID AS ROLE_ID,A0.MBR_ID AS MBR_ID,A0.MBR_TYP_CD AS MBR_TYP_CD,A0.VER_NBR AS ROLE_MBR_VER_NBR,A0.OBJ_ID AS ROLE_MBR_OBJ_ID,A0.ACTV_FRM_DT AS ROLE_MBR_ACTV_FRM_DT ,A0.ACTV_TO_DT AS ROLE_MBR_ACTV_TO_DT,
310                        BO.KIM_TYP_ID AS KIM_TYP_ID, BO.KIM_ATTR_DEFN_ID AS KIM_ATTR_DEFN_ID, BO.ATTR_VAL AS ATTR_VAL, BO.ATTR_DATA_ID AS ATTR_DATA_ID, BO.OBJ_ID AS ATTR_DATA_OBJ_ID, BO.VER_NBR AS ATTR_DATA_VER_NBR,
311                        CO.OBJ_ID AS ATTR_DEFN_OBJ_ID, CO.VER_NBR as ATTR_DEFN_VER_NBR, CO.NM AS ATTR_NAME, CO.LBL as ATTR_DEFN_LBL, CO.ACTV_IND as ATTR_DEFN_ACTV_IND, CO.NMSPC_CD AS ATTR_DEFN_NMSPC_CD, CO.CMPNT_NM AS ATTR_DEFN_CMPNT_NM
312                        FROM KRIM_ROLE_MBR_T A0 JOIN KRIM_ROLE_MBR_ATTR_DATA_T BO ON A0.ROLE_MBR_ID = BO.ROLE_MBR_ID  JOIN KRIM_ATTR_DEFN_T CO ON BO.KIM_ATTR_DEFN_ID = CO.KIM_ATTR_DEFN_ID
313                        WHERE A0.ROLE_ID in ('100000')
314    
315                        UNION ALL
316    
317                        SELECT D0.ROLE_MBR_ID AS ROLE_MBR_ID,D0.ROLE_ID AS ROLE_ID,D0.MBR_ID AS MBR_ID,D0.MBR_TYP_CD AS MBR_TYP_CD,D0.VER_NBR AS ROLE_MBR_VER_NBR,D0.OBJ_ID AS ROLE_MBR_OBJ_ID,D0.ACTV_FRM_DT AS ROLE_MBR_ACTV_FRM_DT ,D0.ACTV_TO_DT AS ROLE_MBR_ACTV_TO_DT,
318                        '' AS KIM_TYP_ID, '' AS KIM_ATTR_DEFN_ID, '' AS ATTR_VAL, '' AS ATTR_DATA_ID, '' AS ATTR_DATA_OBJ_ID, NULL AS ATTR_DATA_VER_NBR,
319                        '' AS ATTR_DEFN_OBJ_ID, NULL as ATTR_DEFN_VER_NBR, '' AS ATTR_NAME, '' as ATTR_DEFN_LBL, '' as ATTR_DEFN_ACTV_IND, '' AS ATTR_DEFN_NMSPC_CD, '' AS ATTR_DEFN_CMPNT_NM
320                        FROM KRIM_ROLE_MBR_T D0
321                        WHERE D0.ROLE_MBR_ID NOT IN (SELECT DISTINCT (E0.ROLE_MBR_ID) FROM KRIM_ROLE_MBR_ATTR_DATA_T E0)
322                        AND D0.ROLE_ID IN ('100000')
323                        */
324    
325                        public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
326                            /*
327                             The query returns multiple lines for each role by joining a role with each of its members. This allows us to get all the role member
328                             and role data in a single query (even though we are duplicating the role information across the role members). The cost of this
329                             comes out to be cheaper than firing indiviudual queries for each role in cases where there are over 500 roles
330                            */
331                            StringBuffer sql1 = new StringBuffer("SELECT "
332                                    + " A0.ROLE_MBR_ID AS ROLE_MBR_ID,A0.ROLE_ID AS ROLE_ID,A0.MBR_ID AS MBR_ID,A0.MBR_TYP_CD AS MBR_TYP_CD,A0.VER_NBR AS ROLE_MBR_VER_NBR,A0.OBJ_ID AS ROLE_MBR_OBJ_ID,A0.ACTV_FRM_DT AS ROLE_MBR_ACTV_FRM_DT ,A0.ACTV_TO_DT AS ROLE_MBR_ACTV_TO_DT, "
333                                    + " BO.KIM_TYP_ID AS KIM_TYP_ID, BO.KIM_ATTR_DEFN_ID AS KIM_ATTR_DEFN_ID, BO.ATTR_VAL AS ATTR_VAL, BO.ATTR_DATA_ID AS ATTR_DATA_ID, BO.OBJ_ID AS ATTR_DATA_OBJ_ID, BO.VER_NBR AS ATTR_DATA_VER_NBR,  "
334                                    + " C0.KIM_ATTR_DEFN_ID AS KIM_ATTR_DEFN_ID, C0.OBJ_ID AS ATTR_DEFN_OBJ_ID, C0.VER_NBR as ATTR_DEFN_VER_NBR, C0.NM AS ATTR_NAME, C0.LBL as ATTR_DEFN_LBL, C0.ACTV_IND as ATTR_DEFN_ACTV_IND, C0.NMSPC_CD AS ATTR_DEFN_NMSPC_CD, C0.CMPNT_NM AS ATTR_DEFN_CMPNT_NM "
335                                    + " FROM KRIM_ROLE_MBR_T A0 JOIN KRIM_ROLE_MBR_ATTR_DATA_T BO ON A0.ROLE_MBR_ID = BO.ROLE_MBR_ID "
336                                    + " JOIN KRIM_ATTR_DEFN_T C0 ON BO.KIM_ATTR_DEFN_ID = C0.KIM_ATTR_DEFN_ID  ");
337    
338                            StringBuffer sql2 = new StringBuffer("SELECT"
339                                    + " D0.ROLE_MBR_ID AS ROLE_MBR_ID,D0.ROLE_ID AS ROLE_ID,D0.MBR_ID AS MBR_ID,D0.MBR_TYP_CD AS MBR_TYP_CD,D0.VER_NBR AS ROLE_MBR_VER_NBR,D0.OBJ_ID AS ROLE_MBR_OBJ_ID,D0.ACTV_FRM_DT AS ROLE_MBR_ACTV_FRM_DT ,D0.ACTV_TO_DT AS ROLE_MBR_ACTV_TO_DT, "
340                                    + " '' AS KIM_TYP_ID, '' AS KIM_ATTR_DEFN_ID, '' AS ATTR_VAL, '' AS ATTR_DATA_ID, '' AS ATTR_DATA_OBJ_ID, NULL AS ATTR_DATA_VER_NBR,"
341                                    + " '' AS KIM_ATTR_DEFN_ID,'' AS ATTR_DEFN_OBJ_ID, NULL as ATTR_DEFN_VER_NBR, '' AS ATTR_NAME, '' as ATTR_DEFN_LBL, '' as ATTR_DEFN_ACTV_IND, '' AS ATTR_DEFN_NMSPC_CD, '' AS ATTR_DEFN_CMPNT_NM "
342                                    + " FROM KRIM_ROLE_MBR_T D0 "
343                                    + " WHERE D0.ROLE_MBR_ID NOT IN (SELECT DISTINCT (E0.ROLE_MBR_ID) FROM KRIM_ROLE_MBR_ATTR_DATA_T E0)");
344    
345                            StringBuffer criteria = new StringBuffer();
346    
347                            List<String> params1 = new ArrayList<String>();
348                            List<String> params2 = new ArrayList<String>();
349    
350                            if (roleIDs != null && !roleIDs.isEmpty()) {
351                                criteria.append("A0.ROLE_ID IN (");
352    
353                                for (String roleId : roleIDs) {
354                                    criteria.append("?,");
355                                    params1.add(roleId);
356                                    params2.add(roleId);
357                                }
358                                criteria.deleteCharAt(criteria.length() - 1);
359                                criteria.append(")");
360                            }
361    
362                            if (memberTypeCd != null) {
363                                if (criteria.length() > 0) {
364                                    criteria.append(" AND ");
365                                }
366    
367                                criteria.append("A0.MBR_TYP_CD = ?");
368                                params1.add(memberTypeCd);
369                                params2.add(memberTypeCd);
370                            }
371    
372                            // Assuming that at least a role id or role member type code is specified
373                            if (criteria.length() > 0) {
374                                sql1.append(" WHERE ");
375                                sql2.append(" AND ");
376                                sql1.append(criteria);
377                                sql2.append(criteria.toString().replaceAll("A0", "D0"));
378                            }
379    
380                            if (qual != null && CollectionUtils.isNotEmpty(qual.keySet())) {
381    
382                                // If Qualifiers present then sql2 should not be returning any result as it finds
383                                // rolemembers with now attributes
384                                sql2 = new StringBuffer();
385    
386                                if (criteria.length() > 0) {
387                                    sql1.append(" AND ");
388                                } else {
389                                    sql1.append(" WHERE ");
390                                }
391    
392                                sql1.append(" EXISTS (SELECT B1.ROLE_MBR_ID FROM KRIM_ROLE_MBR_ATTR_DATA_T B1 WHERE (");
393                                for (Map.Entry<String, String> qualifier : qual.entrySet()) {
394                                    if (StringUtils.isNotEmpty(qualifier.getValue())) {
395                                        String value = (qualifier.getValue()).replace('*', '%');
396                                        sql1.append(" (B1.ATTR_VAL LIKE ? AND B1.KIM_ATTR_DEFN_ID = ? ) ");
397                                        params1.add(value);
398                                        params1.add(qualifier.getKey());
399                                    }
400                                    sql1.append("OR");
401                                }
402                                sql1.delete(sql1.length() - 2, sql1.length());
403                                sql1.append(") AND B1.ROLE_MBR_ID = A0.ROLE_MBR_ID )");
404    
405                            }
406    
407                            StringBuffer sql = new StringBuffer(sql1.toString());
408    
409                            if (sql2.length() > 0) {
410                                sql.append(" UNION ALL ");
411                                sql.append(sql2.toString());
412                            }
413    
414                            sql.append(" ORDER BY ROLE_MBR_ID ");
415    
416                            PreparedStatement statement = connection.prepareStatement(sql.toString());
417                            int i = 1;
418                            for (String param : params1) {
419                                statement.setString(i, param);
420                                i++;
421                            }
422    
423                            if (sql2.length() > 0) {
424                                for (String param : params2) {
425                                    statement.setString(i, param);
426                                    i++;
427                                }
428                            }
429    
430                            return statement;
431                        }
432                    }, new PreparedStatementCallback<List<RoleMemberBo>>() {
433                public List<RoleMemberBo> doInPreparedStatement(
434                        PreparedStatement statement) throws SQLException, DataAccessException {
435                    ResultSet rs = statement.executeQuery();
436                    try {
437                        RoleMemberBo lastRoleMember = null;
438                        while (rs.next()) {
439                            boolean processRolemember = true;
440    
441                            String roleId = rs.getString("ROLE_ID");
442                            String id = rs.getString("ROLE_MBR_ID");
443                            String memberId = rs.getString("MBR_ID");
444    
445                            MemberType memberType = MemberType.fromCode(rs.getString("MBR_TYP_CD"));
446                            DateTime activeFromDate = rs.getDate("ROLE_MBR_ACTV_FRM_DT") == null ? null: new DateTime(rs.getDate("ROLE_MBR_ACTV_FRM_DT"));
447                            DateTime activeToDate =   rs.getDate("ROLE_MBR_ACTV_TO_DT") == null ? null: new DateTime(rs.getDate("ROLE_MBR_ACTV_TO_DT"));
448    
449                            // Since we are joining role members and attributes we would have multiple role member rows
450                            // but one row per attribute so check if its the first time we are seeing the role member
451                            if (lastRoleMember == null || !id.equals(lastRoleMember.getId())) {
452                                RoleMember roleMember = RoleMember.Builder.create(roleId, id, memberId, memberType,
453                                        activeFromDate, activeToDate, new HashMap<String, String>(), "", "").build();
454                                Long roleVersionNbr = rs.getLong("ROLE_MBR_VER_NBR");
455                                String roleObjId = rs.getString("ROLE_MBR_OBJ_ID");
456    
457                                RoleMemberBo roleMemberBo = RoleMemberBo.from(roleMember);
458                                roleMemberBo.setVersionNumber(roleVersionNbr);
459                                roleMemberBo.setObjectId(roleObjId);
460                                List<RoleMemberAttributeDataBo> roleMemAttrBos = new ArrayList<RoleMemberAttributeDataBo>();
461    
462                                roleMemberBo.setAttributeDetails(roleMemAttrBos);
463                                if(roleMemberBo.isActive(new Timestamp(System.currentTimeMillis()))){
464                                    roleMemberBos.add(roleMemberBo);
465                                } else {
466                                    processRolemember = false;
467                                }
468    
469                                lastRoleMember = roleMemberBo;
470                            }
471    
472                            String kimTypeId = rs.getString("KIM_TYP_ID");
473                            String attrKey = rs.getString("KIM_ATTR_DEFN_ID");
474                            String attrVal = rs.getString("ATTR_VAL");
475                            if (processRolemember && StringUtils.isNotEmpty(kimTypeId)) {
476                                KimType theType = KimApiServiceLocator.getKimTypeInfoService().getKimType(kimTypeId);
477                                // Create RoleMemberAttributeDataBo for this row
478                                RoleMemberAttributeDataBo roleMemAttrDataBo = new RoleMemberAttributeDataBo();
479    
480                                KimAttribute.Builder attrBuilder = KimAttribute.Builder.create(rs.getString(
481                                        "ATTR_DEFN_CMPNT_NM"), rs.getString("ATTR_NAME"), rs.getString(
482                                        "ATTR_DEFN_NMSPC_CD"));
483                                attrBuilder.setActive(Truth.strToBooleanIgnoreCase(rs.getString("ATTR_DEFN_ACTV_IND")));
484                                attrBuilder.setAttributeLabel(rs.getString("ATTR_DEFN_LBL"));
485                                attrBuilder.setId(rs.getString("KIM_ATTR_DEFN_ID"));
486                                attrBuilder.setObjectId(rs.getString("ATTR_DEFN_OBJ_ID"));
487                                attrBuilder.setVersionNumber(rs.getLong("ATTR_DEFN_VER_NBR"));
488    
489                                roleMemAttrDataBo.setId(rs.getString("ATTR_DATA_ID"));
490                                roleMemAttrDataBo.setAssignedToId(id);
491                                roleMemAttrDataBo.setKimTypeId(kimTypeId);
492                                roleMemAttrDataBo.setKimType(KimTypeBo.from(theType));
493                                roleMemAttrDataBo.setKimAttributeId(attrBuilder.getId());
494                                roleMemAttrDataBo.setAttributeValue(attrVal);
495                                roleMemAttrDataBo.setVersionNumber(rs.getLong("ATTR_DATA_VER_NBR"));
496                                roleMemAttrDataBo.setObjectId(rs.getString("ATTR_DATA_OBJ_ID"));
497    
498                                roleMemAttrDataBo.setKimAttribute(KimAttributeBo.from(attrBuilder.build()));
499                                lastRoleMember.getAttributeDetails().add(roleMemAttrDataBo);
500                            }
501    
502                        }
503                    } finally {
504                        if (rs != null) {
505                            rs.close();
506                        }
507                    }
508                    return roleMemberBos;
509                }
510            }
511            );
512            return roleMemberBos;
513        }
514    
515        @SuppressWarnings("unchecked")
516        public List<RoleMemberBo> getRoleMembershipsForRoleIdsAsMembers(Collection<String> roleIds, Map<String, String> qualification) {
517            Criteria c = new Criteria();
518    
519            if (roleIds != null && !roleIds.isEmpty()) {
520                c.addIn(KIMPropertyConstants.RoleMember.MEMBER_ID, roleIds);
521            }
522            c.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.ROLE.getCode());
523            addSubCriteriaBasedOnRoleQualification(c, qualification);
524    
525            Query query = QueryFactory.newQuery(RoleMemberBo.class, c);
526            Collection<RoleMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
527            ArrayList<RoleMemberBo> results = new ArrayList<RoleMemberBo>(coll.size());
528            for (RoleMemberBo rm : coll) {
529                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
530                    results.add(rm);
531                }
532            }
533            return results;
534        }
535    
536        @SuppressWarnings("unchecked")
537        public List<RoleMemberBo> getRoleMembershipsForMemberId(String memberType, String memberId, Map<String, String> qualification) {
538            Criteria c = new Criteria();
539            List<RoleMemberBo> parentRoleMembers = new ArrayList<RoleMemberBo>();
540    
541            if (StringUtils.isEmpty(memberId) || StringUtils.isEmpty(memberType)) {
542                return parentRoleMembers;
543            }
544    
545            c.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_ID, memberId);
546            c.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, memberType);
547            addSubCriteriaBasedOnRoleQualification(c, qualification);
548    
549            Query query = QueryFactory.newQuery(RoleMemberBo.class, c);
550            Collection<RoleMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
551            ArrayList<RoleMemberBo> results = new ArrayList<RoleMemberBo>(coll.size());
552            for (RoleMemberBo rm : coll) {
553                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
554                    results.add(rm);
555                }
556            }
557            return results;
558        }
559    
560        @SuppressWarnings("unchecked")
561        public List<RoleMemberBo> getRoleMembersForRoleIdsWithFilters(Collection<String> roleIds, String principalId, Collection<String> groupIds, Map<String, String> qualification) {
562            Criteria c = new Criteria();
563    
564            if (roleIds != null && !roleIds.isEmpty()) {
565                c.addIn(KIMPropertyConstants.RoleMember.ROLE_ID, roleIds);
566            }
567            Criteria orSet = new Criteria();
568            orSet.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.ROLE.getCode());
569            Criteria principalCheck = new Criteria();
570            if (principalId != null) {
571                principalCheck.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_ID, principalId);
572            }
573            principalCheck.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode());
574            orSet.addOrCriteria(principalCheck);
575            Criteria groupCheck = new Criteria();
576            if (groupIds != null && !groupIds.isEmpty()) {
577                groupCheck.addIn(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds);
578            }
579            groupCheck.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode());
580            orSet.addOrCriteria(groupCheck);
581            c.addAndCriteria(orSet);
582            addSubCriteriaBasedOnRoleQualification(c, qualification);
583    
584            Query query = QueryFactory.newQuery(RoleMemberBo.class, c);
585            Collection<RoleMemberBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
586            ArrayList<RoleMemberBo> results = new ArrayList<RoleMemberBo>(coll.size());
587            for (RoleMemberBo rm : coll) {
588                if (rm.isActive(new Timestamp(System.currentTimeMillis()))) {
589                    results.add(rm);
590                }
591            }
592            return results;
593        }
594    
595        public List<RoleBo> getRoles(Map<String, String> fieldValues) {
596            Criteria criteria = new Criteria();
597            Map<String, Map<String, String>> criteriaMap = setupCritMaps(fieldValues);
598    
599            //      List lookupNames = boEntry.getLookupDefinition().getLookupFieldNames();
600            Map<String, String> lookupNames = criteriaMap.get("lookupNames");
601            for (Map.Entry<String, String> entry : lookupNames.entrySet()) {
602                if (StringUtils.isNotBlank(entry.getValue())) {
603                    if (!entry.getKey().equals(KIMPropertyConstants.Principal.PRINCIPAL_NAME)) {
604                        if (entry.getKey().equals(KIMPropertyConstants.Principal.ACTIVE)) {
605                            criteria.addEqualTo(KIMPropertyConstants.Principal.ACTIVE, entry.getValue());
606                        } else {
607                            addLikeToCriteria(criteria, entry.getKey(), entry.getValue());
608                        }
609    
610                    } else {
611                        List<String> roleIds = getRoleIdsForPrincipalName(entry.getValue());
612                        if (roleIds != null && !roleIds.isEmpty()) {
613                            criteria.addIn(KimConstants.PrimaryKeyConstants.ID, roleIds);
614                        } else {
615                            // TODO : if no role id found that means principalname not matched, need to do something to force to return empty list
616                            roleIds.add("NOTFOUND");
617                            criteria.addIn(KimConstants.PrimaryKeyConstants.ID, roleIds);
618                        }
619                    }
620                }
621            }
622            if (!criteriaMap.get("attr").isEmpty()) {
623                String kimTypeId = null;
624                for (Map.Entry<String, String> entry : fieldValues.entrySet()) {
625                    if (entry.getKey().equals("kimTypeId")) {
626                        kimTypeId = entry.getValue();
627                        break;
628                    }
629                }
630                setupAttrCriteria(criteria, criteriaMap.get("attr"), kimTypeId);
631            }
632            if (!criteriaMap.get("perm").isEmpty()) {
633                criteria.addExists(setupPermCriteria(criteriaMap.get("perm")));
634            }
635            if (!criteriaMap.get("resp").isEmpty()) {
636                criteria.addExists(setupRespCriteria(criteriaMap.get("resp")));
637            }
638            if (!criteriaMap.get("group").isEmpty()) {
639                criteria.addExists(setupGroupCriteria(criteriaMap.get("group")));
640            }
641    
642            Query q = QueryFactory.newQuery(RoleBoLite.class, criteria);
643    
644            //pull the list of RoleBoLite, and then add the membership info. This has
645            // been done for performance optimization KULRICE-8847
646            List<RoleBoLite> roleBoLiteList = (List) getPersistenceBrokerTemplate().getCollectionByQuery(q);
647    
648            List<RoleBo> roleBos = new ArrayList<RoleBo>();
649            for (RoleBoLite roleLite : roleBoLiteList) {
650                RoleBo role = RoleBo.from(RoleBoLite.to(roleLite));
651                roleBos.add(role);
652            }
653    
654            return roleBos;
655        }
656    
657        private List<String> getPrincipalIdsForPrincipalName(String principalName) {
658            QueryByCriteria.Builder qb = QueryByCriteria.Builder.create();
659            qb.setPredicates(equal("principals.principalName", principalName));
660            List<EntityDefault> entities = KimApiServiceLocator.getIdentityService().findEntityDefaults(qb.build())
661                    .getResults();
662    
663            List<String> principalIds = new ArrayList<String>();
664            for (EntityDefault entity : entities) {
665                for (Principal principal : entity.getPrincipals()) {
666                    principalIds.add(principal.getPrincipalId());
667                }
668            }
669    
670            return principalIds;
671    
672        }
673    
674        private List<String> getRoleIdsForPrincipalName(String value) {
675            String principalName = value.replace('*', '%');
676            List<String> roleIds = new ArrayList<String>();
677            Criteria memberSubCrit = new Criteria();
678            QueryByCriteria.Builder qb = QueryByCriteria.Builder.create();
679            qb.setPredicates(like("principals.principalName", principalName));
680            List<EntityDefault> entities = KimApiServiceLocator.getIdentityService().findEntityDefaults(qb.build()).getResults();
681            if (entities == null
682                    || entities.size() == 0) {
683                return roleIds;
684            }
685    
686            List<String> principalIds = new ArrayList<String>();
687            for (EntityDefault entity : entities) {
688                for (Principal principal : entity.getPrincipals()) {
689                    principalIds.add(principal.getPrincipalId());
690                }
691            }
692            if (principalIds != null && !principalIds.isEmpty()) {
693                memberSubCrit.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.PRINCIPAL.getCode());
694                memberSubCrit.addIn(KIMPropertyConstants.RoleMember.MEMBER_ID, principalIds);
695    
696                ReportQueryByCriteria memberSubQuery = QueryFactory.newReportQuery(RoleMemberBo.class, memberSubCrit);
697                for (RoleMemberBo roleMbr : (List<RoleMemberBo>) getPersistenceBrokerTemplate().getCollectionByQuery(memberSubQuery)) {
698                    if (roleMbr.isActive(new Timestamp(System.currentTimeMillis())) && !roleIds.contains(roleMbr.getRoleId())) {
699                        roleIds.add(roleMbr.getRoleId());
700                    }
701                }
702            }
703    
704            List<String> groupIds = new ArrayList<String>();
705            for (String principalId : principalIds) {
706                List<String> principalGroupIds = KimApiServiceLocator.getGroupService().getGroupIdsByPrincipalId(
707                        principalId);
708                for (String groupId : principalGroupIds) {
709                    if (!groupIds.contains(groupId)) {
710                        groupIds.add(groupId);
711                    }
712                }
713            }
714    
715            if (groupIds != null && !groupIds.isEmpty()) {
716                Criteria grpRoleCrit = new Criteria();
717                grpRoleCrit.addEqualTo(KIMPropertyConstants.RoleMember.MEMBER_TYPE_CODE, MemberType.GROUP.getCode());
718                grpRoleCrit.addIn(KIMPropertyConstants.RoleMember.MEMBER_ID, groupIds);
719    
720                ReportQueryByCriteria memberSubQuery = QueryFactory.newReportQuery(RoleMemberBo.class, grpRoleCrit);
721    
722                for (RoleMemberBo roleMbr : (List<RoleMemberBo>) getPersistenceBrokerTemplate().getCollectionByQuery(memberSubQuery)) {
723                    if (roleMbr.isActive(new Timestamp(System.currentTimeMillis())) && !roleIds.contains(roleMbr.getRoleId())) {
724                        roleIds.add(roleMbr.getRoleId());
725                    }
726                }
727            }
728    
729            return roleIds;
730        }
731    
732        private Map<String, Map<String, String>> setupCritMaps(Map<String, String> fieldValues) {
733    
734            Map<String, Map<String, String>> critMap = new HashMap<String, Map<String, String>>();
735            List<String> permFieldName = new ArrayList<String>();
736            permFieldName.add("permName");
737            permFieldName.add("permNamespaceCode");
738            permFieldName.add("permTmplName");
739            permFieldName.add("permTmplNamespaceCode");
740            List<String> respFieldName = new ArrayList<String>();
741            respFieldName.add("respName");
742            respFieldName.add("respNamespaceCode");
743            respFieldName.add("respTmplName");
744            respFieldName.add("respTmplNamespaceCode");
745            Map<String, String> permFieldMap = new HashMap<String, String>();
746            Map<String, String> respFieldMap = new HashMap<String, String>();
747            Map<String, String> attrFieldMap = new HashMap<String, String>();
748            Map<String, String> groupFieldMap = new HashMap<String, String>();
749            Map<String, String> lookupNamesMap = new HashMap<String, String>();
750    
751            for (Map.Entry<String, String> entry : fieldValues.entrySet()) {
752                if (StringUtils.isNotBlank(entry.getValue())) {
753                    String nameValue = entry.getValue();
754                    if (permFieldName.contains(entry.getKey())) {
755                        permFieldMap.put(entry.getKey(), nameValue);
756                    } else if (respFieldName.contains(entry.getKey())) {
757                        respFieldMap.put(entry.getKey(), nameValue);
758                    } else if (entry.getKey().startsWith(KimConstants.AttributeConstants.GROUP_NAME)) {
759                        groupFieldMap.put(entry.getKey(), nameValue);
760                    } else if (entry.getKey().contains(".")) {
761                        attrFieldMap.put(entry.getKey(), nameValue).replace('*', '%');
762                    } else {
763                        lookupNamesMap.put(entry.getKey(), nameValue);
764                    }
765                }
766            }
767    
768            critMap.put("perm", permFieldMap);
769            critMap.put("resp", respFieldMap);
770            critMap.put("group", groupFieldMap);
771            critMap.put("attr", attrFieldMap);
772            critMap.put("lookupNames", lookupNamesMap);
773            return critMap;
774        }
775    
776        private void setupAttrCriteria(Criteria crit, Map<String, String> attrCrit, String kimTypeId) {
777            for (Map.Entry<String, String> entry : attrCrit.entrySet()) {
778                Criteria subCrit = new Criteria();
779                addLikeToCriteria(subCrit, "attributes.attributeValue", entry.getValue());
780                addEqualToCriteria(subCrit, "attributes.kimAttributeId", entry.getKey().substring(entry.getKey().indexOf(".") + 1, entry.getKey().length()));
781                addEqualToCriteria(subCrit, "attributes.kimTypeId", kimTypeId);
782                subCrit.addEqualToField("roleId", Criteria.PARENT_QUERY_PREFIX + "id");
783                crit.addExists(QueryFactory.newReportQuery(RoleMemberBo.class, subCrit));
784            }
785        }
786    
787        private ReportQueryByCriteria setupPermCriteria(Map<String, String> permCrit) {
788    
789            Map<String, String> actualCriteriaMap = new HashMap<String, String>();
790            for (Map.Entry<String, String> entry : permCrit.entrySet()) {
791                if (entry.getKey().equals("permTmplName") || entry.getKey().equals("permTmplNamespaceCode")) {
792                    if (entry.getKey().equals("permTmplName")) {
793                        actualCriteriaMap.put("template." + KimConstants.UniqueKeyConstants.PERMISSION_TEMPLATE_NAME, entry.getValue());
794                    } else {
795                        actualCriteriaMap.put("template." + KimConstants.UniqueKeyConstants.NAMESPACE_CODE, entry.getValue());
796                    }
797                }
798    
799                if (entry.getKey().equals("permName") || entry.getKey().equals("permNamespaceCode")) {
800                    if (entry.getKey().equals("permName")) {
801                        actualCriteriaMap.put(KimConstants.UniqueKeyConstants.PERMISSION_NAME, entry.getValue());
802                    } else {
803                        actualCriteriaMap.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, entry.getValue());
804                    }
805                }
806            }
807    
808            Predicate predicate = PredicateUtils.convertMapToPredicate(actualCriteriaMap);
809            List<Permission> permList = KimApiServiceLocator.getPermissionService().findPermissions(
810                    QueryByCriteria.Builder.fromPredicates(predicate)).getResults();
811            List<String> roleIds = null;
812    
813            if (permList != null && !permList.isEmpty()) {
814                roleIds = getRoleIdsForPermissions(permList);
815            }
816    
817            if (roleIds == null || roleIds.isEmpty()) {
818                roleIds = new ArrayList<String>();
819                roleIds.add("-1"); // this forces a blank return.
820            }
821    
822            Criteria memberSubCrit = new Criteria();
823            memberSubCrit.addIn("id", roleIds);
824            memberSubCrit.addEqualToField("id", Criteria.PARENT_QUERY_PREFIX + "id");
825            return QueryFactory.newReportQuery(RoleBo.class, memberSubCrit);
826    
827        }
828    
829        private List<String> getRoleIdsForPermissions(Collection<Permission> permissions) {
830                    if ( permissions.isEmpty() ) {
831                            return new ArrayList<String>(0);
832                    }
833                    List<String> permissionIds = new ArrayList<String>( permissions.size() );
834                    for ( Permission permission : permissions ) {
835                            permissionIds.add( permission.getId() );
836                    }
837                    Criteria c = new Criteria();
838                    c.addIn( "permissionId", permissionIds );
839                    c.addEqualTo( "active", true );
840    
841                    Query query = QueryFactory.newQuery( RolePermissionBo.class, c, true );
842                    Collection<RolePermissionBo> coll = getPersistenceBrokerTemplate().getCollectionByQuery(query);
843                    List<String> roleIds = new ArrayList<String>( coll.size() );
844                    for ( RolePermissionBo rp : coll ) {
845                            roleIds.add( rp.getRoleId() );
846                    }
847                    return roleIds;
848            }
849    
850        private ReportQueryByCriteria setupRespCriteria(Map<String, String> respCrit) {
851            QueryByCriteria.Builder queryByCriteriaBuilder = QueryByCriteria.Builder.create();
852            Map<String, String> actualCriteriaMap = new HashMap<String, String>();
853            for (Map.Entry<String, String> entry : respCrit.entrySet()) {
854                if (entry.getKey().equals("respTmplName") || entry.getKey().equals("respTmplNamespaceCode")) {
855                    if (entry.getKey().equals("respTmplName")) {
856                        actualCriteriaMap.put("template." + KimConstants.UniqueKeyConstants.RESPONSIBILITY_TEMPLATE_NAME, entry.getValue());
857                    } else {
858                        actualCriteriaMap.put("template." + KimConstants.UniqueKeyConstants.NAMESPACE_CODE, entry.getValue());
859                    }
860                }
861                if (entry.getKey().equals("respName") || entry.getKey().equals("respNamespaceCode")) {
862                    if (entry.getKey().equals("respName")) {
863                        actualCriteriaMap.put(KimConstants.UniqueKeyConstants.RESPONSIBILITY_NAME, entry.getValue());
864                    } else {
865                        actualCriteriaMap.put(KimConstants.UniqueKeyConstants.NAMESPACE_CODE, entry.getValue());
866                    }
867                }
868            }
869            Predicate predicate = PredicateUtils.convertMapToPredicate(actualCriteriaMap);
870            queryByCriteriaBuilder.setPredicates(predicate);
871    
872            ResponsibilityService responsibilityService = KimApiServiceLocator.getResponsibilityService();
873            ResponsibilityQueryResults results = responsibilityService.findResponsibilities(queryByCriteriaBuilder.build());
874            List<Responsibility> responsibilities = results.getResults();
875    
876            List<String> roleIds = new ArrayList<String>();
877            for (Responsibility responsibility : responsibilities) {
878                roleIds.addAll(responsibilityService.getRoleIdsForResponsibility(responsibility.getId()));
879            }
880    
881            if (roleIds.isEmpty()) {
882                roleIds.add("-1"); // this forces a blank return.
883            }
884    
885            Criteria memberSubCrit = new Criteria();
886            memberSubCrit.addIn("id", roleIds);
887            memberSubCrit.addEqualToField("id", Criteria.PARENT_QUERY_PREFIX + "id");
888            return QueryFactory.newReportQuery(RoleBo.class, memberSubCrit);
889    
890        }
891    
892        private ReportQueryByCriteria setupGroupCriteria(Map<String,String> groupCrit) {
893    
894            //Map<String,String> searchCrit = new HashMap<String, String>();
895            final QueryByCriteria.Builder searchCrit = QueryByCriteria.Builder.create();
896            Map<String, String> actualCrit = new HashMap<String, String>();
897            for (Entry<String, String> entry : groupCrit.entrySet()) {
898                if (entry.getKey().equals(KimConstants.AttributeConstants.GROUP_NAME)) {
899                    actualCrit.put(KimConstants.AttributeConstants.NAME, entry.getValue());
900                } else { // the namespace code for the group field is named something besides the default. Set it to the default.
901                    actualCrit.put(KimConstants.AttributeConstants.NAMESPACE_CODE, entry.getValue());
902                }
903           }
904    
905           Criteria crit = new Criteria();
906           Predicate predicate = PredicateUtils.convertMapToPredicate(actualCrit);
907           searchCrit.setPredicates(predicate);
908           List<String> groupIds = KimApiServiceLocator.getGroupService().findGroupIds(searchCrit.build());
909    
910           if(groupIds == null || groupIds.isEmpty()){
911               groupIds = new ArrayList<String>();
912               groupIds.add("-1");  // this forces a blank return.
913           }
914           crit.addIn("memberId", groupIds);
915           crit.addEqualToField("roleId", Criteria.PARENT_QUERY_PREFIX + "id");
916    
917            return QueryFactory.newReportQuery(RoleMemberBo.class, crit);
918    
919        }
920    
921        private void addLikeToCriteria(Criteria criteria, String propertyName, String propertyValue) {
922            String[] keyValues = getCaseInsensitiveValues(propertyName, propertyValue);
923            criteria.addLike(keyValues[0], keyValues[1]);
924        }
925    
926        private void addEqualToCriteria(Criteria criteria, String propertyName, String propertyValue) {
927            String[] keyValues = getCaseInsensitiveValues(propertyName, propertyValue);
928            criteria.addEqualTo(keyValues[0], keyValues[1]);
929        }
930    
931        private String[] getCaseInsensitiveValues(String propertyName, String propertyValue) {
932            String[] keyValues = new String[2];
933            keyValues[0] = propertyName == null ? "" : getDbPlatform().getUpperCaseFunction() + "(" + propertyName + ")";
934            keyValues[1] = propertyValue == null ? "" : propertyValue.toUpperCase();
935            return keyValues;
936        }
937    
938        private boolean hasCoreRoleMemberCriteria(Map<String, String> fieldValues) {
939            return StringUtils.isNotEmpty(fieldValues.get(KimConstants.PrimaryKeyConstants.ID)) ||
940                    StringUtils.isNotEmpty(fieldValues.get(KimConstants.PrimaryKeyConstants.SUB_ROLE_ID)) ||
941                    StringUtils.isNotEmpty(fieldValues.get(KimConstants.PrimaryKeyConstants.MEMBER_ID)) ||
942                    StringUtils.isNotEmpty(fieldValues.get(KIMPropertyConstants.KimMember.MEMBER_TYPE_CODE)) ||
943                    StringUtils.isNotEmpty(fieldValues.get(KIMPropertyConstants.KimMember.ACTIVE_FROM_DATE)) ||
944                    StringUtils.isNotEmpty(fieldValues.get(KIMPropertyConstants.KimMember.ACTIVE_TO_DATE));
945        }
946    
947        private boolean hasExtraRoleMemberCriteria(Map<String, String> fieldValues) {
948            return StringUtils.isNotEmpty(fieldValues.get(KimConstants.KimUIConstants.MEMBER_NAME)) ||
949                    StringUtils.isNotEmpty(fieldValues.get(KimConstants.KimUIConstants.MEMBER_NAMESPACE_CODE));
950        }
951    
952        @SuppressWarnings("unchecked")
953        private List<RoleBo> getRoleMembersRoles(String memberNamespaceCode, String memberName) {
954            Criteria queryCriteria = new Criteria();
955            addEqualToCriteria(queryCriteria, KimConstants.UniqueKeyConstants.NAMESPACE_CODE, memberNamespaceCode);
956            addEqualToCriteria(queryCriteria, KimConstants.UniqueKeyConstants.NAME, memberName);
957            Query q = QueryFactory.newQuery(RoleBo.class, queryCriteria);
958            return (List<RoleBo>) getPersistenceBrokerTemplate().getCollectionByQuery(q);
959        }
960    }