001/**
002 * Copyright 2005-2016 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.rice.kim.impl.role;
017
018import org.apache.commons.collections.CollectionUtils;
019import org.apache.commons.lang.StringUtils;
020import org.apache.ojb.broker.query.Criteria;
021import org.apache.ojb.broker.query.Query;
022import org.apache.ojb.broker.query.QueryFactory;
023import org.apache.ojb.broker.query.ReportQueryByCriteria;
024import org.joda.time.DateTime;
025import org.kuali.rice.core.api.criteria.Predicate;
026import org.kuali.rice.core.api.criteria.PredicateFactory;
027import org.kuali.rice.core.api.criteria.PredicateUtils;
028import org.kuali.rice.core.api.criteria.QueryByCriteria;
029import org.kuali.rice.core.api.membership.MemberType;
030import org.kuali.rice.core.api.util.Truth;
031import org.kuali.rice.core.framework.persistence.ojb.dao.PlatformAwareDaoBaseOjb;
032import org.kuali.rice.kim.api.KimConstants;
033import org.kuali.rice.kim.api.common.attribute.KimAttribute;
034import org.kuali.rice.kim.api.group.GroupMember;
035import org.kuali.rice.kim.api.identity.entity.EntityDefault;
036import org.kuali.rice.kim.api.identity.principal.Principal;
037import org.kuali.rice.kim.api.permission.Permission;
038import org.kuali.rice.kim.api.responsibility.Responsibility;
039import org.kuali.rice.kim.api.responsibility.ResponsibilityQueryResults;
040import org.kuali.rice.kim.api.responsibility.ResponsibilityService;
041import org.kuali.rice.kim.api.role.Role;
042import org.kuali.rice.kim.api.role.RoleMember;
043import org.kuali.rice.kim.api.role.RoleMembership;
044import org.kuali.rice.kim.api.services.KimApiServiceLocator;
045import org.kuali.rice.kim.api.type.KimType;
046import org.kuali.rice.kim.impl.KIMPropertyConstants;
047import org.kuali.rice.kim.impl.common.attribute.KimAttributeBo;
048import org.kuali.rice.kim.impl.common.delegate.DelegateTypeBo;
049import org.kuali.rice.kim.impl.common.delegate.DelegateMemberBo;
050import org.kuali.rice.kim.impl.type.KimTypeBo;
051import org.springframework.dao.DataAccessException;
052import org.springframework.jdbc.core.JdbcTemplate;
053import org.springframework.jdbc.core.PreparedStatementCallback;
054import org.springframework.jdbc.core.PreparedStatementCreator;
055import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
056
057import javax.sql.DataSource;
058import java.sql.Connection;
059import java.sql.Date;
060import java.sql.PreparedStatement;
061import java.sql.ResultSet;
062import java.sql.SQLException;
063import java.sql.Timestamp;
064import java.util.ArrayList;
065import java.util.Collection;
066import java.util.HashMap;
067import java.util.List;
068import java.util.Map;
069import java.util.Map.Entry;
070
071import static org.kuali.rice.core.api.criteria.PredicateFactory.*;
072
073public 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}