[Google Android Client Platform] User Guide

Last modified by sasindarukshan on 2012/08/04 13:48

1] Architecture

Xwiki Android Platform Architecture.

2] Domain Model

2.1 Xwiki Domain Model

2.1.1 Overview

XWiki Domain model overview.PNG

2.1.2 Document Model

XWiki Domain Model Composition Diagram.PNG

3] Base Services and Extended Services.

The basic services that should be offered as a platform are provided in two main packages. [1,2] below. Other client application specific services are provided as extended services simply for the ease of use [3]. 

1) org.xwiki.android.svc
        |__ xmodel
        |__ cmn
2) org.xwiki.android. svcbg
3) org.xwiki.android.svcx

Package: svc 
The base services that are with direct relationship to Xwiki Domain model entities such as Document are provided under here.
package : svcbg 
All base back ground services. Ex: Synchronization Service Daemon.
Package: svcx 
All extended Services. These are specific for applications. Ex: .svcx.blog package. Which provides services which are specific to blog client apps.

3.1 Base Services

3.1.1 Document Services

Document Services offer services to  transfer document state to server and persistence in local device.It provides with 2 types of services.

  1. Document Local Services
    Services wich operate in a local context. Ex: saving the document to the local data storage.

2. Document Remote Services
Services wich communicate to the server. Ex: create the a document in the server.
It also handles threading for blocking operations by implementing a callback pattern.
Below Sample shows a sample service call.

It also handles threading for blocking operations by implementing a callback pattern.
Below Sample shows a sample service call.

Document mydoc= new ...        
       
DocumentRemoteSvcs docsvc=new DocumentSvcImpl        
DocumentRemoteSvcCallbacks clbk=new DocumentRemoteSvcCallbacks()
       {
           @Override
           public void onCreated(Document res, boolean success, RaoException  ex)
           {
           }

 
       };        
docsvc.create(mydoc,clbk);

Here the thread calling docsvc.create(...) method does not get blocked. The results of the method call is passed to the Document Svc Call back. If an exception happens during the service execution it is also passed back to the client asynchronically.
This callback method reduces the code in the android activities , since the Main Thread(UI Thread) can now call these long running operations without worryng about ANR (Application Not Responding) s.

The default constructor of the abstract  "callback" class [DocumentRemoteSvcCallbacks()] binds to the Looper of the main UI thread.  When call backs are needed to be invoked it passes a message (here a runnable "java.lang.Runnable" ) to the Loopers message Q and the main UI thread will run the call back method declared above.

callbacks.PNG

Above figure illustrates how the worker thread invokes the Callback method after completing the service operation. It passes a message to the UI thread's looper to run the onCreated(...) callback.

You can run these callbacks using another thread simply by prepairing a looper for that thread and passing the prepaired looper to the callback methods constructor. DocumentRemoteSvcCallbacks(Looper looper). (here looper is the Looper of the thread wich should be invoked by the worker thread to run the callback.)

3.1.1.1 Async Exception handling in Remote Services.

DocumentRemoteSvcCallbacks clbk=new DocumentRemoteSvcCallbacks()
       {
           @Override
           public void onCreated(Document res, boolean success,RaoException  ex)
           {
               if(!success){ handle exception}
           }
          
           @Override
           public void handleException(RestConnectionException e)
           {
             handle network connectivity issue.
            super.handleException(e);
           }
       };

Exceptions due to network connectivity issues, etc that that prevents the service from success are returned back through a separate "handleException(RestConnectionException e)" method. This is done seperately from other exceptions as exception handling code for this is unrelated to which service you had called before.

The RaoException in the onCreated(...) callback reports exceptions that are relevent to the service request. Suchas not satisfying preconditions for the service.
Ex: create(doc) will need as a prerequisite that the related "doc" is not already existing in the server. A RaoException will be asynchronically sent back if this condition is not met.

4] ReSTful Client APIs.

4.1 XWiki REST model for simple-xml

Xwiki Rest Model quick intro:
Xwiki Rest Model is a model used for data transfer between the server and client. The rest model supports two major forms of RESTful data transfer, namely XML, JSON.

Currently XWiki RESTful API is based on JAXB model. But when it comes to Android or any other mobile development we cannot use heavy libraries such as JAXB due to limited storage size of a mobile device. Therefore we built a model for simple-xml which is a light-weight XML parser that suits Android requirements.

For adding simple-xml to your dependency use following XML content in your maven configuration(pom.xml)

<dependency>
<groupId>org.simpleframework</groupId>
<artifactId>simple-xml</artifactId>
<version>2.6</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

4.2 Rest Access Layer

Rest Access Layer is a high level API to communicate with an XWiki instance. This layer contains RESTFul Access Objects (a.k.a Rao s) for main XWiki Domain model entities which are used to manipulate the state of the equivalent entities in the server.

RAL.PNG

Following code snippet shows how to create a document using a DocumentRao.

