001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.ResourceBlocksNotSupportedException;
018    import com.liferay.portal.kernel.dao.orm.ORMException;
019    import com.liferay.portal.kernel.dao.orm.QueryPos;
020    import com.liferay.portal.kernel.dao.orm.SQLQuery;
021    import com.liferay.portal.kernel.dao.orm.Session;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.transaction.Isolation;
027    import com.liferay.portal.kernel.transaction.Propagation;
028    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
029    import com.liferay.portal.kernel.transaction.Transactional;
030    import com.liferay.portal.kernel.util.ListUtil;
031    import com.liferay.portal.model.AuditedModel;
032    import com.liferay.portal.model.GroupedModel;
033    import com.liferay.portal.model.PermissionedModel;
034    import com.liferay.portal.model.PersistedModel;
035    import com.liferay.portal.model.ResourceAction;
036    import com.liferay.portal.model.ResourceBlock;
037    import com.liferay.portal.model.ResourceBlockConstants;
038    import com.liferay.portal.model.ResourceBlockPermissionsContainer;
039    import com.liferay.portal.model.ResourceTypePermission;
040    import com.liferay.portal.model.impl.ResourceBlockImpl;
041    import com.liferay.portal.security.permission.PermissionCacheUtil;
042    import com.liferay.portal.security.permission.PermissionThreadLocal;
043    import com.liferay.portal.security.permission.ResourceBlockIdsBag;
044    import com.liferay.portal.service.PersistedModelLocalService;
045    import com.liferay.portal.service.PersistedModelLocalServiceRegistryUtil;
046    import com.liferay.portal.service.base.ResourceBlockLocalServiceBaseImpl;
047    import com.liferay.util.dao.orm.CustomSQLUtil;
048    
049    import java.util.ArrayList;
050    import java.util.List;
051    import java.util.Map;
052    import java.util.concurrent.Callable;
053    
054    /**
055     * Manages the creation and upkeep of resource blocks and the resources they
056     * contain.
057     *
058     * @author Connor McKay
059     * @author Shuyang Zhou
060     */
061    public class ResourceBlockLocalServiceImpl
062            extends ResourceBlockLocalServiceBaseImpl {
063    
064            @Override
065            public void addCompanyScopePermission(
066                            long companyId, String name, long roleId, String actionId)
067                    throws PortalException, SystemException {
068    
069                    updateCompanyScopePermissions(
070                            companyId, name, roleId, getActionId(name, actionId),
071                            ResourceBlockConstants.OPERATOR_ADD);
072            }
073    
074            @Override
075            public void addCompanyScopePermissions(
076                            long companyId, String name, long roleId, long actionIdsLong)
077                    throws SystemException {
078    
079                    updateCompanyScopePermissions(
080                            companyId, name, roleId, actionIdsLong,
081                            ResourceBlockConstants.OPERATOR_ADD);
082            }
083    
084            @Override
085            public void addGroupScopePermission(
086                            long companyId, long groupId, String name, long roleId,
087                            String actionId)
088                    throws PortalException, SystemException {
089    
090                    updateGroupScopePermissions(
091                            companyId, groupId, name, roleId, getActionId(name, actionId),
092                            ResourceBlockConstants.OPERATOR_ADD);
093            }
094    
095            @Override
096            public void addGroupScopePermissions(
097                            long companyId, long groupId, String name, long roleId,
098                            long actionIdsLong)
099                    throws SystemException {
100    
101                    updateGroupScopePermissions(
102                            companyId, groupId, name, roleId, actionIdsLong,
103                            ResourceBlockConstants.OPERATOR_ADD);
104            }
105    
106            @Override
107            public void addIndividualScopePermission(
108                            long companyId, long groupId, String name, long primKey,
109                            long roleId, String actionId)
110                    throws PortalException, SystemException {
111    
112                    PermissionedModel permissionedModel = getPermissionedModel(
113                            name, primKey);
114    
115                    updateIndividualScopePermissions(
116                            companyId, groupId, name, permissionedModel, roleId,
117                            getActionId(name, actionId), ResourceBlockConstants.OPERATOR_ADD);
118            }
119    
120            @Override
121            public void addIndividualScopePermission(
122                            long companyId, long groupId, String name,
123                            PermissionedModel permissionedModel, long roleId, String actionId)
124                    throws PortalException, SystemException {
125    
126                    updateIndividualScopePermissions(
127                            companyId, groupId, name, permissionedModel, roleId,
128                            getActionId(name, actionId), ResourceBlockConstants.OPERATOR_ADD);
129            }
130    
131            @Override
132            public void addIndividualScopePermissions(
133                            long companyId, long groupId, String name, long primKey,
134                            long roleId, long actionIdsLong)
135                    throws PortalException, SystemException {
136    
137                    PermissionedModel permissionedModel = getPermissionedModel(
138                            name, primKey);
139    
140                    updateIndividualScopePermissions(
141                            companyId, groupId, name, permissionedModel, roleId, actionIdsLong,
142                            ResourceBlockConstants.OPERATOR_ADD);
143            }
144    
145            @Override
146            public void addIndividualScopePermissions(
147                            long companyId, long groupId, String name,
148                            PermissionedModel permissionedModel, long roleId,
149                            long actionIdsLong)
150                    throws SystemException {
151    
152                    updateIndividualScopePermissions(
153                            companyId, groupId, name, permissionedModel, roleId, actionIdsLong,
154                            ResourceBlockConstants.OPERATOR_ADD);
155            }
156    
157            /**
158             * Adds a resource block if necessary and associates the resource block
159             * permissions with it. The resource block will have an initial reference
160             * count of one.
161             *
162             * @param  companyId the primary key of the resource block's company
163             * @param  groupId the primary key of the resource block's group
164             * @param  name the resource block's name
165             * @param  permissionsHash the resource block's permission hash
166             * @param  resourceBlockPermissionsContainer the resource block's
167             *         permissions container
168             * @return the new resource block
169             * @throws SystemException if a system exception occurred
170             */
171            @Override
172            public ResourceBlock addResourceBlock(
173                            long companyId, long groupId, String name, String permissionsHash,
174                            ResourceBlockPermissionsContainer resourceBlockPermissionsContainer)
175                    throws SystemException {
176    
177                    long resourceBlockId = counterLocalService.increment(
178                            ResourceBlock.class.getName());
179    
180                    ResourceBlock resourceBlock = resourceBlockPersistence.create(
181                            resourceBlockId);
182    
183                    resourceBlock.setCompanyId(companyId);
184                    resourceBlock.setGroupId(groupId);
185                    resourceBlock.setName(name);
186                    resourceBlock.setPermissionsHash(permissionsHash);
187                    resourceBlock.setReferenceCount(1);
188    
189                    updateResourceBlock(resourceBlock, false);
190    
191                    resourceBlockPermissionLocalService.addResourceBlockPermissions(
192                            resourceBlockId, resourceBlockPermissionsContainer);
193    
194                    return resourceBlock;
195            }
196    
197            @Override
198            public ResourceBlock deleteResourceBlock(long resourceBlockId)
199                    throws PortalException, SystemException {
200    
201                    ResourceBlock resourceBlock = resourceBlockPersistence.findByPrimaryKey(
202                            resourceBlockId);
203    
204                    return deleteResourceBlock(resourceBlock);
205            }
206    
207            @Override
208            public ResourceBlock deleteResourceBlock(ResourceBlock resourceBlock)
209                    throws SystemException {
210    
211                    resourceBlockPermissionLocalService.deleteResourceBlockPermissions(
212                            resourceBlock.getPrimaryKey());
213    
214                    return resourceBlockPersistence.remove(resourceBlock);
215            }
216    
217            @Override
218            public long getActionId(String name, String actionId)
219                    throws PortalException {
220    
221                    ResourceAction resourcAction =
222                            resourceActionLocalService.getResourceAction(name, actionId);
223    
224                    return resourcAction.getBitwiseValue();
225            }
226    
227            @Override
228            public long getActionIds(String name, List<String> actionIds)
229                    throws PortalException {
230    
231                    long actionIdsLong = 0;
232    
233                    for (String actionId : actionIds) {
234                            ResourceAction resourceAction =
235                                    resourceActionLocalService.getResourceAction(name, actionId);
236    
237                            actionIdsLong |= resourceAction.getBitwiseValue();
238                    }
239    
240                    return actionIdsLong;
241            }
242    
243            @Override
244            public List<String> getActionIds(String name, long actionIdsLong)
245                    throws SystemException {
246    
247                    List<ResourceAction> resourceActions =
248                            resourceActionLocalService.getResourceActions(name);
249    
250                    List<String> actionIds = new ArrayList<String>();
251    
252                    for (ResourceAction resourceAction : resourceActions) {
253                            if ((actionIdsLong & resourceAction.getBitwiseValue()) ==
254                                            resourceAction.getBitwiseValue()) {
255    
256                                    actionIds.add(resourceAction.getActionId());
257                            }
258                    }
259    
260                    return actionIds;
261            }
262    
263            @Override
264            public List<String> getCompanyScopePermissions(
265                            ResourceBlock resourceBlock, long roleId)
266                    throws SystemException {
267    
268                    long actionIdsLong =
269                            resourceTypePermissionLocalService.getCompanyScopeActionIds(
270                                    resourceBlock.getCompanyId(), resourceBlock.getName(), roleId);
271    
272                    return getActionIds(resourceBlock.getName(), actionIdsLong);
273            }
274    
275            @Override
276            public List<String> getGroupScopePermissions(
277                            ResourceBlock resourceBlock, long roleId)
278                    throws SystemException {
279    
280                    long actionIdsLong =
281                            resourceTypePermissionLocalService.getGroupScopeActionIds(
282                                    resourceBlock.getCompanyId(), resourceBlock.getGroupId(),
283                                    resourceBlock.getName(), roleId);
284    
285                    return getActionIds(resourceBlock.getName(), actionIdsLong);
286            }
287    
288            @Override
289            public PermissionedModel getPermissionedModel(String name, long primKey)
290                    throws PortalException, SystemException {
291    
292                    PersistedModelLocalService persistedModelLocalService =
293                            PersistedModelLocalServiceRegistryUtil.
294                                    getPersistedModelLocalService(name);
295    
296                    if (persistedModelLocalService == null) {
297                            throw new ResourceBlocksNotSupportedException();
298                    }
299    
300                    PersistedModel persistedModel =
301                            persistedModelLocalService.getPersistedModel(primKey);
302    
303                    try {
304                            return (PermissionedModel)persistedModel;
305                    }
306                    catch (ClassCastException cce) {
307                            throw new ResourceBlocksNotSupportedException();
308                    }
309            }
310    
311            @Override
312            public List<String> getPermissions(ResourceBlock resourceBlock, long roleId)
313                    throws SystemException {
314    
315                    ResourceBlockPermissionsContainer resourceBlockPermissionsContainer =
316                            resourceBlockPermissionLocalService.
317                                    getResourceBlockPermissionsContainer(
318                                            resourceBlock.getPrimaryKey());
319    
320                    long actionIdsLong = resourceBlockPermissionsContainer.getActionIds(
321                            roleId);
322    
323                    return getActionIds(resourceBlock.getName(), actionIdsLong);
324            }
325    
326            @Override
327            public ResourceBlock getResourceBlock(String name, long primKey)
328                    throws PortalException, SystemException {
329    
330                    PermissionedModel permissionedModel = getPermissionedModel(
331                            name, primKey);
332    
333                    return getResourceBlock(permissionedModel.getResourceBlockId());
334            }
335    
336            @Override
337            public List<Long> getResourceBlockIds(
338                            ResourceBlockIdsBag resourceBlockIdsBag, String name,
339                            String actionId)
340                    throws PortalException {
341    
342                    long actionIdsLong = getActionId(name, actionId);
343    
344                    return resourceBlockIdsBag.getResourceBlockIds(actionIdsLong);
345            }
346    
347            @Override
348            public ResourceBlockIdsBag getResourceBlockIdsBag(
349                            long companyId, long groupId, String name, long[] roleIds)
350                    throws SystemException {
351    
352                    return resourceBlockFinder.findByC_G_N_R(
353                            companyId, groupId, name, roleIds);
354            }
355    
356            @Override
357            public boolean hasPermission(
358                            String name, long primKey, String actionId,
359                            ResourceBlockIdsBag resourceBlockIdsBag)
360                    throws PortalException, SystemException {
361    
362                    PermissionedModel permissionedModel = getPermissionedModel(
363                            name, primKey);
364    
365                    return hasPermission(
366                            name, permissionedModel, actionId, resourceBlockIdsBag);
367            }
368    
369            @Override
370            public boolean hasPermission(
371                            String name, PermissionedModel permissionedModel, String actionId,
372                            ResourceBlockIdsBag resourceBlockIdsBag)
373                    throws PortalException {
374    
375                    long actionIdsLong = getActionId(name, actionId);
376    
377                    return resourceBlockIdsBag.hasResourceBlockId(
378                            permissionedModel.getResourceBlockId(), actionIdsLong);
379            }
380    
381            @Override
382            public boolean isSupported(String name) {
383                    return PersistedModelLocalServiceRegistryUtil.
384                            isPermissionedModelLocalService(name);
385            }
386    
387            @Override
388            @Transactional(
389                    isolation = Isolation.READ_COMMITTED,
390                    propagation = Propagation.REQUIRES_NEW)
391            public void releasePermissionedModelResourceBlock(
392                            PermissionedModel permissionedModel)
393                    throws SystemException {
394    
395                    releaseResourceBlock(permissionedModel.getResourceBlockId());
396            }
397    
398            @Override
399            public void releasePermissionedModelResourceBlock(String name, long primKey)
400                    throws PortalException, SystemException {
401    
402                    PermissionedModel permissionedModel = getPermissionedModel(
403                            name, primKey);
404    
405                    releasePermissionedModelResourceBlock(permissionedModel);
406            }
407    
408            /**
409             * Decrements the reference count of the resource block and updates it in
410             * the database or deletes the resource block if the reference count reaches
411             * zero.
412             *
413             * @param  resourceBlockId the primary key of the resource block
414             * @throws SystemException if a system exception occurred
415             */
416            @Override
417            @Transactional(
418                    isolation = Isolation.READ_COMMITTED,
419                    propagation = Propagation.REQUIRES_NEW)
420            public void releaseResourceBlock(long resourceBlockId)
421                    throws SystemException {
422    
423                    Session session = resourceBlockPersistence.openSession();
424    
425                    while (true) {
426                            try {
427                                    String sql = CustomSQLUtil.get(_RELEASE_RESOURCE_BLOCK);
428    
429                                    SQLQuery sqlQuery = session.createSQLQuery(sql);
430    
431                                    QueryPos qPos = QueryPos.getInstance(sqlQuery);
432    
433                                    qPos.add(resourceBlockId);
434    
435                                    if (sqlQuery.executeUpdate() > 0) {
436                                            ResourceBlock resourceBlock = (ResourceBlock)session.get(
437                                                    ResourceBlockImpl.class, Long.valueOf(resourceBlockId));
438    
439                                            if (resourceBlock.getReferenceCount() == 0) {
440                                                    sql = CustomSQLUtil.get(_DELETE_RESOURCE_BLOCK);
441    
442                                                    sqlQuery = session.createSQLQuery(sql);
443    
444                                                    qPos = QueryPos.getInstance(sqlQuery);
445    
446                                                    qPos.add(resourceBlockId);
447    
448                                                    sqlQuery.executeUpdate();
449                                            }
450                                    }
451    
452                                    resourceBlockPersistence.closeSession(session);
453    
454                                    break;
455                            }
456                            catch (ORMException orme) {
457                                    if (_log.isWarnEnabled()) {
458                                            _log.warn(
459                                                    "Unable to decrement reference count for resource " +
460                                                            "block " + resourceBlockId + ". Retrying.");
461                                    }
462                            }
463                    }
464            }
465    
466            /**
467             * Decrements the reference count of the resource block and updates it in
468             * the database or deletes the resource block if the reference count reaches
469             * zero.
470             *
471             * @param  resourceBlock the resource block
472             * @throws SystemException if a system exception occurred
473             */
474            @Override
475            @Transactional(
476                    isolation = Isolation.READ_COMMITTED,
477                    propagation = Propagation.REQUIRES_NEW)
478            public void releaseResourceBlock(ResourceBlock resourceBlock)
479                    throws SystemException {
480    
481                    releaseResourceBlock(resourceBlock.getResourceBlockId());
482            }
483    
484            @Override
485            public void removeAllGroupScopePermissions(
486                            long companyId, String name, long roleId, long actionIdsLong)
487                    throws SystemException {
488    
489                    List<ResourceTypePermission> resourceTypePermissions =
490                            resourceTypePermissionLocalService.
491                                    getGroupScopeResourceTypePermissions(companyId, name, roleId);
492    
493                    for (ResourceTypePermission resourceTypePermission :
494                                    resourceTypePermissions) {
495    
496                            removeGroupScopePermissions(
497                                    companyId, resourceTypePermission.getGroupId(), name, roleId,
498                                    actionIdsLong);
499                    }
500            }
501    
502            @Override
503            public void removeAllGroupScopePermissions(
504                            long companyId, String name, long roleId, String actionId)
505                    throws PortalException, SystemException {
506    
507                    removeAllGroupScopePermissions(
508                            companyId, name, roleId, getActionId(name, actionId));
509            }
510    
511            @Override
512            public void removeCompanyScopePermission(
513                            long companyId, String name, long roleId, String actionId)
514                    throws PortalException, SystemException {
515    
516                    updateCompanyScopePermissions(
517                            companyId, name, roleId, getActionId(name, actionId),
518                            ResourceBlockConstants.OPERATOR_REMOVE);
519            }
520    
521            @Override
522            public void removeCompanyScopePermissions(
523                            long companyId, String name, long roleId, long actionIdsLong)
524                    throws SystemException {
525    
526                    updateCompanyScopePermissions(
527                            companyId, name, roleId, actionIdsLong,
528                            ResourceBlockConstants.OPERATOR_REMOVE);
529            }
530    
531            @Override
532            public void removeGroupScopePermission(
533                            long companyId, long groupId, String name, long roleId,
534                            String actionId)
535                    throws PortalException, SystemException {
536    
537                    updateGroupScopePermissions(
538                            companyId, groupId, name, roleId, getActionId(name, actionId),
539                            ResourceBlockConstants.OPERATOR_REMOVE);
540            }
541    
542            @Override
543            public void removeGroupScopePermissions(
544                            long companyId, long groupId, String name, long roleId,
545                            long actionIdsLong)
546                    throws SystemException {
547    
548                    updateGroupScopePermissions(
549                            companyId, groupId, name, roleId, actionIdsLong,
550                            ResourceBlockConstants.OPERATOR_REMOVE);
551            }
552    
553            @Override
554            public void removeIndividualScopePermission(
555                            long companyId, long groupId, String name, long primKey,
556                            long roleId, String actionId)
557                    throws PortalException, SystemException {
558    
559                    PermissionedModel permissionedModel = getPermissionedModel(
560                            name, primKey);
561    
562                    updateIndividualScopePermissions(
563                            companyId, groupId, name, permissionedModel, roleId,
564                            getActionId(name, actionId),
565                            ResourceBlockConstants.OPERATOR_REMOVE);
566            }
567    
568            @Override
569            public void removeIndividualScopePermission(
570                            long companyId, long groupId, String name,
571                            PermissionedModel permissionedModel, long roleId, String actionId)
572                    throws PortalException, SystemException {
573    
574                    updateIndividualScopePermissions(
575                            companyId, groupId, name, permissionedModel, roleId,
576                            getActionId(name, actionId),
577                            ResourceBlockConstants.OPERATOR_REMOVE);
578            }
579    
580            @Override
581            public void removeIndividualScopePermissions(
582                            long companyId, long groupId, String name, long primKey,
583                            long roleId, long actionIdsLong)
584                    throws PortalException, SystemException {
585    
586                    PermissionedModel permissionedModel = getPermissionedModel(
587                            name, primKey);
588    
589                    updateIndividualScopePermissions(
590                            companyId, groupId, name, permissionedModel, roleId, actionIdsLong,
591                            ResourceBlockConstants.OPERATOR_REMOVE);
592            }
593    
594            @Override
595            public void removeIndividualScopePermissions(
596                            long companyId, long groupId, String name,
597                            PermissionedModel permissionedModel, long roleId,
598                            long actionIdsLong)
599                    throws SystemException {
600    
601                    updateIndividualScopePermissions(
602                            companyId, groupId, name, permissionedModel, roleId, actionIdsLong,
603                            ResourceBlockConstants.OPERATOR_REMOVE);
604            }
605    
606            @Override
607            public void setCompanyScopePermissions(
608                            long companyId, String name, long roleId, List<String> actionIds)
609                    throws PortalException, SystemException {
610    
611                    updateCompanyScopePermissions(
612                            companyId, name, roleId, getActionIds(name, actionIds),
613                            ResourceBlockConstants.OPERATOR_SET);
614            }
615    
616            @Override
617            public void setCompanyScopePermissions(
618                            long companyId, String name, long roleId, long actionIdsLong)
619                    throws SystemException {
620    
621                    updateCompanyScopePermissions(
622                            companyId, name, roleId, actionIdsLong,
623                            ResourceBlockConstants.OPERATOR_SET);
624            }
625    
626            @Override
627            public void setGroupScopePermissions(
628                            long companyId, long groupId, String name, long roleId,
629                            List<String> actionIds)
630                    throws PortalException, SystemException {
631    
632                    updateGroupScopePermissions(
633                            companyId, groupId, name, roleId, getActionIds(name, actionIds),
634                            ResourceBlockConstants.OPERATOR_SET);
635            }
636    
637            @Override
638            public void setGroupScopePermissions(
639                            long companyId, long groupId, String name, long roleId,
640                            long actionIdsLong)
641                    throws SystemException {
642    
643                    updateGroupScopePermissions(
644                            companyId, groupId, name, roleId, actionIdsLong,
645                            ResourceBlockConstants.OPERATOR_SET);
646            }
647    
648            @Override
649            public void setIndividualScopePermissions(
650                            long companyId, long groupId, String name, long primKey,
651                            long roleId, List<String> actionIds)
652                    throws PortalException, SystemException {
653    
654                    PermissionedModel permissionedModel = getPermissionedModel(
655                            name, primKey);
656    
657                    updateIndividualScopePermissions(
658                            companyId, groupId, name, permissionedModel, roleId,
659                            getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET);
660            }
661    
662            @Override
663            public void setIndividualScopePermissions(
664                            long companyId, long groupId, String name, long primKey,
665                            long roleId, long actionIdsLong)
666                    throws PortalException, SystemException {
667    
668                    PermissionedModel permissionedModel = getPermissionedModel(
669                            name, primKey);
670    
671                    updateIndividualScopePermissions(
672                            companyId, groupId, name, permissionedModel, roleId, actionIdsLong,
673                            ResourceBlockConstants.OPERATOR_SET);
674            }
675    
676            @Override
677            public void setIndividualScopePermissions(
678                            long companyId, long groupId, String name, long primKey,
679                            Map<Long, String[]> roleIdsToActionIds)
680                    throws PortalException, SystemException {
681    
682                    boolean flushEnabled = PermissionThreadLocal.isFlushEnabled();
683    
684                    PermissionThreadLocal.setIndexEnabled(false);
685    
686                    try {
687                            PermissionedModel permissionedModel = getPermissionedModel(
688                                    name, primKey);
689    
690                            for (Map.Entry<Long, String[]> entry :
691                                            roleIdsToActionIds.entrySet()) {
692    
693                                    long roleId = entry.getKey();
694                                    String[] actionIds = entry.getValue();
695    
696                                    updateIndividualScopePermissions(
697                                            companyId, groupId, name, permissionedModel, roleId,
698                                            getActionIds(name, ListUtil.fromArray(actionIds)),
699                                            ResourceBlockConstants.OPERATOR_SET);
700                            }
701                    }
702                    finally {
703                            PermissionThreadLocal.setIndexEnabled(flushEnabled);
704    
705                            PermissionCacheUtil.clearCache();
706                    }
707            }
708    
709            @Override
710            public void setIndividualScopePermissions(
711                            long companyId, long groupId, String name,
712                            PermissionedModel permissionedModel, long roleId,
713                            List<String> actionIds)
714                    throws PortalException, SystemException {
715    
716                    updateIndividualScopePermissions(
717                            companyId, groupId, name, permissionedModel, roleId,
718                            getActionIds(name, actionIds), ResourceBlockConstants.OPERATOR_SET);
719            }
720    
721            @Override
722            public void setIndividualScopePermissions(
723                            long companyId, long groupId, String name,
724                            PermissionedModel permissionedModel, long roleId,
725                            long actionIdsLong)
726                    throws SystemException {
727    
728                    updateIndividualScopePermissions(
729                            companyId, groupId, name, permissionedModel, roleId, actionIdsLong,
730                            ResourceBlockConstants.OPERATOR_SET);
731            }
732    
733            @Override
734            public void updateCompanyScopePermissions(
735                            long companyId, String name, long roleId, long actionIdsLong,
736                            int operator)
737                    throws SystemException {
738    
739                    resourceTypePermissionLocalService.
740                            updateCompanyScopeResourceTypePermissions(
741                                    companyId, name, roleId, actionIdsLong, operator);
742    
743                    List<ResourceBlock> resourceBlocks = resourceBlockPersistence.findByC_N(
744                            companyId, name);
745    
746                    updatePermissions(resourceBlocks, roleId, actionIdsLong, operator);
747    
748                    PermissionCacheUtil.clearCache();
749            }
750    
751            @Override
752            public void updateGroupScopePermissions(
753                            long companyId, long groupId, String name, long roleId,
754                            long actionIdsLong, int operator)
755                    throws SystemException {
756    
757                    resourceTypePermissionLocalService.
758                            updateGroupScopeResourceTypePermissions(
759                                    companyId, groupId, name, roleId, actionIdsLong, operator);
760    
761                    List<ResourceBlock> resourceBlocks =
762                            resourceBlockPersistence.findByC_G_N(companyId, groupId, name);
763    
764                    updatePermissions(resourceBlocks, roleId, actionIdsLong, operator);
765    
766                    PermissionCacheUtil.clearCache();
767            }
768    
769            @Override
770            public void updateIndividualScopePermissions(
771                            long companyId, long groupId, String name,
772                            PermissionedModel permissionedModel, long roleId,
773                            long actionIdsLong, int operator)
774                    throws SystemException {
775    
776                    ResourceBlock resourceBlock =
777                            resourceBlockPersistence.fetchByPrimaryKey(
778                                    permissionedModel.getResourceBlockId());
779    
780                    ResourceBlockPermissionsContainer resourceBlockPermissionsContainer =
781                            null;
782    
783                    if (resourceBlock == null) {
784                            resourceBlockPermissionsContainer =
785                                    resourceTypePermissionLocalService.
786                                            getResourceBlockPermissionsContainer(
787                                                    companyId, groupId, name);
788                    }
789                    else {
790                            resourceBlockPermissionsContainer =
791                                    resourceBlockPermissionLocalService.
792                                            getResourceBlockPermissionsContainer(
793                                                    resourceBlock.getPrimaryKey());
794                    }
795    
796                    long oldActionIdsLong = resourceBlockPermissionsContainer.getActionIds(
797                            roleId);
798    
799                    if (operator == ResourceBlockConstants.OPERATOR_ADD) {
800                            actionIdsLong |= oldActionIdsLong;
801                    }
802                    else if (operator == ResourceBlockConstants.OPERATOR_REMOVE) {
803                            actionIdsLong = oldActionIdsLong & (~actionIdsLong);
804                    }
805    
806                    if (resourceBlock != null) {
807                            if (oldActionIdsLong == actionIdsLong) {
808                                    return;
809                            }
810    
811                            resourceBlockLocalService.releaseResourceBlock(resourceBlock);
812                    }
813    
814                    resourceBlockPermissionsContainer.setPermissions(roleId, actionIdsLong);
815    
816                    String permissionsHash =
817                            resourceBlockPermissionsContainer.getPermissionsHash();
818    
819                    resourceBlockLocalService.updateResourceBlockId(
820                            companyId, groupId, name, permissionedModel, permissionsHash,
821                            resourceBlockPermissionsContainer);
822    
823                    PermissionCacheUtil.clearCache();
824            }
825    
826            @Override
827            @Transactional(
828                    isolation = Isolation.READ_COMMITTED,
829                    propagation = Propagation.REQUIRES_NEW)
830            public ResourceBlock updateResourceBlockId(
831                            long companyId, long groupId, String name,
832                            final PermissionedModel permissionedModel, String permissionsHash,
833                            ResourceBlockPermissionsContainer resourceBlockPermissionsContainer)
834                    throws SystemException {
835    
836                    ResourceBlock resourceBlock = null;
837    
838                    while (true) {
839                            resourceBlock = resourceBlockPersistence.fetchByC_G_N_P(
840                                    companyId, groupId, name, permissionsHash, false);
841    
842                            if (resourceBlock == null) {
843                                    try {
844                                            resourceBlock = addResourceBlock(
845                                                    companyId, groupId, name, permissionsHash,
846                                                    resourceBlockPermissionsContainer);
847                                    }
848                                    catch (SystemException se) {
849                                            if (_log.isWarnEnabled()) {
850                                                    _log.warn(
851                                                            "Unable to add a new resource block. Retrying");
852                                            }
853    
854                                            continue;
855                                    }
856    
857                                    break;
858                            }
859    
860                            Session session = resourceBlockPersistence.openSession();
861    
862                            try {
863                                    String sql = CustomSQLUtil.get(_RETAIN_RESOURCE_BLOCK);
864    
865                                    SQLQuery sqlQuery = session.createSQLQuery(sql);
866    
867                                    QueryPos qPos = QueryPos.getInstance(sqlQuery);
868    
869                                    qPos.add(resourceBlock.getResourceBlockId());
870    
871                                    if (sqlQuery.executeUpdate() > 0) {
872    
873                                            // We currently use an "update set" SQL statement to
874                                            // increment the reference count in a discontinuous manner.
875                                            // We can change it to an "update where" SQL statement to
876                                            // guarantee continuous counts. We are using a SQL statement
877                                            // that allows for a discontinuous count since it is cheaper
878                                            // and continuity is not required.
879    
880                                            resourceBlock.setReferenceCount(
881                                                    resourceBlock.getReferenceCount() + 1);
882    
883                                            break;
884                                    }
885                            }
886                            catch (ORMException orme) {
887                                    if (_log.isWarnEnabled()) {
888                                            _log.warn(
889                                                    "Unable to increment reference count for resource " +
890                                                            "block " + resourceBlock.getResourceBlockId() +
891                                                                    ". Retrying");
892                                    }
893                            }
894                            finally {
895    
896                                    // Prevent Hibernate from automatically flushing out the first
897                                    // level cache since that will lead to a regular update that
898                                    // will overwrite the previous update causing a lost update.
899    
900                                    session.evict(resourceBlock);
901    
902                                    resourceBlockPersistence.closeSession(session);
903                            }
904                    }
905    
906                    permissionedModel.setResourceBlockId(
907                            resourceBlock.getResourceBlockId());
908    
909                    Callable<Void> callable = new Callable<Void>() {
910    
911                            @Override
912                            public Void call() throws Exception {
913                                    permissionedModel.persist();
914    
915                                    return null;
916                            }
917    
918                    };
919    
920                    TransactionCommitCallbackRegistryUtil.registerCallback(callable);
921    
922                    return resourceBlock;
923            }
924    
925            @Override
926            public void verifyResourceBlockId(long companyId, String name, long primKey)
927                    throws PortalException, SystemException {
928    
929                    PermissionedModel permissionedModel = getPermissionedModel(
930                            name, primKey);
931    
932                    ResourceBlock resourceBlock =
933                            resourceBlockPersistence.fetchByPrimaryKey(
934                                    permissionedModel.getResourceBlockId());
935    
936                    if (resourceBlock != null) {
937                            return;
938                    }
939    
940                    if (_log.isWarnEnabled()) {
941                            _log.warn(
942                                    "Resource block " + permissionedModel.getResourceBlockId() +
943                                            " missing for " + name + "#" + primKey);
944                    }
945    
946                    long groupId = 0;
947                    long ownerId = 0;
948    
949                    if (permissionedModel instanceof GroupedModel) {
950                            GroupedModel groupedModel = (GroupedModel)permissionedModel;
951    
952                            groupId = groupedModel.getGroupId();
953                            ownerId = groupedModel.getUserId();
954                    }
955                    else if (permissionedModel instanceof AuditedModel) {
956                            AuditedModel auditedModel = (AuditedModel)permissionedModel;
957    
958                            ownerId = auditedModel.getUserId();
959                    }
960    
961                    resourceLocalService.addResources(
962                            companyId, groupId, ownerId, name, primKey, false, true, true);
963            }
964    
965            protected void updatePermissions(
966                            List<ResourceBlock> resourceBlocks, long roleId, long actionIdsLong,
967                            int operator)
968                    throws SystemException {
969    
970                    for (ResourceBlock resourceBlock : resourceBlocks) {
971                            resourceBlockPermissionLocalService.updateResourceBlockPermission(
972                                    resourceBlock.getPrimaryKey(), roleId, actionIdsLong, operator);
973    
974                            updatePermissionsHash(resourceBlock);
975                    }
976            }
977    
978            protected void updatePermissionsHash(ResourceBlock resourceBlock)
979                    throws SystemException {
980    
981                    ResourceBlockPermissionsContainer resourceBlockPermissionsContainer =
982                            resourceBlockPermissionLocalService.
983                            getResourceBlockPermissionsContainer(resourceBlock.getPrimaryKey());
984    
985                    String permissionsHash =
986                            resourceBlockPermissionsContainer.getPermissionsHash();
987    
988                    resourceBlock.setPermissionsHash(permissionsHash);
989    
990                    updateResourceBlock(resourceBlock);
991            }
992    
993            private static final String _DELETE_RESOURCE_BLOCK =
994                    ResourceBlockLocalServiceImpl.class.getName() +
995                            ".deleteResourceBlock";
996    
997            private static final String _RELEASE_RESOURCE_BLOCK =
998                    ResourceBlockLocalServiceImpl.class.getName() +
999                            ".releaseResourceBlock";
1000    
1001            private static final String _RETAIN_RESOURCE_BLOCK =
1002                    ResourceBlockLocalServiceImpl.class.getName() +
1003                            ".retainResourceBlock";
1004    
1005            private static Log _log = LogFactoryUtil.getLog(
1006                    ResourceBlockLocalServiceImpl.class);
1007    
1008    }