Package org.itsnat.impl.core.registry

Source Code of org.itsnat.impl.core.registry.ItsNatDOMEventListenerRegistryImpl

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

import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import org.itsnat.core.ItsNatException;
import org.itsnat.impl.core.clientdoc.ClientDocumentAttachedClientImpl;
import org.itsnat.impl.core.clientdoc.ClientDocumentStfulImpl;
import org.itsnat.impl.core.clientdoc.SVGWebInfoImpl;
import org.itsnat.impl.core.doc.ItsNatStfulDocumentImpl;
import org.itsnat.impl.core.event.EventListenerInternal;
import org.itsnat.impl.core.jsren.listener.JSRenderItsNatEventListenerImpl;
import org.itsnat.impl.core.listener.*;
import org.itsnat.impl.core.util.HasUniqueId;
import org.itsnat.impl.core.util.MapUniqueId;
import org.w3c.dom.Node;
import org.w3c.dom.events.Event;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;
import org.w3c.dom.views.AbstractView;
import org.w3c.dom.views.DocumentView;

/**
*
* @author jmarranz
*/
public abstract class ItsNatDOMEventListenerRegistryImpl implements Serializable
{
    protected ItsNatStfulDocumentImpl itsNatDoc;
    protected ClientDocumentStfulImpl clientDoc; // Si es null es que el registro es a nivel de documento y pertenece a todos los clientes
    protected int capturingCount;
    protected MapUniqueId<ItsNatDOMEventListenerWrapperImpl> eventListenersById; // No es weak porque necesitamos sujetar el listener wrapper pues es un objeto de uso interno para este fin

    /**
     * Creates a new instance of ItsNatDOMEventListenerRegistryImpl
     */
    public ItsNatDOMEventListenerRegistryImpl(ItsNatStfulDocumentImpl itsNatDoc,ClientDocumentStfulImpl clientDoc)
    {
        this.itsNatDoc = itsNatDoc;
        this.clientDoc = clientDoc; // puede ser null

        this.eventListenersById = new MapUniqueId<ItsNatDOMEventListenerWrapperImpl>(itsNatDoc.getUniqueIdGenerator());
    }

    public ClientDocumentStfulImpl getClientDocumentStful()
    {
        return clientDoc; // puede ser null
    }

    public boolean isEmpty()
    {
        return eventListenersById.isEmpty();
    }

    public void checkValidEventTarget(EventTarget target)
    {
        isValidEventTarget(target,true);
    }

    public boolean isValidEventTarget(EventTarget target,boolean throwErr)
    {
        // MSIE no admite asociar eventos DOM a text nodes y FireFox lo permite pero no los procesa por ej. los clicks
        // En los comentarios s� se permite aunque es absurdo (no pueden ser pulsados etc) delegamos en el programador
        if (target == null) return true; // Derivar si no se permite
        Node node = (Node)target; // nuestro AbstractView implementa Node
        int type = node.getNodeType();
        if (type == Node.TEXT_NODE)
            if (throwErr) throw new ItsNatException("Text node is not allowed",target);
            else return false;
        return true;
    }

    public int getCapturingCount()
    {
        return capturingCount;
    }

    public boolean canAddItsNatDOMEventListener(EventTarget target,EventListener listener)
    {
        if (!ItsNatDOMEventListenerWrapperImpl.canAddItsNatDOMEventListenerWrapper(listener,itsNatDoc, clientDoc))
            return false;
        checkValidEventTarget(target); // Lanza excepci�n si no es v�lido
        return true;
    }

    protected void addItsNatDOMEventListener(ItsNatDOMEventListenerWrapperImpl listenerWrapper)
    {
        eventListenersById.put(listenerWrapper);

        JSRenderItsNatEventListenerImpl.addItsNatEventListenerCode(listenerWrapper,clientDoc);

        if (listenerWrapper.getUseCapture())
            capturingCount++;
    }

    public void removeItsNatDOMEventListener(ItsNatDOMEventListenerWrapperImpl listener,boolean updateClient,boolean expunged)
    {
        // expunged tiene sentido en clases derivadas
        ItsNatDOMEventListenerWrapperImpl listenerRes = removeItsNatDOMEventListenerByIdPrivate(listener.getId(),updateClient);
        if (listenerRes == null)
            return; // Ya se elimin� seguramente
        if (listenerRes != listener)
            throw new ItsNatException("INTERNAL ERROR");
    }

