Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Anchor
top
top

In This Section

Table of Contents
maxLevel2

...

The following figure illustrates the basic steps that are required to make a plugin extendable (consumer) and to create an extension for it (provider):

 

 

 

 

 

Back to Top

 

...

Extension Consumers

Extension consumers are plugin components that consume the extension services of plugins that provide these services. A plugin component becomes a consumer by adding the interface classname Extensible to its interface classnames. The framework recognizes this interface and will register the component in the framework as a plugin component extension consumer.

A consumer can consume the extension services of more than one component and the developer of the plugin component that consumes the service decides how and in what order these services are consumed. The developer therefore has access to the set of extensions that are registered at the consumer component by the getExtensions() method.

Registering a Plugin Consumer Component

By registering the Extensible interface, the component becomes a plugin component consumer and will be ready for consuming extension services in the service framework.

...

Code Block
themeEclipse
String[] componentInterfaces = { Component.class.getName(),
ElementComponent.class.getName(), Extensible.class.getName() };
elementDefinition.setInterfaceClassNames(componentInterfaces);

Registering Consumer Extensions

To define which services a plugin component will consume, you must register the extension services. This can be done by registering the exact interfaces the component will consume:

...

Code Block
themeEclipse
// Extensions
ComponentExtensionImpl viewExtensionPoints = new ComponentExtensionImpl();
viewExtension.setServiceName(ViewExtension.class.getName());
elementDefinition.setExtensions(new ComponentExtensionImpl[] { viewExtension } );

 

Back to Top

 

...

Extension Providers

Extension providers are plugin components that provide extension services for other plugins. A plugin component becomes an extension provider by adding the interface classname ExtensionProvider to its interface classnames. The framework recognizes this interface and will register the component in the framework as a plugin component extension provider.

Register a Plugin Provider Component

By registering the ExtensionProviderinterface, the component becomes a plugin component provider and will be ready to provide extension services to the service framework:

...

  • Always returns the exact same object (singleton instance). This object is cached within the service component
  • Create a new instance of the requested object for each request to the extension service.

Registering Provider Extensions

To define exactly which services a plugin component will provide, the registration of these extensions services is needed. This can be done by registering the exact interfaces the component will provide in the plugin Activator:

...

The extension service interfaces must be registered at the consumer and provider component. The following figure shows the workflow of an example of an extension for the GX Books Example plugin. The extension (provider) extends the findBooks() method of the consumer further by searching web sites and other databases for books when a user executes a search:

 

 

 

Alternate View Extension Example

To extend a plugin with an alternate view, the framework interface ViewExtension is provided by the framework which can be registered by a plugin extension consumer and provider and can be implemented by the provider extension. The alternate view extension is a subclass of the view extension. Registration of the ViewExtension interface in the Activator looks like:

...

Code Block
themeEclipse
public class ExtensionProviderFactory extends SimpleServiceComponent implements ExtensionProvider {

	public Object getServiceInstance(Class interfaceClass) {
		return new AlternateViewProvider(this);
    }
    public String getTargetComponentId() {
		return "com.libris4you.books.bookreviewselement";
    }
}

AlternateViewProvider

The extension should return an implementation of the ViewExtension interface as a result of the call to the getServiceInstance()method. The component that is extended and consumes the view extension will delegate the MVC calls to the controller that is returned by the ViewExtension.getDelegatedController()method:

...

Code Block
themeEclipse
public class AlternateViewProvider implements ViewExtension {
	private Component component;

	AlternateViewProvider(Component component) {
		this.component = component;
    }

	public DelegatedController getDelegatedController() {
		ComponentController controller = new AlternateViewController();
		controller.setComponent(component);
		return controller;
    }
}

AlternateViewController

The controller for the alternate view has access to the parent controllers through getParentand can be used to manipulate the behavior of this parent controller. To override the complete default view of an extension consumer the createEditViews()method should be implemented and its implementation should add a default edit view to the parent controller in order to override the default view of this controller and its component:

...

Code Block
themeEclipse
public class AlternateViewController extends ElementComponentController {
	@Override
	public Object formBackingObject(HttpServletRequest request) 
			throws ServletException {
		super.formBackingObject(request);
		Object fbo = getParentController().formBackingObject(request);
		setDelegatedControllers(fbo, request);
		return fbo;
  }

  @Override
	protected void createEditViews() {
 		super.createEditViews();
		ComponentControllercontroller = (ComponentController) getParentController();
	controller.addEditView("editBookReviewsElement.jspf", "", this.getComponent());
	}
}

