Creating a Custom Flex Filter in WebCenter Sites

image

WebCenter Sites Flex Filters provide a natural mechanism to do some post asset-save processing.  Out of the box, Oracle provides the following 4 Flex Filters: Doc-Type, Thumbnail Creator, Field Copier, and Document Transformation. Generally, these filters can be configured to take an input value from an asset and then do some processing on it resulting in something new. For example, a blob valued attribute named ImageFile can be used as input into the Thumbnail Creator to create a derived attribute containing a thumbnail rendition of the original image. You can find more information about these out of the box filters here. Although these filters will help in many cases, most WCS implementations however will have their own requirements and these OOTB filters will not suffice. Don't fret, as Oracle WebCenter Sites provides the ability for you to create your own filter to do whatever post asset-save processing you require.

There are several steps to creating your custom flex filter and we will cover them here with a real life code example.

The steps are as follows:

  1. Author a Java class to extend the AbstractFlexFilter class and implement 2 required methods
  2. Register the custom filter implementation with WebCenter Sites in the Filters table
  3. Create a Filter Asset by configuring inputs/outputs in the WCS UI
  4. Add the new Flex Filter Asset to a Content Definition
  5. Create an asset which utilizes a definition including the newly created Flex Filter

Author a class to extend the AbstractFlexFilter class

The class CircleMathFilter in the code below extends AbstractFlexFilter. The required method implementations include filterAsset and getLegalArguments. getLegalArguments must be implemented and is rather simple. It's just the Custom Flex Filter's list of inputs and output value descriptions. You can see that this method simply adds 3 textual descriptions to an FTValList. As you can tell by the name, filterAsset is responsible for the actual meat of the post processing. This is the method that will do the work of post processing and adding derived attributes to the Asset Instance. In this example the method reads in the value of the Asset's radius attribute and does some math finally adding the calculated area of a circle with radius r as well as the volume of a sphere with radius r. Yes this is a pretty boring example but you get the picture! Finally I have implemented the optional method getArgumentLegalValues which provides an html style dropdown list containing attributes within the system. If this method is left unimplemented all free-form text values are considered legal (it's not recommended to leave this open to all possible inputs)

You will need to add the following libraries to your java project to jar up the Custom Filter Implementation Class:

  1. assetframework.jar
  2. basic.jar
  3. commons-logging.jar (whatever version you have available)
  4. cs-cache.jar (whatever version you have available)
  5. cs.jar
  6. framework.jar
  7. gator.jar
  8. xcelerate.jar
package com.function1.filters;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import COM.FutureTense.Interfaces.FTValList;
import COM.FutureTense.Interfaces.IList;

import com.openmarket.assetframework.interfaces.AssetTypeManagerFactory;
import com.openmarket.assetframework.interfaces.IAssetManager;
import com.openmarket.assetframework.interfaces.IAssetTypeManager;
import com.openmarket.basic.interfaces.AssetException;
import com.openmarket.gator.flexfilters.AbstractFlexFilter;
import com.openmarket.gator.interfaces.IFilterEnvironment;
import com.openmarket.gator.interfaces.IFilterableAssetInstance;

public class CircleMathFilter extends AbstractFlexFilter
{
	  private static final String ARG_INPUT_RADIUS = "input attribute for radius";
	  private static final String ARG_CIRCLE_AREA = "output attribute for area of a circle";
	  private static final String ARG_SPHERE_VOLUME = "output attribute for volume of a sphere";
	  private Log log;
	  
	  public CircleMathFilter(FTValList filterArguments)
	  {
		super(filterArguments);
		log = LogFactory.getLog("com.function1.filters");
		log.debug("In Constructor of CircleMathFilter");
	  }
	  
