Plugin controller

To the plugin is associated a controller which constitutes the plugin core. Every user actions will be directed to this controller. The controller will perform the assigned treatments and will update, if necessary, the template enabling to fill the bookmarks suggested on the several render masks.

To implement a plugin controller, you just have to create a Java class which extends the class named BasePluginController. This class must be defined in the controller tag of the components’ definition XML file (plugin.xml).

The full name of the basic class is: com.axemble.vdoc.sdk.impl.base.BasePluginController.

Method of the basis class BasePluginController

This basic class gives access to the site module, the plugin information and the execution context.

public abstract class BasePluginController {
	// access to the site template
	final protected ISiteModule getSiteModule();

	// creation of a plugin request
	final protected IPluginRequest newPluginRequest( String path );

	// creation of elements assigned to the promotion
	final protected SEO newSEO();
	final protected Meta newMeta( String name, String content );

	// access to the plugin information
	final public IPlugin getPlugin();
	final public Map getPluginContext();
	final public IRootPluginConfiguration getRootConfiguration();
	final public String getPluginBaseUrl();

	// retrieve an object from the plugin request information
	protected abstract Object getObject( IPluginRequest pluginRequest ) throws Exception;

	// construction of a template from the retrieved object
	protected abstract void buildModel( Object object, IRenderModel model ) throws Exception;

	// construct the unique identifier from the plugin request
	protected abstract String getObjectUniqueIdentifier( IPluginRequest pluginRequest ) throws Exception;

	// retrieve the request from the manipulated object
	protected abstract IPluginRequest getPluginRequest( Object object ) throws Exception;

	// retrieve the request from the unique identifier
	protected abstract IPluginRequest getPluginRequest( String uniqueIdentifier ) throws Exception;

	// determine,depending on the internal data state, the render mask to use
	protected abstract String preparePage( IPluginRequest pluginRequest, IRenderModel renderModel ) throws Exception;
	final protected boolean pageExists( String pageId );

	// position a certain number of needed attributes 
	protected abstract void completePage( IVirtualPage virtualPage ) throws Exception;

	// performing the search
	protected abstract Collection search( String keywords, int maxResults ) throws Exception;
}

Plugin controller life cycle.

The plugin framework requests for the methods exposed by the plugin controller as soon as an URL corresponding to the following format is called:

<protocol>://<server>:<port>/<application>/easysite/<site>/<plugin-uri>

Example of URL meant to a plugin

Every URL elements placed behind plugin-uri are destined to the plugin controller. The following example shows how using the object IPluginRequest to retrieve the request URI and the setting assigned to the URL.

<protocol>://<server>:<port>/<application>/easysite/<site>/<plugin-uri>/shop/article/xyz?arg1=X

IPluginRequest pluginRequest…
pluginRequest.getRequestURI(); // Renvoie /shop/article/xyz
pluginRequest.getParameterValue("arg1"); // Renvoie la valeur "X"

When a URL is called and corresponds to the format enabling to reach a plugin, the plugin framework is called. This one analyzes the URL to define the concerned plugin instance. From the plugin instance found, the plugin framework retrieves the plugin controller assigned and requests the exposed methods.

The first called method is getObject() which lets translate a URL in a functional object.

Example: in the case of an e-catalog, the functional object would be a goods item.

Once the functional object retrieved, the framework calls the method buildModel(). This function enables to enter the values of the plugin bookmarks.

The plugin framework calls then the method preparePage() that will retrieve the page ID (render mask) to use to display information.

The method completePage() is called to process the information assigned to the statistics. For this, a structure is changed in argument: you can then specify some properties values of the manipulated functional object that you would make available for the statistics. Among these properties: the title,the author,the description and the summary are suggested. This structure is the interface IVirtualPage

Moreover, the plugin may be called on the method search() on the execution of search on the website. The call to the search() method will be effective only when the plugin will be added to the search domains of the “search element”.

At last, several other methods may be called by the plugin framework for converting:

  • from the object recover the object IPluginRequest;
  • from the unique identifier recover the object IPluginRequest;
  • from the IPluginRequest recover the unique identifier;
  • from the IPluginRequest recover the functional object;

Example of plugin controller implementation

The following example shows how to produce a plugin controller that permits to retrieve informations of the file system from a defined root folder.

This example instances several notions such as:

  • the scope: represented here by a sub-folder;
  • the position of the bookmark values;
  • the choice of the render mask;
  • the construction of the search template;
  • and the takedown of the plugin request.
public class FSPluginController extends BasePluginController {
	private static final long serialVersionUID = -6864905233548315067L;

	// root folder
	private static final String ROOT_DIRECTORY = "D:/tmp/dummies";

