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