com.uphyca.kitkat.storage.internal.impl.LiveSdkSkyDriveClient.java Source code

Java tutorial

Introduction

Here is the source code for com.uphyca.kitkat.storage.internal.impl.LiveSdkSkyDriveClient.java

Source

/*
 * Copyright (C) 2013 uPhyca Inc. http://www.uphyca.com/
 *
 * Licensed 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.
 */

package com.uphyca.kitkat.storage.internal.impl;

import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;

import com.microsoft.live.LiveAuthClient;
import com.microsoft.live.LiveAuthException;
import com.microsoft.live.LiveAuthListener;
import com.microsoft.live.LiveConnectClient;
import com.microsoft.live.LiveConnectSession;
import com.microsoft.live.LiveDownloadOperation;
import com.microsoft.live.LiveOperation;
import com.microsoft.live.LiveOperationException;
import com.microsoft.live.LiveStatus;
import com.microsoft.live.OverwriteOption;
import com.uphyca.kitkat.storage.internal.SkyDriveClient;
import com.uphyca.kitkat.storage.skydrive.JsonKeys;
import com.uphyca.kitkat.storage.skydrive.Scopes;
import com.uphyca.kitkat.storage.skydrive.SkyDriveObject;

/**
 * LiveSDK for Android??
 * 
 * @see <a href="https://github.com/liveservices/LiveSDK-for-Android/">LiveSDK for Android</a>
 * @author masui@uphyca.com
 */
public class LiveSdkSkyDriveClient implements SkyDriveClient {

    private static final List<String> SCOPES = Arrays.asList(new String[] { Scopes.SIGNIN, //
            Scopes.OFFLINE_ACCESS, //
            Scopes.SKYDRIVE_UPDATE });

    private final Context mContext;
    private final LiveAuthClient mLiveAuthClient;
    private LiveConnectClient mLiveConnectClient;

    public LiveSdkSkyDriveClient(Context context, LiveAuthClient liveAuthClient) {
        mContext = context;
        mLiveAuthClient = liveAuthClient;

    }

    @Override
    public void initializeIfNecessary() {
        if (mLiveConnectClient != null) {
            return;
        }
        final CountDownLatch lock = new CountDownLatch(1);
        mLiveAuthClient.initialize(SCOPES, new LiveAuthListener() {
            @Override
            public void onAuthComplete(LiveStatus status, LiveConnectSession session, Object userState) {
                if (status == LiveStatus.CONNECTED) {
                    mLiveConnectClient = new LiveConnectClient(session);
                }
                lock.countDown();
            }

            @Override
            public void onAuthError(LiveAuthException exception, Object userState) {
                lock.countDown();
            }
        });
        try {
            lock.await();
        } catch (InterruptedException ignore) {
        }
    }

    @Override
    public void login(final Activity activity, final SkyDriveAuthListener listener) {
        mLiveAuthClient.login(activity, SCOPES, new LiveAuthListener() {
            @Override
            public void onAuthComplete(LiveStatus status, LiveConnectSession session, Object userState) {
                if (status == LiveStatus.CONNECTED) {
                    mLiveConnectClient = new LiveConnectClient(session);
                    listener.onAuthComplete();
                    return;
                }
                Exception e = new RuntimeException("Login did not connect. Status is " + status + ".");
                e.fillInStackTrace();
                listener.onAuthError(e);
            }

            @Override
            public void onAuthError(LiveAuthException exception, Object userState) {
                Exception e = new RuntimeException(exception);
                listener.onAuthError(e);
            }
        });
    }

    @Override
    public SkyDriveObject[] get(String documentId) {
        initializeIfNecessary();
        if (mLiveConnectClient == null) {
            return empty();
        }

        final LiveOperation operation;
        try {
            operation = mLiveConnectClient.get(documentId);
        } catch (LiveOperationException ignore) {
            return empty();
        }

        JSONObject syncResult = operation.getResult();
        if (syncResult.has(JsonKeys.ERROR)) {
            return empty();
        }

        if (syncResult.has(JsonKeys.DATA)) {
            JSONArray array = syncResult.optJSONArray(JsonKeys.DATA);
            SkyDriveObject[] objects = new SkyDriveObject[array.length()];
            for (int i = 0, length = array.length(); i < length; ++i) {
                objects[i] = SkyDriveObject.create(array.optJSONObject(i));
            }
            return objects;
        }

        return new SkyDriveObject[] { SkyDriveObject.create(syncResult) };
    }