	// bookmarks names
	public final static String FIELD_NAME = "fldName";
	public final static String FIELD_CREATEDDATE = "fldCreatedDate";
	public final static String FIELD_SIZE = "fldSize";

	protected Object getObject( IPluginRequest pluginRequest ) throws Exception {
		// recovering the URI from the plugin request
		String path = pluginRequest.getRequestURI();

		// recovering the root folder
		File rootDirectory = new File( ROOT_DIRECTORY );

		// construction of the java.io.File object from parameters
		// - root folder ;
		// - plugin scope ;
		// - URI of plugin.
		return new File( rootDirectory.getPath() + File.separator + this.getPlugin().getScope().getValue( FSSectionProvider.FIELD_SCOPE ) + path );
	}
	
	protected IPluginRequest getPluginRequest( Object object ) throws Exception {
		// checking the validity of the object changed in argument
		if ( !( object instanceof File ) ) {
			throw new IllegalArgumentException( "The 'object' argument sould be a java.io.File type." );
		}

		// Construction of a request from the object changed in argument
		return newPluginRequest( "/" + ( (File)object ).getName() );
	}
	
	protected String getObjectUniqueIdentifier( IPluginRequest pluginRequest ) throws Exception {
		// construction of a unique string from the plugin request
		return pluginRequest.getRequestURL();
	}
	
	protected IPluginRequest getPluginRequest( String uniqueIdentifier ) throws Exception {
		// construction of a plugin request from a unique identifier.
		return newPluginRequest( uniqueIdentifier );
	}
	
	protected String preparePage( IPluginRequest pluginRequest, IRenderModel renderModel ) throws Exception {
		// position of the render mask.
		return ( "content" );
	}
	
	protected void buildModel( Object object, IRenderModel model ) throws Exception {
		// template update to fill-in the bookmarks.
		updateModel( object, model );
	}
	
	protected Collection search( String keywords, int maxResults ) throws Exception {
		ArrayList list = new ArrayList();

		File rootDirectory = new File( ROOT_DIRECTORY );

		// respect the search scope
		rootDirectory = new File( rootDirectory.getPath() + File.separator + this.getPlugin().getScope().getValue( FSSectionProvider.FIELD_SCOPE ) );

		File[] directories = rootDirectory.listFiles();

		int index = 0;
		for ( int indexDirectory = 0 ; indexDirectory < directories.length ; indexDirectory++ ) {
			File directory = directories[indexDirectory];
			if ( directory.isDirectory() ) {
				if ( !directory.getName().equals( getInnerPluginScope().getPropertyValue( FSSectionProvider.FIELD_SCOPE ) ) ) {
					continue;
				}

				File[] files = directory.listFiles();
				for ( int indexFile = 0 ; indexFile < files.length ; indexFile++ ) {
					File file = files[indexFile];
					if ( !file.getName().contains( keywords ) ) {
						continue;
					}

					// for each file found, construct an template element of search-type
					SearchResultModelItem searchResult = new SearchResultModelItem();

					// template update from the file.
					updateModel( file, searchResult );
					list.add( searchResult );

					index++;
					if ( index > maxResults ) {
						return list;
					}
				}
			} else {
				File file = directory;
				if ( !file.getName().contains( keywords ) ) {
					continue;
				}

				// construct a template element of search-type
				SearchResultModelItem searchResult = new SearchResultModelItem();

				// template update from the file.
				updateModel( file, searchResult );
				list.add( searchResult );

				index++;
				if ( index > maxResults ) {
					return list;
				}
			}
		}
		return list;
	}
	
	protected void completePage( IVirtualPage virtualPage ) throws Exception {
		IPluginRequest pluginRequest = virtualPage.getPluginRequest();
	
		File file = (File)this.getObject( pluginRequest );
	
		// position of some properties of the displayed page
		virtualPage.setLabel( file.getName() );
	}
	
	private void updateModel( Object object, IModel model ) throws Exception {
		if ( !( object instanceof File ) ) {
			throw new IllegalArgumentException( "The 'object' argument sould be a java.io.File type." );
		}

		File file = (File)object;

		IPluginRequest pluginRequest = getPluginRequest( file );

		// position of the clickable link
		model.setLinkUrl( pluginRequest.getRequestURL() );

		// position of the key
		model.setKey( pluginRequest.getRequestURL() );

		// position of some values corresponding to bookmarks
		model.setValue( FIELD_NAME, file.getName() );
		model.setValue( FIELD_CREATEDDATE, new Timestamp( file.lastModified() ) );
		model.setValue( FIELD_SIZE, new Long( file.length() ) );
	}
}