Document mydoc = ... ;
XWikiApplicationContext ctx = XWikiApplicationContext.getInstance();
RESTfulManager rMngr = ctx.newRESTfulManager();
DocumentRao rao = rMngr.newDocumentRao();
   
try {
 rao.create(doc);

} catch (RestConnectionException e){     
} catch (RaoException e) {
} 

Mind that these operations are long running blocking operations.

4.3 Low Level  XWiki Rest API

All the operations explained under http://platform.xwiki.org/xwiki/bin/view/Features/XWikiRESTfulAPI are directly supported in this API. This API directly deals with XWiki Rest Model.
4.3.1 Sample Usage

Android XWiki REST API is an Android Library (apklib) which covers XWiki RESTful API. Developers should first add this library (xwiki-android-rest) and simple-xml model (xwiki-rest-model-simplexml) to the dependency. Then it can be handle over the model objects and REST methods to communicate with the remote XWiki instance. 

For adding XWiki REST API as a Android Library(apklib)

<dependency>
<groupId>org.xwiki.android</groupId>
<artifactId>xwiki-android-rest</artifactId>
<type>apklib</type>
<version>${project.version}</version>
</dependency>

It is essential to give permissions to your application for accessing network and write date to the storage. Use following permission in AndroidManifest.xml of your application

    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

If you want to retrieve comments of a specific page in XWiki you will find yourself writing some code like this:

import org.xwiki.android.resources.Comments;
import org.xwiki.android.rest.Requests;

...

       // Creates a new Request to the Xwiki instance eg: www.xwiki.org
       Requests request = new Requests("www.xwiki.org");
       
       // Set user credentials if any
       // depending on the action you perform authentication will be mandotory
       request.setAuthentication("Username", "Password");
       
       // Retrieve comments a page providing names of wiki, space and page
       // eg: wikiname ="xwiki", spacename="Blog", pagename="testPage"
       Comments comments = request.requestPageComments("xwiki", "Blog", "testPage");

...

Same way you can add comments to the XWiki. Here is some code

import org.xwiki.android.resources.Comment;

...

       // Creates a new Request to the Xwiki instance eg: www.xwiki.org
       Requests request = new Requests("www.xwiki.org");

       // Creates a new Comment object in Android XWiki REST model
       Comment comment = new Comment();

       // Sets its attributes
       comment.setText("This is a test comment in android rest library");
       ...
       ...

       // add the Comment through the request object
       String s = request.addPageComment("xwiki", "Blog", "testPage", comment);
       
...

Use java docs of the library for identifying all the implemented methods. Requests class centralizes all possible REST services. Therefore any resource in XWiki can be managed through a method call in Requests class.

There is a special case when downloading and uploading attachments since it has to handle with raw data. For attachment downloading REST API provide InputStream from the XWiki and for uploading REST API uses absolute file path and name directly.

4.4 Model Transformation.

For transforming the Xwiki Domain model to Rest model and vice versa, following transformation components are provided.

<<>>

The org.xwiki.android.rest.transformation.DocumentBuilder can be used to transform and assemble Rest Model elements into a XWiki  Domain model Document.

<<>> 

5] Using the Data Access APIs

For Local Data Access/ persistence the platform provides two APIs.

  • SQLite DB Entity Manager.
  • File Store

5.1 File Store

File store is a document database. It's main purpose is to save XWiki Domain model documents.The usage is explained below.

<<fal>>

5.1.1 Sample Usage
XWikiApplicationContext ctx = XWikiApplicationContext.getInstance();
FileStoreManager= ctx.getFileStoreManager();
DocumentFao fao = fMngr.getDocumentFao();

Document doc= ... ;
String tag="my tag";
FSDocumentReference fref = fao.save(doc, tag);

Mind that above data operations are blocking operations.

5.2 Relational Database

<<dao>>

5.2.1 Sample Usage
import org.xwiki.android.data.rdb.EntityManager;
import org.xwiki.android.entity.SyncOutEntity;
import com.j256.ormlite.dao.Dao;

Dao<SyncOutEntity, Integer> dao = em.getDao(SyncOutEntity.class);
     List<SyncOutEntity> list=dao.queryForAll();

6] Dependency Injection

Use XWikiApplicationContext class to get concrete instances of major platform components. You can receive a XWikiApplicationContext by calling android activities getApplicationContext() method. You would write a code as in your Activity.

 XWikiApplicationContextAPI ctx=(XWikiApplicationContext)getApplicationContext();

If you are need a reference to the context outside an Activity you can get the instance as follows.

 
 XWikiApplicationContextAPI ctx= XWikiApplicationContext.getInstance();

The XWikiApplicationContextAPI interface is provided for loose coupling and to give a clear separation from android native services in the context object and the XWiki Platform specific ones. You may refer to the concrete  -

 XWikiApplicationContext ctx=(XWikiApplicationContext)getApplicationContext();

- to have both set of services.

Get Connected