You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by bu...@apache.org on 2014/01/15 10:45:08 UTC

svn commit: r894247 - in /websites/staging/olingo/trunk/content: ./ doc/tutorials/AnnotationProcessorExtension.html

Author: buildbot
Date: Wed Jan 15 09:45:07 2014
New Revision: 894247

Log:
Staging update by buildbot for olingo

Modified:
    websites/staging/olingo/trunk/content/   (props changed)
    websites/staging/olingo/trunk/content/doc/tutorials/AnnotationProcessorExtension.html

Propchange: websites/staging/olingo/trunk/content/
------------------------------------------------------------------------------
--- cms:source-revision (original)
+++ cms:source-revision Wed Jan 15 09:45:07 2014
@@ -1 +1 @@
-1558318
+1558325

Modified: websites/staging/olingo/trunk/content/doc/tutorials/AnnotationProcessorExtension.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/tutorials/AnnotationProcessorExtension.html (original)
+++ websites/staging/olingo/trunk/content/doc/tutorials/AnnotationProcessorExtension.html Wed Jan 15 09:45:07 2014
@@ -90,13 +90,263 @@ Therefore Maven must be called as shown 
 <p>In the generated sample project you now can simply run Maven with the default goal (run <code>mvn</code> in the shell) which compiles the sources and starts an Jetty web server at <code>http://localhost:8080</code>.</p>
 <p>For more detailed documentation about Archetypes in Olingo take a look into the <a href="/doc/sample-setup">sample setup</a> section.</p>
 <h2 id="creation-from-scratch">Creation from Scratch</h2>
-<p>A project which use the Annotation Processor Extension mainly of the model and the <code>ODataServiceFactory</code> implementation. 
-In addition we use Maven so that a <code>pom.xml</code> is necessary for project build and dependency resolution.</p>
+<p>A project which use the Annotation Processor Extension consists mainly of the model beans, the <code>ODataServiceFactory</code> implementation and the web resources (e.g. <code>web.xml</code>). 
+In addition we use Maven so that it is necessary to create a <code>pom.xml</code> for project build information and dependency resolution.</p>
 <h3 id="create-pomxml">Create pom.xml</h3>
+<p>A default <code>pom.xml</code> for building of an <code>WAR-File</code> is created.
+In addition we need the dependency to all necessary <em>Apache Olingo artifacts</em> and to the used <code>JAX-RS</code> implementation which in this sample is <code>Apache CXF</code>.</p>
+<p>The resulting <code>pom.xml</code> then looks like:</p>
+<p>```
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;
+<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/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion></p>
+<p><groupId>org.apache.olingo</groupId>
+  <artifactId>cars-annotations-sample</artifactId>
+  <version>1.0.0-SNAPSHOT</version>
+  <name>${project.artifactId}</name></p>
+<p><packaging>war</packaging></p>
+<p><properties>
+    <!-- Dependency Versions -->
+    <version.cxf>2.7.6</version.cxf>
+    <version.servlet-api>2.5</version.servlet-api>
+    <version.jaxrs-api>2.0-m10</version.jaxrs-api>
+    <version.olingo>1.1.0</version.olingo>
+  </properties></p>
+<p><build>
+    <finalName>${project.artifactId}</finalName>
+    <defaultGoal>clean package</defaultGoal>
+  </build></p>
+<p><dependencies>
+    <!-- Apache Olingo Library dependencies -->
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-api-incubating</artifactId>
+      <version>${version.olingo}</version>
+    </dependency>
+    <dependency>
+      <artifactId>olingo-odata2-api-annotation-incubating</artifactId>
+      <groupId>org.apache.olingo</groupId>
+      <type>jar</type>
+      <version>${version.olingo}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-core-incubating</artifactId>
+      <version>${version.olingo}</version>
+    </dependency>
+    <!-- Apache Olingo Annotation Processor Extension dependencies -->
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-annotation-processor-api-incubating</artifactId>
+      <version>${version.olingo}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.olingo</groupId>
+      <artifactId>olingo-odata2-annotation-processor-core-incubating</artifactId>
+      <version>${version.olingo}</version>
+    </dependency>
+    <!-- Servlet/REST dependencies -->
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>${version.servlet-api}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.ws.rs</groupId>
+      <artifactId>javax.ws.rs-api</artifactId>
+      <version>${version.jaxrs-api}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
+      <version>${version.cxf}</version>
+    </dependency>
+  </dependencies>
+</project></p>
+<p>```</p>
 <h3 id="create-model">Create Model</h3>
