From do-not-reply at jboss.org Tue Aug 17 10:29:18 2010
Content-Type: multipart/mixed; boundary="===============1340532829312352613=="
MIME-Version: 1.0
From: do-not-reply at jboss.org
To: exo-jcr-commits at lists.jboss.org
Subject: [exo-jcr-commits] exo-jcr SVN: r2923 - in
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules: jcr and 1 other
directories.
Date: Tue, 17 Aug 2010 10:29:18 -0400
Message-ID: <201008171429.o7HETIO2015413@svn01.web.mwc.hst.phx2.redhat.com>
--===============1340532829312352613==
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable
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/architect=
ure.xml
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-frame=
work.xml
jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-servi=
ce-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/arc=
hitecture.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr/architec=
ture.xml 2010-08-17 14:20:04 UTC (rev 2922)
+++ jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr/architec=
ture.xml 2010-08-17 14:29:17 UTC (rev 2923)
@@ -1,14 +0,0 @@
-
-
-
-
-
-
- JCR
- eXoJCR
- etc
-
-
- Basic concepts of eXoJCR
-
Modified: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/jcr.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 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 @@
=
-
-
=
=
=
-
+ xmlns:xi=3D"http://www.w3.org/2001/XInclude" />
+
=
+ xmlns:xi=3D"http://www.w3.org/2001/XInclude" />
=
-
+ xmlns:xi=3D"http://www.w3.org/2001/XInclude" />
+
Deleted: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest=
-framework.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-fram=
ework.xml 2010-08-17 14:20:04 UTC (rev 2922)
+++ jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-fram=
ework.xml 2010-08-17 14:29:17 UTC (rev 2923)
@@ -1,472 +0,0 @@
-
-
-
-
-
- REST Framework
-
-
- This describes REST framework before version exo-ws-2.0
-
-
-
- Requirements
-
- 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.
-
- image: Simplified working model
-
- Taking into account HTTP/REST constraints, it is considered that
- Resources (naturally mapped as Java methods) contained in
- ResourceContainer conform with the following conditions:
-
-
-
- they are uniquely identifiable in the same way as it is
- specified for HTTP i.e. using URI
-
-
-
- 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
-
-
-
- they can return data to an HTTP response using all possible
- mechanisms, i.e. as HTTP status, headers and body
-
-
-
- From the implementation point of view:
-
-
-
- the framework should be as much JSR-311 compatible as possib=
le
- for the time the Specification is in draft and fully compatible af=
ter
- the standard's release
-
-
-
- the ResourceContainer components should be deployable and
- accessible in the same way as an ordinary service
-
-
-
-
-
- Implementation
-
- 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 a=
re
- configured within the same configuration file.
-
- ResourceBinder and ResourceDispatcher are two other important
- components of the REST engine. ResourceBinder deals with binding and
- unbinding ResourceContainer. ResourceDispatcher dispatches REST reques=
ts
- to ResourceContainer. ResourceBinder and ResourceDispatcher are also
- components of the ExoContainer
-
-
- ResourceContainer
-
- A ResourceContainer is an annotated java class. Annotations mu=
st
- at least describe URLs and HTTP methods to be served by this contain=
er.
- But they may also describe other parameters, like produced content t=
ype
- or transformers. Transformers are special Java classes, used to
- serialize and deserialize Java objects.
-
- A very simple ResourceContainer may look like this:
-
- @HTTPMethod("GET")
-(a)URITemplate("/test1/{param}/test2/")
-public Response method1(@URIParam("param") String param) {
-//...
-//...
- Response resp =3D Response.Builder.ok().build();
- return resp;
-}
-
- The ResourceContainer described above is very simple, it can s=
erve
- the GET HTTP method for the relative URL /test1/{param}/test2/ where
- {param} can be any string value. Additionally, {param} can be used a=
s a
- method parameter of the container by annotating it as :
- @URIParam("param") String param. For example, in URL /test1/myID/tes=
t2
- the method parameter "param" has the value "myID".
-
- @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 me=
thod
- can be called with the path /testservices/service1/. All
- ResourceContainer methods return Response objects. A Response includ=
es
- HTTP status, an entity (the requested resource), HTTP headers and
- OutputEntityTransformer.
-
-
-
-
-
-
-
- A client sends a request, after some operations, the HTTP requ=
est
- 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 ExoContain=
ers
- ResourceBinder collects all available ResourceContainers and after t=
he
- start passes the list of ResourceContainers to the ResourceDispatche=
r.
- When ResourceDispatcher gets the request from a client it tries to
- search for a valid ResourceContainer. For this search ResourceDispat=
cher
- 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 met=
hods
- can consist only of some well-defined parameters. See the next
- rules:
-
-
-
- Only one parameter of a method can be not annotated. This
- parameter represents the body of the HTTP request.
-
-
-
- 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.
-
-
-
- If the parameter which represents the HTTP request body is
- present, then in the annotation @InputTransformer a java class m=
ust
- be defined that can build the requested parameter from
- java.io.InputStream. About transformation see below. After reque=
st
- processing ResourceContainer creates Request. Request is a speci=
al
- 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.
-
-
-
-
-
- Response
-
- Response is created by Builder. Builder is an inner static Java
- class within Response. Builder has some preset ways to build Respons=
e,
- 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:
-
- //...
-Document doc =3D ....
-Response response =3D Response.Builder.ok().entity(doc, "text/xml").transf=
ormer(new XMLOutputTransformer()).build();
-
- 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 bui=
ld()
- 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.
-
- //...
-(a)HTTPMethod("GET")
-(a)URITemplate("/test/resource1/")
-(a)InputTransformer(XMLInputTransformer.class)
-(a)OutputTransformer(XMLOutputTransformer.class)
-public Response method1(Document inputDoc) {
-//...
- Document doc =3D ....
- Response response =3D Response.Builder.ok(doc, "text/xml").build();
- return response;
-}
-
- InputEntityTransformer is described in the annotation to the
- method "method1". OutputEntityTransformer is described in the annota=
tion
- to the method "method1".
-
-
-
- Transformer
-
- All transformers can be created by EntityTransformerFactory.
- Transformers can be divided in two groups. Transformers from the fir=
st
- one extend the abstract class InputEntityTransformer.
- InputEntityTransformer implements the interface
- GenericInputEntityTransformer, and GenericInputEntityTransformer ext=
ends
- the interface GenericEntityTransformer. This architecture gives the
- possibility to use one class EntityTransformerFactory for creating b=
oth
- types of transformers (input and output). At first we will speak abo=
ut
- InputEntityTransformer.
-
- InputEntityTransformer
-
- All classes which extend the abstract class InputEntitytransfo=
rmer
- 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 abo=
ve,
- SimpleInputTransformer must override the abstract method Object
- readFrom(InputStream entityDataStream). So, a developer needs to cre=
ate
- a class which can build a Java Object from InputStream and then crea=
te
- annotation to ResourceContainer or some method in ResourceContainer.
- This annotation must define the type of InputEntityTransformer. Here=
is
- the code of the annotation InputTransformer.
-
- //...
-(a)Retention(RUNTIME)
-(a)Target({TYPE, METHOD})
-public @interface InputTransformer {
- Class<? extends InputEntityTransformer> value();
-}
-
- 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.
-
- //...
- InputEntityTransformer transformer =3D (InputEntityTransformer) factory_=
.newTransformer(resource.getInputTransformerType());
- transformer.setType(methodParameters[i]);
- params[i] =3D transformer.readFrom(request.getEntityStream());
-//...
- Response response =3D (Response) resource.getServer().invoke(resource.ge=
tResourceContainer(), params);
-
- A developer can find some prepared transformers in the package
- "org.exoplatform.services.rest.transformer".
-
- OutputEntityTransformer
-
- OutputEntityTransformer can be used to serialize the Object wh=
ich
- represents the requested resource to OutputStream.
- OutputEntityTransformer, in future we will call it
- SimpleOutputTransformer, can be defined in a few ways.
-
- 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 f=
or
- serializing and deserializing an object. Serializable
- (Input/Output)Transformer uses the own methods of an entity for
- serialization and deserialization. Here is an example:
-
- /...
-public class SimpleSerializableEntity implements SerializableEntity {
-
- String data;
-
- public SimpleSerializableEntity() {
- }
- =
- public void readObject(InputStream in) throws IOException {
- StringBuffer sb =3D new StringBuffer();
- int rd =3D -1;
- while((rd =3D in.read()) !=3D -1)
- sb.append((char)rd);
- data =3D sb.toString();
- }
-
- public void writeObject(OutputStream out) throws IOException {
- out.write(data.getBytes());
- }
-}
-
- SerializableInputTransformer will try to use the method void
- readObject(InputStream in) and SerializableOutputTransformer will tr=
y to
- use the method void writeObject(OutputStream in).
-
-
-
- Binding and unbinding components (ResourceContainers)
-
- ResourceBinder takes care of binding and unbinding components
- which represent ResourceContainer. All ResourceContainers must be
- defined as ExoContainer components in configuration files, for
- example:
-
- <component>
- <type>org.exoplatform.services.rest.samples.RESTSampleService</=
type>
-</component>
-
- ResourceBinder is an ExoContainer component and implements the
- interface org.picocontainer.Startable (see the picocontainer
- documentation). So at the start of ExoContainer ResourceBinder colle=
cts
- 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:
-
- public class SimpleResourceContainer implements Reso=
urceContainer {
- @HTTPMethod("GET")
- @URITemplate("/services/{id}/service1/")
- @InputTransformer(StringInputTransformer.class)
- @OutputTransformer(StringOutputTransformer.class)
- public Response method1(String data, @URIParam("id") String param) {
- // ... =
- }
-}
-
- 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 define=
d by
- value /services/{id}/service1/, instead of {id} there can be any oth=
er
- 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 obligator=
y,
- 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 annotati=
on
- and of free type is allowed. All other parameters must have String t=
ype
- (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.
-
- 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.
-
-
-
- ResourceDispatcher
-
- 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
-
- public Response method1(String data, @URIParam("id")=
String param) {
-
- The method method1 is described with two parameters. The first
- parameter String data is built from the entity body (InputStream). T=
he
- second one - String param is annotated by a special type Annotation.
- This Annotation has the following code:
-
- @Target(value=3D{PARAMETER})
-(a)Retention(RUNTIME)
-public @interface URIParam {
- String value();
-}
-
- 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, q=
uery
- and uri. Some more information about @ContextParameters.
- @ContextParameters can be set in the configuration file of a
- component:
-
- <component>
-<type>org.exoplatform.services.rest.ResourceDispatcher</type>
- <init-params>
- <properties-param>
- <name>context-params</name>
- <property name=3D"test" value=3D"test_1"/>
- </properties-param>
- </init-params>
-</component>
-
- In this case any service can use this parameter, for
- example:
-
- ...method(@ContextParam("test") String p) {
- System.out.println(p);
-}
-
- After its execution you should see "test_1" in console.
-
- And in each service the next context parameters can be used. T=
he
- name of these parameters are described in ResourceDispatcher:
-
- public static final String CONTEXT_PARAM_HOST =3D "h=
ost";
-public static final String CONTEXT_PARAM_BASE_URI =3D "baseURI";
-public static final String CONTEXT_PARAM_REL_URI =3D "relURI";
-public static final String CONTEXT_PARAM_ABSLOCATION =3D "absLocation";
-
- After that dispatcher finishes collecting parameters that the
- method requires, invokes this method and passes the result to the cl=
ient
- as it is described above.
-
- This part of code can explain how this mechanism works:
-
- //...
- for (int i =3D 0; i < methodParametersAnnotations.length; i++) {
- if (methodParametersAnnotations[i] =3D=3D null) {
- InputEntityTransformer transformer =3D (InputEntityTransformer) =
factory
- .newTransformer(resource.getInputTransformerType());
- transformer.setType(methodParameters[i]);
- params[i] =3D transformer.readFrom(request.getEntityStream());
- } else {
- Constructor<?> constructor =3D methodParameters[i].getCons=
tructor(String.class);
- String constructorParam =3D null;
- Annotation a =3D methodParametersAnnotations[i];
- if (a.annotationType().isAssignableFrom(URIParam.class)) {
- URIParam u =3D (URIParam) a;
- constructorParam =3D request.getResourceIdentifier().getParame=
ters().get(u.value());
- } else if (a.annotationType().isAssignableFrom(HeaderParam.class=
)) {
- HeaderParam h =3D (HeaderParam) a;
- constructorParam =3D request.getHeaderParams().get(h.value());
- } else if (a.annotationType().isAssignableFrom(QueryParam.class)=
) {
- QueryParam q =3D (QueryParam) a;
- constructorParam =3D request.getQueryParams().get(q.value());
- } else if (a.annotationType().isAssignableFrom(ContextParam.clas=
s)) {
- ContextParam c =3D (ContextParam) a;
- constructorParam =3D contextHolder_.get().get(c.value());
- }
- if (methodParameters[i].isAssignableFrom(String.class)) {
- params[i] =3D constructorParam;
- } else {
- params[i] =3D (constructorParam !=3D null) ? constructor.newIn=
stance(constructorParam) : null;
- }
- }
- }
- Response resp =3D (Response) resource.getServer().invoke(resource.ge=
tResourceContainer(), params);
-//...
-
- The more detailed schema looks like this:
-
-
-
-
-
-
-
-
-
Deleted: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest=
-service-tutorial.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-serv=
ice-tutorial.xml 2010-08-17 14:20:04 UTC (rev 2922)
+++ jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws/rest-serv=
ice-tutorial.xml 2010-08-17 14:29:17 UTC (rev 2923)
@@ -1,221 +0,0 @@
-
-
-
-
-
- REST Service Tutorial
-
-
- This article describes REST framework before version
- exo-ws-2.0.
-
-
-
- Introduction
-
- 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.
-
-
-
- Source code
-
- // ...
-(a)URITemplate("/calculator/{item1}/{item2}/")
-public class Calculator implements ResourceContainer {
-}
-
- Writing @URITemplate before the class definit=
ion
- gives you the possibility not to set it for each method. Furthermore t=
he
- class must implement the interface ResourceContainer.
- This interface doesn't have any methods, it is just an indication for =
the
- ResourceBinder. Add the code for adding two
- integers.
-
- // ...
-(a)URITemplate("/calculator/{item1}/{item2}/")
-public class Calculator implements ResourceContainer {
- @QueryTemplate("operation=3Dadd")
- @OutputTransformer(StringOutputTransformer.class)
- @HTTPMethod("GET")
- public Response add(@URIParam("item1") Integer item1,
- @URIParam("item2") Integer item2) {
- StringBuffer sb =3D new StringBuffer();
- sb.append(item1).append(" + ").append(item2).append(" =3D ").append(it=
em1 + item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-}
-
- @QueryTemplate("operation=3Dadd") - only requests with query
- parameters "operation=3Dadd" can reach this method;
- @OutputTransformer(StringOutputTransformer.class) - the output
- transformer; @HTTPMethod("GET") - the HTTP method "GET".
-
- Write the code for other operations in the same way. Then the re=
sult
- should look like:
-
- 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;
-
-(a)URITemplate("/calculator/{item1}/{item2}/")
-(a)OutputTransformer(StringOutputTransformer.class)
-public class Calculator implements ResourceContainer {
- =
- @QueryTemplate("operation=3Dadd")
- @HTTPMethod("GET")
- public Response add(@URIParam("item1") Integer item1, @URIParam("item2")=
Integer item2) {
- StringBuffer sb =3D new StringBuffer();
- sb.append(item1).append(" + ").append(item2).append(" =3D ").append(it=
em1 + item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=3Dsubtract")
- @HTTPMethod("GET")
- public Response subtract(@URIParam("item1") Integer item1, @URIParam("it=
em2") Integer item2) {
- StringBuffer sb =3D new StringBuffer();
- sb.append(item1).append(" - ").append(item2).append(" =3D ").append(it=
em1 - item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=3Dmultiply")
- @HTTPMethod("GET")
- public Response multiply(@URIParam("item1") Integer item1, @URIParam("it=
em2") Integer item2) {
- StringBuffer sb =3D new StringBuffer();
- sb.append(item1).append(" * ").append(item2).append(" =3D ").append(it=
em1 * item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-
- @QueryTemplate("operation=3Ddivide")
- @HTTPMethod("GET")
- public Response divide(@URIParam("item1") Integer item1, @URIParam("item=
2") Integer item2) {
- StringBuffer sb =3D new StringBuffer();
- sb.append(item1).append(" / ").append(item2).append(" =3D ").append(it=
em1 / item2);
- return Response.Builder.ok(sb.toString(), "text/plain").build();
- }
-}
-
- So we are done with the source code.
-
-
-
- Configuration
-
- Create the directory conf/portal and create the file
- configuration.xml in it. Add the following code to this file:
-
- <?xml version=3D"1.0" encoding=3D"ISO-8859-1"?>
-<configuration>
- <component>
- <type>org.exoplatform.services.rest.example.Calculator</type&=
gt;
- </component>
-</configuration>
-
-
-
- Build
-
- Now we must create the following directory structure to get the
- possibility to build the source code using maven.
-
-
-
-
-
-
-
- Then create the file pom.xml using the following:
-
- <project>
- <parent>
- <groupId>org.exoplatform.ws</groupId>
- <artifactId>config</artifactId>
- <version>trunk</version>
- </parent>
-
- <modelVersionɰ.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>
-
- Build this by executing the command:
-
- andrew(a)ubu:~/workspace/calculator$ mvn clean install=
-
-
-
- Deploy
-
- 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: http://forge.objectweb.org/project/download.php?group_=
id=3D151&file_id=3D9862)
-
- So just put the jar file into the lib directory of the tomcat and
- restart it. In the console you should see this message:
-
- [INFO] ResourceBinder - Bind new ResourceContainer: or=
g.exoplatform.services.rest.example.Calculator(a)19846fd
-
- This message indicates that our service was found, bound and is
- ready to work
-
-
-
- Usage
-
- Open your browser and type the following URL: http://localhost:8080/rest/calculator/12/5/?operation=
=3Dadd
- and you should see the next page:
-
-
-
-
-
-
-
- The service is working. This is a very simple example, but it sh=
ould
- help developers use the REST framework.
-
- Try to check other URLs.
-
-
-
- http://localhost:8080/rest/calculator/12/5/?operat=
ion=3Dsubtract
- - must give "12 - 5 =3D 7";
-
-
-
- http://localhost:8080/rest/calculator/12/5/?operat=
ion=3Dmultiply
- - must give "12 * 5 =3D 60";
-
-
-
- http://localhost:8080/rest/calculator/12/5/?operat=
ion=3Ddivide-
- must give "12 / 5 =3D 2" (we are working with integers!);
-
-
-
-
Modified: jcr/trunk/docs/reference/en/src/main/docbook/en-US/modules/ws.xml
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- 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 @@
=
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
--===============1340532829312352613==--