1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.service.persistence;
24  
25  import com.liferay.portal.NoSuchRoleException;
26  import com.liferay.portal.SystemException;
27  import com.liferay.portal.kernel.util.ArrayUtil;
28  import com.liferay.portal.kernel.util.OrderByComparator;
29  import com.liferay.portal.kernel.util.StringMaker;
30  import com.liferay.portal.kernel.util.StringPool;
31  import com.liferay.portal.kernel.util.StringUtil;
32  import com.liferay.portal.kernel.util.Validator;
33  import com.liferay.portal.model.Group;
34  import com.liferay.portal.model.Role;
35  import com.liferay.portal.model.impl.GroupModelImpl;
36  import com.liferay.portal.model.impl.RoleImpl;
37  import com.liferay.portal.model.impl.RoleModelImpl;
38  import com.liferay.portal.model.impl.UserModelImpl;
39  import com.liferay.portal.spring.hibernate.CustomSQLUtil;
40  import com.liferay.portal.spring.hibernate.FinderCache;
41  import com.liferay.portal.spring.hibernate.HibernateUtil;
42  import com.liferay.util.dao.hibernate.QueryPos;
43  import com.liferay.util.dao.hibernate.QueryUtil;
44  
45  import java.util.ArrayList;
46  import java.util.HashMap;
47  import java.util.Iterator;
48  import java.util.LinkedHashMap;
49  import java.util.List;
50  import java.util.Map;
51  
52  import org.hibernate.Hibernate;
53  import org.hibernate.SQLQuery;
54  import org.hibernate.Session;
55  
56  /**
57   * <a href="RoleFinderImpl.java.html"><b><i>View Source</i></b></a>
58   *
59   * @author Brian Wing Shun Chan
60   *
61   */
62  public class RoleFinderImpl implements RoleFinder {
63  
64      public static String COUNT_BY_C_N_D_T =
65          RoleFinder.class.getName() + ".countByC_N_D_T";
66  
67      public static String COUNT_BY_COMMUNITY =
68          RoleFinder.class.getName() + ".countByCommunity";
69  
70      public static String COUNT_BY_ORGANIZATION =
71          RoleFinder.class.getName() + ".countByOrganization";
72  
73      public static String COUNT_BY_USER =
74          RoleFinder.class.getName() + ".countByUser";
75  
76      public static String COUNT_BY_USER_GROUP =
77          RoleFinder.class.getName() + ".countByUserGroup";
78  
79      public static String FIND_BY_USER_GROUP_ROLE =
80          RoleFinder.class.getName() + ".findByUserGroupRole";
81  
82      public static String FIND_BY_C_N =
83          RoleFinder.class.getName() + ".findByC_N";
84  
85      public static String FIND_BY_U_G =
86          RoleFinder.class.getName() + ".findByU_G";
87  
88      public static String FIND_BY_C_N_D_T =
89          RoleFinder.class.getName() + ".findByC_N_D_T";
90  
91      public static String FIND_BY_C_N_S_P =
92          RoleFinder.class.getName() + ".findByC_N_S_P";
93  
94      public static String JOIN_BY_ROLES_PERMISSIONS =
95          RoleFinder.class.getName() + ".joinByRolesPermissions";
96  
97      public static String JOIN_BY_USERS_ROLES =
98          RoleFinder.class.getName() + ".joinByUsersRoles";
99  
100     public int countByR_U(long roleId, long userId) throws SystemException {
101         String finderSQL = Role.class.getName();
102         boolean[] finderClassNamesCacheEnabled = new boolean[] {
103             GroupModelImpl.CACHE_ENABLED, RoleModelImpl.CACHE_ENABLED,
104             GroupModelImpl.CACHE_ENABLED_GROUPS_ROLES,
105             UserModelImpl.CACHE_ENABLED_USERS_GROUPS,
106             UserModelImpl.CACHE_ENABLED_USERS_ORGS,
107             UserModelImpl.CACHE_ENABLED_USERS_ROLES,
108             UserModelImpl.CACHE_ENABLED_USERS_USERGROUPS
109         };
110         String[] finderClassNames = new String[] {
111             Group.class.getName(), Role.class.getName(), "Groups_Roles",
112             "Users_Groups", "Users_Orgs", "Users_Roles", "Users_UserGroups"
113         };
114         String finderMethodName = "customCountByR_U";
115         String finderParams[] = new String[] {
116             Long.class.getName(), Long.class.getName()
117         };
118         Object finderArgs[] = new Object[] {new Long(roleId), new Long(userId)};
119 
120         Object result = null;
121 
122         if (!ArrayUtil.contains(finderClassNamesCacheEnabled, false)) {
123             result = FinderCache.getResult(
124                 finderSQL, finderClassNames, finderMethodName, finderParams,
125                 finderArgs);
126         }
127 
128         if (result == null) {
129             Session session = null;
130 
131             try {
132                 session = HibernateUtil.openSession();
133 
134                 StringMaker sm = new StringMaker();
135 
136                 sm.append("(");
137                 sm.append(CustomSQLUtil.get(COUNT_BY_COMMUNITY));
138                 sm.append(") UNION (");
139                 sm.append(CustomSQLUtil.get(COUNT_BY_ORGANIZATION));
140                 sm.append(") UNION (");
141                 sm.append(CustomSQLUtil.get(COUNT_BY_USER));
142                 sm.append(") UNION (");
143                 sm.append(CustomSQLUtil.get(COUNT_BY_USER_GROUP));
144                 sm.append(")");
145 
146                 SQLQuery q = session.createSQLQuery(sm.toString());
147 
148                 q.addScalar(HibernateUtil.getCountColumnName(), Hibernate.LONG);
149 
150                 QueryPos qPos = QueryPos.getInstance(q);
151 
152                 for (int i = 0; i < 4; i++) {
153                     qPos.add(roleId);
154                     qPos.add(userId);
155                 }
156 
157                 int count = 0;
158 
159                 Iterator<Long> itr = q.list().iterator();
160 
161                 while (itr.hasNext()) {
162                     Long l = itr.next();
163 
164                     if (l != null) {
165                         count += l.intValue();
166                     }
167                 }
168 
169                 FinderCache.putResult(
170                     finderSQL, finderClassNamesCacheEnabled, finderClassNames,
171                     finderMethodName, finderParams, finderArgs,
172                     new Long(count));
173 
174                 return count;
175             }
176             catch (Exception e) {
177                 throw new SystemException(e);
178             }
179             finally {
180                 HibernateUtil.closeSession(session);
181             }
182         }
183         else {
184             return ((Long)result).intValue();
185         }
186     }
187 
188     public int countByC_N_D_T(
189             long companyId, String name, String description, Integer type,
190             LinkedHashMap<String, Object> params)
191         throws SystemException {
192 
193         name = StringUtil.lowerCase(name);
194         description = StringUtil.lowerCase(description);
195 
196         Session session = null;
197 
198         try {
199             session = HibernateUtil.openSession();
200 
201             String sql = CustomSQLUtil.get(COUNT_BY_C_N_D_T);
202 
203             if (type == null) {
204                 sql = StringUtil.replace(sql, "AND (Role_.type_ = ?)", "");
205             }
206 
207             sql = StringUtil.replace(sql, "[$JOIN$]", getJoin(params));
208             sql = StringUtil.replace(sql, "[$WHERE$]", getWhere(params));
209 
210             SQLQuery q = session.createSQLQuery(sql);
211 
212             q.addScalar(HibernateUtil.getCountColumnName(), Hibernate.LONG);
213 
214             QueryPos qPos = QueryPos.getInstance(q);
215 
216             setJoin(qPos, params);
217             qPos.add(companyId);
218             qPos.add(name);
219             qPos.add(name);
220             qPos.add(description);
221             qPos.add(description);
222 
223             if (type != null) {
224                 qPos.add(type);
225             }
226 
227             Iterator<Long> itr = q.list().iterator();
228 
229             if (itr.hasNext()) {
230                 Long count = itr.next();
231 
232                 if (count != null) {
233                     return count.intValue();
234                 }
235             }
236 
237             return 0;
238         }
239         catch (Exception e) {
240             throw new SystemException(e);
241         }
242         finally {
243             HibernateUtil.closeSession(session);
244         }
245     }
246 
247     public List<Role> findByUserGroupRole(long userId, long groupId)
248         throws SystemException {
249 
250         Session session = null;
251 
252         try {
253             session = HibernateUtil.openSession();
254 
255             String sql = CustomSQLUtil.get(FIND_BY_USER_GROUP_ROLE);
256 
257             SQLQuery q = session.createSQLQuery(sql);
258 
259             q.addEntity("Role_", RoleImpl.class);
260 
261             QueryPos qPos = QueryPos.getInstance(q);
262 
263             qPos.add(userId);
264             qPos.add(groupId);
265 
266             return q.list();
267         }
268         catch (Exception e) {
269             throw new SystemException(e);
270         }
271         finally {
272             HibernateUtil.closeSession(session);
273         }
274     }
275 
276     public Role findByC_N(long companyId, String name)
277         throws NoSuchRoleException, SystemException {
278 
279         name = StringUtil.lowerCase(name);
280 
281         boolean finderClassNameCacheEnabled = RoleModelImpl.CACHE_ENABLED;
282         String finderClassName = Role.class.getName();
283         String finderMethodName = "customFindByC_N";
284         String finderParams[] = new String[] {
285             Long.class.getName(), String.class.getName()
286         };
287         Object finderArgs[] = new Object[] {new Long(companyId), name};
288 
289         Object result = FinderCache.getResult(
290             finderClassName, finderMethodName, finderParams, finderArgs);
291 
292         if (result == null) {
293             Session session = null;
294 
295             try {
296                 session = HibernateUtil.openSession();
297 
298                 String sql = CustomSQLUtil.get(FIND_BY_C_N);
299 
300                 SQLQuery q = session.createSQLQuery(sql);
301 
302                 q.addEntity("Role_", RoleImpl.class);
303 
304                 QueryPos qPos = QueryPos.getInstance(q);
305 
306                 qPos.add(companyId);
307                 qPos.add(name);
308 
309                 Iterator<Role> itr = q.list().iterator();
310 
311                 if (itr.hasNext()) {
312                     Role role = itr.next();
313 
314                     FinderCache.putResult(
315                         finderClassNameCacheEnabled, finderClassName,
316                         finderMethodName, finderParams, finderArgs, role);
317 
318                     return role;
319                 }
320             }
321             catch (Exception e) {
322                 throw new SystemException(e);
323             }
324             finally {
325                 HibernateUtil.closeSession(session);
326             }
327 
328             throw new NoSuchRoleException(
329                 "No Role exists with the key {companyId=" + companyId +
330                     ", name=" + name + "}");
331         }
332         else {
333             return (Role)result;
334         }
335     }
336 
337     public List<Role> findByU_G(long userId, long groupId)
338         throws SystemException {
339 
340         return findByU_G(userId, new long[] {groupId});
341     }
342 
343     public List<Role> findByU_G(long userId, long[] groupIds)
344         throws SystemException {
345 
346         Session session = null;
347 
348         try {
349             session = HibernateUtil.openSession();
350 
351             String sql = CustomSQLUtil.get(FIND_BY_U_G);
352 
353             sql = StringUtil.replace(
354                 sql, "[$GROUP_IDS$]", getGroupIds(groupIds, "Groups_Roles"));
355 
356             SQLQuery q = session.createSQLQuery(sql);
357 
358             q.addEntity("Role_", RoleImpl.class);
359 
360             QueryPos qPos = QueryPos.getInstance(q);
361 
362             qPos.add(userId);
363             setGroupIds(qPos, groupIds);
364 
365             return q.list();
366         }
367         catch (Exception e) {
368             throw new SystemException(e);
369         }
370         finally {
371             HibernateUtil.closeSession(session);
372         }
373     }
374 
375     public List<Role> findByU_G(long userId, List<Group> groups)
376         throws SystemException {
377 
378         long[] groupIds = new long[groups.size()];
379 
380         for (int i = 0; i < groups.size(); i++) {
381             Group group = groups.get(i);
382 
383             groupIds[i] = group.getGroupId();
384         }
385 
386         return findByU_G(userId, groupIds);
387     }
388 
389     public List<Role> findByC_N_D_T(
390             long companyId, String name, String description, Integer type,
391             LinkedHashMap<String, Object> params, int begin, int end,
392             OrderByComparator obc)
393         throws SystemException {
394 
395         name = StringUtil.lowerCase(name);
396         description = StringUtil.lowerCase(description);
397 
398         Session session = null;
399 
400         try {
401             session = HibernateUtil.openSession();
402 
403             String sql = CustomSQLUtil.get(FIND_BY_C_N_D_T);
404 
405             if (type == null) {
406                 sql = StringUtil.replace(sql, "AND (Role_.type_ = ?)", "");
407             }
408 
409             sql = StringUtil.replace(sql, "[$JOIN$]", getJoin(params));
410             sql = StringUtil.replace(sql, "[$WHERE$]", getWhere(params));
411             sql = CustomSQLUtil.replaceOrderBy(sql, obc);
412 
413             SQLQuery q = session.createSQLQuery(sql);
414 
415             q.addEntity("Role_", RoleImpl.class);
416 
417             QueryPos qPos = QueryPos.getInstance(q);
418 
419             setJoin(qPos, params);
420             qPos.add(companyId);
421             qPos.add(name);
422             qPos.add(name);
423             qPos.add(description);
424             qPos.add(description);
425 
426             if (type != null) {
427                 qPos.add(type);
428             }
429 
430             return (List<Role>)QueryUtil.list(
431                 q, HibernateUtil.getDialect(), begin, end);
432         }
433         catch (Exception e) {
434             throw new SystemException(e);
435         }
436         finally {
437             HibernateUtil.closeSession(session);
438         }
439     }
440 
441     public Map<String, List<String>> findByC_N_S_P(
442             long companyId, String name, int scope, String primKey)
443         throws SystemException {
444 
445         Session session = null;
446 
447         try {
448             session = HibernateUtil.openSession();
449 
450             String sql = CustomSQLUtil.get(FIND_BY_C_N_S_P);
451 
452             SQLQuery q = session.createSQLQuery(sql);
453 
454             q.addScalar("roleName", Hibernate.STRING);
455             q.addScalar("actionId", Hibernate.STRING);
456 
457             QueryPos qPos = QueryPos.getInstance(q);
458 
459             qPos.add(companyId);
460             qPos.add(name);
461             qPos.add(scope);
462             qPos.add(primKey);
463 
464             Map<String, List<String>> roleMap =
465                 new HashMap<String, List<String>>();
466 
467             Iterator<Object[]> itr = q.list().iterator();
468 
469             while (itr.hasNext()) {
470                 Object[] array = itr.next();
471 
472                 String roleName = (String)array[0];
473                 String actionId = (String)array[1];
474 
475                 List<String> roleList = roleMap.get(roleName);
476 
477                 if (roleList == null) {
478                     roleList = new ArrayList<String>();
479                 }
480 
481                 roleList.add(actionId);
482 
483                 roleMap.put(roleName, roleList);
484             }
485 
486             return roleMap;
487         }
488         catch (Exception e) {
489             throw new SystemException(e);
490         }
491         finally {
492             HibernateUtil.closeSession(session);
493         }
494     }
495 
496     protected String getGroupIds(long[] groupIds, String table) {
497         StringMaker sm = new StringMaker();
498 
499         for (int i = 0; i < groupIds.length; i++) {
500             sm.append(table);
501             sm.append(".groupId = ?");
502 
503             if ((i + 1) < groupIds.length) {
504                 sm.append(" OR ");
505             }
506         }
507 
508         return sm.toString();
509     }
510 
511     protected void setGroupIds(QueryPos qPos, long[] groupIds) {
512         for (int i = 0; i < groupIds.length; i++) {
513             qPos.add(groupIds[i]);
514         }
515     }
516 
517     protected String getJoin(LinkedHashMap<String, Object> params) {
518         if (params == null) {
519             return StringPool.BLANK;
520         }
521 
522         StringMaker sm = new StringMaker();
523 
524         Iterator<Map.Entry<String, Object>> itr = params.entrySet().iterator();
525 
526         while (itr.hasNext()) {
527             Map.Entry<String, Object> entry = itr.next();
528 
529             String key = entry.getKey();
530             Object value = entry.getValue();
531 
532             if (Validator.isNotNull(value)) {
533                 sm.append(getJoin(key));
534             }
535         }
536 
537         return sm.toString();
538     }
539 
540     protected String getJoin(String key) {
541         String join = StringPool.BLANK;
542 
543         if (key.equals("permissionsResourceId")) {
544             join = CustomSQLUtil.get(JOIN_BY_ROLES_PERMISSIONS);
545         }
546         else if (key.equals("usersRoles")) {
547             join = CustomSQLUtil.get(JOIN_BY_USERS_ROLES);
548         }
549 
550         if (Validator.isNotNull(join)) {
551             int pos = join.indexOf("WHERE");
552 
553             if (pos != -1) {
554                 join = join.substring(0, pos);
555             }
556         }
557 
558         return join;
559     }
560 
561     protected String getWhere(LinkedHashMap<String, Object> params) {
562         if (params == null) {
563             return StringPool.BLANK;
564         }
565 
566         StringMaker sm = new StringMaker();
567 
568         Iterator<Map.Entry<String, Object>> itr = params.entrySet().iterator();
569 
570         while (itr.hasNext()) {
571             Map.Entry<String, Object> entry = itr.next();
572 
573             String key = entry.getKey();
574             Object value = entry.getValue();
575 
576             if (Validator.isNotNull(value)) {
577                 sm.append(getWhere(key));
578             }
579         }
580 
581         return sm.toString();
582     }
583 
584     protected String getWhere(String key) {
585         String join = StringPool.BLANK;
586 
587         if (key.equals("permissionsResourceId")) {
588             join = CustomSQLUtil.get(JOIN_BY_ROLES_PERMISSIONS);
589         }
590         else if (key.equals("usersRoles")) {
591             join = CustomSQLUtil.get(JOIN_BY_USERS_ROLES);
592         }
593 
594         if (Validator.isNotNull(join)) {
595             int pos = join.indexOf("WHERE");
596 
597             if (pos != -1) {
598                 join = join.substring(pos + 5, join.length()) + " AND ";
599             }
600         }
601 
602         return join;
603     }
604 
605     protected void setJoin(
606         QueryPos qPos, LinkedHashMap<String, Object> params) {
607 
608         if (params != null) {
609             Iterator<Map.Entry<String, Object>> itr =
610                 params.entrySet().iterator();
611 
612             while (itr.hasNext()) {
613                 Map.Entry<String, Object> entry = itr.next();
614 
615                 Object value = entry.getValue();
616 
617                 if (value instanceof Long) {
618                     Long valueLong = (Long)value;
619 
620                     if (Validator.isNotNull(valueLong)) {
621                         qPos.add(valueLong);
622                     }
623                 }
624                 else if (value instanceof String) {
625                     String valueString = (String)value;
626 
627                     if (Validator.isNotNull(valueString)) {
628                         qPos.add(valueString);
629                     }
630                 }
631             }
632         }
633     }
634 
635 }