+<p>For this sample a simple model with the two entities <em>Manufacturer</em> and <em>Car</em> is created.</p>
+<p>The <em>Manufacturer</em> consists of an <code>Id</code>, <code>Name</code>, <code>Founded</code> and a relation to a list of its <code>Cars</code>.<br />
+The <em>Car</em> consists of an <code>Id</code>, <code>Model</code>, <code>ProductionYear</code>, <code>Price</code> and a relation to its <code>Manufacturer</code>.</p>
+<h4 id="create-java-beans-for-entities">Create Java Beans for Entities</h4>
+<p>For each of both entities first a java bean (<em>POJO</em>) is created in the package <code>org.apache.olingo.sample.annotation.model</code> which looks like:</p>
+<p>```
+package org.apache.olingo.sample.annotation.model;</p>
+<p>/*<em> Imports</em>/</p>
+<p>public class Manufacturer {
+  private String id;
+  private String name;
+  private Calendar founded;
+  private List<Car> cars = new ArrayList<Car>();</p>
+<p>/*<em> getter and setter </em>/
+```</p>
+<p>```
+package org.apache.olingo.sample.annotation.model;</p>
+<p>/*<em> Imports</em>/</p>
+<p>public class Car {
+  private String id;
+  private String model;
+  private Double price;
+  private Integer productionYear;
+  private Manufacturer manufacturer;</p>
+<p>/*<em> getter and setter </em>/
+```</p>
+<h4 id="annotated-created-java-beans">Annotated created Java Beans</h4>
+<p>Now those beans have to be annotated with the annotations of the <em>Annotation Processor Extension</em>.</p>
+<p>Both beans needs at first the <code>@EdmEntityType</code> and <code>@EdmEntitySet</code> annotation to define that they represent an OData Entity. These annotation must be added at the bean class which as example for the <em>Manufacturer</em> then look like:</p>
+<p><code>@EdmEntityType
+@EdmEntitySet
+public class Manufacturer { /** more code */ }</code></p>
+<p>Then all simple properties of the Entity must be annotated with <code>@EdmProperty</code>, the <em>Key</em> for the Entity additional must be annotated with <code>@EdmKey</code> which is in this sample the <code>Id</code> field of the entities.</p>
+<p>For the <em>Manufacturer</em> it then look like:</p>
+<p>```
+@EdmEntityType
+@EdmEntitySet
+public class Manufacturer {
+  @EdmKey
+  @EdmProperty
+  private String id;
+  @EdmProperty
+  private String name;
+  @EdmProperty
+  private Calendar founded;</p>
+<p>/*<em> more code </em>/ }
+```</p>
+<p>A relation to another Entity must be annotated with <code>@EdmNavigationProperty</code>. In this sample this are the bi-directional relation between a <em>Manufacturer</em> and its <em>Cars</em>.  </p>
+<p>For the <em>Manufacturer</em> the added annotation look like:</p>
+<p>```
+@EdmEntityType
+@EdmEntitySet
+public class Manufacturer {
+  /*<em> more code </em>/ </p>
+<p>@EdmNavigationProperty
+  private List<Car> cars = new ArrayList<Car>();</p>
+<p>/*<em> more code </em>/ 
+}
+```</p>
+<p>The complete resulting Entities (POJOs) then look like:</p>
+<p>```
+package org.apache.olingo.sample.annotation.model;</p>
+<p>/*<em> Imports</em>/</p>
+<p>@EdmEntityType
+@EdmEntitySet
+public class Manufacturer {
+  @EdmKey
+  @EdmProperty
+  private String id;
+  @EdmProperty
+  private String name;
+  @EdmProperty
+  private Calendar founded;
+  @EdmNavigationProperty
+  private List<Car> cars = new ArrayList<Car>();</p>
+<p>/*<em> getter and setter </em>/
+```</p>
+<p>and</p>
+<p>```
+package org.apache.olingo.sample.annotation.model;</p>
+<p>/*<em> Imports </em>/</p>
+<p>@EdmEntityType
+@EdmEntitySet
+public class Car {
+  @EdmKey
+  @EdmProperty
+  private String id;
+  @EdmProperty
+  private String model;
+  @EdmProperty
+  private Double price;
+  @EdmProperty
+  private Integer productionYear;
+  @EdmNavigationProperty
+  private Manufacturer manufacturer;</p>
+<p>/*<em> getter and setter </em>/
+```</p>
+<p>The next step is to create the <code>ODataService</code>.</p>
 <h3 id="create-odataservice">Create ODataService</h3>
