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