    private ItsNatDOMEventListenerWrapperImpl removeItsNatDOMEventListenerByIdPrivate(String id,boolean updateClient)
    {
        ItsNatDOMEventListenerWrapperImpl listenerWrapper = eventListenersById.removeById(id);
        if (listenerWrapper == null)
            return null; // Ya se elimin� o nunca se a�adi� (raro)

        if (updateClient)
            JSRenderItsNatEventListenerImpl.removeItsNatEventListenerCode(listenerWrapper,clientDoc);

        if (listenerWrapper.getUseCapture())
            capturingCount--;

        return listenerWrapper;
    }

    protected ItsNatDOMEventListenerWrapperImpl removeItsNatDOMEventListenerById(String id,boolean updateClient)
    {
        return removeItsNatDOMEventListenerByIdPrivate(id,updateClient);
    }

    public ItsNatDOMEventListenerWrapperImpl getItsNatDOMEventListenerById(String listenerId)
    {
        return eventListenersById.get(listenerId);
    }

    /**
     * Devolvemos un array y no un iterador o una colecci�n interna porque al procesar los
     * handlers es posible que se a�adan o se quiten listenerList (el iterador fallar�a)
     */
    public abstract EventListener[] getEventListenersArrayCopy(EventTarget target,String type,boolean useCapture);

    public void renderItsNatDOMEventListeners(final ClientDocumentAttachedClientImpl clientDoc)
    {
        // Usado para renderizar los listeners de documento para un cliente nuevo
        if ((clientDoc == null) || (getClientDocumentStful() != null))
            throw new ItsNatException("INTERNAL ERROR");

        if (eventListenersById.isEmpty()) return;

        LinkedList<ItsNatDOMEventListenerWrapperImpl> svgWebNodes = null;
        for(Map.Entry<String,ItsNatDOMEventListenerWrapperImpl> entry : eventListenersById.entrySet())
        {
            ItsNatDOMEventListenerWrapperImpl listenerWrapper = entry.getValue();

            if (!clientDoc.canReceiveNormalEvents(listenerWrapper))
                continue;

            EventTarget currTarget = listenerWrapper.getCurrentTarget();
            if (SVGWebInfoImpl.isSVGNodeProcessedBySVGWebFlash((Node)currTarget,clientDoc))
            {
                // Si el nodo es procesado por SVGWeb Flash no podemos enviar ahora el registro del listener
                // al cliente pues el nodo SVG no existe hasta que se renderize lo cual
                // sabemos que ha ocurrido tras el evento SVGLoad de la p�gina.
                if (svgWebNodes == null) svgWebNodes = new LinkedList<ItsNatDOMEventListenerWrapperImpl>();
                svgWebNodes.add(listenerWrapper);
                continue;
            }
           
            JSRenderItsNatEventListenerImpl.addItsNatEventListenerCode(listenerWrapper,clientDoc);
        }

        if (svgWebNodes != null)
        {
            final LinkedList<ItsNatDOMEventListenerWrapperImpl> svgWebNodes2 = svgWebNodes;
            EventListener listener = new EventListenerInternal()
            {
                public void handleEvent(Event evt)
                {
                    for(ItsNatDOMEventListenerWrapperImpl listenerWrapper : svgWebNodes2)
                    {
                        if (!eventListenersById.containsKey(listenerWrapper))
                            continue; // Ha sido eliminado mientras se procesaba el evento SVGLoad

                        JSRenderItsNatEventListenerImpl.addItsNatEventListenerCode(listenerWrapper,clientDoc);
                    }
                }
            };
            AbstractView view = ((DocumentView)itsNatDoc.getDocument()).getDefaultView();
            clientDoc.addEventListener((EventTarget)view,"SVGLoad",listener,false);
        }
    }

    public void removeAllItsNatDOMEventListeners(boolean updateClient)
    {
        if (eventListenersById.isEmpty()) return;

        ItsNatDOMEventListenerWrapperImpl[] listenerList = eventListenersById.toArray(new ItsNatDOMEventListenerWrapperImpl[eventListenersById.size()]);
       
        for(int i = 0; i < listenerList.length; i++)
        {
            ItsNatDOMEventListenerWrapperImpl listener = listenerList[i];
            removeItsNatDOMEventListener(listener,updateClient,false);
        }
    }
}
TOP

Related Classes of org.itsnat.impl.core.registry.ItsNatDOMEventListenerRegistryImpl

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.