user1134181
user1134181

Reputation:

How to write a custom evaluator for Share in Alfresco 4.2.2?

For example, I need the evaluator, which I could use to show the action in Share. If the current user is the author of the document, then I'll show the action.

The project structure is presented below (alf221-action-share):

C:\EclipseWorkspaces\alfresco\alf221-action-share>tree /F
...
├───build
│   ├───classes
│   │   └───com
│   │       └───firm
│   │           └───alfresco
│   │               └───alf221
│   │                   └───evaluators
│   │                           UsersCompareEvaluator.class
│   │
│   ├───dist
│   └───lib
│           alf221-action-share.jar
│
└───src
    └───main
        ├───com
        │   └───firm
        │       └───alfresco
        │           └───alf221
        │               └───evaluators
        │                       UsersCompareEvaluator.java
        │
        └───resources
            ├───alfresco
            │   └───web-extension
            │       │   alf221-action-share-slingshot-application-context.x
            │       │
            │       └───messages
            │               alf221-action-share.properties
            │
            └───META-INF
                │   share-config-custom.xml
                │
                └───resources
                    └───components
                        └───documentlibrary
                            └───actions
                                    firm-exclude-participant-16.png

In the UsersCompareEvaluator class, I'm just trying to determine the current user:

package com.firm.alfresco.alf221.evaluators;

import org.alfresco.web.ui.common.component.evaluator.BaseEvaluator;
import org.springframework.extensions.surf.RequestContext;
import org.springframework.extensions.surf.support.ThreadLocalRequestContext;
import org.springframework.extensions.webscripts.connector.User;


public class UsersCompareEvaluator extends BaseEvaluator {

    @Override
    public boolean evaluate() {
        RequestContext requestContext = ThreadLocalRequestContext.getRequestContext();
        User user = requestContext.getUser();

        System.out.println("CURRENT USER IS ... " + user.getName());

        return true;
    }
}

My alf221-action-share-slingshot-application-context.xml:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 
'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>

   <bean id="com.firm.alf221-action-share.resources" 
       class="org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent">
      <property name="resourceBundles">
         <list>
            <value>alfresco.web-extension.messages.alf221-action-share</value>
         </list>
      </property>
   </bean>

    <bean id="evaluator.doclib.action.isDocumentOnApproval" 
          parent="evaluator.doclib.metadata.value">
        <property name="accessor" value="node.properties.idocs:documentStatus" />
        <property name="comparator">
            <bean class="org.alfresco.web.evaluator.StringEqualsComparator">
                <property name="value" value="onApproval" />
            </bean>
        </property>
    </bean>

    <bean id="evaluator.doclib.action.isCurrentUserAuthor" 
          class="com.firm.alfresco.alf221.evaluators.UsersCompareEvaluator" />

</beans>

My share-config-custom.xml:

<alfresco-config>

    <config evaluator="string-compare" condition="DocLibActions">
        <actions>
            <action id="firm-exclude-participant" 
                    type="javascript" 
                    label="actions.firm.exclude-participant" 
                    icon="document-change-type">

                <param name="function">onActionTkbFormDialog</param>
                <permissions>
                    <permission allow="true">Write</permission>
                </permissions>
                <param name="itemKind">action</param>
                <param name="itemId">exclude-participant</param>
                <param name="mode">create</param>
                <param name="successMessage">message.exclude-participant.success</param>
                <param name="failureMessage">message.exclude-participant.failure</param>
                <evaluator>evaluator.doclib.action.isDocumentOnApproval</evaluator>
                <evaluator>evaluator.doclib.action.isCurrentUserAuthor</evaluator>
            </action>
        </actions>

        <actionGroups>
            <actionGroup id="document-details">
                <action index="500" id="firm-exclude-participant" />
            </actionGroup>
        </actionGroups>

    </config>

</alfresco-config>

The jar-file I placed in the following path: /opt/tomcat7/webapps/share/WEB-INF/lib

Everything works perfectly, except the my custom evaluator. In this configuration, Share does not work... In the logs I see the following:

[aleksey@alfresco01 tomcat7]$ sudo vi share.log
...
Caused by: java.lang.NoClassDefFoundError: org/alfresco/web/ui/common/component/evaluator/BaseEvaluator
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2928)
        at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1174)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1669)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
        at org.springframework.util.ClassUtils.forName(ClassUtils.java:257)
        at org.springframework.beans.factory.support.AbstractBeanDefinition.resolveBeanClass(AbstractBeanDefinition.java:408)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doResolveBeanClass(AbstractBeanFactory.java:1271)
        at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1242)
        ... 22 more
