package org.itsnat.droid.impl.browser; import android.content.Context; import android.os.AsyncTask; import org.itsnat.droid.ClientErrorMode; import org.itsnat.droid.HttpRequestResult; import org.itsnat.droid.ItsNatDroidException; import org.itsnat.droid.ItsNatDroidServerResponseException; import org.itsnat.droid.OnHttpRequestErrorListener; import org.itsnat.droid.OnHttpRequestListener; import org.itsnat.droid.impl.dom.ParsedResource; import org.itsnat.droid.impl.dom.ResourceDescRemote; import org.itsnat.droid.impl.domparser.XMLDOMParserContext; import org.itsnat.droid.impl.domparser.XMLDOMRegistry; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by jmarranz on 9/10/14. */ public class DownloadResourcesHttpClient extends GenericHttpClientBaseImpl { public DownloadResourcesHttpClient(ItsNatDocImpl itsNatDoc) { super(itsNatDoc); } protected String getPageURLBase() { return itsNatDoc.getPageImpl().getPageURLBase(); } public void request(ResourceDescRemote resDescRemote,boolean async) { List<ResourceDescRemote> resDescRemoteList = new ArrayList<ResourceDescRemote>(); resDescRemoteList.add(resDescRemote); request(resDescRemoteList, async); } public void request(List<ResourceDescRemote> resDescRemoteList,boolean async) { PageImpl page = getPageImpl(); ItsNatDroidBrowserImpl browser = page.getItsNatDroidBrowserImpl(); Context ctx = page.getContext(); String pageURLBase = getPageURLBase(); HttpRequestData httpRequestData = new HttpRequestData(page); String itsNatServerVersion = page.getItsNatServerVersion(); Map<String,ParsedResource> urlResDownloadedMap = new HashMap<String,ParsedResource>(); // es temporal, sólo dura durante la request, la cual suele cargar múltiples recursos y a veces de forma repetida XMLDOMRegistry xmlDOMRegistry = browser.getItsNatDroidImpl().getXMLDOMRegistry(); XMLDOMParserContext xmlDOMParserContext = new XMLDOMParserContext(xmlDOMRegistry,ctx); if (async) { requestAsync(resDescRemoteList,pageURLBase,httpRequestData,itsNatServerVersion,urlResDownloadedMap,xmlDOMParserContext); } else { requestSync(resDescRemoteList,pageURLBase,httpRequestData,itsNatServerVersion,urlResDownloadedMap,xmlDOMParserContext); } } private void requestSync(List<ResourceDescRemote> resDescRemoteList,String pageURLBase,HttpRequestData httpRequestData,String itsNatServerVersion,Map<String,ParsedResource> urlResDownloadedMap,XMLDOMParserContext xmlDOMParserContext) { List<HttpRequestResultOKImpl> resultList; try { resultList = executeInBackground(resDescRemoteList,pageURLBase,httpRequestData,itsNatServerVersion,urlResDownloadedMap,xmlDOMParserContext); } catch (Exception ex) { int errorMode = itsNatDoc.getClientErrorMode(); onFinishError(this,ex,errorListener,errorMode); return; // No se puede seguir } onFinishOk(this,resultList,httpRequestListener,errorListener); } private void requestAsync(List<ResourceDescRemote> resDescRemoteList,String pageURLBase,HttpRequestData httpRequestData,String itsNatServerVersion,Map<String,ParsedResource> urlResDownloadedMap,XMLDOMParserContext xmlDOMParserContext) { int errorMode = itsNatDoc.getClientErrorMode(); HttpDownloadResourcesAsyncTask task = new HttpDownloadResourcesAsyncTask(resDescRemoteList,this,pageURLBase,httpRequestData, httpRequestListener,errorListener,errorMode,itsNatServerVersion,urlResDownloadedMap,xmlDOMParserContext); task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); // Con execute() a secas se ejecuta en un "pool" de un sólo hilo sin verdadero paralelismo } public static List<HttpRequestResultOKImpl> executeInBackground(List<ResourceDescRemote> resDescRemoteList,String pageURLBase,HttpRequestData httpRequestData, String itsNatServerVersion, Map<String,ParsedResource> urlResDownloadedMap,XMLDOMParserContext xmlDOMParserContext) throws Exception { // Llamado en multithread en caso de async HttpResourceDownloader resDownloader = new HttpResourceDownloader(pageURLBase,httpRequestData,itsNatServerVersion,urlResDownloadedMap,xmlDOMParserContext); return resDownloader.downloadResources(resDescRemoteList); } public static void onFinishOk(DownloadResourcesHttpClient parent,List<HttpRequestResultOKImpl> resultList,OnHttpRequestListener httpRequestListener,OnHttpRequestErrorListener errorListener) { for (HttpRequestResultOKImpl result : resultList) { try { parent.processResult(result, httpRequestListener); } catch (Exception ex) { if (errorListener != null) { HttpRequestResult resultError = (ex instanceof ItsNatDroidServerResponseException) ? ((ItsNatDroidServerResponseException)ex).getHttpRequestResult() : result; errorListener.onError(parent.getPageImpl(), ex, resultError); return; // Paramos en el primer error } else { if (ex instanceof ItsNatDroidException) throw (ItsNatDroidException)ex; else throw new ItsNatDroidException(ex); } } } } public static void onFinishError(DownloadResourcesHttpClient parent,Exception ex,OnHttpRequestErrorListener errorListener,int errorMode) { HttpRequestResult result = (ex instanceof ItsNatDroidServerResponseException) ? ((ItsNatDroidServerResponseException)ex).getHttpRequestResult() : null; ItsNatDroidException exFinal = GenericHttpClientBaseImpl.convertException(ex); if (errorListener != null) { errorListener.onError(parent.getPageImpl(),exFinal, result); } else { if (errorMode != ClientErrorMode.NOT_CATCH_ERRORS) { // Error del servidor, lo normal es que haya lanzado una excepción ItsNatDocImpl itsNatDoc = parent.getItsNatDocImpl(); itsNatDoc.showErrorMessage(true, result,exFinal, errorMode); } else throw exFinal; } } }