-<h3 id="deploy">Deploy</h3>
-<h2 id="deeper-look">Deeper look</h2>
+<p>The <code>ODataService</code> is created via an <code>ODataServiceFactory</code> implementation.
+For the sample a <code>AnnotationSampleServiceFactory</code> in the package <code>org.apache.olingo.sample.annotation.processor</code> is created which  extends the <code>ODataServiceFactory</code>. The resulting code look like:</p>
+<p>```
+package org.apache.olingo.sample.annotation.processor;</p>
+<p>/*<em> Imports </em>/</p>
+<p>public class AnnotationSampleServiceFactory extends ODataServiceFactory {
+  @Override
+  public ODataService createService(final ODataContext context) throws ODataException {
+    return null;
+  }
+}
+<code>``   
+In the</code>createService(...)<code>method now the</code>ODataService<code>needs to be created.
+The _Annotation Processor Extension_ provides therefore the method</code>createAnnotationService(...)<code>within the</code>AnnotationServiceFactory` which can be used. This method require as parameter the <em>Package</em> which contains the <em>Model</em> in form of annotated POJOs (as created in the section <em>Create the Model</em>).  </p>
+<p>For a persistence between several request it is necessary to hold the created <code>ODataService</code> in an static instance. In the sample the <a href="http://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom">Initialization on demand holder idiom</a> is used.</p>
+<p>As result the implementation look like:</p>
+<p>```
+public class AnnotationSampleServiceFactory extends ODataServiceFactory {</p>
+<p>/*<em>
+   * Instance holder for all annotation relevant instances which should be used as singleton
+   * instances within the ODataApplication (ODataService)
+   </em>/
+  private static class AnnotationInstances {
+    final static String MODEL_PACKAGE = "org.apache.olingo.sample.annotation.model";
+    final static ODataService ANNOTATION_ODATA_SERVICE;</p>
+<div class="codehilite"><pre><span class="n">static</span> <span class="p">{</span>
+  <span class="k">try</span> <span class="p">{</span>
+    <span class="n">ANNOTATION_ODATA_SERVICE</span> <span class="p">=</span> <span class="n">AnnotationServiceFactory</span><span class="p">.</span><span class="n">createAnnotationService</span><span class="p">(</span><span class="n">MODEL_PACKAGE</span><span class="p">);</span>
+  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">ODataApplicationException</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">throw</span> <span class="n">new</span> <span class="n">RuntimeException</span><span class="p">(</span>&quot;<span class="n">Exception</span> <span class="n">during</span> <span class="n">sample</span> <span class="n">data</span> <span class="n">generation</span><span class="p">.</span>&quot;<span class="p">,</span> <span class="n">ex</span><span class="p">);</span>
+  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">ODataException</span> <span class="n">ex</span><span class="p">)</span> <span class="p">{</span>
+    <span class="n">throw</span> <span class="n">new</span> <span class="n">RuntimeException</span><span class="p">(</span>&quot;<span class="n">Exception</span> <span class="n">during</span> <span class="n">data</span> <span class="n">source</span> <span class="n">initialization</span> <span class="n">generation</span><span class="p">.</span>&quot;<span class="p">,</span> <span class="n">ex</span><span class="p">);</span>
+  <span class="p">}</span>
+<span class="p">}</span>
+</pre></div>
+
+
+<p>}</p>
+<p>public ODataService createService(final ODataContext context) throws ODataException {
+AnnotationsValueAccess
+    return AnnotationInstances.ANNOTATION_ODATA_SERVICE;
+  }
+```</p>
+<p>Now the model as well as the service creation is done.
+The next step is to provide the necessary resources to run the application within an application server. </p>
+<h3 id="create-web-application-resources">Create Web Application resources</h3>
+<p>To deploy and run the application on an application server it is necessary to provide a <code>web.xml</code> which defines the <code>JAX-RS</code> entry point which then calls the sample application.</p>
+<p>For this sample <code>Apache CXF</code> is used (see <code>&lt;servlet-class&gt;org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet&lt;/servlet-class&gt;</code>) which need as parameter the <code>javax.ws.rs.Application</code> and the <code>org.apache.olingo.odata2.service.factory</code>.</p>
+<p>Therefore the <code>web.xml</code> is created in the <code>src/main/webapp/WEB-INF</code> folder with following content:</p>
+<p>```
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+    id="WebApp_ID" version="2.5">
+    <display-name>org.apache.olingo.sample.annotation</display-name>
+    <servlet>
+        <servlet-name>ServiceServlet</servlet-name>
+        <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet</servlet-class>
+        <init-param>
+            <param-name>javax.ws.rs.Application</param-name>
+            <param-value>org.apache.olingo.odata2.core.rest.app.ODataApplication</param-value>
+        </init-param>
+        <init-param>
+            <param-name>org.apache.olingo.odata2.service.factory</param-name>
+            <param-value>org.apache.olingo.sample.annotation.processor.AnnotationSampleServiceFactory</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet></p>
+<div class="codehilite"><pre><span class="nt">&lt;servlet-mapping&gt;</span>
+    <span class="nt">&lt;servlet-name&gt;</span>ServiceServlet<span class="nt">&lt;/servlet-name&gt;</span>
+    <span class="nt">&lt;url-pattern&gt;</span>/AnnotationSample.svc/*<span class="nt">&lt;/url-pattern&gt;</span>
+<span class="nt">&lt;/servlet-mapping&gt;</span>
+</pre></div>
+
+
+<p></web-app>
+```</p>
+<h3 id="deploy-and-run">Deploy and Run</h3>
+<p>Build the project with maven via <code>mvm clean package</code> and copy the resulting <code>WAR-File</code> from the projects <code>target</code> folder in the <code>deploy</code> folder of the application server.</p>
+<p>Now just navigate to the URL (e.g. <code>http://localhost:8080/cars-annotations-sample/AnnotationSample.svc</code>).</p>
+<h2 id="more-detailed-look">More detailed look</h2>
 <p>A more detailed look into the Annotation Processor Extension can be found in the <a href="https://wiki.apache.org/Olingo/Documentation/AnnotationProcessor">wiki</a>.</p>