You are looking at documentation for an older release. Not what you want? See the current release documentation.
UIExtensionManager
This class is used to manage all extensions available in the system. The target is to create the ability to add a new extension dynamically without changing anything in the source code. UIExtensionManager is implemented by UIExtensionManagerImpl.
<component>
<key>org.exoplatform.webui.ext.UIExtensionManager</key>
<type>org.exoplatform.webui.ext.impl.UIExtensionManagerImpl</type>
</component>
UIExtensionPlugin
This class allows you to define new extensions in the configuration file dynamically (for example: configuration.xml
). As you want
UIExtensionManager
to manage every extension, you have to plug
UIExtensionPlugin
into it:
<external-component-plugins>
<target-component>org.exoplatform.webui.ext.UIExtensionManager</target-component>
<component-plugin>
<name>add.action</name>
<set-method>registerUIExtensionPlugin</set-method>
<type>org.exoplatform.webui.ext.UIExtensionPlugin</type>
...
</component-plugin>
</external-component-plugins>
Definition of UI Extensions
Each UI Extension is defined as an object param:
...
<object-param>
<name>EditPage</name>
<object type="org.exoplatform.webui.ext.UIExtension">
<field name="type"><string>org.exoplatform.wiki.UIPageToolBar</string></field>
<field name="rank"><int>300</int></field>
<field name="name"><string>EditPage</string></field>
<field name="component"><string>org.exoplatform.wiki.webui.control.action.EditPageActionComponent</string></field>
</object>
</object-param>
...
In which:
Name: the extension's name.
Object Type: point to the UI Extension lib class.
Type: the "parent" UI component which is extended by your UI Extension.
Rank: used to sort by Collection of UI Extension.
Component: point to the UI Extension definition class.
UI Extension Definition class
This class is used to define filters, actions and templates of each UI Extension:
@ComponentConfig(
events =
{(listeners = EditPageActionComponent.EditPageActionListener.class);})
public class EditPageActionComponent extends UIComponent {
private static final List<UIExtensionFilter> FILTERS = Arrays.asList(new UIExtensionFilter[] { new IsViewModeFilter() });
@UIExtensionFilters
public List<UIExtensionFilter> getFilters() {
return FILTERS;
}
public static class EditPageActionListener extends UIPageToolBarActionListener<EditPageActionComponent> {
@Override
protected void processEvent(Event<EditPageActionComponent> event) throws Exception {
...
super.processEvent(event);
}
}
...
Parent UI Component
This is what your UI Extension will be added to (in this example, the parent UI Componet is UIPageToolBar). All extensions of this component are got by UIExtensionManager.
UIExtensionManager manager = getApplicationComponent(UIExtensionManager.class);
List<UIExtension> extensions = manager.getUIExtensions(EXTENSION_TYPE);
public List<ActionComponent> getActions() throws Exception {
....
List<UIExtension> extensions = manager.getUIExtensions(EXTENSION_TYPE);
if (extensions != null) {
for (UIExtension extension : extensions) {
UIComponent component = manager.addUIExtension(extension, context, this);
// Child UI Component has been made by UI Extension
// It's available to use now
...
}
}
return activeActions;
}
Each UI Extension has a list of filters depending on variety of purposes. It indicates which UI Extension is accepted and which is denied. You are free to create your own filter extended from UIExtensionAbstractFilter. Internal filters are part of the business logic of your component. For example, if your component is only dedicated to articles, you will add an internal filter to your component that will check the type of the current document.
public class IsViewModeFilter extends UIExtensionAbstractFilter {
public IsViewModeFilter(String messageKey) {
super(messageKey, UIExtensionFilterType.MANDATORY);
}
@Override
public boolean accept(Map<String, Object> context) throws Exception {
UIWikiPortlet wikiPortlet = (UIWikiPortlet) context.get(UIWikiPortlet.class.getName());
return(wikiPortlet.getWikiMode() == WikiMode.VIEW||wikiPortlet.getWikiMode() == WikiMode.VIEWREVISION);
}
@Override
public void onDeny(Map<String, Object> context) throws Exception {
// TODO Auto-generated method stub
}
Your filter will define which type of filter it belongs to (in UIExtensionFilterType). There are 4 types:
Types | Description |
---|---|
MANDATORY | Checks if the action related to the extension can be launched and if the component related to the extension can be added to the WebUI tree. This filter is required to launch the action and add the component related to the extension to the WebUI tree. If it succeeds, you need to check the other filters. If it fails, you need to stop. |
REQUISITE | Checks if the action related to the extension can be launched. This filter is required to launch the action to the WebUI tree. If it succeeds, you need to check the other filters. If it fails, you need to stop. |
REQUIRED | Checks if the action related to the extension can be launched and can be used for adding warnings. This filter is required to launch the action. If it succeeds or fails, you need to check the other filters. |
OPTIONAL | Checks if the action related to the extension can be launched and can be used for the auditing purpose. This filter is not required to launch the action. If it succeeds or fails, you need to check the other filters. |
There are 2 conditions for filtering: Accept and onDeny.
Accept: Describe the "Accept" condition, and how a UI Extension can accept by a context.
onDeny: What you will do after the filter denies a UI Extension by a specific context (generating a message for pop-up form, for example).
You have known how and where the filter is put in a UI Component, but when it is gonna fire?
It falls into 2 situations: when you get it and when it is action fire. Thus, you should ensure that your UI Extension is always trapped by its filter.
External filters are mainly used to add new filters that are not related to the business logic to your component. A good example is the UserACLFilter which allows you to filter by access permissions.
For example, to make the EditPage action only be used by manager:/platform/administrators, do as follows:
Create an external filter:
public class UserACLFilter implements UIExtensionFilter {
/**
* The list of all access permissions allowed
*/
protected List<String> permissions;
/**
* {@inheritDoc}
*/
public boolean accept(Map<String, Object> context) throws Exception {
if (permissions == null || permissions.isEmpty()) {
return true;
}
ExoContainer container = ExoContainerContext.getCurrentContainer();
UserACL userACL = (UserACL) container.getComponentInstance(UserACL.class);
for (int i = 0, length = permissions.size(); i < length; i++) {
String permission = permissions.get(i);
if (userACL.hasPermission(permission)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*/
public UIExtensionFilterType getType() {
return UIExtensionFilterType.MANDATORY;
}
/**
* {@inheritDoc}
*/
public void onDeny(Map<String, Object> context) throws Exception {}
}
Add the external filter to a UI Extension in the configuration.xml
file:
<object-param>
<name>EditPage</name>
<object type="org.exoplatform.webui.ext.UIExtension">
<field name="type"> <string>org.exoplatform.wiki.UIPageToolBar</string> </field>
<field name="rank"><int>300</int></field>
<field name="name"> <string>EditPage</string> </field>
<field name="component"><string>org.exoplatform.wiki.webui.control.action.EditPageActionComponent</string> </field>
<!-- The external filters -->
<field name="extendedFilters">
<collection type="java.util.ArrayList">
<value>
<object type="org.exoplatform.webui.ext.filter.impl.UserACLFilter">
<field name="permissions">
<collection type="java.util.ArrayList">
<value>
<string>manager:/platform/administrators</string>
</value>
</collection>
</field>
</object>
</value>
</collection>
</field>
</object>
</object-param>