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)); ClientDocumentStfulDelegateImpl clientDoc = nodeCache.getClientDocumentStfulDelegate(); 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 String getNodeReference( Node node, boolean cacheIfPossible, boolean errIfNull, ClientDocumentStfulDelegateImpl clientDoc) { // El código devuelto debe ser enviado al cliente y ejecutado pues puede llevar información de // cacheado y haber sido cacheado ahora en el servidor if (node == null) if (errIfNull) throw new ItsNatException("No specified node"); else return "null"; ItsNatStfulDocumentImpl itsNatDoc = clientDoc.getItsNatStfulDocument(); Document doc = itsNatDoc.getDocument(); if (node == ((DocumentView) doc).getDefaultView()) return "itsNatDoc.win"; else if (node == doc) return "itsNatDoc.doc"; else if (node == doc.getDoctype()) return "itsNatDoc.doc.doctype"; else if (node == doc.getDocumentElement()) return "itsNatDoc.doc.documentElement"; // Es una tentación considerar también el caso document.body pero creo recordar // que en Safari y XHTML el API DOM no es el HTML DOM sino DOM Core a secas. // node no puede ser nulo, ya está comprobado antes NodeLocationImpl nodeLoc = clientDoc.getNodeLocation(node, cacheIfPossible); return getNodeReference( nodeLoc, errIfNull); // errIfNull puede ser false si se quiere, es redundante pues ya se chequeó // antes }
private NodeLocationWithParentImpl( Node node, String id, String path, Node cachedParent, String cachedParentId, boolean cacheIfPossible, ClientDocumentStfulDelegateImpl 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 static NodeLocationWithParentImpl getNodeLocationWithParent( Node node, boolean cacheIfPossible, ClientDocumentStfulDelegateImpl 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); } }
@Override public Object appendChildNodes( Node parent, String parentVarName, boolean beforeParent, InsertAsMarkupInfoImpl insertMarkupInfo, ClientDocumentStfulDelegateImpl clientDoc) { CannotInsertAsMarkupCauseImpl cannotInsertMarkup = canInsertAllChildrenAsMarkup( (Element) parent, clientDoc.getItsNatStfulDocument().getItsNatStfulDocumentTemplateVersion(), insertMarkupInfo); if (cannotInsertMarkup == null) { // Sabemos que el retorno, innerMarkup, nunca es nulo en este contexto InnerMarkupCodeImpl innerMarkup = appendChildrenAsMarkup(parentVarName, parent, clientDoc); return innerMarkup; } else { InsertAsMarkupInfoImpl insertMarkupInfoNextLevel = cannotInsertMarkup.createInsertAsMarkupInfoNextLevel(); // Puede ser null return super.appendChildNodes( parent, parentVarName, beforeParent, insertMarkupInfoNextLevel, clientDoc); } }