Java tutorial
/* * Copyright (c) 2014 Moodstocks SAS * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package io.winch.phonegap.plugin; import io.winch.android.Enumerator; import io.winch.android.LoadElement; import io.winch.android.SyncElement; import io.winch.android.Winch; import io.winch.android.WinchError; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.apache.cordova.CallbackContext; import org.apache.cordova.CordovaArgs; import org.apache.cordova.CordovaPlugin; import org.apache.cordova.PluginResult; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.content.Context; import android.util.Base64; import android.util.Log; public class WinchPlugin extends CordovaPlugin implements Winch.SyncListener, Winch.LoadListener { public static final String TAG = WinchPlugin.class.getSimpleName(); // methods strings public static final String OPEN = "open"; public static final String SYNC = "sync"; public static final String LOAD = "load"; public static final String COUNT = "count"; public static final String GET = "get"; public static final String GETSTRING = "getString"; public static final String GETBASE64 = "getBase64"; public static final String PUT = "put"; public static final String PUTSTRING = "putString"; public static final String PUTBASE64 = "putBase64"; public static final String ITERATEASSTRING = "iterateAsString"; public static final String ITERATEASBASE64 = "iterateAsBase64"; public static final String REMOVE = "remove"; public static final String CLOSE = "close"; public static final String DROP = "drop"; // result object keys public static final String STATUS = "status"; public static final String PROGRESS = "progress"; public static final String KEY = "key"; public static final String DATA = "data"; public static final String CODE = "code"; public static final String MESSAGE = "message"; // sync & load status public static int STATUS_START = 1; public static int STATUS_PROGRESS = 2; public static int STATUS_COMPLETED = 3; private Winch mWinch = null; private CallbackContext syncCallback; private CallbackContext loadCallback; public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { if (action.equals(OPEN)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { open(callbackContext, args); } }); return true; } else if (action.equals(SYNC)) { this.syncCallback = callbackContext; this.sync(args); return true; } else if (action.equals(LOAD)) { this.loadCallback = callbackContext; this.load(args); return true; } else if (action.equals(COUNT)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { count(callbackContext, args); } }); return true; } else if (action.equals(GET)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { get(callbackContext, args); } }); return true; } else if (action.equals(GETSTRING)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { getString(callbackContext, args); } }); return true; } else if (action.equals(GETBASE64)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { getBase64(callbackContext, args); } }); return true; } else if (action.equals(PUT)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { CordovaArgs cordovaArgs = new CordovaArgs(args); put(callbackContext, cordovaArgs); } }); return true; } else if (action.equals(PUTSTRING)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { putString(callbackContext, args); } }); return true; } else if (action.equals(PUTBASE64)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { putBase64(callbackContext, args); } }); return true; } else if (action.equals(ITERATEASSTRING)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { iterateAsString(callbackContext, args); } }); return true; } else if (action.equals(ITERATEASBASE64)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { iterateAsBase64(callbackContext, args); } }); return true; } else if (action.equals(REMOVE)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { remove(callbackContext, args); } }); return true; } else if (action.equals(CLOSE)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { close(callbackContext); } }); return true; } else if (action.equals(DROP)) { cordova.getThreadPool().execute(new Runnable() { @Override public void run() { drop(callbackContext, args); } }); return true; } return false; } @Override public void onDestroy() { super.onDestroy(); try { mWinch.close(); } catch (WinchError e) { e.printStackTrace(); } } // plugin methods private void open(CallbackContext callbackContext, JSONArray args) { try { Context context = this.cordova.getActivity(); String filename = args.getString(0); String ds_id = args.getString(1); String app_secret = args.getString(2); String path = Winch.pathFromFilesDir(context, filename); mWinch = Winch.db(context, path, ds_id, app_secret); callbackContext.success(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e) { e.printStackTrace(); } } private void sync(JSONArray args) { try { List<SyncElement> syncElements = new ArrayList<SyncElement>(); JSONObject params = args.getJSONObject(0); Iterator<?> iter = params.keys(); // iterate to retrieve sync pairs while (iter.hasNext()) { String namespace = (String) iter.next(); String syncOption = params.getString(namespace); SyncElement se = new SyncElement(namespace, syncOption); syncElements.add(se); } mWinch.sync(this, syncElements); } catch (JSONException e1) { e1.printStackTrace(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); this.syncCallback.sendPluginResult(r); } } private void load(JSONArray args) { try { List<LoadElement> loadElements = new ArrayList<LoadElement>(); JSONObject params = args.getJSONObject(0); Iterator<?> iter = params.keys(); // iterate to retrieve load pairs while (iter.hasNext()) { String namespace = (String) iter.next(); String key = params.getString(namespace); LoadElement le = new LoadElement(namespace, key); loadElements.add(le); } mWinch.load(this, loadElements); } catch (JSONException e) { e.printStackTrace(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); this.loadCallback.sendPluginResult(r); } } private void count(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); int count = mWinch.getNamespace(namespace).count(); PluginResult r = new PluginResult(PluginResult.Status.OK, count); callbackContext.sendPluginResult(r); } catch (JSONException e) { e.printStackTrace(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } } private void get(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); String key = args.getString(1); byte[] value = mWinch.getNamespace(namespace).get(key); PluginResult pr = new PluginResult(PluginResult.Status.OK, value, true); callbackContext.sendPluginResult(pr); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e1) { e1.printStackTrace(); } } private void getString(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); String key = args.getString(1); String value = mWinch.getNamespace(namespace).getString(key); PluginResult pr = new PluginResult(PluginResult.Status.OK, value); callbackContext.sendPluginResult(pr); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e1) { e1.printStackTrace(); } } private void getBase64(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); String key = args.getString(1); byte[] value = mWinch.getNamespace(namespace).get(key); String base64 = Base64.encodeToString(value, Base64.NO_WRAP); PluginResult pr = new PluginResult(PluginResult.Status.OK, base64); callbackContext.sendPluginResult(pr); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e1) { e1.printStackTrace(); } } private void put(CallbackContext callbackContext, CordovaArgs args) { try { String namespace = args.getString(0); String key = args.getString(1); byte[] data = args.getArrayBuffer(2); mWinch.getNamespace(namespace).put(key, data); callbackContext.success(); } catch (JSONException e) { e.printStackTrace(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } } private void putString(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); String key = args.getString(1); String data = args.getString(2); mWinch.getNamespace(namespace).putString(key, data); callbackContext.success(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e) { e.printStackTrace(); } } private void putBase64(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); String key = args.getString(1); String base64 = args.getString(2); byte[] data = Base64.decode(base64, Base64.NO_WRAP); mWinch.getNamespace(namespace).put(key, data); callbackContext.success(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e) { e.printStackTrace(); } } private void iterateAsString(final CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); Enumerator it1 = new Enumerator() { public int next() { JSONObject obj = new JSONObject(); try { obj.put(KEY, key); obj.put(DATA, new String(data)); } catch (JSONException e) { e.printStackTrace(); } PluginResult r = new PluginResult(PluginResult.Status.OK, obj); r.setKeepCallback(true); callbackContext.sendPluginResult(r); return Enumerator.Code.NONE; } }; mWinch.getNamespace(namespace).enumerate(it1); } catch (JSONException e1) { e1.printStackTrace(); } catch (WinchError e) { e.log(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } PluginResult r = new PluginResult(PluginResult.Status.OK, false); r.setKeepCallback(false); callbackContext.sendPluginResult(r); } private void iterateAsBase64(final CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); Enumerator it1 = new Enumerator() { public int next() { JSONObject obj = new JSONObject(); try { obj.put(KEY, key); String base64 = Base64.encodeToString(data, Base64.NO_WRAP); obj.put(DATA, base64); } catch (JSONException e) { e.printStackTrace(); } PluginResult r = new PluginResult(PluginResult.Status.OK, obj); r.setKeepCallback(true); callbackContext.sendPluginResult(r); return Enumerator.Code.NONE; } }; mWinch.getNamespace(namespace).enumerate(it1); } catch (JSONException e1) { e1.printStackTrace(); } catch (WinchError e) { e.log(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } PluginResult r = new PluginResult(PluginResult.Status.OK, false); r.setKeepCallback(false); callbackContext.sendPluginResult(r); } private void remove(CallbackContext callbackContext, JSONArray args) { try { String namespace = args.getString(0); String key = args.getString(1); mWinch.getNamespace(namespace).remove(key); callbackContext.success(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = this.buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } catch (JSONException e) { e.printStackTrace(); } } private void close(CallbackContext callbackContext) { try { mWinch.close(); callbackContext.success(); } catch (WinchError e) { e.printStackTrace(); PluginResult r = buildErrorResult(e.getErrorCode(), e.getMessage()); callbackContext.sendPluginResult(r); } } private void drop(CallbackContext callbackContext, JSONArray args) { try { mWinch.drop(args.getString(0)); callbackContext.success(); } catch (JSONException e) { e.printStackTrace(); } catch (WinchError e) { e.printStackTrace(); callbackContext.error(e.getErrorCode()); } } // sync listeners @Override public void onDBSyncComplete(ArrayList<SyncElement> syncElements) { Log.d(TAG, "Sync completed."); PluginResult r = buildProgressResult(STATUS_COMPLETED, 1, false); this.syncCallback.sendPluginResult(r); mWinch.unregisterListener(this); } @Override public void onDBSyncFailed(ArrayList<SyncElement> syncElements, WinchError win_err) { Log.d(TAG, "Sync failed"); PluginResult r = buildErrorResult(win_err.getErrorCode(), win_err.getMessage()); this.syncCallback.sendPluginResult(r); mWinch.unregisterListener(this); } @Override public void onDBSyncProgress(ArrayList<SyncElement> syncElements, float progress) { Log.d(TAG, "Sync in progress: " + progress); PluginResult r = buildProgressResult(STATUS_PROGRESS, progress, true); this.syncCallback.sendPluginResult(r); } @Override public void onDBSyncStart(ArrayList<SyncElement> syncElements) { Log.d(TAG, "Sync starting..."); PluginResult r = buildProgressResult(STATUS_START, 0, true); this.syncCallback.sendPluginResult(r); } // load listeners @Override public void onLoadComplete(ArrayList<LoadElement> arg0) { Log.d(TAG, "Load completed."); PluginResult r = buildProgressResult(STATUS_COMPLETED, 1, false); this.loadCallback.sendPluginResult(r); mWinch.unregisterListener(this); } @Override public void onLoadFailed(ArrayList<LoadElement> arg0, WinchError win_err) { Log.d(TAG, "Load failed."); PluginResult r = buildErrorResult(win_err.getErrorCode(), win_err.getMessage()); this.loadCallback.sendPluginResult(r); mWinch.unregisterListener(this); } @Override public void onLoadProgress(ArrayList<LoadElement> arg0, float progress) { Log.d(TAG, "Load in progress: " + progress); PluginResult r = buildProgressResult(STATUS_PROGRESS, progress, true); this.loadCallback.sendPluginResult(r); } @Override public void onLoadStart(ArrayList<LoadElement> arg0) { Log.d(TAG, "Load starting..."); PluginResult r = buildProgressResult(STATUS_START, 0, true); this.loadCallback.sendPluginResult(r); } // Helper methods private PluginResult buildProgressResult(int status, float progress, boolean keepCallback) { JSONObject obj = new JSONObject(); try { obj.put(STATUS, status); obj.put(PROGRESS, progress); } catch (JSONException e) { e.printStackTrace(); } PluginResult r = new PluginResult(PluginResult.Status.OK, obj); r.setKeepCallback(keepCallback); return r; } private PluginResult buildErrorResult(int errorCode, String errorMessage) { JSONObject obj = new JSONObject(); try { obj.put(CODE, errorCode); obj.put(MESSAGE, errorMessage); } catch (JSONException e1) { e1.printStackTrace(); } PluginResult r = new PluginResult(PluginResult.Status.ERROR, obj); r.setKeepCallback(false); return r; } }