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