You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by mi...@apache.org on 2014/09/16 14:33:57 UTC

svn commit: r1625261 [8/8] - in /olingo/site/trunk: content/ content/doc/odata2/ content/doc/odata2/tutorials/ content/doc/odata4/ content/doc/odata4/tutorials/ templates/

Added: olingo/site/trunk/content/doc/odata4/tutorials/osgi.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/osgi.mdtext?rev=1625261&view=auto
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/osgi.mdtext (added)
+++ olingo/site/trunk/content/doc/odata4/tutorials/osgi.mdtext Tue Sep 16 12:33:56 2014
@@ -0,0 +1,83 @@
+Title:
+Notice:    Licensed to the Apache Software Foundation (ASF) under one
+           or more contributor license agreements.  See the NOTICE file
+           distributed with this work for additional information
+           regarding copyright ownership.  The ASF licenses this file
+           to you under the Apache License, Version 2.0 (the
+           "License"); you may not use this file except in compliance
+           with the License.  You may obtain a copy of the License at
+           .
+             http://www.apache.org/licenses/LICENSE-2.0
+           .
+           Unless required by applicable law or agreed to in writing,
+           software distributed under the License is distributed on an
+           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+           KIND, either express or implied.  See the License for the
+           specific language governing permissions and limitations
+           under the License.
+
+# OSGi Support
+
+All Apache Olingo artifacts are OSGi enabled and build as bundles. Apache Olingo is using the [Apache Felix bundle plugin for Maven](http://felix.apache.org/site/apache-felix-maven-bundle-plugin-bnd.html) to generate the manifest.mf file for each bundle.
+
+The bundles expose the complete api (`org.apache.olingo.odata2.api.*`). From the implementation part (`org.apache.olingo.odata2.core.*`) only a minimum set of packages is exposed.
+
+There is a difficulty in relation to class loading because of Apache Olingo core bundle has to load a specific custom service implementation without having a direct dependency to it.
+
+In Apache Olingo OData2 Version 1.0.0 we solve this issue as follow: 
+
+### Servlet Filter in OSGi
+
+It is assumed that an OData service implementation is deployed as a native web application (war) or as web application bundle (OSGi Enterprise Expert Group on the RFC66 Web Container specification). In both cases the Apache Olingo core bundle is not aware of this application and its classloader cannot load applications service factory by default. 
+
+Adding this servlet filter to the service servlet configuration can solve this problem. The filter can bind the application classloader to the servlet request object, which is then used by the Apache Olingo core bundle to load applications factory class. 
+
+	:::java
+	public class ServiceFactoryFilter implements Filter {
+	
+	  @Override
+	  public void doFilter(ServletRequest request, ServletResponse response, 
+	     FilterChain chain) throws IOException, ServletException { 
+	     
+	    request.setAttribute(ODataServiceFactory.FACTORY_CLASSLOADER_LABEL, 
+	       MyServiceFactory.class.getClassLoader()); 
+	  
+	     chain.doFilter(request, response); 
+	  }
+	}
+
+### Extended OSGi Support
+
+The filter approach works fine for servlets but the Apache Olingo library can be used also for different, non-servlet based scenarios.  
+
+##### Implement own ODataApplication
+
+A service has to implement an own `ODataApplication` and return the service factory class:
+
+	
+	:::java
+	import org.apache.olingo.odata2.core.rest.app.AbstractODataApplication;
+	
+	public class CarODataApplication extends AbstractODataApplication {
+	
+	  @Override
+	  public Class<? extends ODataServiceFactory> getServiceFactoryClass() { 
+	     return CarODataServiceFactory.class; 
+	  }
+	}
+
+##### Register Application in Servlet Context
+
+Then register the application for any JAX-RS servlet implementation. Here it is the Apache CXF JAX-RS servlet.
+
+	:::xml
+	<servlet>
+	  <servlet-name>CarServiceServlet</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.sample.osgi.CarODataApplication</param-value>
+	  </init-param>
+	  <load-on-startup>1</load-on-startup>
+	</servlet>
+

Added: olingo/site/trunk/content/doc/odata4/tutorials/read_expand.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/read_expand.mdtext?rev=1625261&view=auto
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/read_expand.mdtext (added)
+++ olingo/site/trunk/content/doc/odata4/tutorials/read_expand.mdtext Tue Sep 16 12:33:56 2014
@@ -0,0 +1,244 @@
+Title:
+Notice:    Licensed to the Apache Software Foundation (ASF) under one
+           or more contributor license agreements.  See the NOTICE file
+           distributed with this work for additional information
+           regarding copyright ownership.  The ASF licenses this file
+           to you under the Apache License, Version 2.0 (the
+           "License"); you may not use this file except in compliance
+           with the License.  You may obtain a copy of the License at
+           .
+             http://www.apache.org/licenses/LICENSE-2.0
+           .
+           Unless required by applicable law or agreed to in writing,
+           software distributed under the License is distributed on an
+           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+           KIND, either express or implied.  See the License for the
+           specific language governing permissions and limitations
+           under the License.
+
+# Read Scenario - Read with $expand
+
+---
+
+### How To Guide - Extend basic read scenario with support for $expand
+
+This How To Guide shows how to extend the basic read scenario with support for the $expand system query option.
+It shows how to call the `EntityProvider.writeEntry(...)` and `EntityProvider.writeEntrySet(...)` methods with the necessary `EntityProviderWriteProperties` set and how to implement the necessary `OnWriteEntryContent OnWriteFeedContent` callbacks.
+
+### Prerequisites
+
+Setup of [Basic Read Scenario](basicread)
+
+### Shortcut 
+
+If you like to directly experiment with the results of the extented basic read scenario, you can use this shortcut: 
+
+  - Download and unzip [Olingo Tutorial 'Basic Read with $expand extension' Project](apache-olingo-tutorial-adv_read_expand.zip) to your local drive which is your OData Tutorial project folder (referenced as `$ODATA_PROJECT_HOME` in the tutorial).
+  - Start the command line tool and execute the following command in the folder `$ODATA_PROJECT_HOME` 
+    - `mvn eclipse:eclipse clean install` 
+  - Go into Eclipse and import the project into your workspace by... 
+    - Menu *File -> Import*... 
+    - *Existing projects into workspace*, then choose the `$ODATA_PROJECT_HOME` folder 
+    - Select both projects *olingo.odata2.sample.service* and *olingo.odata2.sample.web* and press *Finish*. 
+
+### Set Up your development project 
+
+If [Basic Read Scenario](basicread) is already set up there is nothing additional to do. Otherwise please refer to the Prerequisites section of the [Basic Read Scenario](basicread).
+
+### Extend Basic Read Scenario
+The steps to extend the basic read with $expand support for the Car and Manufacturer entities (not entity sets) are to provide the expanded data via ODataCallbacks and register these for the corresponding navigation properties. 
+
+### Implement OnWriteEntryContent and OnWriteFeedContent callbacks
+To support `$expand` for a single entry the interface `org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent` must be implemented. This provides the method `WriteEntryCallbackResult retrieveEntryResult(WriteEntryCallbackContext context) throws ODataApplicationException;` which is called during processing from the `EntityProvider` to receive the necessary data which than is inlined in the response.
+
+In our sample we create a class `MyCallback` which implements `org.apache.olingo.odata2.api.ep.callback.OnWriteEntryContent` in following way:
+
+##### Sample Code
+
+    :::java
+    @Override
+    public WriteEntryCallbackResult retrieveEntryResult(WriteEntryCallbackContext context) throws ODataApplicationException {
+    WriteEntryCallbackResult result = new WriteEntryCallbackResult();
+
+      try {
+        if (isNavigationFromTo(context, ENTITY_SET_NAME_CARS, ENTITY_NAME_MANUFACTURER)) {
+        EntityProviderWriteProperties inlineProperties = EntityProviderWriteProperties.serviceRoot(serviceRoot)
+            .expandSelectTree(context.getCurrentExpandSelectTreeNode())
+            .build();
+
+          Map<String, Object> keys = context.extractKeyFromEntryData();
+          Integer carId = (Integer) keys.get("Id");
+          result.setEntryData(dataStore.getManufacturerFor(carId));
+          result.setInlineProperties(inlineProperties);
+        }
+      } catch (EdmException e) {
+      // TODO: should be handled and not only logged
+      LOG.error("Error in $expand handling.", e);
+      } catch (EntityProviderException e) {
+      // TODO: should be handled and not only logged
+      LOG.error("Error in $expand handling.", e);
+      }
+    
+      return result;
+    }
+
+Within this method we first check if the source entity and navigation property are correct for our case (via the method `isNavigationFromTo(...):boolean)`, then we create the `EntityProviderWriteProperties` with the new (current) `ExpandSelectTreeNode`, receive the data from our `DataStore` and put all into the result which then will be further processed by the `EntityProvider`.
+
+### Implementation for $expand for an entity set
+To support `$expand` for a feed of entries (entity set) the interface `org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent` must be implemented. These provides the method `WriteFeedCallbackResult retrieveFeedResult(WriteFeedCallbackContext context) throws ODataApplicationException;` which is called during processing from the `EntityProvider` to receive the necessary data which than is inlined in the response.
+
+It is possible to create an additional callback class but for convenience we expand our already created callback (`MyCallback`) to implement `org.apache.olingo.odata2.api.ep.callback.OnWriteFeedContent` and provide the method implementation in following way:
+
+##### Sample Code
+
+    :::java
+    @Override
+    public WriteFeedCallbackResult retrieveFeedResult(WriteFeedCallbackContext context) throws ODataApplicationException {
+    WriteFeedCallbackResult result = new WriteFeedCallbackResult();
+      try {
+        if(isNavigationFromTo(context, ENTITY_SET_NAME_MANUFACTURERS, ENTITY_SET_NAME_CARS)) {
+        EntityProviderWriteProperties inlineProperties = EntityProviderWriteProperties.serviceRoot(serviceRoot)
+            .expandSelectTree(context.getCurrentExpandSelectTreeNode())
+            .selfLink(context.getSelfLink())
+            .build();
+
+          Map<String, Object> keys = context.extractKeyFromEntryData();
+          Integer manufacturerId = (Integer) keys.get("Id");
+          result.setFeedData(dataStore.getCarsFor(manufacturerId));
+          result.setInlineProperties(inlineProperties);
+        }
+      } catch (EdmException e) {
+      // TODO: should be handled and not only logged
+      LOG.error("Error in $expand handling.", e);
+      } catch (EntityProviderException e) {
+      // TODO: should be handled and not only logged
+      LOG.error("Error in $expand handling.", e);
+      }
+      return result;
+    }
+
+Within this method we first check if the source entity and navigation property are correct for our case (via the method `isNavigationFromTo(...):boolean)`, then we create the `EntityProviderWriteProperties` with the new (current) `ExpandSelectTreeNode`, receive the data from our `DataStore` and put all into the result which then will be further processed by the `EntityProvider`.
+
+This example shows that the basic callback logic between `OnWriteEntryConten`t and `OnWriteFeedContent` is very similar. Validation of current element (optional), preparing of `EntityProviderWriteProperties`, receive of data and putting all together into corresponding result object (`WriteEntryCallbackResult` or `WriteFeedCallbackResult`).
+
+To improve code readability the `isNavigationFromTo(...):boolean` method was also added to the class. The method is used to check if the retrieved request is related to given entity set and navigation:
+
+#### Sample Code
+
+    :::java
+    private boolean isNavigationFromTo(WriteCallbackContext context, String entitySetName, String navigationPropertyName) throws EdmException {
+      if(entitySetName == null || navigationPropertyName == null) {
+      return false;
+      }
+      EdmEntitySet sourceEntitySet = context.getSourceEntitySet();
+      EdmNavigationProperty navigationProperty = context.getNavigationProperty();
+      return entitySetName.equals(sourceEntitySet.getName()) && navigationPropertyName.equals(navigationProperty.getName());
+    }
+
+### Extend ODataSingleProcessor.readEntity(...)
+The necessary callbacks (`MyCallback` class) now has to be registered during the corresponding `readEntity(...)` call. Therefore we first create a map with the property name as key and the according callback as value. Additional we need to create the `ExpandSelectTreeNode` based on current element position. Both then have to be set in the `EntityProviderWritePropertiesBuilder`. 
+
+The following code show the few lines we need for extending the read of a car with its expanded manufacturer.
+
+    :::java
+    // create and register callback
+    Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+    callbacks.put(ENTITY_NAME_MANUFACTURER, new MyCallback(dataStore, serviceRoot));
+    ExpandSelectTreeNode expandSelectTreeNode = UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+    propertiesBuilder.expandSelectTree(expandSelectTreeNode).callbacks(callbacks);
+
+
+The following code show the few lines we need for extending the read of a manufacturer with its expanded cars.
+
+    :::java
+    // create and register callback
+    Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+    callbacks.put(ENTITY_SET_NAME_CARS, new MyCallback(dataStore, serviceRoot));
+    ExpandSelectTreeNode expandSelectTreeNode = UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+    propertiesBuilder.expandSelectTree(expandSelectTreeNode).callbacks(callbacks);
+
+
+The complete `readEntity(...)` method should now look like:
+
+    :::java
+    public ODataResponse readEntity(GetEntityUriInfo uriInfo, String contentType) throws ODataException {
+    
+      if (uriInfo.getNavigationSegments().size() == 0) {
+      EdmEntitySet entitySet = uriInfo.getStartEntitySet();
+
+        if (ENTITY_SET_NAME_CARS.equals(entitySet.getName())) {
+        int id = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        Map<String, Object> data = dataStore.getCar(id);
+        
+          if (data != null) {
+          URI serviceRoot = getContext().getPathInfo().getServiceRoot();
+          ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(serviceRoot);
+          
+            // create and register callback
+          Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+          callbacks.put(ENTITY_NAME_MANUFACTURER, new MyCallback(dataStore, serviceRoot));
+          ExpandSelectTreeNode expandSelectTreeNode = UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+            //
+            propertiesBuilder.expandSelectTree(expandSelectTreeNode).callbacks(callbacks);
+
+             return EntityProvider.writeEntry(contentType, entitySet, data, propertiesBuilder.build());
+          }
+        } else if (ENTITY_SET_NAME_MANUFACTURERS.equals(entitySet.getName())) {
+          int id = getKeyValue(uriInfo.getKeyPredicates().get(0));
+          Map<String, Object> data = dataStore.getManufacturer(id);
+        
+          if (data != null) {
+            URI serviceRoot = getContext().getPathInfo().getServiceRoot();
+            ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(serviceRoot);
+  
+            // create and register callback
+            Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+            callbacks.put(ENTITY_SET_NAME_CARS, new MyCallback(dataStore, serviceRoot));
+            ExpandSelectTreeNode expandSelectTreeNode = UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+            //
+            propertiesBuilder.expandSelectTree(expandSelectTreeNode).callbacks(callbacks);
+
+            return EntityProvider.writeEntry(contentType, entitySet, data, propertiesBuilder.build());
+          }
+        }
+
+        throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+
+      } else if (uriInfo.getNavigationSegments().size() == 1) {
+        //navigation first level, simplified example for illustration purposes only
+        EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+        if (ENTITY_SET_NAME_MANUFACTURERS.equals(entitySet.getName())) {
+          int carKey = getKeyValue(uriInfo.getKeyPredicates().get(0));
+          return EntityProvider.writeEntry(contentType, uriInfo.getTargetEntitySet(), dataStore.getManufacturer(carKey),   EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).build());
+        }
+
+        throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+      }
+
+      throw new ODataNotImplementedException();
+    }
+
+Now we can test out `$expand` extension in the web application.
+
+### Deploy, run and test $expand
+
+Like in the basic read scenario follow these steps:
+
+  - Build your project: `mvn clean install` 
+  - When build finished in Eclipse, run the Web Application via *Run As -> Run on Server* 
+  - After successful server start and deployment the following uris from the basic read sample work as before: 
+    - Show the Manufacturers: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers) 
+    - Show one Manufacturer: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)) 
+    - Show the Cars: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars) 
+    - Show one Car: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)) 
+    - Show the related Manufacturer of a Car: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)/Manufacturer](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)/Manufacturer) 
+    - Show the related Cars of a Manufacturer: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)/Cars](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)/Cars) 
+  - And in addition we can now expand the car and manufacturer with each other: 
+    - Show Car with its Manufacturer: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)?$expand=Manufacturer ](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)?$expand=Manufacturer )
+    - Show Manufacturer with its Cars: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)?$expand=Cars](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)?$expand=Cars) 
+
+### Further Information
+
+Next extension step for read scenario are read of [Media Resources](read_media-resource). 
+
+  
\ No newline at end of file

