Package org.itsnat.impl.core.jsren

Source Code of org.itsnat.impl.core.jsren.JSScriptUtilImpl

/*
  ItsNat Java Web Application Framework
  Copyright (C) 2007-2011 Jose Maria Arranz Santamaria, Spanish citizen

  This software is free software; you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as
  published by the Free Software Foundation; either version 3 of
  the License, or (at your option) any later version.
  This software is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details. You should have received
  a copy of the GNU Lesser General Public License along with this program.
  If not, see <http://www.gnu.org/licenses/>.
*/

package org.itsnat.impl.core.jsren;

import java.io.Serializable;
import org.itsnat.core.ItsNatException;
import org.itsnat.core.script.ScriptExpr;
import org.itsnat.core.script.ScriptUtil;
import org.itsnat.impl.core.doc.ItsNatStfulDocumentImpl;
import org.itsnat.impl.core.clientdoc.NodeCacheRegistryImpl;
import org.itsnat.impl.core.clientdoc.ClientDocStfulTask;
import org.itsnat.impl.core.clientdoc.ClientDocumentStfulImpl;
import org.itsnat.impl.core.jsren.dom.node.JSRenderNodeImpl;
import org.itsnat.impl.core.path.NodeLocationImpl;
import org.itsnat.impl.core.path.NodeLocationWithParentImpl;
import org.w3c.dom.Node;

/**
*
* @author jmarranz
*/
public abstract class JSScriptUtilImpl implements ScriptUtil,Serializable
{
    /**
     * Creates a new instance of ScriptUtil
     */
    public JSScriptUtilImpl()
    {
    }

    public abstract ItsNatStfulDocumentImpl getItsNatStfulDocument();
    public abstract ClientDocumentStfulImpl getCurrentClientDocumentStful();

    public String getNodeReference(Node node)
    {
        if (node == null) return "null";
        preventiveNodeCaching(node);
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();
        // Es muy importante el cacheIfPossible = false pues antes hemos hecho
        // un esfuerzo en cachear y enviar al cliente, se trata de minimizar los
        // problemas que pueden ocurrir si el usuario no env�a el c�digo, para
        // ello la llamada JavaScript debe ser "s�lo lectura" es decir sin cambio de estado
        // para ello evitamos el cacheado del propio nodo y de padres.
        return clientDoc.getNodeReference(node,false,true);
    }

    public String getTransportableStringLiteral(String text)
    {
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();

        return JSRenderImpl.toTransportableStringLiteral(text,clientDoc.getBrowser());
    }

    public String getTransportableCharLiteral(char c)
    {
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();

        return JSRenderImpl.getTransportableCharLiteral(c,clientDoc.getBrowser());
    }

    public String encodeURIComponent(String text)
    {
        return JSRenderImpl.encodeURIComponent(text);
    }

    public String encodeURIComponent(char c)
    {
        return JSRenderImpl.encodeURIComponent(c);
    }

    public String getCallMethodCode(Object obj,String methodName,Object[] params)
    {
        return getCallMethodCode(obj,methodName,params,false);
    }

    public String getCallMethodCode(Object obj,String methodName,Object[] params,boolean endSentence)
    {
        preventiveNodeCaching(obj);
        preventiveNodeCaching(params);
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();
        // cacheIfPossible = false al igual que en getNodeReference
        return JSRenderMethodCallImpl.getCallMethodCode(obj,methodName,params,endSentence,false,clientDoc);
    }

    public String getSetPropertyCode(Object obj,String propertyName,Object value)
    {
        return getSetPropertyCode(obj,propertyName,value,false);
    }

    public String getSetPropertyCode(Object obj,String propertyName,Object value,boolean endSentence)
    {
        preventiveNodeCaching(obj);
        preventiveNodeCaching(value);
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();
        // cacheIfPossible = false al igual que en getNodeReference
        return JSRenderImpl.getSetPropertyCode(obj,propertyName,value,endSentence,false,clientDoc);
    }

    public String getGetPropertyCode(Object obj,String propertyName)
    {
        return getGetPropertyCode(obj,propertyName,false);
    }

    public String getGetPropertyCode(Object obj,String propertyName,boolean endSentence)
    {
        preventiveNodeCaching(obj);
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();
        // cacheIfPossible = false al igual que en getNodeReference
        return JSRenderImpl.getGetPropertyCode(obj,propertyName,endSentence,false,clientDoc);
    }

    public String toScript(Object value)
    {
        preventiveNodeCaching(value);
        ClientDocumentStfulImpl clientDoc = getCurrentClientDocumentStful();
        // cacheIfPossible = false al igual que en getNodeReference
        return JSRenderImpl.javaToJS(value,false,clientDoc);
    }

    public ScriptExpr createScriptExpr(Object value)
    {
        return new JScriptExprImpl(value,this);
    }

