Skip to content
This repository has been archived by the owner on Sep 26, 2023. It is now read-only.

User Guide

Taras Kunyk edited this page May 13, 2015 · 4 revisions

Quickstart

Create Drupal client

First we need to create DrupalClient, where we pass base server url and context.

DrupalClient client = new DrupalClient("http:\\my.server.com", getContext());

You can also use alternative constructors to specify request queue or login manager.

Implement Drupal Entity

In order to implement drupa entity you need to extend AbstractDrupalEntity or AbstractDrupalArrayEntity and implement abstract methods.

public class MyDrupalEntity extends AbstractDrupalEntity {

    private String pageNumber;

    public MyDrupalEntity(DrupalClient client) {
        super(client);
    }

    /**
     * @return relative path to entity on the server.
     */
    @Override
    protected String getPath() {
        return "entities/" + entityId;
    }

    /**
     * @return item post parameters if needed. 
     * Note: method will be called for post request only and in case 
     * if null is returned - serialized object will be posted.
     */
    @Override
    protected Map<String, String> getItemRequestPostParameters() {
        return null;
    }

    /**
     * @return parameters for each request type get/post/delete or patch
     */
    @Override
    protected Map<String, String> getItemRequestGetParameters(BaseRequest.RequestMethod method) {
        switch (method) {
            case GET:
                Map<String, String> result = new HashMap<String, String>();
                result.put("page", pageNumber);
                return result;
            case POST:
            case PATCH:
            case DELETE:
            default:
                return null;
        }
    }

    public void setPageNumber(String pageNumber) {
        this.pageNumber = pageNumber;
    }
}

Instantiate Drupal Entity

MyDrupalEntity entity = new MyDrupalEntity(client);
entity.setPageNumber(104);

Perform server requests

Synchronous

Class<?> myResponseClass = MyResponseClass.class;
boolean isSynchronous = true;

// Fetch entity from server
ResponseData response = entity.pullFromServer(isSynchronous, null, null);

// Post entity to server
ResponseData response = entity.pushToServer(isSynchronous, myResponseClass , null, null);

// Patch entity on server
entity.createSnapshot();
entity.setValue1(...);
entity.setValie2(...);
if(entity.isModified()) {
    ResponseData response = entity.patchServerData(isSynchronous, myResponseClass , null, null);
}

// Remove entity from server
ResponseData response = entity.deleteFromServer(isSynchronous, myResponseClass , null, null);

Asynchronous

Class<?> myResponseClass = MyResponseClass.class;
final Tag myTag = new Tag(); // TODO provide more details
OnEntityRequestListener listener = new OnEntityRequestListener() {

    @Override
    public void onRequestCompleted(AbstractBaseDrupalEntity entity, Object tag, ResponseData data) {
        if (tag == myTag) {
            //Handle response;
        }
    }

    @Override
    public void onRequestCanceled(AbstractBaseDrupalEntity entity, Object tag) {
        if (tag == myTag) {
            //Handle response cancel;
        }
    }

    @Override
    public void onRequestFailed(AbstractBaseDrupalEntity entity, Object tag, VolleyError error) {
        if (tag == myTag) {
            //Handle response failure;
        }
    }
};

boolean isSynchronous = false;

// Fetch entity from server
entity.pullFromServer(isSynchronous, listener, myTag );

// Post entity to server
entity.pushToServer(isSynchronous, myResponseClass , listener, myTag );

// Patch entity on server
entity.createSnapshot();
entity.setValue1(...);
entity.setValie2(...);
if(entity.canPatch()) {
    entity.patchServerData(isSynchronous, myResponseClass , listener, myTag );
}

// Remove entity from server
entity.deleteFromServer(isSynchronous, myResponseClass , listener, myTag );

Extra Features Guide

User re-login

Just update following methods in your ILoginManager implementation:

@override
boolean shouldRestoreLogin()
{
	return true;
}

@override
boolean canRestoreLogin()
{
	//Define if you actually are able to restore login session (e.g. have some stored access token or credentials) and return true only if you are able to.	
}

@override
boolean restoreLoginData(RequestQueue queue)
{
	//Try to restore login session, reading some cached data or calling server authentication method. return true if login restore succeed.
}

Login restoring workflow:

  1. Server api call returns 401 status code;
  2. canRestoreLogin check (if true go to 3. else go to 5.)
  3. restoreLoginData call (if true go to 4. else go to 5.)
  4. Second api call attempt performed( if 401 code returned go to 5. else go to 6.)
  5. Return error, call onLoginRestoreFailed method
  6. Return result

Server connectivity state tracking

API doesn't monitor wi-fi connectivity state. It just notifies user in case if there was no response from server. And when this connection is detected (due to successful response receiving). Currently this feature is partially implemented and isn't able to distinguish different services (So it acts fine only in case if you are using single server or have to monitor internet accessibility).

In order to use this feature you have to setup your OnConnectionStateChangedObserver to ConnectionManager:

ConnectionManager manager = ConnectionManager.instance();
OnConnectionStateChangedObserver myObserver = new OnConnectionStateChangedObserver()
{
	@override
	public void onConnectionStateChanged(boolean connectionPresent)
	{
		//Perform some action.
	}
}

//To register observer
manager.registerObserver(myObserver);

//To unregister observer
manager.unregisterObserver(myObserver);

Note: Observer doesn't monitor connectivity state itself - it's reacting based on request results. So you don't have to check it's state before sending requests to server (Otherwise your requests will never be started again ).

Duplicate request filter

This feature allows user to reject or attach similar simultaneous requests to the server. Similarity is defined based on url, request post/get parameters, headers and request/return types.

myClient.setDuplicateRequestPolicy(DuplicateRequestPolicy.ATTACH);

There are 3 request policy's available now:

  • ALLOW - all requests are performed
  • ATTACH - only first unique request from queue will be performed all other listeners will be attached to this request and triggered.
  • REJECT - only first unique request from queue will be performed and it's listener triggered. onCancel() listener method will be called for all requests skipped.

Multipart entity submitting

AbstractMultipartDrupalEntity class allows user to perform post and put multipart entity requests Note: pull and patch methods aren't supported by this entity.

Multipart entity serializer is checking if non-transient field implements IMultiPartEntityPartinterface if so - getContentBody method is called and toString otherwise.

There are few default IMultiPartEntityPartimplementaitons available:

  • StringMultipartEntityPart
  • FileMultipartEntityPart
  • StreamMultipartEntityPart

File fetching from server

AbstractDrupalByteEntity class allows user to pullFromServer files from server using DruplaClient model.
Note: patch ,post and put methods aren't supported by this entity. There are 2 default implementations of this entity:

  • DrupalByteEntity used for generic file pulling
  • DrupalImageEntityoptimized for image pulling

DrupalImageView

This view is providing DrupalClient-powered image loading (custom login/re-login schemes and duplicate request filter functionality) and optimized for displaying within scrollable content.

DrupalImageView provides fixedBounds flag, allowing it to skip layout refreshing on image loaded complete event. Which is especially beneficial within scrollable containers such as ListView, Gallery, ViewPager .

Also this view supports xml-based parameter setting: you can provide fixedBounds, noImageResource and srcPath flags in android xml file.

You can configure DrupalClient used by setting it directly to the view:

DrupalImageView imageView;
imageView.setLocalClient(myCLient)

or with static method. In that case all instances of 'DrupalImageView' will use this client (in case if no local client was set to the view)

DrupalImageView.setupSharedClient(myDrupalClient);
Clone this wiki locally