/* * Copyright (C) 2014 Divide.io * * 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.divide.client.web; import com.google.gson.Gson; import com.google.inject.Inject; import io.divide.client.Config; import io.divide.shared.logging.Logger; import retrofit.Profiler; import retrofit.RequestInterceptor; import retrofit.RestAdapter; import retrofit.client.OkClient; import retrofit.converter.GsonConverter; import rx.Observer; import rx.Subscription; import rx.schedulers.Schedulers; import rx.subjects.PublishSubject; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import static retrofit.RequestInterceptor.RequestFacade; public abstract class AbstractWebManager<T> { private static Logger logger = Logger.getLogger(AbstractWebManager.class); private static Logger retrologger = Logger.getLogger("Retrofit"); private static Boolean connectionReceiverRegistered = false; static final Map<Long,AbstractWebManager> webManagers = new HashMap<Long,AbstractWebManager>(); protected Config config; private List<OnRequestInterceptor> requestInterceptors = new CopyOnWriteArrayList<OnRequestInterceptor>(); private RestAdapter restAdapter; private T t; private PublishSubject<RequestObject> requestEventPublisher = PublishSubject.create(); private PublishSubject<Boolean> connectionEventPublisher = PublishSubject.create(); protected abstract Class<T> getType(); @Inject protected AbstractWebManager(Config config){ this.config = config; initAdapter(config); // synchronized (connectionReceiverRegistered){ // if(!connectionReceiverRegistered){ // config.app.registerReceiver(CONNECTION_RECIEVER, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); // connectionReceiverRegistered = true; // } // } } protected void initAdapter(Config config){ Class<T> type = getType(); if(type==null)throw new IllegalStateException("getType can not be null"); if(!webManagers.containsKey(config.id)){ logger.debug("Creating new RestAdapter for: " + config.id); restAdapter = createRestAdapter(config); webManagers.put(config.id,this); } else { restAdapter = webManagers.get(config.id).restAdapter; } t = restAdapter.create(type); } public T getWebService(){ return t; } private RestAdapter createRestAdapter(Config config){ RestAdapter.Builder builder = new RestAdapter.Builder(); builder.setClient( new OkClient( config.client ) ) .setEndpoint(config.serverUrl) .setLogLevel(RestAdapter.LogLevel.FULL) .setLog(new RestAdapter.Log() { @Override public void log(String s) { retrologger.debug(s); } }) .setConverter(new GsonConverter(new Gson())) .setRequestInterceptor(new RequestInterceptor() { @Override public void intercept(RequestFacade requestFacade) { onRequest(requestFacade); } }) .setProfiler(new Profiler() { @Override public Object beforeCall() { return null; } @Override public void afterCall(RequestInformation requestInformation, long l, int i, Object o) { retrologger.error("afterCall(" + requestInformation.getRelativePath() + ":" + requestInformation.getMethod() + ": " + i + " : " + o); requestEventPublisher.onNext(new RequestObject(requestInformation,l,i,o)); } }); return builder.build(); } private void onRequest(final RequestFacade requestFacade){ for(OnRequestInterceptor ori : requestInterceptors) ori.onRequest(requestFacade); } public void addConnectionListener(ConnectionListener listener){ Subscription subscription = connectionEventPublisher .subscribeOn(Schedulers.io()) .subscribe(listener.getObserver()); } public final void addResponseObserver(Observer<RequestObject> observer){ Subscription subscription = requestEventPublisher .subscribeOn(Schedulers.io()) .subscribe(observer); } protected void addRequestInterceptor(OnRequestInterceptor requestInterceptor){ requestInterceptors.add(requestInterceptor); } }