    public ScriptReference createScriptReference(Object value)
    {
        // POR AHORA NO ES PUBLICO.
        // Quiz�s m�s adelante cuando se haga un modelo completo de metaprogramaci�n
        // JavaScript en java
        return new JSReferenceImpl(value,this);
    }

    protected abstract void checkAllClientsCanReceiveJSCode();

    protected boolean isNodeCachedWithId(Node node,String id,ClientDocumentStfulImpl clientDoc)
    {
        NodeCacheRegistryImpl nodeCache = clientDoc.getNodeCacheRegistry(); // No puede ser nula
        Node nodeCached = nodeCache.getNodeById(id);
        return node == nodeCached;
    }

    protected void preventiveNodeCaching(Node node,String id,ClientDocumentStfulImpl clientDoc)
    {
        NodeCacheRegistryImpl nodeCache = clientDoc.getNodeCacheRegistry(); // No puede ser nula
        nodeCache.addNode(node,id); // node no puede ser nulo (dar� error)

        // Con cacheIfPossible = true tambi�n cacheamos padres, minimizando problemas.
        NodeLocationWithParentImpl nodeLoc = NodeLocationWithParentImpl.getNodeLocationWithParentUsingCache(node,id,true,nodeCache);
        if (!nodeLoc.isJustCached())
            throw new ItsNatException("INTERNAL ERROR");
        clientDoc.addCodeToSend( JSRenderNodeImpl.addNodeToCache(nodeLoc) );
    }

    public boolean preventiveNodeCaching(Object obj)
    {
        if (obj == null) return false;
        if (!(obj instanceof Node)) return false;

        return preventiveNodeCaching((Node)obj);
    }

    public boolean preventiveNodeCaching(final Node node)
    {
        if (node == null) return false;

        /* Cada cliente tiene su propia cache sin embargo lo normal
         * es que la cadena de localizaci�n del nodo se env�e a todos
         * los clientes usando ItsNatDocument.addCodeToSend(Object)
         * por tanto tenemos que conseguir que la misma cadena valga
         * para todos los clientes.
         * En el caso de paths absolutos no hay problema pues el path absoluto
         * es el mismo en todos los clientes (salvo IE Mobile en donde los comentarios son invisibles)
         * pero si el nodo est� cacheado es un problema pues los ids pueden ser diferentes.
         * Por ello lo que hacemos es eliminar el nodo en cuesti�n de las cach�s
         * y volverlo a a�adir usando un mismo id, como los ids son generados por el documento
         * no hay problema de compartici�n entre los cach�s de los clientes.
         * Adem�s as� evitamos el posible error de que el programador no env�e
         * el nodo al cliente o a todos los clientes por olvido por error antes de enviar etc,
         * pues al generar la cadena podr�a cachearse autom�ticamente en ese momento en el servidor
         * y no enterarse el cliente (al no recibir la cadena), al estar ya cacheado no hay problema.
         * Esto puede no funcionar con IE Mobile si la cach� est� desactivada, hay comentarios o <meta> por medio en el c�lculo del path absoluto
         * y hay control remoto, debido a que el path absoluto calculado por el cliente principal
         * no ser� el mismo que el necesario para el cliente de control remoto, ya sea IE Mobile
         * el principal o el remoto.
         */

        checkAllClientsCanReceiveJSCode();

        ItsNatStfulDocumentImpl itsNatDoc = getItsNatStfulDocument();
        if (!itsNatDoc.isNodeCacheEnabled())
            return false; // Se generan paths absolutos

        if (!NodeCacheRegistryImpl.isCacheableNode(node,itsNatDoc.getDocument()))
            return false; // No es cacheable por lo que no est� en las caches ni puede estar

        return preventiveNodeCaching2(node);
    }

    protected abstract boolean preventiveNodeCaching2(final Node node);

    protected boolean preventiveNodeCachingOneClient(Node node,ClientDocumentStfulImpl clientDoc)
    {
        NodeCacheRegistryImpl nodeCache = clientDoc.getNodeCacheRegistry(); // No puede ser nula la cach�
        String oldId = nodeCache.getId(node);
        if (oldId != null) return false; // Ya est� cacheado y s�lo hay un cliente

        ItsNatStfulDocumentImpl itsNatDoc = getItsNatStfulDocument();
        String id = NodeCacheRegistryImpl.generateUniqueId(itsNatDoc);
        preventiveNodeCaching(node,id,clientDoc);

        return true;
    }

    protected boolean preventiveNodeCaching(Object[] nodes)
    {
        if (nodes == null) return false;
        boolean someOneCached = false;
        for(int i = 0; i < nodes.length; i++)
            if (preventiveNodeCaching(nodes[i])) someOneCached = true;
        return someOneCached;
    }

}
TOP

Related Classes of org.itsnat.impl.core.jsren.JSScriptUtilImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.