All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gh.bmd.jrt.android.v11.routine.DefaultAndroidChannelBuilder Maven / Gradle / Ivy

There is a newer version: 6.0.0
Show newest version
/*
 * 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.gh.bmd.jrt.android.v11.routine;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Fragment;
import android.os.Build.VERSION_CODES;

import com.gh.bmd.jrt.android.builder.AndroidChannelBuilder;
import com.gh.bmd.jrt.android.builder.AndroidRoutineBuilder;
import com.gh.bmd.jrt.android.builder.AndroidRoutineBuilder.CacheStrategy;
import com.gh.bmd.jrt.android.builder.AndroidRoutineBuilder.ClashResolution;
import com.gh.bmd.jrt.android.runner.Runners;
import com.gh.bmd.jrt.builder.RoutineConfiguration;
import com.gh.bmd.jrt.channel.OutputChannel;
import com.gh.bmd.jrt.common.ClassToken;
import com.gh.bmd.jrt.runner.Execution;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * Default implementation of an Android channel builder.
 * 

* Created by davide on 1/14/15. */ @TargetApi(VERSION_CODES.HONEYCOMB) class DefaultAndroidChannelBuilder implements AndroidChannelBuilder { private final WeakReference mContext; private final int mInvocationId; private CacheStrategy mCacheStrategy; private RoutineConfiguration mConfiguration; /** * Constructor. * * @param activity the context activity. * @param invocationId the invocation ID. * @throws java.lang.NullPointerException if the activity is null. */ DefaultAndroidChannelBuilder(@Nonnull final Activity activity, final int invocationId) { this((Object) activity, invocationId); } /** * Constructor. * * @param fragment the context fragment. * @param invocationId the invocation ID. * @throws java.lang.NullPointerException if the fragment is null. */ DefaultAndroidChannelBuilder(@Nonnull final Fragment fragment, final int invocationId) { this((Object) fragment, invocationId); } /** * Constructor. * * @param context the context instance. * @param invocationId the invocation ID. * @throws java.lang.NullPointerException if the context is null. */ @SuppressWarnings("ConstantConditions") private DefaultAndroidChannelBuilder(@Nonnull final Object context, final int invocationId) { if (context == null) { throw new NullPointerException("the channel context must not be null"); } mContext = new WeakReference(context); mInvocationId = invocationId; } @Nonnull public OutputChannel buildChannel() { final Object context = mContext.get(); if (context == null) { return JRoutine.on(MissingLoaderInvocation.factoryOf()).callSync(); } final AndroidRoutineBuilder builder; if (context instanceof Activity) { final Activity activity = (Activity) context; builder = JRoutine.onActivity(activity, new MissingToken()).withId(mInvocationId); } else if (context instanceof Fragment) { final Fragment fragment = (Fragment) context; builder = JRoutine.onFragment(fragment, new MissingToken()).withId(mInvocationId); } else { throw new IllegalArgumentException( "invalid context type: " + context.getClass().getCanonicalName()); } return builder.withConfiguration(mConfiguration) .onClash(ClashResolution.KEEP_THAT) .onComplete(mCacheStrategy) .callAsync(); } @Nonnull public AndroidChannelBuilder onComplete(@Nullable final CacheStrategy cacheStrategy) { mCacheStrategy = cacheStrategy; return this; } public void purge() { final WeakReference context = mContext; if (context.get() != null) { Runners.mainRunner() .run(new PurgeExecution(context, mInvocationId), 0, TimeUnit.MILLISECONDS); } } public void purge(@Nullable final Object input) { final WeakReference context = mContext; if (context.get() != null) { final List inputList = Collections.singletonList(input); Runners.mainRunner().run(new PurgeInputsExecution(context, mInvocationId, inputList), 0, TimeUnit.MILLISECONDS); } } public void purge(@Nullable final Object... inputs) { final WeakReference context = mContext; if (context.get() != null) { final List inputList = (inputs == null) ? Collections.emptyList() : Arrays.asList(inputs); Runners.mainRunner().run(new PurgeInputsExecution(context, mInvocationId, inputList), 0, TimeUnit.MILLISECONDS); } } public void purge(@Nullable final Iterable inputs) { final WeakReference context = mContext; if (context.get() != null) { final List inputList; if (inputs == null) { inputList = Collections.emptyList(); } else { inputList = new ArrayList(); for (final Object input : inputs) { inputList.add(input); } } Runners.mainRunner().run(new PurgeInputsExecution(context, mInvocationId, inputList), 0, TimeUnit.MILLISECONDS); } } @Nonnull public AndroidChannelBuilder withConfiguration( @Nullable final RoutineConfiguration configuration) { mConfiguration = configuration; return this; } /** * Missing loader invocation token. * * @param the data type. */ private static class MissingToken extends ClassToken> { } /** * Execution implementation purging the loader with a specific ID. */ private static class PurgeExecution implements Execution { private final WeakReference mContext; private final int mInvocationId; /** * Constructor. * * @param context the context reference. * @param invocationId the invocation ID. */ private PurgeExecution(@Nonnull final WeakReference context, final int invocationId) { mContext = context; mInvocationId = invocationId; } public void run() { final Object context = mContext.get(); if (context != null) { LoaderInvocation.purgeLoader(context, mInvocationId); } } } /** * Execution implementation purging the loader with a specific ID and inputs. */ private static class PurgeInputsExecution implements Execution { private final WeakReference mContext; private final List mInputs; private final int mInvocationId; /** * Constructor. * * @param context the context reference. * @param invocationId the invocation ID. * @param inputs the list of inputs. */ private PurgeInputsExecution(@Nonnull final WeakReference context, final int invocationId, @Nonnull final List inputs) { mContext = context; mInvocationId = invocationId; mInputs = inputs; } public void run() { final Object context = mContext.get(); if (context != null) { LoaderInvocation.purgeLoader(context, mInvocationId, mInputs); } } } }