/* * Copyright 2015 Victor Albertos * * 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 io.rx_cache2.internal; import io.reactivex.BackpressureStrategy; import io.reactivex.Maybe; import io.reactivex.Observable; import io.reactivex.ObservableSource; import io.reactivex.Single; import io.rx_cache2.EncryptKey; import io.rx_cache2.Migration; import io.rx_cache2.MigrationCache; import io.rx_cache2.SchemeMigration; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; public final class ProxyProviders implements InvocationHandler { private final io.rx_cache2.internal.ProcessorProviders processorProviders; private final ProxyTranslator proxyTranslator; public ProxyProviders(RxCache.Builder builder, Class<?> providersClass) { processorProviders = DaggerRxCacheComponent.builder() .rxCacheModule(new RxCacheModule(builder.getCacheDirectory(), builder.useExpiredDataIfLoaderNotAvailable(), builder.getMaxMBPersistenceCache(), getEncryptKey(providersClass), getMigrations(providersClass), builder.getJolyglot())) .build().providers(); proxyTranslator = new ProxyTranslator(); } public String getEncryptKey(Class<?> providersClass) { EncryptKey encryptKey = providersClass.getAnnotation(EncryptKey.class); if (encryptKey == null) return null; return encryptKey.value(); } public List<MigrationCache> getMigrations(Class<?> providersClass) { List<MigrationCache> migrations = new ArrayList<>(); Annotation annotation = providersClass.getAnnotation(SchemeMigration.class); if (annotation == null) return migrations; SchemeMigration schemeMigration = (SchemeMigration) annotation; for (Migration migration : schemeMigration.value()) { migrations.add(new MigrationCache(migration.version(), migration.evictClasses())); } return migrations; } @Override public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { return Observable.defer(new Callable<ObservableSource<?>>() { @Override public ObservableSource<?> call() throws Exception { Observable observable = processorProviders.process(proxyTranslator.processMethod(method, args)); Class<?> methodType = method.getReturnType(); if (methodType == Observable.class) return Observable.just(observable); if (methodType == Single.class) return Observable.just(Single.fromObservable(observable)); if (methodType == Maybe.class) { return Observable.just(Maybe.fromSingle(Single.fromObservable(observable))); } if (method.getReturnType() == io.reactivex.Flowable.class) { return Observable.just(observable.toFlowable(BackpressureStrategy.MISSING)); } String errorMessage = method.getName() + io.rx_cache2.internal.Locale.INVALID_RETURN_TYPE; throw new RuntimeException(errorMessage); } }).blockingFirst(); } Observable<Void> evictAll() { return processorProviders.evictAll(); } }