	  @Override
	  public void filterAsset(IFilterEnvironment env, 
			  	  String filterIdentifier, 
			  	  FTValList filterArguments, 
			  	  IFilterableAssetInstance ifilterableassetinstance)
	  throws AssetException
	  {
	    try
	    {
	      
	      String sInputAttr = getAttrID(env, filterArguments, ARG_INPUT_RADIUS);
	      
	      double r = (Double.parseDouble(getStringValue(sInputAttr, ifilterableassetinstance)));
	      
	        if (getAttrID(env, filterArguments, ARG_CIRCLE_AREA) != null) {
	          ifilterableassetinstance.addDerivedDataValue(
	            filterIdentifier, 
	            getAttrID(env, filterArguments, ARG_CIRCLE_AREA), 
	            String.valueOf(Math.PI*r*r));
	        }
	        if (getAttrID(env, filterArguments, ARG_SPHERE_VOLUME) != null) {
	            ifilterableassetinstance.addDerivedDataValue(
	              filterIdentifier, 
	              getAttrID(env, filterArguments, ARG_SPHERE_VOLUME), 
	              String.valueOf((4.0/3.0)*Math.PI*r*r*r));
	         }
	    }catch(Exception e){
	    	//Error during filter
	    	log.debug(e);
	    }
	  }
	 
	  @Override
	  public FTValList getLegalArguments(IFilterEnvironment ifilterenvironment, 
			                     String filterIdentifier) throws AssetException
	  {
	    FTValList ftValList = new FTValList();
	    ftValList.setValString(ARG_INPUT_RADIUS, ARG_INPUT_RADIUS);
	    ftValList.setValString(ARG_CIRCLE_AREA, ARG_CIRCLE_AREA);
	    ftValList.setValString(ARG_SPHERE_VOLUME, ARG_SPHERE_VOLUME);
	    return ftValList;
	  }
	  
	@Override
	public String[] getArgumentLegalValues(IFilterEnvironment env, 
		   String filterIdentifier, String argumentName)throws AssetException
	{
	  if ((argumentName.equals(ARG_CIRCLE_AREA)) || 
	    (argumentName.equals(ARG_SPHERE_VOLUME)) ||
	    (argumentName.equals(ARG_INPUT_RADIUS)))
	  {
	    IAssetTypeManager atm = 
	      AssetTypeManagerFactory.getATM(env.getICS());
	    String attrType = env.getAttributeType();
	    IAssetManager am = atm.locateAssetManager(attrType);
	    IList tl = am.getAllAssetListSorted(null);
	    if (!tl.hasData()) {
	      return new String[0];
	    }
	    String[] rval = new String[tl.numRows()];
	    try
	    {
	      int i = 0;
	      while (tl.moveToRow(3, i + 1))
	      {
	        rval[i] = tl.getValue("name");
	        i++;
	      }
	    }
	    catch (NoSuchFieldException e)
	    {
	      throw new AssetException(e.getMessage());
	    }
	    return rval;
	  }
	  return null;
	}
	  
	private String getStringValue(String attribId, 
			  IFilterableAssetInstance instance) throws Exception
	{
	  IList listInput = instance.getAttribute(attribId);
	  if ((listInput != null) && (listInput.hasData()))
	  {
	    for (int i = 0; i < listInput.numColumns(); i++) {
	      log.debug(listInput.getColumnName(i));
	    }
	    return listInput.getValue("value");
	  }
	  log.debug(" The list is empty");
	  return null;
	}
}

 

Register the custom filter implementation with WebCenter Sites in the Filters table

Drop the jar file containing the Flex Filter implementation in to the WEB-INF/lib folder under your application server where WCS is installed AND Add an entry into the Filters table as depicted below.

 

Create a Filter Asset by configuring inputs/outputs in the WCS UI

 

Add the new Flex Asset to a Content Definition

 

Create an asset which utilizes a definition including the newly created Flex Filter

Finally to test out your new Flex Filter, simply create a new Content Asset in the Contributor UI. In this case we've created a Circle asset with a radius of 3. Upon Save the filter is invoked, some Math is done and the derived attributes are added. Viola!

 

Hopefully you found this end to end example of creating a WebCenter Sites Custom Flex Filter useful.

Until next time!

-Mitul

Subscribe to Our Newsletter

Stay In Touch