    @Override
    public File download(String documentId) throws IOException {
        initializeIfNecessary();
        if (mLiveConnectClient == null) {
            return null;
        }
        String path = documentId + "/content";

        final LiveDownloadOperation download;
        try {
            download = mLiveConnectClient.download(path);
        } catch (LiveOperationException ignore) {
            return null;
        }

        InputStream in = null;
        try {
            File temp = File.createTempFile("document", null, mContext.getCacheDir());
            in = download.getStream();
            drain(in, temp);
            return temp;
        } finally {
            closeQuietly(in);
        }
    }

    @Override
    public String upload(String path, String name, File file) throws IOException {
        initializeIfNecessary();
        if (mLiveConnectClient == null) {
            return null;
        }

        try {
            LiveOperation post = mLiveConnectClient.upload(path, name, file, OverwriteOption.Overwrite);
            JSONObject result = post.getResult();
            if (result.has(JsonKeys.ERROR)) {
                JSONObject error = result.optJSONObject(JsonKeys.ERROR);
                String message = error.optString(JsonKeys.MESSAGE);
                IOException ioException = new IOException(message);
                ioException.fillInStackTrace();
                throw ioException;
            }
            try {
                return result.getString(JsonKeys.ID);
            } catch (JSONException e) {
                IOException ioException = new IOException(e.getMessage());
                ioException.initCause(e);
                throw ioException;
            }
        } catch (LiveOperationException e) {
            IOException ioException = new IOException(e.getMessage());
            ioException.initCause(e);
            throw ioException;
        }
    }

    @Override
    public String mkdir(String path, String name) throws IOException {
        initializeIfNecessary();
        if (mLiveConnectClient == null) {
            return null;
        }

        Map<String, String> folder = new HashMap<>();
        folder.put(JsonKeys.NAME, name);
        folder.put(JsonKeys.DESCRIPTION, null);
        try {
            LiveOperation post = mLiveConnectClient.post(path, new JSONObject(folder));
            JSONObject result = post.getResult();
            if (result.has(JsonKeys.ERROR)) {
                JSONObject error = result.optJSONObject(JsonKeys.ERROR);
                String message = error.optString(JsonKeys.MESSAGE);
                IOException ioException = new IOException(message);
                ioException.fillInStackTrace();
                throw ioException;
            }
            try {
                return result.getString(JsonKeys.ID);
            } catch (JSONException e) {
                IOException ioException = new IOException(e.getMessage());
                ioException.initCause(e);
                throw ioException;
            }
        } catch (LiveOperationException e) {
            IOException ioException = new IOException(e.getMessage());
            ioException.initCause(e);
            throw ioException;
        }
    }

    @Override
    public String touch(String path, String name) throws IOException {
        initializeIfNecessary();
        if (mLiveConnectClient == null) {
            return null;
        }

        File temp = File.createTempFile("document", null, mContext.getCacheDir());
        if (!temp.exists()) {
            IOException ioException = new IOException("Failed to touch " + name);
            ioException.fillInStackTrace();
            throw ioException;
        }
        return upload(path, name, temp);
    }

    @Override
    public void delete(String path) throws IOException {
        initializeIfNecessary();
        if (mLiveConnectClient == null) {
            return;
        }
        try {
            mLiveConnectClient.delete(path);
        } catch (LiveOperationException e) {
            IOException ioException = new IOException("Failed to delete " + path);
            ioException.initCause(e);
            throw ioException;
        }
    }

    private static SkyDriveObject[] empty() {
        return new SkyDriveObject[0];
    }

    private static void drain(InputStream in, File dest) throws IOException {
        OutputStream out = new BufferedOutputStream(new FileOutputStream(dest));
        try {
            byte[] buf = new byte[8192];
            for (int c; (c = in.read(buf)) > -1;) {
                out.write(buf, 0, c);
            }
            out.flush();
        } finally {
            closeQuietly(out);
        }
    }

    private static void closeQuietly(Closeable res) {
        if (res == null) {
            return;
        }
        try {
            res.close();
        } catch (IOException e) {
        }
    }
}