1. Rest Overview
2. Restful Web Service
2.1 HTTP Method
2.2 Formats
2.3 Rest configuration
2.4 Create a rest service
REST-style architectures consist of clients and servers. Clients initiate requests to servers; servers process requests and return appropriate responses. Requests and responses are built around the transfer of "representations" of "resources". A resource can be essentially any coherent and meaningful concept that may be addressed. A representation of a resource is typically a document that captures the current or intended state of a resource.
At any particular time, a client can either be in transition between application states or "at rest". A client in a rest state is able to interact with its user, but creates no load and consumes no per-client storage on the set of servers or on the network.
The client begins sending requests when it is ready to make the transition to a new state. While one or more requests are outstanding, the client is considered to be in transition. The representation of each application state contains links that may be used next time the client chooses to initiate a new state transition.
REST was initially described in the context of HTTP, but is not limited to that protocol. RESTful architectures can be based on other Application Layer protocols if they already provide a rich and uniform vocabulary for applications based on the transfer of meaningful representational state. RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on top of it.
here is the convention we should follow:
| Method | Definition |
|---|---|
| GET | get a Resource. It should never modify a state |
| POST | Create a Resource (or anything that don't fit elsewhere) |
| PUT | Update a Resource |
| DELETE | Delete a Resource |
We should support this format for all our APIs
listener
The default format is JSON.
The format of the response can be specified by a parameter in the request: "format" Specify the format requested.
First we have to register rest service class to the configuration file in the package named conf.portal
<configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd" xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"> <component> <type>org.exoplatform.services.ecm.publication.REST.presentation.document.publication.PublicationGetDocumentRESTService</type> </component> </configuration>
We start to create GetEditedDocumentRESTService that implements from the ResourceContainer interface.
@Path("/presentation/document/edit/")
public class GetEditedDocumentRESTService implements ResourceContainer {
@Path("/{repository}/")
@GET
public Response getLastEditedDoc(@PathParam("repository") String repository,
@QueryParam("showItems") String showItems) throws Exception {
........
}
}
| Parameters | Definition |
|---|---|
| @Path("/presentation/document/edit/") | Specified the URI path that a resource or class method will serve requests for. |
| @PathParam("repository") | Binds the value repository of a URI parameter or a path segment containing the template parameter to a resource method parameter, resource class field, or resource class bean property. |
| @QueryParam("showItems") | Binds the value showItems of a HTTP query parameter to a resource method parameter, resource class field, or resource class bean property. |
This article's goal to describe how to create an sample of ui extension.
1. Overview
2. How to add your own tab in ECM Administration
2.1 Add your own UIAction
2.2 Add your action listener
2.3 Deploy your application
2.4 Define label for your actions and register resource bundle
2.5 Run your own ui extension sample
Since DMS 2.5, it is possible to extend the File Explorer and the ECM Administration with the UI Extension Framework. Indeed, you can add your own action buttons to the File Explorer and/or add your own managers to the ECM Administration.
Create a pom.xml from the following content
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.exoplatform.ecms</groupId>
<artifactId>exo-ecms-examples-uiextension-framework</artifactId>
<version>2.2.0-SNAPSHOT</version>
</parent>
<artifactId>exo-ecms-examples-uiextension-framework-manage-wcm-cache</artifactId>
<name>eXo WCM Cache Examples </name>
<description>eXo WCM Cache Examples </description>
<dependencies>
<dependency>
<groupId>org.exoplatform.kernel</groupId>
<artifactId>exo.kernel.container</artifactId>
<version>2.2.5-GA</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.commons</groupId>
<artifactId>exo.platform.commons.webui.ext</artifactId>
<version>1.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.ecms</groupId>
<artifactId>exo-ecms-core-webui</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.exoplatform.ecms</groupId>
<artifactId>exo-ecms-core-webui-administration</artifactId>
<version>2.1.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.jar</include>
<include>**/*.pom</include>
<include>**/*.conf</include>
<include>**/*.gtmpl</include>
<include>**/*.gif</include>
<include>**/*.jpg</include>
<include>**/*.png</include>
</includes>
</resource>
</resources>
</build>
</project>Create the directories src/main/java and start launching mvn eclipse:eclipse* You can then, launch your eclipse and import this new project
Create a new class called org.exoplatform.wcm.component.cache.UIWCMCacheComponent that extends org.exoplatform.ecm.webui.component.admin.manager.UIAbstractManagerComponent
The webui framework allows you to be notified when a given action has been triggered, you just need to call your own action listener as follow (ACTIONNAME)ActionListener Example : You create your own action listener name CacheView, so your action listener then will be named as CacheViewActionListener
first thing we will do, add a static inner class called CacheViewActionListener that extends org.exoplatform.ecm.webui.component.admin.listener.UIECMAdminControlPanelActionListener
See below the expected code
public class CacheViewComponent extends UIAbstractManagerComponent {
public static class CacheViewActionListener extends UIECMAdminControlPanelActionListener<UIWCMCacheComponent> {
public void processEvent(Event<UIWCMCacheComponent> event) throws Exception {UIECMAdminPortlet portlet = event.getSource().getAncestorOfType(UIECMAdminPortlet.class);
UIECMAdminWorkingArea uiWorkingArea = portlet.getChild(UIECMAdminWorkingArea.class);
uiWorkingArea.setChild(UIWCMCachePanel.class) ;
event.getRequestContext().addUIComponentToUpdateByAjax(uiWorkingArea);
}
}Create the directories src/main/java and launch mvn eclipse:eclipse* You can then, launch your eclipse and import this new project
Create a new configuration file conf/portal/configuration.xml to register your action with the service org.exoplatform.webui.ext.UIExtensionManager, as below:
<?xml version="1.0" encoding="ISO-8859-1"?>
<configuration
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd"
xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">
<external-component-plugins>
<target-component>org.exoplatform.webui.ext.UIExtensionManager</target-component>
<component-plugin>
<name>Add.Actions</name>
<set-method>registerUIExtensionPlugin</set-method>
<type>org.exoplatform.webui.ext.UIExtensionPlugin</type>
<init-params>
<object-param>
<name>CacheView</name>
<object type="org.exoplatform.webui.ext.UIExtension">
<field name="type"><string>org.exoplatform.ecm.dms.UIECMAdminControlPanel</string></field>
<field name="name"><string>CacheView</string></field>
<field name="category"><string>GlobalAdministration</string></field>
<field name="component"><string>org.exoplatform.wcm.component.cache.UIWCMCacheComponent</string></field>
</object>
</object-param>
<object-param>
<name>UIWCMCacheManager</name>
<object type="org.exoplatform.webui.ext.UIExtension">
<field name="type"><string>org.exoplatform.ecm.dms.UIECMAdminControlPanel</string></field>
<field name="name"><string>UIWCMCacheManager</string></field>
<field name="category"><string>GlobalAdministration</string></field>
<field name="component"><string>org.exoplatform.wcm.manager.cache.UIWCMCacheManagerComponent</string></field>
</object>
</object-param>
</init-params>
</component-plugin>
</external-component-plugins>
</configuration>
Launch mvn clean install and copy the file target/exo-ecms-examples-webui-2.1.0-SNAPSHOT.jar into (TOMCATHOME)/lib
All resources can be located in the src/main/resource package because we will seperate the resources(.xml, images, conf file) and the code. This is very useful in hierarchical structure.
Create ExamplePortleten.xml with following content and add it to src/main/resource package
<?xml version="1.0" encoding="UTF-8"?>
<bundle>
<!--
################################################################################
# org.exoplatform.wcm.component.cache.UIWCMCacheForm #
################################################################################
-->
<UIWCMCacheForm>
<action>
<Cancel>Cancel</Cancel>
<Save>Save</Save>
<Clear>Clear the cache</Clear>
</action>
<label>
<maxsize>Max size :</maxsize>
<livetime>Live time in sec :</livetime>
<isCacheEnable>Cache enabled(should always be on production enviroment)</isCacheEnable>
<hit>Hit count :</hit>
<currentSize>Current size</currentSize>
<miss>Miss count :</miss>
</label>
</UIWCMCacheForm>
<!--
################################################################################
# org.exoplatform.wcm.manager.cache.UIWCMCacheManagerForm #
################################################################################
-->
<UIWCMCacheManagerForm>
<action>
<Cancel>Cancel</Cancel>
<Save>Save</Save>
<Clear>Clear the cache</Clear>
</action>
<label>
<cacheModify>Cache to modify :</cacheModify>
<maxsize>Max size :</maxsize>
<livetime>Live time in sec :</livetime>
<isCacheEnable>Cache enabled(should always be on production enviroment)</isCacheEnable>
<hit>Hit count :</hit>
<currentSize>Current size</currentSize>
<miss>Miss count :</miss>
</label>
</UIWCMCacheManagerForm>
<UIECMAdminControlPanel>
<tab>
<label>
<GlobalAdministration>Global Administration</GlobalAdministration>
</label>
</tab>
<label>
<UIWCMCache>WCM Cache</UIWCMCache>
<UIWCMCachePanel>WCM Cache Administration</UIWCMCachePanel>
<UIWCMCacheManager>Managing Caches</UIWCMCacheManager>
<UIWCMCacheManagerPanel>WCM Cache Management</UIWCMCacheManagerPanel>
</label>
</UIECMAdminControlPanel>
</bundle>We have to add the following content to configuration.xml to register the resource bundle.
By being added this configuration, the resource bundle has been completely separated our resource bundle from the original system, this is so clearly useful, we got an independent plugin.
<external-component-plugins>
<!-- The full qualified name of the ResourceBundleService -->
<target-component>org.exoplatform.services.resources.ResourceBundleService</target-component>
<component-plugin>
<!-- The name of the plugin -->
<name>ResourceBundle Plugin</name>
<!-- The name of the method to call on the ResourceBundleService in order to register the ResourceBundles -->
<set-method>addResourceBundle</set-method>
<!-- The full qualified name of the BaseResourceBundlePlugin -->
<type>org.exoplatform.services.resources.impl.BaseResourceBundlePlugin</type>
<init-params>
<values-param>
<name>init.resources</name>
<description>Store the following resources into the db for the first launch </description>
<value>locale.portlet.cache.ExamplePortlet</value>
</values-param>
<values-param>
<name>portal.resource.names</name>
<description>The properties files of the portal , those file will be merged
into one ResoruceBundle properties </description>
<value>locale.portlet.cache.ExamplePortlet</value>
</values-param>
</init-params>
</component-plugin>
</external-component-plugins>