001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.ResourceBlocksNotSupportedException;
018    import com.liferay.portal.kernel.dao.orm.ORMException;
019    import com.liferay.portal.kernel.dao.orm.QueryPos;
020    import com.liferay.portal.kernel.dao.orm.SQLQuery;
021    import com.liferay.portal.kernel.dao.orm.Session;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.transaction.Isolation;
027    import com.liferay.portal.kernel.transaction.Propagation;
028    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
029    import com.liferay.portal.kernel.transaction.Transactional;
030    import com.liferay.portal.kernel.util.ListUtil;
031    import com.liferay.portal.model.AuditedModel;
032    import com.liferay.portal.model.GroupedModel;
033    import com.liferay.portal.model.PermissionedModel;
034    import com.liferay.portal.model.PersistedModel;
035    import com.liferay.portal.model.ResourceAction;
036    import com.liferay.portal.model.ResourceBlock;
037    import com.liferay.portal.model.ResourceBlockConstants;
038    import com.liferay.portal.model.ResourceBlockPermissionsContainer;
039    import com.liferay.portal.model.ResourceTypePermission;
040    import com.liferay.portal.model.impl.ResourceBlockImpl;
041    import com.liferay.portal.security.permission.PermissionCacheUtil;
042    import com.liferay.portal.security.permission.PermissionThreadLocal;
043    import com.liferay.portal.security.permission.ResourceBlockIdsBag;
044    import com.liferay.portal.service.PersistedModelLocalService;
045    import com.liferay.portal.service.PersistedModelLocalServiceRegistryUtil;
046    import com.liferay.portal.service.base.ResourceBlockLocalServiceBaseImpl;
047    import com.liferay.util.dao.orm.CustomSQLUtil;
048    
049    import java.util.ArrayList;
050    import java.util.List;
051    import java.util.Map;
052    import java.util.concurrent.Callable;
053    
054    /**
055     * Manages the creation and upkeep of resource blocks and the resources they
056     * contain.
057     *
058     * @author Connor McKay
059     * @author Shuyang Zhou
060     */
061    public class ResourceBlockLocalServiceImpl
062            extends ResourceBlockLocalServiceBaseImpl {
063    
064            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);
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                            resourceBlockLocalService.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                                            // On success, manually flush to enforce database row lock
800    
801                                            resourceBlockPersistence.flush();
802                                    }
803                                    catch (SystemException se) {
804                                            if (_log.isWarnEnabled()) {
805                                                    _log.warn(
806                                                            "Unable to add a new resource block. Retrying");
807                                            }
808    
809                                            // On failure, cancel all pending persistent entities
810    
811                                            Session session =
812                                                    resourceBlockPersistence.getCurrentSession();
813    
814                                            session.clear();
815    
816                                            continue;
817                                    }
818    
819                                    break;
820                            }
821    
822                            Session session = resourceBlockPersistence.openSession();
823    
824                            try {
825                                    String sql = CustomSQLUtil.get(_RETAIN_RESOURCE_BLOCK);
826    
827                                    SQLQuery sqlQuery = session.createSQLQuery(sql);
828    
829                                    QueryPos qPos = QueryPos.getInstance(sqlQuery);
830    
831                                    qPos.add(resourceBlock.getResourceBlockId());
832    
833                                    if (sqlQuery.executeUpdate() > 0) {
834    
835                                            // We currently use an "update set" SQL statement to
836                                            // increment the reference count in a discontinuous manner.
837                                            // We can change it to an "update where" SQL statement to
838                                            // guarantee continuous counts. We are using a SQL statement
839                                            // that allows for a discontinuous count since it is cheaper
840                                            // and continuity is not required.
841    
842                                            resourceBlock.setReferenceCount(
843                                                    resourceBlock.getReferenceCount() + 1);
844    
845                                            break;
846                                    }
847                            }
848                            catch (ORMException orme) {
849                                    if (_log.isWarnEnabled()) {
850                                            _log.warn(
851                                                    "Unable to increment reference count for resource " +
852                                                            "block " + resourceBlock.getResourceBlockId() +
853                                                                    ". Retrying");
854                                    }
855                            }
856                            finally {
857    
858                                    // Prevent Hibernate from automatically flushing out the first
859                                    // level cache since that will lead to a regular update that
860                                    // will overwrite the previous update causing a lost update.
861    
862                                    session.evict(resourceBlock);
863    
864                                    resourceBlockPersistence.closeSession(session);
865                            }
866                    }
867    
868                    permissionedModel.setResourceBlockId(
869                            resourceBlock.getResourceBlockId());
870    
871                    Callable<Void> callable = new Callable<Void>() {
872    
873                            public Void call() throws Exception {
874                                    permissionedModel.persist();
875    
876                                    return null;
877                            }
878    
879                    };
880    
881                    TransactionCommitCallbackRegistryUtil.registerCallback(callable);
882    
883                    return resourceBlock;
884            }
885    
886            public void verifyResourceBlockId(long companyId, String name, long primKey)
887                    throws PortalException, SystemException {
888    
889                    PermissionedModel permissionedModel = getPermissionedModel(
890                            name, primKey);
891    
892                    ResourceBlock resourceBlock =
893                                    resourceBlockPersistence.fetchByPrimaryKey(
894                            permissionedModel.getResourceBlockId());
895    
896                    if (resourceBlock == null) {
897                            if (_log.isWarnEnabled()) {
898                                    _log.warn(
899                                            "Resource block " + permissionedModel.getResourceBlockId() +
900                                                    " missing for " + name + "#" + primKey);
901                            }
902    
903                            long groupId = 0;
904                            long ownerId = 0;
905    
906                            if (permissionedModel instanceof GroupedModel) {
907                                    GroupedModel groupedModel = (GroupedModel)permissionedModel;
908    
909                                    groupId = groupedModel.getGroupId();
910                                    ownerId = groupedModel.getUserId();
911                            }
912                            else if (permissionedModel instanceof AuditedModel) {
913                                    AuditedModel auditedModel = (AuditedModel)permissionedModel;
914    
915                                    ownerId = auditedModel.getUserId();
916                            }
917    
918                            resourceLocalService.addResources(
919                                    companyId, groupId, ownerId, name, primKey, false, true, true);
920                    }
921            }
922    
923            protected void updatePermissions(
924                            List<ResourceBlock> resourceBlocks, long roleId, long actionIdsLong,
925                            int operator)
926                    throws SystemException {
927    
928                    for (ResourceBlock resourceBlock : resourceBlocks) {
929                            resourceBlockPermissionLocalService.updateResourceBlockPermission(
930                                    resourceBlock.getPrimaryKey(), roleId, actionIdsLong, operator);
931    
932                            updatePermissionsHash(resourceBlock);
933                    }
934            }
935    
936            protected void updatePermissionsHash(ResourceBlock resourceBlock)
937                    throws SystemException {
938    
939                    ResourceBlockPermissionsContainer resourceBlockPermissionsContainer =
940                            resourceBlockPermissionLocalService.
941                            getResourceBlockPermissionsContainer(resourceBlock.getPrimaryKey());
942    
943                    String permissionsHash =
944                            resourceBlockPermissionsContainer.getPermissionsHash();
945    
946                    resourceBlock.setPermissionsHash(permissionsHash);
947    
948                    updateResourceBlock(resourceBlock);
949            }
950    
951            private static final String _DELETE_RESOURCE_BLOCK =
952                    ResourceBlockLocalServiceImpl.class.getName() +
953                            ".deleteResourceBlock";
954    
955            private static final String _RELEASE_RESOURCE_BLOCK =
956                    ResourceBlockLocalServiceImpl.class.getName() +
957                            ".releaseResourceBlock";
958    
959            private static final String _RETAIN_RESOURCE_BLOCK =
960                    ResourceBlockLocalServiceImpl.class.getName() +
961                            ".retainResourceBlock";
962    
963            private static Log _log = LogFactoryUtil.getLog(
964                    ResourceBlockLocalServiceImpl.class);
965    
966    }