Can't reference a permission helper class

thumbnail
Carlos Durán, modified 3 Years ago. New Member Posts: 21 Join Date: 11/5/14 Recent Posts

Asked in Stackoverflow

I've created a permission helper class for my Question entity following the steps explained here:

package net.carlosduran.nomedes.web.internal.security.permission.resource;

import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.security.permission.PermissionChecker;
import com.liferay.portal.kernel.security.permission.resource.ModelResourcePermission;

import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import net.carlosduran.nomedes.db.model.Question;

@Component(immediate = true)
public class QuestionPermission {

    public static boolean contains(
            PermissionChecker permissionChecker, Question question, String actionId) throws PortalException {

        return _questionModelResourcePermission.contains(permissionChecker, question, actionId);
    }

    public static boolean contains(
            PermissionChecker permissionChecker, long entryId, String actionId) throws PortalException {

        return _questionModelResourcePermission.contains(permissionChecker, entryId, actionId);
    }

    @Reference(
            target = "(model.class.name=net.carlosduran.nomedes.db.model.Question)", 
            unbind = "-")
    protected void setEntryModelPermission(ModelResourcePermission<Question> modelResourcePermission) {

        _questionModelResourcePermission = modelResourcePermission;
    }

    private static ModelResourcePermission<Question> _questionModelResourcePermission;

}

In a MVCRenderCommand class I reference it this way:

@Reference
protected QuestionPermission _questionPermission;


If I include this reference, the render class doesn't work (I've tried it with different render classes).

In the moment I delete it, the render class works without a problem.The code for the service.xml file is this:

<?xml version="1.0"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 7.4.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_7_4_0.dtd">

<service-builder dependency-injector="ds" package-path="net.carlosduran.nomedes.db">
    <namespace>Nomedes</namespace>
    <entity name="Question" local-service="true" uuid="true">


        <!-- PK fields -->

        <column name="questionId" primary="true" type="long"></column>

        <!-- Group instance -->

        <column name="groupId" type="long"></column>

        <!-- Audit fields -->

        <column name="companyId" type="long"></column>
        <column name="userId" type="long"></column>
        <column name="userName" type="String"></column>
        <column name="createDate" type="Date"></column>
        <column name="modifiedDate" type="Date"></column>
        <column name="title" type="String"></column>
        <column name="summary" type="String"></column>
        <column name="description" type="String"></column>
        <column name="status" type="int" />
        <column name="statusByUserId" type="long" />
        <column name="statusByUserName" type="String" />
        <column name="statusDate" type="Date" />
        
        <finder name="GroupId" return-type="Collection">
            <finder-column name="groupId"></finder-column>
        </finder>
        <reference entity="Group" package-path="com.liferay.portal"></reference>
    </entity>
    <exceptions>
        <exception>QuestionValidation</exception>
    </exceptions>
</service-builder>

Can anyone tell me what's wrong? Thanks

thumbnail
Olaf Kock, modified 3 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts

As there is no interface, it looks like you're not assuming any alternative implementation of your helper class, so you might want to think about not making it a component at all.

This would mean that you'd need to provide the reference to the modelResourcePermission from outside, e.g. during construction, and make it a @Reference in the component where you instantiate the helper class.

That being said: If your RenderCommand does not start when the @Reference is in, that might be because of transitive missing dependencies. E.g. if your helper class misses dependencies (like: The ModelResourcePermission<Question>). You might want to validate if your component comes up at all, and gets initialized with this ModelResourcePermission. I've not used parameterized generic classes as references, assuming that they'd need to be deployed with exactly that class as their service.

thumbnail
Carlos Durán, modified 3 Years ago. New Member Posts: 21 Join Date: 11/5/14 Recent Posts

The problem is not the helper class exactly. It's cause by this code fragment:

@Reference(
	target = "(model.class.name=net.carlosduran.nomedes.db.model.Question)", 
	unbind = "-")
protected void setEntryModelPermission(ModelResourcePermission<Question> modelResourcePermission) {

	_questionModelResourcePermission = modelResourcePermission;
}

If I comment it, render works, but permissions don't.

thumbnail
Olaf Kock, modified 3 Years ago. Liferay Legend Posts: 6441 Join Date: 9/23/08 Recent Posts

That's what I meant: I've not seen generic/parameterized classes (in this case ModelResourcePermission<Question>) as service references. That's not to say it doesn't work, but I'd expect the parameter's type to match with the service declaration in the component that you implement. It might​​​​​​​ be enough to pass ModelResourcePermission, as you filter by the reference's target already.

Anyway - as mentioned on stackoverflow: Please observe the crossposting netiquette (linked there) and link all of your crossposts. Otherwise you'd generate duplicate work, because in other locations nobody knows what effort has been made elsewhere.

thumbnail
Carlos Durán, modified 3 Years ago. New Member Posts: 21 Join Date: 11/5/14 Recent Posts

The problem was that I miss to add a service attribute to the component annotation in the QuestionPermission class.

service = QuestionPermission.class

After adding it, it works fine. It would look like this:

@Component(
	immediate = true,
	service = QuestionPermission.class
)