001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.ResourceActionsException;
018    import com.liferay.portal.kernel.bean.BeanPropertiesUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.search.SearchEngineUtil;
024    import com.liferay.portal.kernel.util.ListUtil;
025    import com.liferay.portal.model.AuditedModel;
026    import com.liferay.portal.model.GroupedModel;
027    import com.liferay.portal.model.PermissionedModel;
028    import com.liferay.portal.model.Resource;
029    import com.liferay.portal.model.ResourceConstants;
030    import com.liferay.portal.model.ResourcePermission;
031    import com.liferay.portal.model.Role;
032    import com.liferay.portal.model.RoleConstants;
033    import com.liferay.portal.model.impl.ResourceImpl;
034    import com.liferay.portal.security.permission.PermissionCacheUtil;
035    import com.liferay.portal.security.permission.PermissionThreadLocal;
036    import com.liferay.portal.security.permission.ResourceActionsUtil;
037    import com.liferay.portal.service.ServiceContext;
038    import com.liferay.portal.service.base.ResourceLocalServiceBaseImpl;
039    import com.liferay.portal.util.ResourcePermissionsThreadLocal;
040    
041    import java.util.Arrays;
042    import java.util.Iterator;
043    import java.util.List;
044    
045    import org.apache.commons.lang.time.StopWatch;
046    
047    /**
048     * Provides the local service for accessing, adding, and updating resources.
049     *
050     * <p>
051     * Permissions in Liferay are defined for resource/action pairs. Some resources,
052     * known as portlet resources, define actions that the end-user can perform with
053     * respect to a portlet window. Other resources, known as model resources,
054     * define actions that the end-user can perform with respect to the
055     * service/persistence layer.
056     * </p>
057     *
058     * <p>
059     * On creating an entity instance, you should create resources for it. The
060     * following example demonstrates adding resources for an instance of a model
061     * entity named <code>SomeWidget</code>. The IDs of the actions permitted for
062     * the group and guests are passed in from the service context.
063     * </p>
064     *
065     * <p>
066     * <pre>
067     * <code>
068     * resourceLocalService.addModelResources(
069     *              SomeWidget.getCompanyId(), SomeWidget.getGroupId(), userId,
070     *              SomeWidget.class.getName(), SomeWidget.getPrimaryKey(),
071     *              serviceContext.getGroupPermissions, serviceContext.getGuestPermissions);
072     * </code>
073     * </pre>
074     * </p>
075     *
076     * <p>
077     * Just prior to deleting an entity instance, you should delete its resource at
078     * the individual scope. The following example demonstrates deleting a resource
079     * associated with the <code>SomeWidget</code> model entity at the scope
080     * individual scope.
081     * </p>
082     *
083     * <p>
084     * <pre>
085     * <code>
086     * resourceLocalService.deleteResource(
087     *              SomeWidget.getCompanyId(), SomeWidget.class.getName(),
088     *              ResourceConstants.SCOPE_INDIVIDUAL, SomeWidget.getPrimaryKey());
089     * </code>
090     * </pre>
091     * </p>
092     *
093     * @author Brian Wing Shun Chan
094     * @author Wilson S. Man
095     * @author Raymond Aug??
096     * @author Julio Camarero
097     * @author Connor McKay
098     */
099    public class ResourceLocalServiceImpl extends ResourceLocalServiceBaseImpl {
100    
101            /**
102             * Adds resources for the model, always creating a resource at the
103             * individual scope and only creating resources at the group, group
104             * template, and company scope if such resources don't already exist.
105             *
106             * <ol>
107             * <li>
108             * If the service context specifies that default group or default guest
109             * permissions are to be added, then only default permissions are added. See
110             * {@link com.liferay.portal.service.ServiceContext#setAddGroupPermissions(
111             * boolean)} and {@link
112             * com.liferay.portal.service.ServiceContext#setAddGuestPermissions(
113             * boolean)}.
114             * </li>
115             * <li>
116             * Else ...
117             * <ol>
118             * <li>
119             * If the service context specifies to derive default permissions, then
120             * default group and guest permissions are derived from the model and
121             * added. See {@link
122             * com.liferay.portal.service.ServiceContext#setDeriveDefaultPermissions(
123             * boolean)}.
124             * </li>
125             * <li>
126             * Lastly group and guest permissions from the service
127             * context are applied. See {@link
128             * com.liferay.portal.service.ServiceContext#setGroupPermissions(String[])}
129             * and {@link
130             * com.liferay.portal.service.ServiceContext#setGuestPermissions(String[])}.
131             * </li>
132             * </ol>
133             *
134             * </li>
135             * </ol>
136             *
137             * @param  auditedModel the model to associate with the resources
138             * @param  serviceContext the service context to apply. Can set whether to
139             *         add the model's default group and guest permissions, set whether
140             *         to derive default group and guest permissions from the model, set
141             *         group permissions to apply, and set guest permissions to apply.
142             * @throws PortalException if no portal actions could be found associated
143             *         with the model or if a portal exception occurred
144             * @throws SystemException if a system exception occurred
145             */
146            @Override
147            public void addModelResources(
148                            AuditedModel auditedModel, ServiceContext serviceContext)
149                    throws PortalException, SystemException {
150    
151                    if (serviceContext.isAddGroupPermissions() ||
152                            serviceContext.isAddGuestPermissions()) {
153    
154                            addResources(
155                                    auditedModel.getCompanyId(), getGroupId(auditedModel),
156                                    auditedModel.getUserId(), auditedModel.getModelClassName(),
157                                    String.valueOf(auditedModel.getPrimaryKeyObj()), false,
158                                    serviceContext.isAddGroupPermissions(),
159                                    serviceContext.isAddGuestPermissions(),
160                                    getPermissionedModel(auditedModel));
161                    }
162                    else {
163                            if (serviceContext.isDeriveDefaultPermissions()) {
164                                    serviceContext.deriveDefaultPermissions(
165                                            getGroupId(auditedModel), auditedModel.getModelClassName());
166                            }
167    
168                            addModelResources(
169                                    auditedModel.getCompanyId(), getGroupId(auditedModel),
170                                    auditedModel.getUserId(), auditedModel.getModelClassName(),
171                                    String.valueOf(auditedModel.getPrimaryKeyObj()),
172                                    serviceContext.getGroupPermissions(),
173                                    serviceContext.getGuestPermissions(),
174                                    getPermissionedModel(auditedModel));
175                    }
176            }
177    
178            /**
179             * Adds resources for the model with the name and primary key, always
180             * creating a resource at the individual scope and only creating resources
181             * at the group, group template, and company scope if such resources don't
182             * already exist.
183             *
184             * @param  companyId the primary key of the portal instance
185             * @param  groupId the primary key of the group
186             * @param  userId the primary key of the user adding the resources
187             * @param  name a name for the resource, typically the model's class name
188             * @param  primKey the primary key of the model instance, optionally
189             *         <code>0</code> if no instance exists
190             * @param  groupPermissions the group permissions to be applied
191             * @param  guestPermissions the guest permissions to be applied
192             * @throws PortalException if no portal actions could be found associated
193             *         with the model or if a portal exception occurred
194             * @throws SystemException if a system exception occurred
195             */
196            @Override
197            public void addModelResources(
198                            long companyId, long groupId, long userId, String name,
199                            long primKey, String[] groupPermissions, String[] guestPermissions)
200                    throws PortalException, SystemException {
201    
202                    addModelResources(
203                            companyId, groupId, userId, name, String.valueOf(primKey),
204                            groupPermissions, guestPermissions, null);
205            }
206    
207            /**
208             * Adds resources for the model with the name and primary key string, always
209             * creating a resource at the individual scope and only creating resources
210             * at the group, group template, and company scope if such resources don't
211             * already exist.
212             *
213             * @param  companyId the primary key of the portal instance
214             * @param  groupId the primary key of the group
215             * @param  userId the primary key of the user adding the resources
216             * @param  name a name for the resource, typically the model's class name
217             * @param  primKey the primary key string of the model instance, optionally
218             *         an empty string if no instance exists
219             * @param  groupPermissions the group permissions to be applied
220             * @param  guestPermissions the guest permissions to be applied
221             * @throws PortalException if no portal actions could be found associated
222             *         with the model or if a portal exception occurred
223             * @throws SystemException if a system exception occurred
224             */
225            @Override
226            public void addModelResources(
227                            long companyId, long groupId, long userId, String name,
228                            String primKey, String[] groupPermissions,
229                            String[] guestPermissions)
230                    throws PortalException, SystemException {
231    
232                    addModelResources(
233                            companyId, groupId, userId, name, primKey, groupPermissions,
234                            guestPermissions, null);
235            }
236    
237            /**
238             * Adds resources for the entity with the name and primary key, always
239             * creating a resource at the individual scope and only creating resources
240             * at the group, group template, and company scope if such resources don't
241             * already exist.
242             *
243             * @param  companyId the primary key of the portal instance
244             * @param  groupId the primary key of the group
245             * @param  userId the primary key of the user adding the resources
246             * @param  name a name for the resource, which should be a portlet ID if the
247             *         resource is a portlet or the resource's class name otherwise
248             * @param  primKey the primary key of the resource instance, optionally
249             *         <code>0</code> if no instance exists
250             * @param  portletActions whether to associate portlet actions with the
251             *         resource
252             * @param  addGroupPermissions whether to add group permissions
253             * @param  addGuestPermissions whether to add guest permissions
254             * @throws PortalException if no portal actions could be found associated
255             *         with the resource or if a portal exception occurred
256             * @throws SystemException if a system exception occurred
257             */
258            @Override
259            public void addResources(
260                            long companyId, long groupId, long userId, String name,
261                            long primKey, boolean portletActions, boolean addGroupPermissions,
262                            boolean addGuestPermissions)
263                    throws PortalException, SystemException {
264    
265                    addResources(
266                            companyId, groupId, userId, name, String.valueOf(primKey),
267                            portletActions, addGroupPermissions, addGuestPermissions, null);
268            }
269    
270            /**
271             * Adds resources for the entity with the name and primary key string,
272             * always creating a resource at the individual scope and only creating
273             * resources at the group, group template, and company scope if such
274             * resources don't already exist.
275             *
276             * @param  companyId the primary key of the portal instance
277             * @param  groupId the primary key of the group
278             * @param  userId the primary key of the user adding the resources
279             * @param  name a name for the resource, which should be a portlet ID if the
280             *         resource is a portlet or the resource's class name otherwise
281             * @param  primKey the primary key string of the resource instance,
282             *         optionally an empty string if no instance exists
283             * @param  portletActions whether to associate portlet actions with the
284             *         resource
285             * @param  addGroupPermissions whether to add group permissions
286             * @param  addGuestPermissions whether to add guest permissions
287             * @throws PortalException if no portal actions could be found associated
288             *         with the resource or if a portal exception occurred
289             * @throws SystemException if a system exception occurred
290             */
291            @Override
292            public void addResources(
293                            long companyId, long groupId, long userId, String name,
294                            String primKey, boolean portletActions, boolean addGroupPermissions,
295                            boolean addGuestPermissions)
296                    throws PortalException, SystemException {
297    
298                    addResources(
299                            companyId, groupId, userId, name, primKey, portletActions,
300                            addGroupPermissions, addGuestPermissions, null);
301            }
302    
303            /**
304             * Adds resources for the entity with the name. Use this method if the user
305             * is unknown or irrelevant and there is no current entity instance.
306             *
307             * @param  companyId the primary key of the portal instance
308             * @param  groupId the primary key of the group
309             * @param  name a name for the resource, which should be a portlet ID if the
310             *         resource is a portlet or the resource's class name otherwise
311             * @param  portletActions whether to associate portlet actions with the
312             *         resource
313             * @throws PortalException if no portal actions could be found associated
314             *         with the resource or if a portal exception occurred
315             * @throws SystemException if a system exception occurred
316             */
317            @Override
318            public void addResources(
319                            long companyId, long groupId, String name, boolean portletActions)
320                    throws PortalException, SystemException {
321    
322                    addResources(
323                            companyId, groupId, 0, name, null, portletActions, false, false);
324            }
325    
326            /**
327             * Deletes the resource associated with the model at the scope.
328             *
329             * @param  auditedModel the model associated with the resource
330             * @param  scope the scope of the resource. For more information see {@link
331             *         com.liferay.portal.model.ResourceConstants}.
332             * @throws PortalException if a portal exception occurred
333             * @throws SystemException if a system exception occurred
334             */
335            @Override
336            public void deleteResource(AuditedModel auditedModel, int scope)
337                    throws PortalException, SystemException {
338    
339                    deleteResource(
340                            auditedModel.getCompanyId(), auditedModel.getModelClassName(),
341                            scope, String.valueOf(auditedModel.getPrimaryKeyObj()),
342                            getPermissionedModel(auditedModel));
343            }
344    
345            /**
346             * Deletes the resource matching the primary key at the scope.
347             *
348             * @param  companyId the primary key of the portal instance
349             * @param  name the resource's name, which should be a portlet ID if the
350             *         resource is a portlet or the resource's class name otherwise
351             * @param  scope the scope of the resource. For more information see {@link
352             *         com.liferay.portal.model.ResourceConstants}.
353             * @param  primKey the primary key of the resource instance
354             * @throws PortalException if a portal exception occurred
355             * @throws SystemException if a system exception occurred
356             */
357            @Override
358            public void deleteResource(
359                            long companyId, String name, int scope, long primKey)
360                    throws PortalException, SystemException {
361    
362                    deleteResource(companyId, name, scope, String.valueOf(primKey), null);
363            }
364    
365            /**
366             * Deletes the resource matching the primary key at the scope.
367             *
368             * @param  companyId the primary key of the portal instance
369             * @param  name the resource's name, which should be a portlet ID if the
370             *         resource is a portlet or the resource's class name otherwise
371             * @param  scope the scope of the resource. For more information see {@link
372             *         com.liferay.portal.model.ResourceConstants}.
373             * @param  primKey the primary key string of the resource instance
374             * @throws PortalException if a portal exception occurred
375             * @throws SystemException if a system exception occurred
376             */
377            @Override
378            public void deleteResource(
379                            long companyId, String name, int scope, String primKey)
380                    throws PortalException, SystemException {
381    
382                    deleteResource(companyId, name, scope, primKey, null);
383            }
384    
385            /**
386             * Returns a new resource with the name and primary key at the scope.
387             *
388             * @param  companyId the primary key of the portal instance
389             * @param  name a name for the resource, which should be a portlet ID if the
390             *         resource is a portlet or the resource's class name otherwise
391             * @param  scope the scope of the resource. For more information see {@link
392             *         com.liferay.portal.model.ResourceConstants}.
393             * @param  primKey the primary key string of the resource
394             * @return the new resource
395             */
396            @Override
397            public Resource getResource(
398                    long companyId, String name, int scope, String primKey) {
399    
400                    Resource resource = new ResourceImpl();
401    
402                    resource.setCompanyId(companyId);
403                    resource.setName(name);
404                    resource.setScope(scope);
405                    resource.setPrimKey(primKey);
406    
407                    return resource;
408            }
409    
410            /**
411             * Returns <code>true</code> if the roles have permission to perform the
412             * action on the resources.
413             *
414             * @param  userId the primary key of the user performing the permission
415             *         check
416             * @param  resourceId the primary key of the resource, typically the scope
417             *         group ID representing the scope in which the permission check is
418             *         being performed
419             * @param  resources the resources for which permissions are to be checked
420             * @param  actionId the primary key of the action to be performed on the
421             *         resources
422             * @param  roleIds the primary keys of the roles
423             * @return <code>true</code> if the roles have permission to perform the
424             *         action on the resources;<code>false</code> otherwise
425             * @throws PortalException if any one of the roles with the primary keys
426             *         could not be found or if a resource action with the action ID
427             *         could not be found
428             * @throws SystemException if a system exception occurred
429             */
430            @Override
431            public boolean hasUserPermissions(
432                            long userId, long resourceId, List<Resource> resources,
433                            String actionId, long[] roleIds)
434                    throws PortalException, SystemException {
435    
436                    StopWatch stopWatch = null;
437    
438                    if (_log.isDebugEnabled()) {
439                            stopWatch = new StopWatch();
440    
441                            stopWatch.start();
442                    }
443    
444                    int block = 1;
445    
446                    boolean hasUserPermissions =
447                            resourcePermissionLocalService.hasResourcePermission(
448                                    resources, roleIds, actionId);
449    
450                    logHasUserPermissions(userId, resourceId, actionId, stopWatch, block++);
451    
452                    return hasUserPermissions;
453            }
454    
455            /**
456             * Updates the resources for the model, replacing their group and guest
457             * permissions with new ones from the service context.
458             *
459             * @param  auditedModel the model associated with the resources
460             * @param  serviceContext the service context to be applied. Can set group
461             *         and guest permissions.
462             * @throws PortalException if a portal exception occurred
463             * @throws SystemException if a system exception occurred
464             */
465            @Override
466            public void updateModelResources(
467                            AuditedModel auditedModel, ServiceContext serviceContext)
468                    throws PortalException, SystemException {
469    
470                    updateResources(
471                            auditedModel.getCompanyId(), getGroupId(auditedModel),
472                            auditedModel.getModelClassName(),
473                            String.valueOf(auditedModel.getPrimaryKeyObj()),
474                            serviceContext.getGroupPermissions(),
475                            serviceContext.getGuestPermissions(),
476                            getPermissionedModel(auditedModel));
477            }
478    
479            /**
480             * Updates resources matching the group, name, and primary key at the
481             * individual scope, setting new group and guest permissions.
482             *
483             * @param  companyId the primary key of the portal instance
484             * @param  groupId the primary key of the group
485             * @param  name the resource's name, which should be a portlet ID if the
486             *         resource is a portlet or the resource's class name otherwise
487             * @param  primKey the primary key of the resource instance
488             * @param  groupPermissions the group permissions to be applied
489             * @param  guestPermissions the guest permissions to be applied
490             * @throws PortalException if a portal exception occurred
491             * @throws SystemException if a system exception occurred
492             */
493            @Override
494            public void updateResources(
495                            long companyId, long groupId, String name, long primKey,
496                            String[] groupPermissions, String[] guestPermissions)
497                    throws PortalException, SystemException {
498    
499                    updateResources(
500                            companyId, groupId, name, String.valueOf(primKey), groupPermissions,
501                            guestPermissions, null);
502            }
503    
504            /**
505             * Updates resources matching the group, name, and primary key string at the
506             * individual scope, setting new group and guest permissions.
507             *
508             * @param  companyId the primary key of the portal instance
509             * @param  groupId the primary key of the group
510             * @param  name the resource's name, which should be a portlet ID if the
511             *         resource is a portlet or the resource's class name otherwise
512             * @param  primKey the primary key string of the resource instance
513             * @param  groupPermissions the group permissions to be applied
514             * @param  guestPermissions the guest permissions to be applied
515             * @throws PortalException if a portal exception occurred
516             * @throws SystemException if a system exception occurred
517             */
518            @Override
519            public void updateResources(
520                            long companyId, long groupId, String name, String primKey,
521                            String[] groupPermissions, String[] guestPermissions)
522                    throws PortalException, SystemException {
523    
524                    updateResources(
525                            companyId, groupId, name, primKey, groupPermissions,
526                            guestPermissions, null);
527            }
528    
529            /**
530             * Updates resources matching the name, primary key string and scope,
531             * replacing the primary key of their resource permissions with the new
532             * primary key.
533             *
534             * @param  companyId the primary key of the portal instance
535             * @param  name the resource's name, which should be a portlet ID if the
536             *         resource is a portlet or the resource's class name otherwise
537             * @param  scope the scope of the resource. For more information see {@link
538             *         com.liferay.portal.model.ResourceConstants}.
539             * @param  primKey the primary key string of the resource instance
540             * @param  newPrimKey the new primary key string of the resource
541             * @throws SystemException if a system exception occurred
542             */
543            @Override
544            public void updateResources(
545                            long companyId, String name, int scope, String primKey,
546                            String newPrimKey)
547                    throws SystemException {
548    
549                    if (resourceBlockLocalService.isSupported(name)) {
550    
551                            // Assuming that this method is used when the primary key of an
552                            // existing record is changed, then nothing needs to happen here, as
553                            // it should still have its resource block ID.
554    
555                    }
556                    else {
557                            updateResourcePermissions(
558                                    companyId, name, scope, primKey, newPrimKey);
559                    }
560            }
561    
562            protected void addGroupPermissions(
563                            long companyId, long groupId, long userId, String name,
564                            Resource resource, boolean portletActions,
565                            PermissionedModel permissionedModel)
566                    throws PortalException, SystemException {
567    
568                    List<String> actions = null;
569    
570                    if (portletActions) {
571                            actions = ResourceActionsUtil.getPortletResourceGroupDefaultActions(
572                                    name);
573                    }
574                    else {
575                            actions = ResourceActionsUtil.getModelResourceGroupDefaultActions(
576                                    name);
577                    }
578    
579                    String[] actionIds = actions.toArray(new String[actions.size()]);
580    
581                    if (resourceBlockLocalService.isSupported(name)) {
582                            addGroupPermissionsBlocks(
583                                    groupId, resource, actions, permissionedModel);
584                    }
585                    else {
586                            addGroupPermissions(groupId, resource, actionIds);
587                    }
588            }
589    
590            protected void addGroupPermissions(
591                            long groupId, Resource resource, String[] actionIds)
592                    throws PortalException, SystemException {
593    
594                    Role role = roleLocalService.getDefaultGroupRole(groupId);
595    
596                    resourcePermissionLocalService.setResourcePermissions(
597                            resource.getCompanyId(), resource.getName(), resource.getScope(),
598                            resource.getPrimKey(), role.getRoleId(), actionIds);
599            }
600    
601            protected void addGroupPermissionsBlocks(
602                            long groupId, Resource resource, List<String> actionIds,
603                            PermissionedModel permissionedModel)
604                    throws PortalException, SystemException {
605    
606                    if (permissionedModel == null) {
607                            throw new IllegalArgumentException("Permissioned model is null");
608                    }
609    
610                    // Scope is assumed to always be individual
611    
612                    Role role = roleLocalService.getDefaultGroupRole(groupId);
613    
614                    resourceBlockLocalService.setIndividualScopePermissions(
615                            resource.getCompanyId(), groupId, resource.getName(),
616                            permissionedModel, role.getRoleId(), actionIds);
617            }
618    
619            protected void addGuestPermissions(
620                            long companyId, long groupId, long userId, String name,
621                            Resource resource, boolean portletActions,
622                            PermissionedModel permissionedModel)
623                    throws PortalException, SystemException {
624    
625                    List<String> actions = null;
626    
627                    if (portletActions) {
628                            actions = ResourceActionsUtil.getPortletResourceGuestDefaultActions(
629                                    name);
630                    }
631                    else {
632                            actions = ResourceActionsUtil.getModelResourceGuestDefaultActions(
633                                    name);
634                    }
635    
636                    String[] actionIds = actions.toArray(new String[actions.size()]);
637    
638                    if (resourceBlockLocalService.isSupported(name)) {
639                            addGuestPermissionsBlocks(
640                                    companyId, groupId, resource, actions, permissionedModel);
641                    }
642                    else {
643                            addGuestPermissions(companyId, resource, actionIds);
644                    }
645            }
646    
647            protected void addGuestPermissions(
648                            long companyId, Resource resource, String[] actionIds)
649                    throws PortalException, SystemException {
650    
651                    Role guestRole = roleLocalService.getRole(
652                            companyId, RoleConstants.GUEST);
653    
654                    resourcePermissionLocalService.setResourcePermissions(
655                            resource.getCompanyId(), resource.getName(), resource.getScope(),
656                            resource.getPrimKey(), guestRole.getRoleId(), actionIds);
657            }
658    
659            protected void addGuestPermissionsBlocks(
660                            long companyId, long groupId, Resource resource,
661                            List<String> actionIds, PermissionedModel permissionedModel)
662                    throws PortalException, SystemException {
663    
664                    if (permissionedModel == null) {
665                            throw new IllegalArgumentException("Permissioned model is null");
666                    }
667    
668                    // Scope is assumed to always be individual
669    
670                    Role guestRole = roleLocalService.getRole(
671                            companyId, RoleConstants.GUEST);
672    
673                    resourceBlockLocalService.setIndividualScopePermissions(
674                            resource.getCompanyId(), groupId, resource.getName(),
675                            permissionedModel, guestRole.getRoleId(), actionIds);
676            }
677    
678            protected void addModelResources(
679                            long companyId, long groupId, long userId, Resource resource,
680                            String[] groupPermissions, String[] guestPermissions,
681                            PermissionedModel permissionedModel)
682                    throws PortalException, SystemException {
683    
684                    // Owner permissions
685    
686                    Role ownerRole = roleLocalService.getRole(
687                            companyId, RoleConstants.OWNER);
688    
689                    List<String> ownerActionIds =
690                            ResourceActionsUtil.getModelResourceActions(resource.getName());
691    
692                    ownerActionIds = ListUtil.copy(ownerActionIds);
693    
694                    filterOwnerActions(resource.getName(), ownerActionIds);
695    
696                    String[] ownerPermissions = ownerActionIds.toArray(
697                            new String[ownerActionIds.size()]);
698    
699                    // Group permissions
700    
701                    Role defaultGroupRole = null;
702    
703                    if (groupId > 0) {
704                            defaultGroupRole = roleLocalService.getDefaultGroupRole(groupId);
705    
706                            if (groupPermissions == null) {
707                                    groupPermissions = new String[0];
708                            }
709                    }
710    
711                    // Guest permissions
712    
713                    Role guestRole = roleLocalService.getRole(
714                            companyId, RoleConstants.GUEST);
715    
716                    if (guestPermissions == null) {
717                            guestPermissions = new String[0];
718                    }
719    
720                    if (resourceBlockLocalService.isSupported(resource.getName())) {
721                            if (permissionedModel == null) {
722                                    throw new IllegalArgumentException(
723                                            "Permissioned model is null");
724                            }
725    
726                            // Scope is assumed to always be individual
727    
728                            resourceBlockLocalService.setIndividualScopePermissions(
729                                    resource.getCompanyId(), groupId, resource.getName(),
730                                    permissionedModel, ownerRole.getRoleId(), ownerActionIds);
731    
732                            if (groupId > 0) {
733                                    resourceBlockLocalService.setIndividualScopePermissions(
734                                            resource.getCompanyId(), groupId, resource.getName(),
735                                            permissionedModel, defaultGroupRole.getRoleId(),
736                                            Arrays.asList(groupPermissions));
737                            }
738    
739                            resourceBlockLocalService.setIndividualScopePermissions(
740                                    resource.getCompanyId(), groupId, resource.getName(),
741                                    permissionedModel, guestRole.getRoleId(),
742                                    Arrays.asList(guestPermissions));
743                    }
744                    else {
745                            resourcePermissionLocalService.setOwnerResourcePermissions(
746                                    resource.getCompanyId(), resource.getName(),
747                                    resource.getScope(), resource.getPrimKey(),
748                                    ownerRole.getRoleId(), userId, ownerPermissions);
749    
750                            if (groupId > 0) {
751                                    resourcePermissionLocalService.setResourcePermissions(
752                                            resource.getCompanyId(), resource.getName(),
753                                            resource.getScope(), resource.getPrimKey(),
754                                            defaultGroupRole.getRoleId(), groupPermissions);
755                            }
756    
757                            resourcePermissionLocalService.setResourcePermissions(
758                                    resource.getCompanyId(), resource.getName(),
759                                    resource.getScope(), resource.getPrimKey(),
760                                    guestRole.getRoleId(), guestPermissions);
761                    }
762            }
763    
764            protected void addModelResources(
765                            long companyId, long groupId, long userId, String name,
766                            String primKey, String[] groupPermissions,
767                            String[] guestPermissions, PermissionedModel permissionedModel)
768                    throws PortalException, SystemException {
769    
770                    if (!PermissionThreadLocal.isAddResource()) {
771                            return;
772                    }
773    
774                    validate(name, false);
775    
776                    if (primKey == null) {
777                            return;
778                    }
779    
780                    // Individual
781    
782                    Resource resource = getResource(
783                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
784    
785                    // Permissions
786    
787                    boolean flushEnabled = PermissionThreadLocal.isFlushEnabled();
788    
789                    PermissionThreadLocal.setIndexEnabled(false);
790    
791                    try {
792                            addModelResources(
793                                    companyId, groupId, userId, resource, groupPermissions,
794                                    guestPermissions, permissionedModel);
795                    }
796                    finally {
797                            PermissionThreadLocal.setIndexEnabled(flushEnabled);
798    
799                            PermissionCacheUtil.clearCache();
800    
801                            SearchEngineUtil.updatePermissionFields(name, primKey);
802                    }
803            }
804    
805            protected void addResources(
806                            long companyId, long groupId, long userId, Resource resource,
807                            boolean portletActions, PermissionedModel permissionedModel)
808                    throws PortalException, SystemException {
809    
810                    List<String> actionIds = null;
811    
812                    if (portletActions) {
813                            actionIds = ResourceActionsUtil.getPortletResourceActions(
814                                    resource.getName());
815                    }
816                    else {
817                            actionIds = ResourceActionsUtil.getModelResourceActions(
818                                    resource.getName());
819    
820                            actionIds = ListUtil.copy(actionIds);
821    
822                            filterOwnerActions(resource.getName(), actionIds);
823                    }
824    
825                    Role role = roleLocalService.getRole(companyId, RoleConstants.OWNER);
826    
827                    if (resourceBlockLocalService.isSupported(resource.getName())) {
828                            if (permissionedModel == null) {
829                                    throw new IllegalArgumentException(
830                                            "Permissioned model is null");
831                            }
832    
833                            // Scope is assumed to always be individual
834    
835                            resourceBlockLocalService.setIndividualScopePermissions(
836                                    resource.getCompanyId(), groupId, resource.getName(),
837                                    permissionedModel, role.getRoleId(), actionIds);
838                    }
839                    else {
840                            resourcePermissionLocalService.setOwnerResourcePermissions(
841                                    resource.getCompanyId(), resource.getName(),
842                                    resource.getScope(), resource.getPrimKey(), role.getRoleId(),
843                                    userId, actionIds.toArray(new String[actionIds.size()]));
844                    }
845            }
846    
847            protected void addResources(
848                            long companyId, long groupId, long userId, String name,
849                            String primKey, boolean portletActions, boolean addGroupPermissions,
850                            boolean addGuestPermissions, PermissionedModel permissionedModel)
851                    throws PortalException, SystemException {
852    
853                    if (!PermissionThreadLocal.isAddResource()) {
854                            return;
855                    }
856    
857                    validate(name, portletActions);
858    
859                    if (primKey == null) {
860                            return;
861                    }
862    
863                    // Individual
864    
865                    Resource resource = getResource(
866                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
867    
868                    // Permissions
869    
870                    boolean flushEnabled = PermissionThreadLocal.isFlushEnabled();
871    
872                    PermissionThreadLocal.setIndexEnabled(false);
873    
874                    List<ResourcePermission> resourcePermissions =
875                            resourcePermissionPersistence.findByC_N_S_P(
876                                    companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
877    
878                    ResourcePermissionsThreadLocal.setResourcePermissions(
879                            resourcePermissions);
880    
881                    try {
882                            addResources(
883                                    companyId, groupId, userId, resource, portletActions,
884                                    permissionedModel);
885    
886                            // Group permissions
887    
888                            if ((groupId > 0) && addGroupPermissions) {
889                                    addGroupPermissions(
890                                            companyId, groupId, userId, name, resource, portletActions,
891                                            permissionedModel);
892                            }
893    
894                            // Guest permissions
895    
896                            if (addGuestPermissions) {
897    
898                                    // Don't add guest permissions when you've already added group
899                                    // permissions and the given group is the guest group.
900    
901                                    addGuestPermissions(
902                                            companyId, groupId, userId, name, resource, portletActions,
903                                            permissionedModel);
904                            }
905                    }
906                    finally {
907                            ResourcePermissionsThreadLocal.setResourcePermissions(null);
908    
909                            PermissionThreadLocal.setIndexEnabled(flushEnabled);
910    
911                            PermissionCacheUtil.clearCache();
912    
913                            SearchEngineUtil.updatePermissionFields(name, primKey);
914                    }
915            }
916    
917            protected void deleteResource(
918                            long companyId, String name, int scope, String primKey,
919                            PermissionedModel permissionedModel)
920                    throws PortalException, SystemException {
921    
922                    if (resourceBlockLocalService.isSupported(name)) {
923                            if (permissionedModel == null) {
924                                    throw new IllegalArgumentException(
925                                            "Permissioned model is null");
926                            }
927    
928                            resourceBlockLocalService.releasePermissionedModelResourceBlock(
929                                    permissionedModel);
930    
931                            return;
932                    }
933    
934                    resourcePermissionLocalService.deleteResourcePermissions(
935                            companyId, name, scope, primKey);
936            }
937    
938            protected void filterOwnerActions(String name, List<String> actionIds) {
939                    List<String> defaultOwnerActions =
940                            ResourceActionsUtil.getModelResourceOwnerDefaultActions(name);
941    
942                    if (defaultOwnerActions.isEmpty()) {
943                            return;
944                    }
945    
946                    Iterator<String> itr = actionIds.iterator();
947    
948                    while (itr.hasNext()) {
949                            String actionId = itr.next();
950    
951                            if (!defaultOwnerActions.contains(actionId)) {
952                                    itr.remove();
953                            }
954                    }
955            }
956    
957            protected long getGroupId(AuditedModel auditedModel) {
958                    long groupId = 0;
959    
960                    if (auditedModel instanceof GroupedModel) {
961                            GroupedModel groupedModel = (GroupedModel)auditedModel;
962    
963                            groupId = BeanPropertiesUtil.getLongSilent(
964                                    groupedModel, "resourceGroupId", groupedModel.getGroupId());
965                    }
966    
967                    return groupId;
968            }
969    
970            protected PermissionedModel getPermissionedModel(
971                    AuditedModel auditedModel) {
972    
973                    PermissionedModel permissionedModel = null;
974    
975                    if (auditedModel instanceof PermissionedModel) {
976                            permissionedModel = (PermissionedModel)auditedModel;
977                    }
978    
979                    return permissionedModel;
980            }
981    
982            protected void logHasUserPermissions(
983                    long userId, long resourceId, String actionId, StopWatch stopWatch,
984                    int block) {
985    
986                    if (!_log.isDebugEnabled()) {
987                            return;
988                    }
989    
990                    _log.debug(
991                            "Checking user permissions block " + block + " for " + userId +
992                                    " " + resourceId + " " + actionId + " takes " +
993                                            stopWatch.getTime() + " ms");
994            }
995    
996            protected void updateResourceBlocks(
997                            long companyId, long groupId, Resource resource,
998                            String[] groupPermissions, String[] guestPermissions,
999                            PermissionedModel permissionedModel)
1000                    throws PortalException, SystemException {
1001    
1002                    if (permissionedModel == null) {
1003                            throw new IllegalArgumentException("Permissioned model is null");
1004                    }
1005    
1006                    // Scope is assumed to always be individual
1007    
1008                    Role role = roleLocalService.getDefaultGroupRole(groupId);
1009    
1010                    resourceBlockLocalService.setIndividualScopePermissions(
1011                            companyId, groupId, resource.getName(), permissionedModel,
1012                            role.getRoleId(), Arrays.asList(groupPermissions));
1013    
1014                    role = roleLocalService.getRole(companyId, RoleConstants.GUEST);
1015    
1016                    resourceBlockLocalService.setIndividualScopePermissions(
1017                            companyId, groupId, resource.getName(), permissionedModel,
1018                            role.getRoleId(), Arrays.asList(guestPermissions));
1019            }
1020    
1021            protected void updateResourcePermissions(
1022                            long companyId, long groupId, Resource resource,
1023                            String[] groupPermissions, String[] guestPermissions)
1024                    throws PortalException, SystemException {
1025    
1026                    Role role = roleLocalService.getDefaultGroupRole(groupId);
1027    
1028                    resourcePermissionLocalService.setResourcePermissions(
1029                            resource.getCompanyId(), resource.getName(), resource.getScope(),
1030                            resource.getPrimKey(), role.getRoleId(), groupPermissions);
1031    
1032                    role = roleLocalService.getRole(companyId, RoleConstants.GUEST);
1033    
1034                    resourcePermissionLocalService.setResourcePermissions(
1035                            resource.getCompanyId(), resource.getName(), resource.getScope(),
1036                            resource.getPrimKey(), role.getRoleId(), guestPermissions);
1037            }
1038    
1039            protected void updateResourcePermissions(
1040                            long companyId, String name, int scope, String primKey,
1041                            String newPrimKey)
1042                    throws SystemException {
1043    
1044                    List<ResourcePermission> resourcePermissions =
1045                            resourcePermissionLocalService.getResourcePermissions(
1046                                    companyId, name, scope, primKey);
1047    
1048                    for (ResourcePermission resourcePermission : resourcePermissions) {
1049                            resourcePermission.setPrimKey(newPrimKey);
1050    
1051                            resourcePermissionPersistence.update(resourcePermission);
1052                    }
1053            }
1054    
1055            protected void updateResources(
1056                            long companyId, long groupId, String name, String primKey,
1057                            String[] groupPermissions, String[] guestPermissions,
1058                            PermissionedModel permissionedModel)
1059                    throws PortalException, SystemException {
1060    
1061                    Resource resource = getResource(
1062                            companyId, name, ResourceConstants.SCOPE_INDIVIDUAL, primKey);
1063    
1064                    if (groupPermissions == null) {
1065                            groupPermissions = new String[0];
1066                    }
1067    
1068                    if (guestPermissions == null) {
1069                            guestPermissions = new String[0];
1070                    }
1071    
1072                    if (resourceBlockLocalService.isSupported(name)) {
1073                            updateResourceBlocks(
1074                                    companyId, groupId, resource, groupPermissions,
1075                                    guestPermissions, permissionedModel);
1076                    }
1077                    else {
1078                            updateResourcePermissions(
1079                                    companyId, groupId, resource, groupPermissions,
1080                                    guestPermissions);
1081                    }
1082            }
1083    
1084            protected void validate(String name, boolean portletActions)
1085                    throws PortalException {
1086    
1087                    List<String> actions = null;
1088    
1089                    if (portletActions) {
1090                            actions = ResourceActionsUtil.getPortletResourceActions(name);
1091                    }
1092                    else {
1093                            actions = ResourceActionsUtil.getModelResourceActions(name);
1094                    }
1095    
1096                    if (actions.size() == 0) {
1097                            throw new ResourceActionsException(
1098                                    "There are no actions associated with the resource " + name);
1099                    }
1100            }
1101    
1102            private static Log _log = LogFactoryUtil.getLog(
1103                    ResourceLocalServiceImpl.class);
1104    
1105    }