ddraper

Sub-Component Evaluations

Blog Post created by ddraper on Jul 29, 2011

Introduction

In the last blog post I showed how to extend a Component and hide its default Sub-Component through the use of an Evaluation. In this blog post I'm going delve further into Evaluations and introduce Evaluators demonstrating how they should be defined and how they can be used. These extensibility features are available in the latest Alfresco Community source code and will later appear in Alfresco Enterprise 4.0.

 

Tutorial

We're going to create a similar module to the last one - but instead of hiding the title bar on the user dashboard we're going to hide the title bar on the site dashboard, but only if the site has a specific name.

 

Update the 'blog-demo.xml' file and add the following module definition:

 

<module>
    <id>Blog Module (Conditionally Hide Title)</id>
    <components>
        <component>
            <scope>page</scope>
            <region-id>title</region-id>
            <source-id>site/{site}/dashboard</source-id>
            <sub-components>
                <sub-component id='default'>
                    <evaluations>
                        <evaluation id='HideIfBlogDemoSite'>
                            <evaluators>
                                <evaluator type='blog.demo.evaluator'></evaluator>
                            </evaluators>
                            <render>false</render>
                        </evaluation>
                    </evaluations>
                </sub-component>
            </sub-components>
        </component>
    </components>
</module>

 

Site dashboards are similar to user dashboards in that new configuration is created from a preset for each new site. This means we need to target our component using the {site} parameter (we could of course accomplish the same objective by specifying a specific site in the 'source-id' if we wanted, but this blog is about evaluators!)

 

The evaluator 'type' attribute must map to a Spring bean id defined in the application context. We therefore need to create this Evaluator and defined it as a Spring bean.

 

First create the following class:

 

package blog.demo;

import java.util.Map;
import org.springframework.extensions.surf.RequestContext;
import org.springframework.extensions.surf.extensibility.impl.DefaultSubComponentEvaluator;

public class BlogDemoEvaluator extends DefaultSubComponentEvaluator
{
    public boolean evaluate(RequestContext context, Map<String, String> params)
    {
        boolean result;
        String site = context.getUriTokens().get('site');
        if (site == null)
        {
            site = context.getParameter('site');
        }
        result = (site != null && site.equals('blogdemo'));
        return result;
    }
}

 

Then create a new file called 'spring-surf-extensibility-context.xml' and place it in a new 'org.springframework.extensions.surf' package in your JAR file (any file that fits the pattern 'org.springframework.extensions.surf.*-context' will get processed into the application context). This file should contain the following:

 

<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns='http://www.springframework.org/schema/beans'
              xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
              xsi:schemaLocation='http://www.springframework.org/schema/beans
                                  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd'>

    <bean id='blog.demo.evaluator' class='blog.demo.BlogDemoEvaluator'/>
</beans>

 

Build and deploy your JAR to Alfresco Share as described in the previous blog posts and then restart the web server.

 

Log on to Alfresco Share and create 2 new sites: 'BlogDemo' and 'SomeOtherSite' - as the new module has not yet been deployed you should see the title bar on both sites.

 

Screen shot of Blog Demo site with the title displayedScreen shot of Some Other Site With Title displayed

 

Now go to the Module Deployment WebScript (http://localhost:8080/share/page/modules/deploy - assuming you're using the defaults, adjust as necessary) and deploy the new module (see previous posts for detailed instructions on deploying modules).

 

When you refresh the dashboard pages for the 'BlogDemo' and 'SomeOtherSite' sites you should see that the title bar is displayed on the latter, but not the former.

 

Screen shot of Blog Demo Site with no title

 

Evaluators can also accept parameters in order that they can be easily re-used. Update the 'blog-demo.xml' file so that the evaluator is configured as follows:

 

<evaluator type='blog.demo.evaluator'>
<params>
        <site>someothersite</site>
    </params>
</evaluator>

 

...and modify the BlogDemoEvaluator class 'evaluate' method so that it looks like this:

 

public boolean evaluate(RequestContext context, Map<String, String> params)
{
    boolean result;
    String site = context.getUriTokens().get('site');
    if (site == null)
    {
        site = context.getParameter('site');
    }

String targetSite = params.get('site');
    result = (site != null && site.equals(targetSite));
    return result;
}

 

Re-build and re-deploy the JAR and then restart the web server and you should now see that the 'SomeOtherSite' title bar is hidden and the 'BlogDemo' title bar is displayed.

 

Screenshot of Some Other Site With No Title

 

When setting evaluator parameters the element name is the parameter key and the element value is the parameter value. All of the configured parameters will be passed as the 'params' argument when the 'evaluate' method is called. Parameters can also accept token substitution - so you could set a parameter of:

 

<site>{site}</site>

 

Which would make the evaluator pass regardless of whatever site dashboard is being displayed (although this would be a rather pointless exercise!).

 

Background Information

 

Evaluations

The purpose of an Evaluation is to dynamically alter a Sub-Component based on the current request. This is done by either changing the Web Script URL, updating the properties passed to the Web Script or preventing the Sub-Component from rendering entirely (which was demonstrated in the previous blog post).

 

A Sub-Component should be defined with a default Web Script URL and properties which will be used if no evaluations are configured or none of the evaluations that are configured evaluate successfully. If more than one evaluation is defined then each will be processed in turn and the first to evaluate successfully will have the opportunity to override the Web Script URL and/or properties or to hide the Sub-Component.

 

Evaluations are processed in the order in which they are defined in the configuration file. Evaluations defined in extension modules are processed before evaluations in the 'base' Component configuration. If more than one extension module defines evaluations for the same Sub-Component then they processed in the deployment order defined through the Module Deployment UI (/service/page/modules/deploy).

 

We've used evaluations internally to update add, hide and change various Sub-Components in the Document Library page depending upon what type of site is being viewed.

 

Evaluators

Every Sub-Component Evaluator must be configured in the Spring application context as a bean and must implement the org.springframework.extensions.surf.extensibility.SubComponentEvaluator interface. The interface defines a single method called evaluate that takes a org.springframework.extensions.surf.RequestContext and a parameter map as arguments.

 

A Sub-Component Evaluation will call the evaluate method on each Evaluator that is configured with and will only be considered to have evaluated successfully if every evaluate method returns true.

 

A number of SubComponentEvaluator instances are already configured in the Alfresco Share application context for testing various criteria (e.g. whether or not the requested page relates to a particular site) but it is a fairly simple exercise to create your own instances.

 

The RequestContext instance passed into the evaluate method will let you access pretty much everything you need to know about the request being evaluated (there's too much information to list, the best way to see everything available would be to attach a Java debugger to the web server and set a break point in an evaluator an inspect an instance).

 

 

 

 

 

<module>

 

<id>Blog Module (Conditionally Hide Title)</id>

 

<components>

 

<component>

 

<scope>page</scope>

 

<region-id>title</region-id>

 

<source-id>site/{site}/dashboard</source-id>

 

<sub-components>

 

<sub-component id='default'>

 

<evaluations>

 

<evaluation id='HideIfBlogDemoSite'>

 

<evaluators>

 

<evaluator type='blog.demo.evaluator'></evaluator>

 

</evaluators>

 

<render>false</render>

 

</evaluation>

 

</evaluations>

 

</sub-component>

 

</sub-components>

 

</component>

 

</components>

 

</module>

 

 

Outcomes