Package org.itsnat.impl.core.path

Source Code of org.itsnat.impl.core.path.NodeLocationWithParentImpl

/*
  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.path;

import java.util.ArrayList;
import org.itsnat.core.ItsNatException;
import org.itsnat.impl.core.clientdoc.ClientDocumentStfulImpl;
import org.itsnat.impl.core.clientdoc.NodeCacheRegistryImpl;
import org.itsnat.impl.core.jsren.JSRenderImpl;
import org.w3c.dom.Node;

/**
*
* @author jmarranz
*/
public class NodeLocationWithParentImpl extends NodeLocationImpl
{
    protected NodeLocationImpl nodeLocationDeleg;
    protected Node cachedParent;
    protected String cachedParentId;
    protected ArrayList<String> newCachedParentIds;

    private NodeLocationWithParentImpl(Node node,String id,String path,Node cachedParent,String cachedParentId,boolean cacheIfPossible,ClientDocumentStfulImpl clientDoc)
    {
        super(clientDoc);

        if (node == null) throw new ItsNatException("INTERNAL ERROR");          
       
        this.nodeLocationDeleg = getNodeLocationNotParent(node, id, path, clientDoc);

        this.cachedParent = cachedParent;
        this.cachedParentId = cachedParentId;

        NodeCacheRegistryImpl nodeCache = clientDoc.getNodeCacheRegistry();
        if ((nodeCache != null) && cacheIfPossible) // Aunque est� cacheado el nodo principal aprovechamos para cachear los padres.
        {
            // Cacheamos unos cuantos padres inmediatos para que los nodos "adyacentes" (de la zona en general)
            // puedan encontrarse m�s r�pidamente, sobre todo si el cachedParent no se encontr� o est� muy arriba.

            int maxParents = 3; // Un valor razonable para evitar cachear en exceso nodos padre (y enviar demasiado JavaScript)
                                // que a lo mejor no se usan nunca ni para el c�lculo de paths
            Node currParent = node.getParentNode();
            for(int i = 0; (currParent != null) && (currParent != cachedParent) && (i < maxParents); i++)
            {
                String parentId = nodeCache.getId(currParent);
                if (parentId == null) // No cacheado
                {
                    parentId = nodeCache.addNode(currParent);
                    if (parentId != null)
                    {
                        // Hemos cacheado un nuevo nodo, DEBEMOS LLAMAR toJSArray y enviar al cliente
                        // de otra manera el cliente NO se enterar� de este cacheado.
                        if (newCachedParentIds == null)
                            this.newCachedParentIds = new ArrayList<String>(maxParents);
                        newCachedParentIds.add(parentId);
                        currParent = currParent.getParentNode();
                        i++;
                    }
                    else currParent = null; // No se puede cachear, paramos
                }
                else currParent = null; // Ya cacheado, paramos
            }
        }
       
        if ((nodeLocationDeleg instanceof NodeLocationAlreadyCachedNotParentImpl) && !isNull(cachedParentId)) throw new ItsNatException("INTERNAL ERROR");       
    }

    public NodeLocationWithParentImpl(Node node,String id,String path,boolean cacheIfPossible,ClientDocumentStfulImpl clientDoc)
    {
        this(node,id,path,null,null,cacheIfPossible,clientDoc);
    }

    @Override
    public Node getNode()
    {
        return nodeLocationDeleg.getNode();
    }
   
    public boolean isJustCached()
    {
        return nodeLocationDeleg.isJustCached();
    }   
   
    private String getCachedParentId()
    {
        return cachedParentId;
    }

    /* Este m�todo no se necesita fuera */
    protected String getCachedParentIdJS()
    {
        return JSRenderImpl.toLiteralStringJS(getCachedParentId());
    }