Added: olingo/site/trunk/content/doc/odata4/tutorials/read_media-resource.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/read_media-resource.mdtext?rev=1625261&view=auto
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/read_media-resource.mdtext (added)
+++ olingo/site/trunk/content/doc/odata4/tutorials/read_media-resource.mdtext Tue Sep 16 12:33:56 2014
@@ -0,0 +1,403 @@
+Title:
+Notice:    Licensed to the Apache Software Foundation (ASF) under one
+           or more contributor license agreements.  See the NOTICE file
+           distributed with this work for additional information
+           regarding copyright ownership.  The ASF licenses this file
+           to you under the Apache License, Version 2.0 (the
+           "License"); you may not use this file except in compliance
+           with the License.  You may obtain a copy of the License at
+           .
+             http://www.apache.org/licenses/LICENSE-2.0
+           .
+           Unless required by applicable law or agreed to in writing,
+           software distributed under the License is distributed on an
+           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+           KIND, either express or implied.  See the License for the
+           specific language governing permissions and limitations
+           under the License.
+
+# Media Resources 
+
+---
+
+### How To Guide - Extend read scenario with support for media resources
+
+This How To Guide shows how to extend the read scenario (with `$expand` extension) with support for Media Link Entries and Media Resources.
+
+The tutorial introduces a new resource (Driver), shows how to extend the according `readEntitySet(...)` and `readEntity(...)` and introduces the new method `readEntityMedia(uriInfo:GetMediaResourceUriInfo, contentType:String):ODataResponse` within the `MyODataSingleProcessor`.
+
+### Prerequisites
+Setup of [Read Scenario with `$expand`](read_expand) extension
+(which has as prerequisite Setup of [Basic Read Scenario](basicread))
+
+
+### Shortcut
+If you like to directly experiment with the results of the extented basic read scenario, you can use this shortcut: 
+
+  - Download and unzip the [Olingo Tutorial 'Basic Read with Media Resource extension' Project](apache-olingo-tutorial-adv_read_mediaresource.zip) to your local drive which is your OData Tutorial project folder (referenced as `$ODATA_PROJECT_HOME` in the turorial).
+  - Start the command line tool and run maven in the folder `$ODATA_PROJECT_HOME` to build the war file which then can be deployed. 
+  - Deploy the resulting war to your favorite application server. 
+    - For a Tomcat application server copy the war into the *$TOMCAT_HOME/webapps* folder and start the server via `$TOMCAT_HOME/bin/startup.sh` (at Windows via `$TOMCAT_HOME/bin/startup.bat`). 
+  - Optional: To import the sample project into Eclipse run the following steps:
+    - Start the command line tool and run `mvn eclipse:eclipse clean install` in the folder `$ODATA_PROJECT_HOME` to generate the Eclipse project settings and do an initial build. 
+    - Go into Eclipse and import the project into your workspace by...
+      - Menue "File" -> "Import..."
+      - "Existing projects into workspace" then choose the olingo.odata2.sample folder
+      - Select both projects olingo.odata2.sample.service and olingo.odata2.sample.web and press "Finish"
+
+### Hints
+  - Sometimes a code extension needs one or more new/additional imports. These are not shown in the examples because it would blow up the source code examples and normally the IDE should support an auto fix of missing imports during typing of the code or after an insert of copied code. 
+
+### Extend Read Scenario
+The steps to extend the read scenario (already with `$expand` support) with support for a Driver which is a media link entry with an associated media resource and therefore contains an image as media is to override and implement the `readEntityMedia(uriInfo:GetMediaResourceUriInfo, contentType:String):ODataResponse` method within the `MyODataSingleProcessor`.
+
+All $value requests - where $value is the next segment to an entity type instance identified by an EntitySet with key predicate or a navigation property (to one relation or key predicate for to many relation) - to the service are delegated to this method which then handles the creation of the according response. 
+
+### Extend MyEdmProvider and MyODataSingleProcessor
+
+#### Small sample code Prerequisites
+Not directly related to the OData Library parts but necessary for the sample project is the extension of the DataStore with methods to access the new Driver and the binary data for the media resource of the Driver.
+Because this extension is more boilerplate code with no direct OData impact it is recommended to simply copy the DataStore.java into the project.
+As conclusion following methods are added which are accessed from the `MyODataSingleProcessor`:
+
+  - `readDriverImage(entitySet:EdmEntitySet, id:int):byte[]` 
+  - `getDriverFor(carId:int):Map<String, Object> `
+  - `getCarFor(driverKey:int):Map<String, Object>` 
+  - `getDriver(id:int):Map<String, Object> `
+  - `getDrivers():List<Map<String, Object>>` 
+
+Additional and in conclusion with the `DataStore` three images (png) are added to the sample project. These images are located in */sample-service/src/main/resources/* and are named Driver_'x'.png were 'x' is replaced by a number.
+To really get an image for a media resource request it is necessary to copy these images (or create own PNG files which follows the naming schema).
+If nothing is copied/created the sample will still work but does not show an image for a media resource request (instead a HTTP Response 404 - Entity not found is shown). 
+
+** Extend MyEdmProvider with Driver data model **<br>
+
+First the new Driver is added in the EDM. 
+The Driver gets a Key (Id) and some properties (Name, Surname, Nickname, Updates). For simplification currently we do not add any associations to another entities.
+
+To mark the Driver as a media link entry with an associated media resource extension it is mandatory to set the stream property to true via the `setHasStream(true)` method when creating the `EntityType`.
+
+As conclusion the `getEntityType(…)` method is extended as follows:
+
+##### Sample Code
+
+    :::java
+    …
+      } else if (ENTITY_TYPE_1_3.getName().equals(edmFQName.getName())) {
+        List<Property> properties = new ArrayList<Property>();
+        properties.add(new SimpleProperty().setName("Id").setType(EdmSimpleTypeKind.Int32).setFacets(new Facets().setNullable(false)));
+        properties.add(new SimpleProperty().setName("Name").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setNullable(false).setMaxLength(50)));
+        properties.add(new SimpleProperty().setName("Surname").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setNullable(false).setMaxLength(80))
+                        .setCustomizableFeedMappings(new CustomizableFeedMappings().setFcTargetPath(EdmTargetPath.SYNDICATION_TITLE)));
+        properties.add(new SimpleProperty().setName("Nickname").setType(EdmSimpleTypeKind.String).setFacets(new Facets().setNullable(true).setMaxLength(50)));
+        properties.add(new SimpleProperty().setName("Updated").setType(EdmSimpleTypeKind.DateTime)
+            .setFacets(new Facets().setNullable(false).setConcurrencyMode(EdmConcurrencyMode.Fixed))
+            .setCustomizableFeedMappings(new CustomizableFeedMappings().setFcTargetPath(EdmTargetPath.SYNDICATION_UPDATED)));
+
+        // Navigation properties
+        List<NavigationProperty> navigationProperties = new ArrayList<NavigationProperty>();
+        
+        // Key
+        List<PropertyRef> keyProperties = new ArrayList<PropertyRef>();
+        keyProperties.add(new PropertyRef().setName("Id"));
+        Key key = new Key().setKeys(keyProperties);
+
+        // finish
+        return new EntityType().setName(ENTITY_TYPE_1_3.getName())
+            .setProperties(properties)
+            .setHasStream(true)
+            .setKey(key)
+            .setNavigationProperties(navigationProperties)
+            .setMapping(new Mapping().setMimeType("image/png"));
+    }
+    ...
+
+In addition it is necessary to extend the `getSchemas(…)` method with the according `EntityType` and `EntitySet` of the new Driver.
+
+    :::java
+    entityTypes.add(getEntityType(ENTITY_TYPE_1_3));
+    entitySets.add(getEntitySet(ENTITY_CONTAINER, ENTITY_SET_NAME_DRIVERS));
+
+And at last following constants are added to the `MyEdmProvider` for cleaner code.
+
+    :::java
+      static final String ENTITY_SET_NAME_DRIVERS = "Drivers";
+      static final String ENTITY_NAME_DRIVER = "Driver";
+      private static final FullQualifiedName ENTITY_TYPE_1_3 = new FullQualifiedName(NAMESPACE, ENTITY_NAME_DRIVER);
+
+**Extend `MyODataSingleProcessor` with `readEntityMedia(uriInfo:GetMediaResourceUriInfo, contentType:String):ODataResponse` method**<br>
+All requests for media resources are done via the specified $value property in the URL (e.g. *.../MyODataSample.svc/Drivers(1)/$value*). Such a request will be dispatched to an `EntityMediaProcessor` which is in our case the `MyODataSingleProcessor` (inherited from `ODataSingleProcessor`).
+To handle now such read requests for our media resources we override and implement the `readEntityMedia(uriInfo:GetMediaResourceUriInfo, contentType:String):ODataResponse` method.
+For our scenario we simply have to validate the correct requested target `EntitySet`, get the key for requesting the data from our `DataStore` (which contains the binary data of our media resource), use the `EntityProvider` to write the data and at last build the `ODataResponse`.
+Seems a lot but in code this are only these few lines:
+
+
+    :::java
+    @Override
+    public ODataResponse readEntityMedia(final GetMediaResourceUriInfo uriInfo, final String contentType) throws ODataException {
+    
+      final EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+      if(ENTITY_SET_NAME_DRIVERS.equals(entitySet.getName())) {
+        int id = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        byte[] image = dataStore.readDriverImage(entitySet, id);
+        if (image == null) {
+          throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+        }
+      
+        String mimeType = "image/png";
+        return ODataResponse.fromResponse(EntityProvider.writeBinary(mimeType, image)).build();
+      }
+    
+      throw new ODataNotImplementedException();
+    }
+
+With these extension it is possible to read the media resource, but for access to the Driver `EntitySet` and `Entity` the according read methods have to be extended.
+
+** Extend existing `readEntitySet(...)` and `readEntity(...)` methods in `MyODataSingleProcessor` methods **<br>
+For access to the Driver as `Entity` and as `EntitySet` the according `readreadEntitySet(...)` and `readEntity(...)` methods have to be extended.
+
+But its quite the same procedure as in the basic read. Validate the requested Entity, get the key for requesting the `DataStore` and write the result data via the `EntityProvider`.
+
+The resulting extension for `readEntity(…)`:
+
+    :::java
+      } else if (ENTITY_SET_NAME_DRIVERS.equals(entitySet.getName())) {
+        int id = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        Map<String, Object> data = dataStore.getDriver(id);
+
+        if (data != null) {
+          URI serviceRoot = getContext().getPathInfo().getServiceRoot();
+          ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(serviceRoot);
+
+          return EntityProvider.writeEntry(contentType, entitySet, data, propertiesBuilder.build());
+        }
+and `readEntitySet(…)`:
+
+      } else if (ENTITY_SET_NAME_DRIVERS.equals(entitySet.getName())) {
+        return EntityProvider.writeFeed(contentType, entitySet, dataStore.getDrivers(),     EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).build());
+
+
+**Conclusion for media resource extension**<br>
+After finishing all steps above the project can be built and deployed containing a Driver type which is a media link entry with associated media resource. *Congratulations.*
+
+For a more interesting sample and to update before learned knowledge about associations and `$expand` it is recommended to finish this HowTo with the creation of an association between a Driver and his Car with supported `$expand`.
+
+**Extend Driver with association to Car**<br>
+For a more interesting sample we now create an association between a Driver and his Car.
+
+**Extend Driver and Car in MyEdmProvider with a navigation property**<br>
+At first we introduce the necessary constants:
+
+    :::java
+      private static final FullQualifiedName ASSOCIATION_DRIVER_CAR = new FullQualifiedName(NAMESPACE, "Driver_Car-Car_Driver");
+    
+      private static final String ROLE_1_3 = "Car_Driver";
+      private static final String ROLE_3_1 = "Driver_Car";
+    
+      private static final String ASSOCIATION_SET = "Cars_Manufacturers";
+      private static final String ASSOCIATION_SET_CARS_DRIVERS = "Cars_Drivers";
+
+Then the `getSchemas()` in `MyEdmProvider` is extended with the new association:
+
+    associations.add(getAssociation(ASSOCIATION_DRIVER_CAR));
+    ...
+    associationSets.add(getAssociationSet(ENTITY_CONTAINER, ASSOCIATION_DRIVER_CAR, ENTITY_SET_NAME_DRIVERS, ROLE_3_1));
+Next step is the extension of the entity types in `getEntityType()` in `MyEdmProvider`.
+
+For the Car:
+
+    :::java
+      if (ENTITY_TYPE_1_1.getName().equals(edmFQName.getName())) {
+    ...
+        navigationProperties.add(new NavigationProperty().setName("Driver")
+            .setRelationship(ASSOCIATION_DRIVER_CAR).setFromRole(ROLE_1_3).setToRole(ROLE_3_1));
+    …
+    }
+
+And the Driver:
+
+    :::java
+      if (ENTITY_TYPE_1_3.getName().equals(edmFQName.getName())) {
+    ...
+        properties.add(new SimpleProperty().setName("CarId").setType(EdmSimpleTypeKind.Int32));
+    ...
+        navigationProperties.add(new NavigationProperty().setName("Car").setRelationship(ASSOCIATION_DRIVER_CAR).setFromRole(ROLE_3_1).setToRole(ROLE_1_3));
+    ...
+    }
+
+At last the `getAssociation(…)` and `getAssociationSet(...)` has also to be extended and has to look like:
+
+    :::java
+    @Override
+    public Association getAssociation(FullQualifiedName edmFQName) throws ODataException {
+      if (NAMESPACE.equals(edmFQName.getNamespace())) {
+        if (ASSOCIATION_CAR_MANUFACTURER.getName().equals(edmFQName.getName())) {
+          return new Association().setName(ASSOCIATION_CAR_MANUFACTURER.getName())
+            .setEnd1(new AssociationEnd().setType(ENTITY_TYPE_1_1).setRole(ROLE_1_1).setMultiplicity(EdmMultiplicity.MANY))
+            .setEnd2(new AssociationEnd().setType(ENTITY_TYPE_1_2).setRole(ROLE_1_2).setMultiplicity(EdmMultiplicity.ONE));
+        } else if (ASSOCIATION_DRIVER_CAR.getName().equals(edmFQName.getName())) {
+        return new Association().setName(ASSOCIATION_DRIVER_CAR.getName())
+            .setEnd1(new AssociationEnd().setType(ENTITY_TYPE_1_1).setRole(ROLE_1_3).setMultiplicity(EdmMultiplicity.ONE))
+            .setEnd2(new AssociationEnd().setType(ENTITY_TYPE_1_3).setRole(ROLE_3_1).setMultiplicity(EdmMultiplicity.ONE));
+        }
+      }
+      return null;
+    }
+
+
+
+    @Override
+    public AssociationSet getAssociationSet(String entityContainer, FullQualifiedName association, String sourceEntitySetName, String sourceEntitySetRole) throws ODataException {
+      if (ENTITY_CONTAINER.equals(entityContainer)) {
+        if (ASSOCIATION_CAR_MANUFACTURER.equals(association)) {
+          return new AssociationSet().setName(ASSOCIATION_SET)
+            .setAssociation(ASSOCIATION_CAR_MANUFACTURER)
+            .setEnd1(new AssociationSetEnd().setRole(ROLE_1_2).setEntitySet(ENTITY_SET_NAME_MANUFACTURERS))
+            .setEnd2(new AssociationSetEnd().setRole(ROLE_1_1).setEntitySet(ENTITY_SET_NAME_CARS));
+        } else if (ASSOCIATION_DRIVER_CAR.equals(association)) {
+          return new AssociationSet().setName(ASSOCIATION_SET_CARS_DRIVERS)
+            .setAssociation(ASSOCIATION_DRIVER_CAR)
+            .setEnd1(new AssociationSetEnd().setRole(ROLE_3_1).setEntitySet(ENTITY_SET_NAME_DRIVERS))
+            .setEnd2(new AssociationSetEnd().setRole(ROLE_1_3).setEntitySet(ENTITY_SET_NAME_CARS));
+        }
+      }
+      return null;
+    }
+
+
+**Extend existing `readreadEntitySet(...)` and `readEntity(...)` methods in `MyODataSingleProcessor`**<br>
+For cleaner code we introduce at first following method in the `MyODataSingleProcessor` which validate if the uri contains the expected association.
+
+    :::java
+    private boolean isAssociation(GetEntityUriInfo uriInfo, String startName, String targetName) throws EdmException {
+      if(startName == null || targetName == null) {
+      return false;
+      }
+      EdmEntitySet startEntitySet = uriInfo.getStartEntitySet();
+      EdmEntitySet targetEntitySet = uriInfo.getTargetEntitySet();
+    
+      return startName.equals(startEntitySet.getName()) && targetName.equals(targetEntitySet.getName());
+    }
+
+The procedure should be already familiar. At first it is checked for the correct association of the requested Entity, then the key for requesting the DataStore is get as well as the data and then result data is written via the `EntityProvider`.
+
+    :::java
+    } else if (uriInfo.getNavigationSegments().size() == 1) {
+      //navigation first level, simplified example for illustration purposes only
+      EdmEntitySet entitySet = uriInfo.getTargetEntitySet();
+      
+      Map<String, Object> data = null;
+      
+      if (ENTITY_SET_NAME_MANUFACTURERS.equals(entitySet.getName())) {
+        int carKey = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        data = dataStore.getManufacturerFor(carKey);
+      } else if(isAssociation(uriInfo, ENTITY_SET_NAME_CARS, ENTITY_SET_NAME_DRIVERS)) {
+        int carKey = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        data = dataStore.getDriverFor(carKey);
+      } else if(isAssociation(uriInfo, ENTITY_SET_NAME_DRIVERS, ENTITY_SET_NAME_CARS)) {
+        int driverKey = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        data = dataStore.getCarFor(driverKey);
+      }
+      
+      if(data != null) {
+        return EntityProvider.writeEntry(contentType, uriInfo.getTargetEntitySet(), 
+            data, EntityProviderWriteProperties.serviceRoot(getContext().getPathInfo().getServiceRoot()).build());
+      }
+
+      throw new ODataNotFoundException(ODataNotFoundException.ENTITY);
+    }
+
+**Add $expand support for Driver to/from Car association**<br>
+The last missing step is to add the `$expand` support for the new Driver to/from Car association.
+
+**Extend MyCallback for Driver and Car association**<br>
+Add first the extension in the MyCallback for each entity is done in the `retrieveEntryResult()` method.
+The procedure is similar to the Cars - Manufacturers association. At first it is checked for the correct association of the requested Entity, then the key for requesting the DataStore is get as well as the data and then result data is attached to the `WriteEntryCallbackResult`.
+
+The resulting method extension is:
+
+    :::java
+    ...
+      if(isNavigationFromTo(context, ENTITY_SET_NAME_CARS, ENTITY_NAME_DRIVER)) {
+        EntityProviderWriteProperties inlineProperties = EntityProviderWriteProperties.serviceRoot(serviceRoot)
+            .expandSelectTree(context.getCurrentExpandSelectTreeNode())
+            .build();
+
+        Map<String, Object> keys = context.extractKeyFromEntryData();
+        Integer carId = (Integer) keys.get("Id");
+        result.setEntryData(dataStore.getDriverFor(carId));
+        result.setInlineProperties(inlineProperties);
+        
+      } else if(isNavigationFromTo(context, ENTITY_SET_NAME_DRIVERS, ENTITY_NAME_CAR)) {
+        EntityProviderWriteProperties inlineProperties = EntityProviderWriteProperties.serviceRoot(serviceRoot)
+            .expandSelectTree(context.getCurrentExpandSelectTreeNode())
+            .build();
+
+        Map<String, Object> keys = context.extractKeyFromEntryData();
+        Integer driverId = (Integer) keys.get("Id");
+        result.setEntryData(dataStore.getCarFor(driverId));
+        result.setInlineProperties(inlineProperties);        
+      }
+    ...
+
+**Add registration of MyCallback for Driver and Car association**<br>
+After extension of `MyCallback` it is necessary to register a callback within the `readEntity()` in the `MyODataSingleProcessor`.
+
+For the Driver we add the complete callback registration (code between the comments) which results in final code for the complete Driver Entity handling:
+
+    :::java
+    ...
+       } else if (ENTITY_SET_NAME_DRIVERS.equals(entitySet.getName())) {
+        int id = getKeyValue(uriInfo.getKeyPredicates().get(0));
+        Map<String, Object> data = dataStore.getDriver(id);
+
+        if (data != null) {
+          URI serviceRoot = getContext().getPathInfo().getServiceRoot();
+          ODataEntityProviderPropertiesBuilder propertiesBuilder = EntityProviderWriteProperties.serviceRoot(serviceRoot);
+
+          // create and register callback
+          Map<String, ODataCallback> callbacks = new HashMap<String, ODataCallback>();
+          callbacks.put(ENTITY_NAME_CAR, new MyCallback(dataStore, serviceRoot));
+          ExpandSelectTreeNode expandSelectTreeNode = UriParser.createExpandSelectTree(uriInfo.getSelect(), uriInfo.getExpand());
+          propertiesBuilder.expandSelectTree(expandSelectTreeNode).callbacks(callbacks);
+          // end callback handling
+
+          return EntityProvider.writeEntry(contentType, entitySet, data, propertiesBuilder.build());
+        }
+      }
+    ...
+
+For the Car it is only necessary to add the single code line below to register the additional callback and enable the `$expand`:
+
+    :::java
+      if (ENTITY_SET_NAME_CARS.equals(entitySet.getName())) {
+    ...
+          callbacks.put(ENTITY_NAME_DRIVER, new MyCallback(dataStore, serviceRoot));
+    ...
+    }
+
+Deploy, run and test
+Like in the basic read scenario follow these steps:
+
+  - Build your project mvn clean install 
+  - Deploy in Web Application server. When using within Eclipse simply run the Web Application via Run As -> Run on Server 
+  - After successful server start and deployment the following uris from the read scenario work as before: 
+    - Show the Manufacturers: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers) 
+    - Show one Manufacturer: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)) 
+    - Show the Cars: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars) 
+    - Show one Car: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)) 
+    - Show the related Manufacturer of a Car: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)/Manufacturer](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)/Manufacturer) 
+    - Show the related Cars of a Manufacturer: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)/Cars ](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)/Cars )
+    - Show Car with its Manufacturer: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)?$expand=Manufacturer ](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Cars(2)?$expand=Manufacturer )
+    - Show Manufacturer with its Cars: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)?$expand=Cars ](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Manufacturers(1)?$expand=Cars )
+  - And in addition we now can access the drivers with their media resource ($value) and the association to their car. 
+    - Show one Driver: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)) 
+    - Show Media Resource of Driver: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)/$value](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)/$value) 
+    - Show Car of the Driver: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)/Car](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)/Car) 
+   - Show Driver with expanded Car: [http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)?$expand=Car ](http://localhost:8080/olingo.odata2.sample.cars.web/MyODataSample.svc/Drivers(3)?$expand=Car )
+
+### Conclusion
+After finishing all steps of this tutorial your project contains three different entities with relations between them and one of them with media link entry and media resource support.
+
+If something does not compile or run it is recommended to compare to the complete sample project source code in the [Olingo Tutorial 'Basic Read with Media Resource extension' Project](apache-olingo-tutorial-adv_read_mediaresource). 
+For more details about how to use/setup the project in the zip see section ***Shortcut***.
\ No newline at end of file

Added: olingo/site/trunk/content/doc/odata4/tutorials/servlet.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/doc/odata4/tutorials/servlet.mdtext?rev=1625261&view=auto
==============================================================================
--- olingo/site/trunk/content/doc/odata4/tutorials/servlet.mdtext (added)
+++ olingo/site/trunk/content/doc/odata4/tutorials/servlet.mdtext Tue Sep 16 12:33:56 2014
@@ -0,0 +1,74 @@
+Title:
+Notice:    Licensed to the Apache Software Foundation (ASF) under one
+           or more contributor license agreements.  See the NOTICE file
+           distributed with this work for additional information
+           regarding copyright ownership.  The ASF licenses this file
+           to you under the Apache License, Version 2.0 (the
+           "License"); you may not use this file except in compliance
+           with the License.  You may obtain a copy of the License at
+           .
+             http://www.apache.org/licenses/LICENSE-2.0
+           .
+           Unless required by applicable law or agreed to in writing,
+           software distributed under the License is distributed on an
+           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+           KIND, either express or implied.  See the License for the
+           specific language governing permissions and limitations
+           under the License.
+
+# Servlet Support
+
+Originally the Olingo OData 2.0 server library has been implemented 
+based on JAX-RS to take advantage of the REST based CXF features.
+
+With the development of Olingo URI parser it was possible now also 
+to offer a purely servlet-based approach. This has some advantages 
+on restricted runtime environments and reduces the amount of 
+required dependencies. Disadvantage is that some REST features
+which are out of the box are not available.
+
+Both solutions JAX-RS and Non-JAX-RS are supported.
+
+For testing the feature it is recommended to start with the 
+[sample setup](http://olingo.incubator.apache.org/doc/odata2/sample-setup.html) using the Olingo archetype and do the following 
+modifications.
+
+### Maven Dependencies
+
+For a plain servlet based approach it is possible to exclude JAX-RS 
+dependencies. A simple way is to exclude them with Maven:
+
+    <dependency>
+      <groupId>org.apache.olingo:olingo</groupId>
+      <artifactId>odata2-core-incubating</artifactId>
+      <version>1.2.0</version>
+      <exclusions>
+        <exclusion>  
+          <groupId>javax.ws.rs</groupId>
+          <artifactId>javax.ws.rs-api</artifactId>
+        </exclusion>
+      </exclusions> 
+    </dependency>
+
+A JAX-RS implementation dependency like Apache CXF is not required 
+for runtime.
+
+### Adopt web.xml
+
+For using the servlet based approach only a new Servlet must be 
+configured in web.xml file:
+
+    <servlet>
+        <servlet-name>NonJaxRSReferenceScenarioServlet</servlet-name>
+        <servlet-class>org.apache.olingo.odata2.core.servlet.ODataServlet</servlet-class>
+        <init-param>
+            <param-name>org.apache.olingo.odata2.service.factory</param-name>
+            <param-value>org.apache.olingo.odata2.ref.processor.ScenarioServiceFactory</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+
+Ensure that all runtime dependencies to Apache CXF are removed from 
+the sample project.
+
+After this modification the service should work like before.

Modified: olingo/site/trunk/content/documentation2.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/documentation2.mdtext?rev=1625261&r1=1625260&r2=1625261&view=diff
==============================================================================
--- olingo/site/trunk/content/documentation2.mdtext (original)
+++ olingo/site/trunk/content/documentation2.mdtext Tue Sep 16 12:33:56 2014
@@ -22,9 +22,9 @@ Notice:    Licensed to the Apache Softwa
 
 ### How to Start
 
-* [Sample Project Setup with Maven Archetypes](/doc/sample-setup.html)
-* [Run with Tomcat](/doc/tomcat.html)
-* [Maven Dependencies](/doc/dependencies.html)
+* [Sample Project Setup with Maven Archetypes](/doc/odata2/sample-setup.html)
+* [Run with Tomcat](/doc/odata2/tomcat.html)
+* [Maven Dependencies](/doc/odata2/dependencies.html)
 
 ---
 
@@ -76,7 +76,6 @@ Notice:    Licensed to the Apache Softwa
 
 ### Olingo Project Setup (Contributors)
 
-* [Git and Maven Support](/doc/maven.html)
-* [Eclipse IDE Support](/doc/eclipse.html)
+* [Git and Maven Support](/doc/odata2/maven.html)
+* [Eclipse IDE Support](/doc/odata2/eclipse.html)
 * [Release Documentation](doc/release.html)
-

Modified: olingo/site/trunk/content/download.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/download.mdtext?rev=1625261&r1=1625260&r2=1625261&view=diff
==============================================================================
--- olingo/site/trunk/content/download.mdtext (original)
+++ olingo/site/trunk/content/download.mdtext Tue Sep 16 12:33:56 2014
@@ -16,49 +16,31 @@ Notice:    Licensed to the Apache Softwa
            specific language governing permissions and limitations
            under the License.
 
-# Download OData 2.0 Java Library
+# Downloads for Apache Olingo
 
-Apache Olingo OData2 is a collection of Java libraries for 
+### Download Apache Olingo OData 2.0 Java Library
+Apache Olingo OData2 is a collection of Java libraries for
 implementing [OData V2][1] protocol clients or servers.
 
-### Release 2.0.0 (2014-07-11)
+[Download options for latest release 2.0.0 (2014-07-11)](/doc/odata2/download.html)
 
-[Full download page][2], [release notes][3]
+##### Maven
+Apache Olingo OData2 artifacts are available at [Maven Central](http://search.maven.org/#search|ga|1|org.apache.olingo). For POM dependencies see [here](/doc/odata2/maven.html).
 
-The Apache Olingo OData2 2.0.0 release is a major release. 
 
-### Commodity Packages
+### Download Apache Olingo OData 4.0 Java Library
+Apache Olingo OData4 is a collection of Java libraries for
+implementing [OData V4][1] protocol clients (Android/Java) or servers.
 
-Package | zip | Description
-------- | --- | -----
-Olingo OData2 Library            | [Download](http://www.apache.org/dyn/closer.cgi/olingo/odata2/rel-2.0.0/olingo-odata2-dist-lib-2.0.0-lib.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-lib-2.0.0-lib.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-lib-2.0.0-lib.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-lib-2.0.0-lib.zip.asc)) | All you need to implement an OData V2 client or server.
-Olingo OData2 Sources            | [Download](http://www.apache.org/dyn/closer.cgi/olingo/odata2/rel-2.0.0/olingo-odata2-parent-2.0.0-source-release.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-parent-2.0.0-source-release.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-parent-2.0.0-source-release.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-parent-2.0.0-source-release.zip.asc)) | Olingo OData2 source code.
-Olingo OData2 Docs               | [Download](http://www.apache.org/dyn/closer.cgi/olingo/odata2/rel-2.0.0/olingo-odata2-dist-javadoc-2.0.0-javadoc.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-javadoc-2.0.0-javadoc.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-javadoc-2.0.0-javadoc.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-javadoc-2.0.0-javadoc.zip.asc)) | Documentation and JavaDoc.
-Olingo OData2 JPA Processor      | [Download](http://www.apache.org/dyn/closer.cgi/olingo/odata2/rel-2.0.0/olingo-odata2-dist-jpa-2.0.0-jpa.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-jpa-2.0.0-jpa.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-jpa-2.0.0-jpa.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-jpa-2.0.0-jpa.zip.asc)) | All you need to expose your JPA model as OData service.
-Olingo OData2 Java Annotation Processor      | [Download](http://www.apache.org/dyn/closer.cgi/olingo/odata2/rel-2.0.0/olingo-odata2-dist-janos-2.0.0-janos.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-janos-2.0.0-janos.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-janos-2.0.0-janos.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-janos-2.0.0-janos.zip.asc)) | Use Java Annotations for an easy OData service.
-Olingo OData2 Reference Scenario | [Download](http://www.apache.org/dyn/closer.cgi/olingo/odata2/rel-2.0.0/olingo-odata2-dist-ref-2.0.0-ref.zip) ([md5](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-ref-2.0.0-ref.zip.md5), [sha512](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-ref-2.0.0-ref.zip.sha512), [pgp](https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/olingo-odata2-dist-ref-2.0.0-ref.zip.asc)) | Deployable WAR files with reference scenario services using <a href="http://cxf.apache.org">Apache CXF</a>.
+[Download options for latest release 4.0.0-beta-01 (to be announced)](/doc/odata4/download.html)
 
-### Maven
+##### Maven
+Apache Olingo OData4 artifacts are available at [Maven Central](http://search.maven.org/#search|ga|1|org.apache.olingo). For POM dependencies see [here](/doc/odata4/maven.html).
 
-Apache Olingo OData2 artifacts are available at [Maven Central](http://search.maven.org/#search|ga|1|org.apache.olingo). For POM dependencies see [here](/doc/maven.html).
+### Download Olingo OData Client for JavaScript Library
+The Olingo OData Client for JavaScript (odatajs) is a library written in JavaScript that enables browser based frontend applications to easily use the OData protocol for communication with application servers.
 
-### Older Releases
-
-For older releases please refer to [Archives][4] 
-or you can get them [using Maven](doc/maven.html).
-
-### Verify Authenticity of Downloads package
-
-While downloading the packages, make yourself familiar 
-on how to verify their integrity, authenticity and provenience 
-according to the Apache Software Foundation best practices.
-Please make sure you check the following resources:
-
-  - [Artifact verification](verification.html) details
-  - Developers and release managers PGP keys are publicly available [here](http://apache.org/dist/incubator/olingo/KEYS).
+[Download options for latest release 4.0.0-beta-01 (2014-09-15)](/doc/javascript/download.html)
 
 
   [1]: http://odata.org
-  [2]: https://dist.apache.org/repos/dist/release/olingo/odata2/rel-2.0.0/
-  [3]: https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12314520&version=12327170
-  [4]: http://archive.apache.org/dist/olingo/
\ No newline at end of file

Modified: olingo/site/trunk/content/index.mdtext
URL: http://svn.apache.org/viewvc/olingo/site/trunk/content/index.mdtext?rev=1625261&r1=1625260&r2=1625261&view=diff
==============================================================================
--- olingo/site/trunk/content/index.mdtext (original)
+++ olingo/site/trunk/content/index.mdtext Tue Sep 16 12:33:56 2014
@@ -36,7 +36,7 @@ features like the support of JPA persist
 </p>
 <p>
   <a class="btn btn-lg btn-primary" style="float: right; margin-left:10px" href="/doc/javascript/index.html" role="button">JavaScript</a>
-  <a class="btn btn-lg btn-primary" style="float: right; margin-left:10px" href="/documentation.html" role="button">Java</a>
+  <a class="btn btn-lg btn-primary" style="float: right; margin-left:10px" href="/doc/odata2/index.html" role="button">Java</a>
   <!-- TODO change style via bootstrap -->
   <span style="-webkit-user-select: none;
 background-color: rgb(66, 139, 202);

Modified: olingo/site/trunk/templates/skeleton.html
URL: http://svn.apache.org/viewvc/olingo/site/trunk/templates/skeleton.html?rev=1625261&r1=1625260&r2=1625261&view=diff
==============================================================================
--- olingo/site/trunk/templates/skeleton.html (original)
+++ olingo/site/trunk/templates/skeleton.html Tue Sep 16 12:33:56 2014
@@ -64,7 +64,7 @@
               <li class="dropdown">
                   <a href="#" class="dropdown-toggle" data-toggle="dropdown">Download <b class="caret"></b></a>
                   <ul class="dropdown-menu">
-                      <li><a href="/download.html">Download OData 2.0 Java</a></li>
+                      <li><a href="/doc/odata2/download.html">Download OData 2.0 Java</a></li>
                       <li><a href="/doc/javascript/download.html">Download OData 4.0 JavaScript</a></li>
                   </ul>
               </li>
@@ -72,7 +72,7 @@
               <li class="dropdown">
                   <a href="#" class="dropdown-toggle" data-toggle="dropdown">Documentation <b class="caret"></b></a>
                   <ul class="dropdown-menu">
-                    <li><a href="/documentation.html">Documentation OData 2.0 Java</a></li>
+                    <li><a href="/doc/odata2/index.html">Documentation OData 2.0 Java</a></li>
                     <li><a href="/doc/javascript/index.html">Documentation OData 4.0 JavaScript</a></li>
                   </ul>
               </li>
@@ -89,7 +89,7 @@
 				                Apache Olingo, Olingo, Apache, the Apache feather, and
 				the Apache Olingo project logo are trademarks of the Apache Software
 				Foundation.</p>
-        <small><a href="/doc/privacy.html">Privacy</a></small>
+        <small><a href="/doc/odata2/privacy.html">Privacy</a></small>
       </div>
     </div><!-- /container -->
     <!-- Bootstrap core JavaScript