Author: sergiykarpenko
Date: 2010-08-17 10:29:17 -0400 (Tue, 17 Aug 2010)
New Revision: 2923
Removed:
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr/architecture.xml
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml
Modified:
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws.xml
Log:
EXOJCR-892: few chapters removed removed
Deleted: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr/architecture.xml
===================================================================
---
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr/architecture.xml 2010-08-17
14:20:04 UTC (rev 2922)
+++
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr/architecture.xml 2010-08-17
14:29:17 UTC (rev 2923)
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter id="architecture" xreflabel="architectural">
- <?dbhtml filename="ch-architecture.html"?>
- <chapterinfo>
- <keywordset>
- <keyword>JCR</keyword>
- <keyword>eXoJCR</keyword>
- <keyword>etc</keyword>
- </keywordset>
- </chapterinfo>
- <title>Basic concepts of eXoJCR</title>
-</chapter>
Modified: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
===================================================================
--- jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-17 14:20:04
UTC (rev 2922)
+++ jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml 2010-08-17 14:29:17
UTC (rev 2923)
@@ -9,9 +9,6 @@
<xi:include href="jcr/intro.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
- <xi:include href="jcr/architecture.xml"
-
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
<!-- common configs -->
<xi:include href="jcr/configuration.xml"
@@ -55,14 +52,14 @@
<!-- statistics configs -->
<xi:include href="jcr/statistics.xml"
-
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
<!-- data container configs -->
<xi:include href="jcr/data-container.xml"
-
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
<xi:include href="jcr/data-container-howto.xml"
-
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+
xmlns:xi="http://www.w3.org/2001/XInclude" />
+
</part>
Deleted: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml
===================================================================
---
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml 2010-08-17
14:20:04 UTC (rev 2922)
+++
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-framework.xml 2010-08-17
14:29:17 UTC (rev 2923)
@@ -1,472 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter>
- <?dbhtml filename="ch-ws.html"?>
-
- <title>REST Framework</title>
-
- <important>
- <para>This describes REST framework before version exo-ws-2.0</para>
- </important>
-
- <section>
- <title>Requirements</title>
-
- <para>The purpose of eXo REST framework is to make eXo services (i.e. the
- components deployed inside eXo Container) simple and transparently
- accessible via HTTP in RESTful manner. In other words those services
- should be viewed as a set of REST Resources - endpoints of the HTTP
- request-response chain, we call those services ResourceContainers.</para>
-
- <para>image: Simplified working model</para>
-
- <para>Taking into account HTTP/REST constraints, it is considered that
- Resources (naturally mapped as Java methods) contained in
- ResourceContainer conform with the following conditions:</para>
-
- <itemizedlist>
- <listitem>
- <para>they are uniquely identifiable in the same way as it is
- specified for HTTP i.e. using URI</para>
- </listitem>
-
- <listitem>
- <para>they can accept data from an HTTP request using all possible
- mechanisms, i.e. as a part of an URL, as URI parameters, as HTTP
- headers and body</para>
- </listitem>
-
- <listitem>
- <para>they can return data to an HTTP response using all possible
- mechanisms, i.e. as HTTP status, headers and body</para>
- </listitem>
- </itemizedlist>
-
- <para>From the implementation point of view:</para>
-
- <itemizedlist>
- <listitem>
- <para>the framework should be as much JSR-311 compatible as possible
- for the time the Specification is in draft and fully compatible after
- the standard's release</para>
- </listitem>
-
- <listitem>
- <para>the ResourceContainer components should be deployable and
- accessible in the same way as an ordinary service</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Implementation</title>
-
- <para>In our REST architecture implementation, an HTTPServlet is the
- front-end for the REST engine. In this RESTful framework, endpoints for
- HTTP request are represented by java classes (ResourceContainers). All
- ResourceContainers are run as components of an ExoContainer, so they are
- configured within the same configuration file.</para>
-
- <para>ResourceBinder and ResourceDispatcher are two other important
- components of the REST engine. ResourceBinder deals with binding and
- unbinding ResourceContainer. ResourceDispatcher dispatches REST requests
- to ResourceContainer. ResourceBinder and ResourceDispatcher are also
- components of the ExoContainer</para>
-
- <section>
- <title>ResourceContainer</title>
-
- <para>A ResourceContainer is an annotated java class. Annotations must
- at least describe URLs and HTTP methods to be served by this container.
- But they may also describe other parameters, like produced content type
- or transformers. Transformers are special Java classes, used to
- serialize and deserialize Java objects.</para>
-
- <para>A very simple ResourceContainer may look like this:</para>
-
- <programlisting>@HTTPMethod("GET")
-@URITemplate("/test1/{param}/test2/")
-public Response method1(@URIParam("param") String param) {
-//...
-//...
- Response resp = Response.Builder.ok().build();
- return resp;
-}</programlisting>
-
- <para>The ResourceContainer described above is very simple, it can serve
- the GET HTTP method for the relative URL /test1/{param}/test2/ where
- {param} can be any string value. Additionally, {param} can be used as a
- method parameter of the container by annotating it as :
- @URIParam("param") String param. For example, in URL /test1/myID/test2
- the method parameter "param" has the value
"myID".</para>
-
- <para>@URITemplate may be used for annotating classes or methods. If the
- TYPE scope annotation is for example @URITemplate("/testservices/") and
- a METHOD scope annotation is @URITemplate("/service1/") then that method
- can be called with the path /testservices/service1/. All
- ResourceContainer methods return Response objects. A Response includes
- HTTP status, an entity (the requested resource), HTTP headers and
- OutputEntityTransformer.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-scheme.png" />
- </imageobject>
- </mediaobject>
-
- <para>A client sends a request, after some operations, the HTTP request
- is parsed into three parts: the HTTP request stream, which consists of
- the body of the request, HTTP headers and query parameters. Then
- ResourceDispatcher gets this request. During the start of ExoContainers
- ResourceBinder collects all available ResourceContainers and after the
- start passes the list of ResourceContainers to the ResourceDispatcher.
- When ResourceDispatcher gets the request from a client it tries to
- search for a valid ResourceContainer. For this search ResourceDispatcher
- uses @HTTPMethod, @URITemplate and @ProducedMimeType annotations. The
- last one is not always necessary, if it is not specified this is set in
- / (all mime types). When ResourceDispatcher found the "right"
- ResourceContainer it tries to call a method with some parameters.
- ResourceDispatcher will send only parameters which ResourceContainer
- requests. In the code example above the parameter is a part of the
- requested URL between "/test1/" and "/test2/".
ResourceContainer methods
- can consist only of some well-defined parameters. See the next
- rules:</para>
-
- <itemizedlist>
- <listitem>
- <para>Only one parameter of a method can be not annotated. This
- parameter represents the body of the HTTP request.</para>
- </listitem>
-
- <listitem>
- <para>All other parameters should be of java.lang.String types or
- must have a constructor with the java.lang.String parameter and must
- have annotation.</para>
- </listitem>
-
- <listitem>
- <para>If the parameter which represents the HTTP request body is
- present, then in the annotation @InputTransformer a java class must
- be defined that can build the requested parameter from
- java.io.InputStream. About transformation see below. After request
- processing ResourceContainer creates Request. Request is a special
- Java object which consists of HTTP status, a response header, an
- entity, a transformer. The entity is a representation of the
- requested resource. If Response has an entity it also must have
- OutputEntityTransformer. OutputEntityTransformer can be set in a few
- different ways.</para>
- </listitem>
- </itemizedlist>
- </section>
-
- <section>
- <title>Response</title>
-
- <para>Response is created by Builder. Builder is an inner static Java
- class within Response. Builder has some preset ways to build Response,
- for example (see code example above). The method ok() creates Builder
- with status 200 (OK HTTP status) and ok() returns again a Builder
- object. In this way a developer can again call other Builder methods.
- For example:</para>
-
- <programlisting>//...
-Document doc = ....
-Response response = Response.Builder.ok().entity(doc,
"text/xml").transformer(new
XMLOutputTransformer()).build();</programlisting>
-
- <para>In the code example above Response has HTTP status 200, an XML
- document like entity, a Content-Type header "text/xml" and
- OutputEntityTransformer of type XMLOutputTransformer. The method build()
- should be called at the end of process. In the same way a developer can
- build some other prepared Responses, like CREATED, NO CONTENT,
- FORBIDDEN, INTERNAL ERROR and other. In this example we set
- OutputEntityTransformer directly. Another mechanism to do this is the
- same like in the case with InputEntityTransformer.</para>
-
- <programlisting>//...
-@HTTPMethod("GET")
-@URITemplate("/test/resource1/")
-(a)InputTransformer(XMLInputTransformer.class)
-(a)OutputTransformer(XMLOutputTransformer.class)
-public Response method1(Document inputDoc) {
-//...
- Document doc = ....
- Response response = Response.Builder.ok(doc, "text/xml").build();
- return response;
-}</programlisting>
-
- <para>InputEntityTransformer is described in the annotation to the
- method "method1". OutputEntityTransformer is described in the annotation
- to the method "method1".</para>
- </section>
-
- <section>
- <title>Transformer</title>
-
- <para>All transformers can be created by EntityTransformerFactory.
- Transformers can be divided in two groups. Transformers from the first
- one extend the abstract class InputEntityTransformer.
- InputEntityTransformer implements the interface
- GenericInputEntityTransformer, and GenericInputEntityTransformer extends
- the interface GenericEntityTransformer. This architecture gives the
- possibility to use one class EntityTransformerFactory for creating both
- types of transformers (input and output). At first we will speak about
- InputEntityTransformer.</para>
-
- <para><command>InputEntityTransformer</command></para>
-
- <para>All classes which extend the abstract class InputEntitytransformer
- must override the method ObjectreadFrom(InputStream entityDataStream).
- This method must return an object with the same type as
- ResourceContainer requires in method parameters (one not annotated
- parameter). This mechanism works in the following way. For example, a
- class which extends InputEntityTransformer will be called
- SimpleInputTransformer. So, SimpleInputTransformer must have a simple
- constructor (without any parameters). SimpleInputTransformer also has
- two methods void setType(Class entityType) and Class getType(). Those
- methods are described in InputEntityTransformer. And, as we said above,
- SimpleInputTransformer must override the abstract method Object
- readFrom(InputStream entityDataStream). So, a developer needs to create
- a class which can build a Java Object from InputStream and then create
- annotation to ResourceContainer or some method in ResourceContainer.
- This annotation must define the type of InputEntityTransformer. Here is
- the code of the annotation InputTransformer.</para>
-
- <programlisting>//...
-@Retention(RUNTIME)
-@Target({TYPE, METHOD})
-public @interface InputTransformer {
- Class<? extends InputEntityTransformer> value();
-}</programlisting>
-
- <para>Then ResourceDispatcher gets InputTransformer from the factory
- during runtime then builds an Object from stream and adds it to the
- parameter array. See the code below.</para>
-
- <programlisting>//...
- InputEntityTransformer transformer = (InputEntityTransformer)
factory_.newTransformer(resource.getInputTransformerType());
- transformer.setType(methodParameters[i]);
- params[i] = transformer.readFrom(request.getEntityStream());
-//...
- Response response = (Response)
resource.getServer().invoke(resource.getResourceContainer(),
params);</programlisting>
-
- <para>A developer can find some prepared transformers in the package
- "org.exoplatform.services.rest.transformer".</para>
-
- <para><command>OutputEntityTransformer</command></para>
-
- <para>OutputEntityTransformer can be used to serialize the Object which
- represents the requested resource to OutputStream.
- OutputEntityTransformer, in future we will call it
- SimpleOutputTransformer, can be defined in a few ways.</para>
-
- <para>Now some more words about transformation. The RESTful framework
- has two multi-purpose input/output transformers. One of them is
- JAXB(Input/Output)Transformer, and another one is
- Serializable(Input/Output)Transformer. The first one uses JAXB API for
- serializing and deserializing an object. Serializable
- (Input/Output)Transformer uses the own methods of an entity for
- serialization and deserialization. Here is an example:</para>
-
- <programlisting>/...
-public class SimpleSerializableEntity implements SerializableEntity {
-
- String data;
-
- public SimpleSerializableEntity() {
- }
-
- public void readObject(InputStream in) throws IOException {
- StringBuffer sb = new StringBuffer();
- int rd = -1;
- while((rd = in.read()) != -1)
- sb.append((char)rd);
- data = sb.toString();
- }
-
- public void writeObject(OutputStream out) throws IOException {
- out.write(data.getBytes());
- }
-}</programlisting>
-
- <para>SerializableInputTransformer will try to use the method void
- readObject(InputStream in) and SerializableOutputTransformer will try to
- use the method void writeObject(OutputStream in).</para>
- </section>
-
- <section>
- <title>Binding and unbinding components (ResourceContainers)</title>
-
- <para>ResourceBinder takes care of binding and unbinding components
- which represent ResourceContainer. All ResourceContainers must be
- defined as ExoContainer components in configuration files, for
- example:</para>
-
- <programlisting><component>
-
<type>org.exoplatform.services.rest.samples.RESTSampleService</type>
-</component></programlisting>
-
- <para>ResourceBinder is an ExoContainer component and implements the
- interface org.picocontainer.Startable (see the picocontainer
- documentation). So at the start of ExoContainer ResourceBinder collects
- all available ResourceContainers. ResourceBinder makes validation for
- all ResourceContainers. At least each ResourceContainer must have the
- @HTTPMethod annotation and @URITemplate annotation. Other annotations
- are not obligatory. It's not allowed to have few ResourceContainers or
- methods with the same @HTTPMethod and @URITemplate annotation value. For
- example, if one container/method has the following code:</para>
-
- <programlisting>public class SimpleResourceContainer implements
ResourceContainer {
- @HTTPMethod("GET")
- @URITemplate("/services/{id}/service1/")
- @InputTransformer(StringInputTransformer.class)
- @OutputTransformer(StringOutputTransformer.class)
- public Response method1(String data, @URIParam("id") String param) {
- // ...
- }
-}</programlisting>
-
- <para>than another component with @HTTPMethod("GET") and
- @URITemplate("/services/service1/{id}/") can't be bound. And now
we'll
- try to explain this situation. On the one hand URITemplate is defined by
- value /services/{id}/service1/, instead of {id} there can be any other
- string value, so the combination /services/service1/service1/ is
- possible and valid. On the other hand another URITemplate
- /services/service1/{id}/ can have the string service1 instead of {id},
- so for this resource the combination /services/service1/service1/ is
- possible and valid. And now we have two resources with the same
- URITemplate and the same HTTPMethod. This situation is not obligatory,
- we can't say what method we must call! In this case ResourceBinder
- generates InvalidResourceDescriptorException. Binder also checks the
- method parameters. In parameters only one parameter without annotation
- and of free type is allowed. All other parameters must have String type
- (or have a constructor with String) and be annotated. In other cases
- InvalidResourceDescriptorException* is generated. If all components have
- the "right" @HTTPMethod and @URITemplate annotations they should be
- bound without any problems. ResourceDispather gets a collection of
- ResourceContainers during the start and everything is ready to serve a
- request.</para>
-
- <para>Note: within the scope of one component (one class) validation for
- URI templates is not implemented, so a developer must take care of
- @URITemplate and @HTTPMethod. Both of them must not be the same for
- different methods. Except if @QueryTemplate or/and @ProducedMimeTypes
- annotation is used.</para>
- </section>
-
- <section>
- <title>ResourceDispatcher</title>
-
- <para>Now let's talk about the features of ResourceDispatcher.
- ResourceDispatcher is the main part of the RESTful engine. Above we said
- some words about transformation and the role of ResourceDispatcher in
- this process. Now we are ready to talk about annotated method
- parameters. In one of the code examples above you could see the next
- construction</para>
-
- <programlisting>public Response method1(String data,
@URIParam("id") String param) {</programlisting>
-
- <para>The method method1 is described with two parameters. The first
- parameter String data is built from the entity body (InputStream). The
- second one - String param is annotated by a special type Annotation.
- This Annotation has the following code:</para>
-
- <programlisting>@Target(value={PARAMETER})
-@Retention(RUNTIME)
-public @interface URIParam {
- String value();
-}</programlisting>
-
- <para>How does it work? After having found the right method
- ResourceDispatcher gets the list of method parameters and starts
- handling them. Dispatcher tries to find the not annotated parameter
- (this entity body) and addresses InputEntityTransformer in order to
- build the required Object from InputStream. When dispatcher finds an
- annotated parameter it checks the type of annotation. It is possible to
- have four types of annotation: @URIParam, @HeaderParam, @QueryParam and
- @ContextParameter. If dispatcher has found the annotation
- @URIParam("id") then it takes the parameter with the key "id"
from
- ResourceDescription and adds it into the parameter array. The same
- situation is with header, context and query parameters. So within the
- method a developer gets only the necessary parameters from header, query
- and uri. Some more information about @ContextParameters.
- @ContextParameters can be set in the configuration file of a
- component:</para>
-
- <programlisting><component>
-<type>org.exoplatform.services.rest.ResourceDispatcher</type>
- <init-params>
- <properties-param>
- <name>context-params</name>
- <property name="test" value="test_1"/>
- </properties-param>
- </init-params>
-</component></programlisting>
-
- <para>In this case any service can use this parameter, for
- example:</para>
-
- <programlisting>...method(@ContextParam("test") String p) {
- System.out.println(p);
-}</programlisting>
-
- <para>After its execution you should see "test_1" in
console.</para>
-
- <para>And in each service the next context parameters can be used. The
- name of these parameters are described in ResourceDispatcher:</para>
-
- <programlisting>public static final String CONTEXT_PARAM_HOST =
"host";
-public static final String CONTEXT_PARAM_BASE_URI = "baseURI";
-public static final String CONTEXT_PARAM_REL_URI = "relURI";
-public static final String CONTEXT_PARAM_ABSLOCATION =
"absLocation";</programlisting>
-
- <para>After that dispatcher finishes collecting parameters that the
- method requires, invokes this method and passes the result to the client
- as it is described above.</para>
-
- <para>This part of code can explain how this mechanism works:</para>
-
- <programlisting>//...
- for (int i = 0; i < methodParametersAnnotations.length; i++) {
- if (methodParametersAnnotations[i] == null) {
- InputEntityTransformer transformer = (InputEntityTransformer) factory
- .newTransformer(resource.getInputTransformerType());
- transformer.setType(methodParameters[i]);
- params[i] = transformer.readFrom(request.getEntityStream());
- } else {
- Constructor<?> constructor =
methodParameters[i].getConstructor(String.class);
- String constructorParam = null;
- Annotation a = methodParametersAnnotations[i];
- if (a.annotationType().isAssignableFrom(URIParam.class)) {
- URIParam u = (URIParam) a;
- constructorParam =
request.getResourceIdentifier().getParameters().get(u.value());
- } else if (a.annotationType().isAssignableFrom(HeaderParam.class)) {
- HeaderParam h = (HeaderParam) a;
- constructorParam = request.getHeaderParams().get(h.value());
- } else if (a.annotationType().isAssignableFrom(QueryParam.class)) {
- QueryParam q = (QueryParam) a;
- constructorParam = request.getQueryParams().get(q.value());
- } else if (a.annotationType().isAssignableFrom(ContextParam.class)) {
- ContextParam c = (ContextParam) a;
- constructorParam = contextHolder_.get().get(c.value());
- }
- if (methodParameters[i].isAssignableFrom(String.class)) {
- params[i] = constructorParam;
- } else {
- params[i] = (constructorParam != null) ?
constructor.newInstance(constructorParam) : null;
- }
- }
- }
- Response resp = (Response)
resource.getServer().invoke(resource.getResourceContainer(), params);
-//...</programlisting>
-
- <para>The more detailed schema looks like this:</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-scheme-detailed.png" />
- </imageobject>
- </mediaobject>
- </section>
- </section>
-</chapter>
Deleted:
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml
===================================================================
---
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml 2010-08-17
14:20:04 UTC (rev 2922)
+++
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-service-tutorial.xml 2010-08-17
14:29:17 UTC (rev 2923)
@@ -1,221 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<chapter>
- <?dbhtml filename="ch-ws.html"?>
-
- <title>REST Service Tutorial</title>
-
- <important>
- <para>This article describes REST framework before version
- exo-ws-2.0.</para>
- </important>
-
- <section>
- <title>Introduction</title>
-
- <para>This HOW-TO explains how to create your own REST based services. In
- this HOW-TO we will create a simple calculator, which can do basic
- operations with integers.</para>
- </section>
-
- <section>
- <title>Source code</title>
-
- <programlisting>// ...
-@URITemplate("/calculator/{item1}/{item2}/")
-public class Calculator implements ResourceContainer {
-}</programlisting>
-
- <para>Writing <command>@URITemplate</command> before the class
definition
- gives you the possibility not to set it for each method. Furthermore the
- class must implement the interface <command>ResourceContainer</command>.
- This interface doesn't have any methods, it is just an indication for the
- <command>ResourceBinder</command>. Add the code for adding two
- integers.</para>
-
- <programlisting>// ...
-@URITemplate("/calculator/{item1}/{item2}/")
-public class Calculator implements ResourceContainer {
- @QueryTemplate("operation=add")
- @OutputTransformer(StringOutputTransformer.class)
- @HTTPMethod("GET")
- public Response add(@URIParam("item1") Integer item1,
- @URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" + ").append(item2).append(" =
").append(item1 + item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-}</programlisting>
-
- <para>@QueryTemplate("operation=add") - only requests with query
- parameters "operation=add" can reach this method;
- @OutputTransformer(StringOutputTransformer.class) - the output
- transformer; @HTTPMethod("GET") - the HTTP method
"GET".</para>
-
- <para>Write the code for other operations in the same way. Then the result
- should look like:</para>
-
- <programlisting>package org.exoplatform.services.rest.example;
-
-import org.exoplatform.services.rest.HTTPMethod;
-import org.exoplatform.services.rest.OutputTransformer;
-import org.exoplatform.services.rest.QueryTemplate;
-import org.exoplatform.services.rest.Response;
-import org.exoplatform.services.rest.URIParam;
-import org.exoplatform.services.rest.URITemplate;
-import org.exoplatform.services.rest.container.ResourceContainer;
-import org.exoplatform.services.rest.transformer.StringOutputTransformer;
-
-@URITemplate("/calculator/{item1}/{item2}/")
-(a)OutputTransformer(StringOutputTransformer.class)
-public class Calculator implements ResourceContainer {
-
- @QueryTemplate("operation=add")
- @HTTPMethod("GET")
- public Response add(@URIParam("item1") Integer item1,
@URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" + ").append(item2).append(" =
").append(item1 + item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=subtract")
- @HTTPMethod("GET")
- public Response subtract(@URIParam("item1") Integer item1,
@URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" - ").append(item2).append(" =
").append(item1 - item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=multiply")
- @HTTPMethod("GET")
- public Response multiply(@URIParam("item1") Integer item1,
@URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" * ").append(item2).append(" =
").append(item1 * item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=divide")
- @HTTPMethod("GET")
- public Response divide(@URIParam("item1") Integer item1,
@URIParam("item2") Integer item2) {
- StringBuffer sb = new StringBuffer();
- sb.append(item1).append(" / ").append(item2).append(" =
").append(item1 / item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-}</programlisting>
-
- <para>So we are done with the source code.</para>
- </section>
-
- <section>
- <title>Configuration</title>
-
- <para>Create the directory conf/portal and create the file
- configuration.xml in it. Add the following code to this file:</para>
-
- <programlisting><?xml version="1.0"
encoding="ISO-8859-1"?>
-<configuration>
- <component>
-
<type>org.exoplatform.services.rest.example.Calculator</type>
- </component>
-</configuration></programlisting>
- </section>
-
- <section>
- <title>Build</title>
-
- <para>Now we must create the following directory structure to get the
- possibility to build the source code using maven.</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-build-process.png" />
- </imageobject>
- </mediaobject>
-
- <para>Then create the file pom.xml using the following:</para>
-
- <programlisting><project>
- <parent>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>config</artifactId>
- <version>trunk</version>
- </parent>
-
- <modelVersion&#624;.0.0</modelVersion>
- <groupId>org.exoplatform.ws.rest</groupId>
- <artifactId>simple.calculator</artifactId>
- <packaging>jar</packaging>
- <version>trunk</version>
- <description>Simple REST service</description>
-
- <dependencies>
- <dependency>
- <groupId>org.exoplatform.ws.rest</groupId>
- <artifactId>exo.rest.core</artifactId>
- <version>trunk</version>
- </dependency>
- </dependencies>
-</project></programlisting>
-
- <para>Build this by executing the command:</para>
-
- <programlisting>andrew@ubu:~/workspace/calculator$ mvn clean
install</programlisting>
- </section>
-
- <section>
- <title>Deploy</title>
-
- <para>We have done all now. Then copy the jar file from the target
- directory of project exo-tomcat into the server with all prepared stuff
- for REST services. (You can download it here: <link
-
linkend="???">http://forge.objectweb.org/project/download.ph...
-
- <para>So just put the jar file into the lib directory of the tomcat and
- restart it. In the console you should see this message:</para>
-
- <programlisting>[INFO] ResourceBinder - Bind new ResourceContainer:
org.exoplatform.services.rest.example.Calculator@19846fd</programlisting>
-
- <para>This message indicates that our service was found, bound and is
- ready to work</para>
- </section>
-
- <section>
- <title>Usage</title>
-
- <para>Open your browser and type the following URL: <link
-
linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=add</link>
- and you should see the next page:</para>
-
- <mediaobject>
- <imageobject>
- <imagedata fileref="images/rest-run-process.png" />
- </imageobject>
- </mediaobject>
-
- <para>The service is working. This is a very simple example, but it should
- help developers use the REST framework.</para>
-
- <para>Try to check other URLs.</para>
-
- <itemizedlist>
- <listitem>
- <para><link
-
linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=subtract</link>
- - must give "12 - 5 = 7";</para>
- </listitem>
-
- <listitem>
- <para><link
-
linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=multiply</link>
- - must give "12 * 5 = 60";</para>
- </listitem>
-
- <listitem>
- <para><link
-
linkend="???">http://localhost:8080/rest/calculator/12/5/?operation=divide</link>-
- must give "12 / 5 = 2" (we are working with integers!);</para>
- </listitem>
- </itemizedlist>
- </section>
-</chapter>
Modified: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws.xml
===================================================================
--- jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws.xml 2010-08-17 14:20:04
UTC (rev 2922)
+++ jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws.xml 2010-08-17 14:29:17
UTC (rev 2923)
@@ -8,53 +8,47 @@
<xi:include href="ws/ws.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/introduction-to-rest.xml"
+
+ <xi:include href="ws/introduction-to-rest.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/rest-service-tutorial.xml"
+
+ <xi:include href="ws/rest-migration-to-jsr311.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/rest-migration-to-jsr311.xml"
+
+ <xi:include href="ws/groovy-scripts-as-rest-services.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/groovy-scripts-as-rest-services.xml"
+
+ <xi:include href="ws/soap-service-tutorial.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/rest-framework.xml"
+
+ <xi:include href="ws/central-authentication-service-configuration.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/soap-service-tutorial.xml"
+
+ <xi:include href="ws/kerberos-sso-on-active-directory.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/central-authentication-service-configuration.xml"
+
+ <xi:include href="ws/oauth.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/kerberos-sso-on-active-directory.xml"
+
+ <xi:include href="ws/cometd.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/oauth.xml"
+
+ <xi:include href="ws/cometd-cluster.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/cometd.xml"
+
+ <xi:include href="ws/framework-for-cross-domain-ajax.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/cometd-cluster.xml"
+
+ <xi:include href="ws/cometd-cluster-bench.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/framework-for-cross-domain-ajax.xml"
+
+ <xi:include href="ws/javascript-webdav-library.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/cometd-cluster-bench.xml"
+
+ <xi:include href="ws/exo-ws-2-0.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/javascript-webdav-library.xml"
+
+ <xi:include href="ws/exo-ws-2-0-1.xml"
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/exo-ws-2-0.xml"
-
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
- <xi:include href="ws/exo-ws-2-0-1.xml"
-
xmlns:xi="http://www.w3.org/2001/XInclude" />
-
+
</part>