    public String toJSNodeLocation(boolean errIfNull)
    {
        this.used = true;

        nodeLocationDeleg.setUsed();
       
        if (nodeLocationDeleg instanceof NodeLocationAlreadyCachedNotParentImpl)
        {
            NodeLocationAlreadyCachedNotParentImpl nodeLocDeleg = (NodeLocationAlreadyCachedNotParentImpl)nodeLocationDeleg;
            if (newCachedParentIds == null)
                return nodeLocDeleg.getIdJS(); // 1 item
            else
                return "[" + nodeLocDeleg.getIdJS() + "," + toJSArrayCachedParents() + "]"; // 2 items el segundo un array
        }
        else if (nodeLocationDeleg instanceof NodeLocationPathBasedNotParentImpl)
        {
            NodeLocationPathBasedNotParentImpl nodeLocDeleg = (NodeLocationPathBasedNotParentImpl)nodeLocationDeleg;           
           
            StringBuilder code = new StringBuilder();
            code.append( "[" + getCachedParentIdJS() + "," + nodeLocDeleg.getIdJS() + "," + nodeLocDeleg.getPathJS() )// 3 items
            if (newCachedParentIds != null)
                code.append( "," + toJSArrayCachedParents() ); // 4 items (el �ltimo un array dentro de array)
            code.append( "]" );
            return code.toString();
        }
        else throw new ItsNatException("INTERNAL ERROR");
    }

    protected String toJSArrayCachedParents()
    {
        StringBuilder code = new StringBuilder();
        code.append( "[" ); // Array dentro de array
        for(int i = 0; i < newCachedParentIds.size(); i++)
        {
            String parentId = newCachedParentIds.get(i);
            String parentIdJS = JSRenderImpl.toLiteralStringJS(parentId);
            if (i != 0) code.append(",");
            code.append(parentIdJS);
        }
        code.append( "]" );
        return code.toString();
    }

    public static NodeLocationWithParentImpl getNodeLocationWithParentUsingCache(Node node,String id,boolean cacheIfPossible,NodeCacheRegistryImpl nodeCache)
    {
        // nodeCache NO puede ser nulo

        // Se supone que el nodo no ha sido cacheado en el cliente todav�a  aunque tenga
        // un id asignado en el servidor (este id puede ser null si no ha sido cacheado en el servidor)
        // por lo que hay que obtener un path, absoluto o relativo respecto a un padre cacheado.

        // Buscamos un nodo padre que est� cacheado para evitar formar un path
        // absoluto que lleva tiempo.

        String parentId = null;
        Node parent = node;

        do
        {
            parent = parent.getParentNode();
            parentId = nodeCache.getId(parent); // si cachedParent es null devuelve null
        }
        while((parentId == null)&&(parent != null));

        ClientDocumentStfulImpl clientDoc = nodeCache.getClientDocumentStful();
        String path = clientDoc.getStringPathFromNode(node,parent); // Si cachedParent es null (cachedParentId es null) devuelve un path absoluto

        return new NodeLocationWithParentImpl(node,id,path,parent,parentId,cacheIfPossible,clientDoc);
    }

    public static NodeLocationWithParentImpl getNodeLocationWithParent(Node node,String id,String path,Node parent,String parentId,boolean cacheIfPossible,ClientDocumentStfulImpl clientDoc)
    {
        return new NodeLocationWithParentImpl(node,id,path,parent,parentId,cacheIfPossible,clientDoc);
    }

    public static NodeLocationWithParentImpl getNodeLocationWithParent(Node node,boolean cacheIfPossible,ClientDocumentStfulImpl clientDoc)
    {
        // Si cacheIfPossible es true y se cachea el nodo, el location DEBE enviarse al cliente y resolverse para cachear en el cliente

        NodeCacheRegistryImpl nodeCache = clientDoc.getNodeCacheRegistry();
        if (nodeCache != null)
        {
            String id = nodeCache.getId(node);
            if (id != null)
            {
                return new NodeLocationWithParentImpl(node,id,null,cacheIfPossible,clientDoc); // S�lo se necesita el id del nodo, cuando est� en la cach� no necesitamos el string path que es una tarea que consume mucho tiempo tanto en el servidor como en el cliente
            }
            else // No cacheado
            {
                if (cacheIfPossible)
                {
                    id = nodeCache.addNode(node); // Si el nodo no es cacheable o la cach� est� bloqueada (s�lo lectural) devuelve null, no pasa nada por no poder cachear
                    return getNodeLocationWithParentUsingCache(node,id,true,nodeCache);
                }
                else
                {
                    String path = clientDoc.getStringPathFromNode(node);
                    return new NodeLocationWithParentImpl(node,null,path,false,clientDoc); // cacheIfPossible es false
                }
            }
        }
        else // El documento tiene el cache desactivado
        {
            String path = clientDoc.getStringPathFromNode(node);
            return new NodeLocationWithParentImpl(node,null,path,cacheIfPossible,clientDoc);
        }
    }

}
TOP

Related Classes of org.itsnat.impl.core.path.NodeLocationWithParentImpl

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.