package org.itsnat.droid.impl.browser; import android.content.Context; import android.view.View; import org.apache.http.params.HttpParams; import org.itsnat.droid.HttpRequestResult; import org.itsnat.droid.ItsNatDoc; import org.itsnat.droid.ItsNatDroidBrowser; import org.itsnat.droid.ItsNatDroidException; import org.itsnat.droid.OnEventErrorListener; import org.itsnat.droid.OnHttpRequestErrorListener; import org.itsnat.droid.OnScriptErrorListener; import org.itsnat.droid.OnServerStateLostListener; import org.itsnat.droid.Page; import org.itsnat.droid.PageRequest; import org.itsnat.droid.UserData; import org.itsnat.droid.impl.ItsNatDroidImpl; import org.itsnat.droid.impl.dom.layout.XMLDOMLayout; import org.itsnat.droid.impl.domparser.XMLDOMParserContext; import org.itsnat.droid.impl.util.UserDataImpl; import org.itsnat.droid.impl.xmlinflated.InflatedXML; import org.itsnat.droid.impl.xmlinflated.InflatedXMLPage; import org.itsnat.droid.impl.xmlinflated.layout.InflatedXMLLayoutPageImpl; import org.itsnat.droid.impl.xmlinflater.XMLInflater; import org.itsnat.droid.impl.xmlinflater.layout.XMLInflaterLayout; import org.itsnat.droid.impl.xmlinflater.layout.page.XMLInflaterLayoutPage; import java.io.StringReader; import java.util.List; import java.util.Map; import bsh.EvalError; import bsh.Interpreter; import bsh.NameSpace; /** * Created by jmarranz on 4/06/14. */ public abstract class PageImpl implements Page { protected final PageRequestImpl pageRequestCloned; // Nos interesa únicamente para el reload, es un clone del original por lo que podemos tomar datos del mismo sin miedo a cambiarse protected final HttpRequestResultOKImpl httpReqResult; protected final XMLDOMParserContext xmlDOMParserContext; protected final int bitmapDensityReference; protected final XMLInflaterLayoutPage xmlInflaterLayoutPage; protected final String uniqueIdForInterpreter; protected final Interpreter interp; protected final ItsNatDocImpl itsNatDoc; protected OnScriptErrorListener scriptErrorListener; protected OnEventErrorListener eventErrorListener; protected OnServerStateLostListener stateLostListener; protected OnHttpRequestErrorListener httpReqErrorListener; protected UserDataImpl userData; protected boolean dispose; public PageImpl(PageRequestImpl pageRequestToClone,PageRequestResult pageReqResult) { this.pageRequestCloned = pageRequestToClone.clonePageRequest(); // De esta manera conocemos como se ha creado pero así podemos reutilizar el PageRequestImpl original this.httpReqResult = pageReqResult.getHttpRequestResultOKImpl(); this.xmlDOMParserContext = pageReqResult.getXMLDOMParserContext(); this.scriptErrorListener = pageRequestToClone.getOnScriptErrorListener(); HttpRequestResultOKImpl httpReqResult = pageReqResult.getHttpRequestResultOKImpl(); Integer bitmapDensityReference = httpReqResult.getBitmapDensityReference(); // Sólo está definida en el caso de ItsNat server, por eso se puede pasar por el usuario también a través del PageRequest this.bitmapDensityReference = bitmapDensityReference != null ? bitmapDensityReference : pageRequestCloned.getBitmapDensityReference(); ItsNatDroidImpl itsNatDroid = pageRequestCloned.getItsNatDroidBrowserImpl().getItsNatDroidImpl(); ItsNatDroidBrowserImpl browser = pageRequestCloned.getItsNatDroidBrowserImpl(); this.uniqueIdForInterpreter = browser.getUniqueIdGenerator().generateId("i"); // i = interpreter this.interp = new Interpreter(new StringReader(""), System.out, System.err, false, new NameSpace(browser.getInterpreter().getNameSpace(), uniqueIdForInterpreter)); // El StringReader está copiado del código fuente de beanshell2 https://code.google.com/p/beanshell2/source/browse/branches/v2.1/src/bsh/Interpreter.java // Definimos pronto el itsNatDoc para que los layout include tengan algún soporte de scripting de ItsNatDoc por ejemplo toast, eval, alert etc antes de inflarlos this.itsNatDoc = ItsNatDocImpl.createItsNatDoc(this); // Casi el último para que PageImpl esté ya bien creado antes de inicializar ItsNatDocImpl, el xmlInflaterLayoutPage siguiente necesita acceder a ItsNatDocImpl desde PageImpl XMLDOMLayout domLayout = pageReqResult.getXMLDOMLayout(); this.xmlInflaterLayoutPage = (XMLInflaterLayoutPage)XMLInflaterLayout.createXMLInflaterLayout(itsNatDroid, domLayout, this.bitmapDensityReference, pageRequestCloned.getAttrResourceInflaterListener(), getContext(), this); View rootView = xmlInflaterLayoutPage.inflateLayout(null,-1); try { interp.set("itsNatDoc", itsNatDoc); } catch (EvalError ex) { throw new ItsNatDroidException(ex); } catch (Exception ex) { throw new ItsNatDroidException(ex); } StringBuilder methods = new StringBuilder(); methods.append("alert(data){itsNatDoc.alert(data);}"); methods.append("toast(value,duration){itsNatDoc.toast(value,duration);}"); methods.append("toast(value){itsNatDoc.toast(value);}"); methods.append("eval(code){itsNatDoc.eval(code);}"); itsNatDoc.eval(methods.toString()); // Rarísimo que de error InflatedXMLLayoutPageImpl inflatedLayoutPage = xmlInflaterLayoutPage.getInflatedXMLLayoutPageImpl(); List<String> scriptList = inflatedLayoutPage.getScriptList(); if (!scriptList.isEmpty()) { for (String code : scriptList) { itsNatDoc.eval(code); } } finishLoad(pageReqResult); } public abstract void finishLoad(PageRequestResult pageReqResult); public static PageImpl getPageImpl(XMLInflater xmlInflater) { InflatedXML inflatedXML = xmlInflater.getInflatedXML(); return getPageImpl(inflatedXML); } public static PageImpl getPageImpl(InflatedXML inflatedXML) { if (inflatedXML instanceof InflatedXMLPage) // Contiene un PageImpl return ((InflatedXMLPage)inflatedXML).getPageImpl(); return null; } public XMLDOMParserContext getXMLDOMParserContext() { return xmlDOMParserContext; } public ItsNatDroidBrowserImpl getItsNatDroidBrowserImpl() { return pageRequestCloned.getItsNatDroidBrowserImpl(); } public PageRequestImpl getPageRequestClonedImpl() { return pageRequestCloned; } @Override public ItsNatDroidBrowser getItsNatDroidBrowser() { return getItsNatDroidBrowserImpl(); } @Override public Map<String, List<String>> getRequestProperties() { return pageRequestCloned.getRequestProperties(); } public RequestPropertyMap getRequestPropertyMapImpl() { return getPageRequestClonedImpl().getRequestPropertyMap(); } public HttpParams getHttpParams() { return getPageRequestClonedImpl().getHttpParams(); } @Override public int getConnectTimeout() { return getPageRequestClonedImpl().getConnectTimeout(); } @Override public int getReadTimeout() { return getPageRequestClonedImpl().getReadTimeout(); } @Override public HttpRequestResult getHttpRequestResult() { return getHttpRequestResultOKImpl(); } public HttpRequestResultOKImpl getHttpRequestResultOKImpl() { return httpReqResult; } public int getBitmapDensityReference() { return bitmapDensityReference; } public int getClientErrorMode() { return pageRequestCloned.getClientErrorMode(); } @Override public String getURL() { return pageRequestCloned.getURL(); } public String getPageURLBase() // Para la carga de recursos (scripts, imágenes etc) { return pageRequestCloned.getPageURLBase(); } public abstract String getItsNatServerVersion(); public InflatedXMLLayoutPageImpl getInflatedXMLLayoutPageImpl() { return xmlInflaterLayoutPage.getInflatedXMLLayoutPageImpl(); } public XMLInflaterLayoutPage getXMLInflaterLayoutPage() { return xmlInflaterLayoutPage; } public Interpreter getInterpreter() { return interp; } public Context getContext() { return pageRequestCloned.getContext(); } public UserData getUserData() { if (userData == null) this.userData = new UserDataImpl(); return userData; } public ItsNatDoc getItsNatDoc() { return getItsNatDocImpl(); } public ItsNatDocImpl getItsNatDocImpl() { return itsNatDoc; } public OnEventErrorListener getOnEventErrorListener() { return eventErrorListener; } @Override public void setOnEventErrorListener(OnEventErrorListener listener) { this.eventErrorListener = listener; } public OnScriptErrorListener getOnScriptErrorListener() { return scriptErrorListener; } @Override public void setOnScriptErrorListener(OnScriptErrorListener listener) { this.scriptErrorListener = listener; } public OnServerStateLostListener getOnServerStateLostListener() { return stateLostListener; } public void setOnServerStateLostListener(OnServerStateLostListener listener) { this.stateLostListener = listener; } public OnHttpRequestErrorListener getOnHttpRequestErrorListener() { return httpReqErrorListener; } public void setOnHttpRequestErrorListener(OnHttpRequestErrorListener listener) { this.httpReqErrorListener = listener; } public PageRequest reusePageRequest() { return pageRequestCloned.clonePageRequest(); } public boolean isDisposed() { return dispose; } public void dispose() { if (dispose) return; this.dispose = true; } }