Caused by: java.lang.ClassNotFoundException: org.alfresco.web.ui.common.component.evaluator.BaseEvaluator
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1702)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
        ... 33 more

If in the evaluator I implement the ActionEvaliator interface and try to identify the current user as follows...

public class UsersCompareEvaluator implements ActionEvaluator  {

    private Map<Object, Object> registeredBeans = 
        Context.getProcessEngineConfiguration().getBeans();
    private ServiceRegistry registry = 
        (ServiceRegistry)registeredBeans.get(ActivitiConstants.SERVICE_REGISTRY_BEAN_KEY);
    private AuthenticationService authenticationService = 
        registry.getAuthenticationService();  

    @Override
    public boolean evaluate(Node node) {
        System.out.println("CURRENT USER IS ... " + 
            authenticationService.getCurrentUserName());

        return true;
    }

    @Override
    public boolean evaluate(Object object) {
        if(object instanceof Node) {
            return evaluate((Node)object);
        } 

        return false;
    }
}

...and put my jar file in the same place (/opt/tomcat7/webapps/share/WEB-INF/lib) - then I get the following exception:

...
Caused by: java.lang.ClassNotFoundException: org.alfresco.web.action.ActionEvaluator
...

I tried to package my custom evaluator into the separate jar and place it here: /opt/tomcat7/webapps/alfresco/WEB-INF/lib. But how can I refer to this evaluator from the Share?

For example, I have a separate project (alf221-custom-evaluator):

C:\EclipseWorkspaces\alfresco\alf221-custom-evaluator>tree /F
...
└───src
    └───main
        ├───com
        │   └───firm
        │       └───alfresco
        │           └───alf221
        │               └───evaluators
        │                       UsersCompareEvaluator.java
        │
        └───resources
            └───alfresco
                └───web-extension
                        alf221-custom-evaluator-slingshot-application-context.xml

In alf221-custom-evaluator-slingshot-application-context.xml I specify the following:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 
'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
    <bean id="evaluator.doclib.action.runtime.user" 
          class="com.firm.alfresco.alf221.evaluators.UsersCompareEvaluator" />
</beans>                                    

Then, in the share-config-custom.xml that is placed in alf221-action-share, I specify the following:

...
<evaluator>evaluator.doclib.action.runtime.user</evaluator>
...

In this case I get the following warning message:

...
2018-01-03 12:10:59,956  WARN  [web.scripts.ActionEvaluatorHelper] [http-bio-8888-exec-8] Evaluator 'evaluator.doclib.action.runtime.user' not found.
...

And my custom evaluator does not work.

How to write a custom evaluator for Share in Alfresco 4.2.2?

I would be very grateful for the information. Thanks to all.

Upvotes: 4

Views: 808

Answers (1)

user1134181
user1134181

Reputation:

It seems that I have found the solution... The thing is that I used the BaseEvaluator class from the Alfresco library. The same name class is represented in the Share library.

I.e. there are two jar files:

In alfresco-share-4.2.2.5.jar#uzip/org/alfresco/web/evaluator I found all that I needed.

This solution now works:

package com.firm.alfresco.alf221.evaluators;

// was import org.alfresco.web.ui.common.component.evaluator.BaseEvaluator;
import org.alfresco.web.evaluator.BaseEvaluator;
import org.json.simple.JSONObject;
import org.springframework.extensions.surf.RequestContext;
import org.springframework.extensions.surf.support.ThreadLocalRequestContext;
import org.springframework.extensions.webscripts.connector.User;


public class UsersCompareEvaluator extends BaseEvaluator  {

    @Override
    public boolean evaluate(JSONObject jSONObject) {
        RequestContext requestContext = ThreadLocalRequestContext.getRequestContext();
        User user = requestContext.getUser();

        System.out.println("CURRENT USER IS ... " + user.getName());

        return true;
    }
}

Now I can see in the catalina.out that:

CURRENT USER IS ... admin

All other necessary information can be obtained from JSONObject (the current user can also be obtained by using the getUserId() method inherited from BaseEvaluator class.).

Upvotes: 4

Related Questions