Implement Alternate View (JSP)

To provide an alternate view for a consumer plugin component a JSP file must be provided in the src/main/resources/editpresentationdirectory of the plugin. This JSP view must be added as a view in the createEditViews()method of the controller as can be seen in the above example.

To add the view to the controller the method addEditView(String jspLocation, String viewname, Component component) must be used. The third component argument needs to tell the parent controller where to the find the exact location of the JSP which is determined by ID of the component bundle that provides the JSP.

 

Back to Top

 

...

Publishing and Subscribing to Events

The publish and subscribe pattern is a pattern in which publishers broadcast an event which is received by the subscribers. A subscriber subscribes itself to particular types of events such that it only receives events in which it has interest.

...

Each of the above object types implements an event interface: PageEvent, PageModelEvent, PageVersionEvent, MediaItemEvent, MediaItemVersionEvent, ElementEvent, and WebsiteEvent. These implementations are used to publish RETRIEVE, COPY, DELETE, MOVE, CREATE, and UPDATE events. The scope of these events is the content type’s class, for example Page.class. In addition, HistoryEvent is used to publish the CHANGED event, and PublicationStatusEvent is published to indicate that the publication status of a content item has changed. The scope of these events depends on the content type, and that the latter does not have an event action.

XperienCentral nl.gx.webmanager.services.event Package

The nl.gx.webmanager.services.event package contains the following interfaces:

...

In addition to the standard actions (create, copy, update, move, retrieve, and delete), you can also create custom actions that perform other functions. These custom actions can also be published and subscribed to. If you want to publish custom events, you will need to implement a custom event and publish this event using the Event Manager service.

Writing an Event Handler

A custom event handler should implement the nl.gx.webmanager.services.event.EventHandler interface. This interface contains only one method, which is onEvent. The onEvent method takes the event that triggered the handler as input argument. The event contains information about the action that triggered the event, the component that did throw the event and the event type (PRE or POST). What to do with the event is up to the implementation of the event handler.

...

Code Block
themeEclipse
public class CustomMediaItemEventHandler implements EventHandler {
	public CustomMediaItemEventHandler() {
	}

	public void onEvent(Event event) {
		if (event instanceof MediaItemEvent) {
			MediaItemEvent mediaItemEvent = (MediaItemEvent) event;

			// Get the media item version
			MediaItemVersion mediaItemVersion = null;
			if (mediaItemEvent.getMediaItem().getCurrent() != null) {
				mediaItemVersion = mediaItemEvent.getMediaItem().getCurrent();
			} else {
				mediaItemVersion = mediaItemEvent.getMediaItem().getPlanned();
			}

			// Check if this really is our custom article 
			// media item version
			if (!CustomArticleMediaItemVersion.class.isAssignableFrom(mediaItemVersion.getClass())) {
				return;
			}

			// Handle the event
			if (event.getEventAction().equals(EntityEvent. CREATE)) {
				handleCreateEvent(mediaItemEvent, mediaItemVersion);
			}
			if (event.getEventAction().equals(EntityEvent.DELETE)){
				handleDeleteEvent(mediaItemEvent, mediaItemVersion);
			}
		}
	}    

	/**
	* Does something when an article of our custom type is created.
	*/
	private void handleCreateEvent(MediaItemEvent mediaItemEvent, MediaItemVersion mediaItemVersion) {
		...
	}

	/**
	* Does something when an article of our custom type is deleted.
	*/
	private void handleDeleteEvent(MediaItemEvent mediaItemEvent, MediaItemVersion mediaItemVersion) {
		...
	}
}

Subscribing to Events

To subscribe the event handler to particular events, the handler must be subscribed by the publisher (the Event Manager service). The EventManagerService interface contains the following methods:

...

Code Block
themeEclipse
public class CustomMediaItemComponent extends SimpleMediaItemComponent {
	private CustomEventHandler myEventHandler = null;

	public void onStart() {
	// Initialize new event handler
	myEventHandler = new CustomEventHandler();
    
	// Subscribe to media item post event 
	myEventManagerService.subscribe(myEventHandler, Event.Type.POST, MediaItem.class);        
	}
	public void onStop() {
    // Unsubscribe to media item post event
	myEventHandler.unsubscribe(myEventHandler, Event.Type.POST, MediaItem.class);
    }
}

Publishing Events

To publish specific events, use the Event Manager service. This service contains a method publish(Event) which should be used to publish your event in XperienCentral.

...