org.ohmage.dagger.OhmageModule.java Source code

Java tutorial

Introduction

Here is the source code for org.ohmage.dagger.OhmageModule.java

Source

/*
 * Copyright (C) 2013 ohmage
 *
 * 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 org.ohmage.dagger;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.net.Uri;

import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.squareup.okhttp.HttpResponseCache;
import com.squareup.okhttp.OkHttpClient;

import org.ohmage.app.InstallSurveyDependencies;
import org.ohmage.app.InstallSurveyDependencies.InstallSurveyDependenciesFragment;
import org.ohmage.app.MainActivity;
import org.ohmage.app.Ohmage;
import org.ohmage.app.OhmageAuthenticator;
import org.ohmage.app.OhmageErrorHandler;
import org.ohmage.app.OhmageService;
import org.ohmage.app.OhmletActivity;
import org.ohmage.app.SurveyActivity;
import org.ohmage.app.SurveyActivity.SurveyPromptLoader;
import org.ohmage.auth.AuthHelper;
import org.ohmage.auth.AuthUtil;
import org.ohmage.auth.AuthenticateFragment;
import org.ohmage.auth.Authenticator;
import org.ohmage.auth.CreateAccountFragment;
import org.ohmage.auth.SignInFragment;
import org.ohmage.auth.oauth.OAuthActivity;
import org.ohmage.auth.oauth.OAuthActivity.OAuthFragment;
import org.ohmage.fragments.HomeFragment;
import org.ohmage.fragments.InstallDependenciesDialog;
import org.ohmage.fragments.OhmletsFragment;
import org.ohmage.fragments.OhmletsGridFragment;
import org.ohmage.fragments.OhmletsSearchFragment;
import org.ohmage.fragments.StreamsFragment;
import org.ohmage.fragments.SurveysFragment;
import org.ohmage.operators.ContentProviderSaver;
import org.ohmage.prompts.BasePrompt;
import org.ohmage.prompts.Prompt;
import org.ohmage.prompts.PromptFragment;
import org.ohmage.provider.ContentProviderReader;
import org.ohmage.provider.StreamContentProvider;
import org.ohmage.reminders.base.TriggerInit;
import org.ohmage.log.AppLogSyncAdapter;
import org.ohmage.sync.OhmageSyncAdapter;
import org.ohmage.sync.ResponseSyncAdapter;
import org.ohmage.sync.StreamSyncAdapter;
import org.ohmage.tasks.LogoutTaskFragment;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import retrofit.RequestInterceptor;
import retrofit.RestAdapter;
import retrofit.RestAdapter.Builder;
import retrofit.RestAdapter.LogLevel;
import retrofit.client.OkClient;
import retrofit.client.Request;
import retrofit.converter.GsonConverter;

@Module(injects = { MainActivity.class, AuthenticateFragment.class, Authenticator.class,
        CreateAccountFragment.class, SignInFragment.class, LogoutTaskFragment.class, StreamContentProvider.class,
        StreamSyncAdapter.class, OhmageAuthenticator.class, OhmletsSearchFragment.class,
        OhmletsGridFragment.OhmletAdapter.class, OhmletsFragment.class, OhmageSyncAdapter.class,
        OhmletActivity.class, OhmletActivity.OhmletFragment.class, OhmletActivity.JoinOhmletDialog.class,
        ContentProviderSaver.class, ContentProviderReader.class, SurveysFragment.class, HomeFragment.class,
        SurveyActivity.class, PromptFragment.class, SurveyPromptLoader.class, ResponseSyncAdapter.class,
        AppLogSyncAdapter.class, StreamsFragment.class, InstallSurveyDependencies.class,
        InstallSurveyDependenciesFragment.class, InstallDependenciesDialog.class, SurveyActivity.class,
        OAuthActivity.class, OAuthFragment.class, }, complete = false, library = true)
public class OhmageModule {

    @Provides
    @Singleton
    AccountManager provideAccountManager(@ForApplication Context context) {
        return AccountManager.get(context);
    }

    @Provides
    @Singleton
    AuthHelper provideAuthHelper(@ForApplication Context context) {
        return new AuthHelper(context);
    }

    @Provides
    @Singleton
    Gson provideGson() {
        GsonBuilder gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
                .registerTypeAdapterFactory(new LowercaseEnumTypeAdapterFactory())
                .registerTypeAdapter(Prompt.class, new BasePrompt.PromptDeserializer())
                .registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
                    @Override
                    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
                        if ((src == Math.floor(src)) && !Double.isInfinite(src)) {
                            return context.serialize(src.intValue());
                        }

                        return context.serialize(src);
                    }
                });
        TriggerInit.injectDeserializers(gson);
        return gson.create();
    }

    @Provides
    @Singleton
    OkHttpClient providesOkHttpClient(@ForApplication Context context) {
        // Create an HTTP client that uses a cache on the file system.
        OkHttpClient okHttpClient = new OkHttpClient();
        try {
            HttpResponseCache cache = new HttpResponseCache(context.getCacheDir(), 1024);
            okHttpClient.setResponseCache(cache);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Add an authenticator to handle 401 error by updating the token
        okHttpClient.setAuthenticator(new OhmageAuthenticator());

        return okHttpClient;
    }

    @Provides
    OhmageService provideOhmageService(final OkHttpClient okHttpClient, Gson gson) {

        Executor executor = Executors.newCachedThreadPool();

        // Add the ohmage token to each outgoing request for the current user
        RequestInterceptor requestInterceptor = new RequestInterceptor() {
            @Override
            public void intercept(RequestFacade request) {
                AccountManager accountManager = AccountManager.get(Ohmage.app());
                Account[] accounts = accountManager.getAccountsByType(AuthUtil.ACCOUNT_TYPE);
                if (accounts.length != 0) {
                    String token = accountManager.peekAuthToken(accounts[0], AuthUtil.AUTHTOKEN_TYPE);
                    if (token != null) {
                        request.addHeader("Authorization", "bearer " + token);
                    }
                }
            }
        };

        RestAdapter restAdapter = new Builder().setExecutors(executor, executor)
                .setConverter(new GsonConverter(gson)).setClient(new OkClient(okHttpClient) {
                    @Override
                    protected HttpURLConnection openConnection(Request request) throws IOException {
                        HttpURLConnection ret = super.openConnection(request);

                        String path = Uri.parse(request.getUrl()).getPath();
                        // For these specific paths we should not follow redirects
                        if ("/ohmage/oauth/authorize".equals(path)
                                || "/ohmage/oauth/authorization_with_token".equals(path)) {
                            ret.setInstanceFollowRedirects(false);
                        }

                        return ret;
                    }
                }).setLogLevel(LogLevel.FULL).setErrorHandler(new OhmageErrorHandler())
                .setServer(Ohmage.getUrl(Ohmage.app())).setRequestInterceptor(requestInterceptor).build();

        return restAdapter.create(OhmageService.class);

    }

    /**
     * Factory which translates strings from the server to enums
     */
    public static class LowercaseEnumTypeAdapterFactory implements TypeAdapterFactory {
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
            Class<T> rawType = (Class<T>) type.getRawType();
            if (!rawType.isEnum()) {
                return null;
            }

            final Map<String, T> lowercaseToConstant = new HashMap<String, T>();
            for (T constant : rawType.getEnumConstants()) {
                lowercaseToConstant.put(toLowercase(constant), constant);
            }

            return new TypeAdapter<T>() {
                public void write(JsonWriter out, T value) throws IOException {
                    if (value == null) {
                        out.nullValue();
                    } else {
                        out.value(toLowercase(value));
                    }
                }

                public T read(JsonReader reader) throws IOException {
                    if (reader.peek() == JsonToken.NULL) {
                        reader.nextNull();
                        return null;
                    } else {
                        return lowercaseToConstant.get(reader.nextString());
                    }
                }
            };
        }

        private String toLowercase(Object o) {
            return o.toString().toLowerCase(Locale.US);
        }
    }
}