DOMBasedEventListenerRegistryByTargetTooImpl.java :  » Ajax » ItsNat » org » itsnat » impl » core » listener » Java Open Source

Java Open Source » Ajax » ItsNat 
ItsNat » org » itsnat » impl » core » listener » DOMBasedEventListenerRegistryByTargetTooImpl.java
/*
  ItsNat Java Web Application Framework
  Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
  Author: Jose Maria Arranz Santamaria

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version. See the GNU Affero General Public 
  License for more details. See the copy of the GNU Affero General Public License
  included in this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.itsnat.impl.core.listener;

import java.util.Iterator;
import java.util.LinkedList;
import org.itsnat.impl.core.ItsNatDocumentImpl;
import org.itsnat.impl.core.listener.DOMBasedEventTargetListenerList.Pair;
import org.itsnat.impl.core.util.WeakMapPluggable;
import org.w3c.dom.events.EventListener;
import org.w3c.dom.events.EventTarget;

public abstract class DOMBasedEventListenerRegistryByTargetTooImpl extends DOMBasedEventListenerRegistryImpl implements WeakMapPluggable.ExpungeListener
{
    protected WeakMapPluggable remoteListenersByTarget = new WeakMapPluggable(this);
    
    // Evitamos "sujetar" los nodos DOM porque un listener slo tiene 
    // sentido (por lo menos en ItsNat) si el nodo est vinculado al Document
    // por lo que si est en el Document ya est sujeto, si no est en el Document
    // (y nadie ms lo sujeta) evitamos as memory leaks en programadores descuidados
    // que no liberan listeners por ejemplo antes nodos que ser pierden
    // al eliminarse su fragmento. Esto funciona incluso con el AutoCleanEventListeners desactivado.
    // Esto no es suficiente con componentes que son listeners s mismos en donde olvidemos hacer dispose(),
    // estos necesitan el AutoCleanEventListeners tambin activado para que pueda actuar el Garbage Collector,
    // porque el registro sujeta a los componentes con referencias normales por ejemplo en remoteListenersById
    // y el propio componente tiene una referencia normal al nodo, la simple
    // eliminacin del nodo del documento no libera al nodo para el GC pues hay ms referencias.
    
    /** Creates a new instance of DOMBasedEventListenerRegistryByTargetTooImpl */
    public DOMBasedEventListenerRegistryByTargetTooImpl(ItsNatDocumentImpl itsNatDoc)
    {
        super(itsNatDoc);
    }
    
    public void addDOMBasedEventListener(DOMBasedEventListenerWrapperImpl listenerWrapper)
    {
        super.addDOMBasedEventListener(listenerWrapper);
        
        EventTarget target = listenerWrapper.getEventTarget();

        DOMBasedEventTargetListenerList targetList = (DOMBasedEventTargetListenerList)remoteListenersByTarget.get(target);
        if (targetList == null)
        {
            targetList = newDOMBasedEventTargetListenerList(false);
            remoteListenersByTarget.put(target,targetList);
        }            

        String id = listenerWrapper.getId();
        String type = listenerWrapper.getType();
        boolean useCapture = listenerWrapper.getUseCapture();
        EventListener listener = listenerWrapper.getEventListener();
        targetList.addEventListener(type,useCapture,listener,id);                    
    }     
    
    public void removeAllDOMBasedEventListeners(EventTarget target,boolean updateClient)
    {    
        if (!isValidEventTarget(target,false)) return; // No pudo registrarse, nos ahorramos una bsqueda intil        
  
        DOMBasedEventTargetListenerList targetList = (DOMBasedEventTargetListenerList)remoteListenersByTarget.get(target);
        if (targetList == null)
            return;      
        
        LinkedList listeners = targetList.getAllEventListeners();
        if (listeners == null) 
            return;
        
        for(Iterator it = listeners.iterator(); it.hasNext(); )
        {
            Pair pair = (Pair)it.next();
            String id = pair.getId(); 
            
            removeDOMBasedEventListenerByIdOnly(id,updateClient);                      
        }
        
        targetList.removeAllEventListeners();
        
        remoteListenersByTarget.remove(target);
    }
    
    public DOMBasedEventListenerWrapperImpl removeDOMBasedEventListener(EventTarget target,String type,boolean useCapture,EventListener listener,boolean updateClient)
    {
        if (!isValidEventTarget(target,false)) return null; // No pudo registrarse, nos ahorramos una bsqueda intil
                
        DOMBasedEventTargetListenerList targetList = (DOMBasedEventTargetListenerList)remoteListenersByTarget.get(target);
        if (targetList == null)
            return null;
        
        String id = targetList.removeEventListener(type,useCapture,listener);
        
        if (targetList.isEmpty())
            remoteListenersByTarget.remove(target);
        
        return removeDOMBasedEventListenerByIdOnly(id,updateClient);
    }            
    
    public EventListener[] getDOMBasedEventListeners(EventTarget target,String type,boolean useCapture)
    {
        if (!isValidEventTarget(target,false)) return null; // Nos ahorramos la bsqueda
        
        DOMBasedEventTargetListenerList targetList = (DOMBasedEventTargetListenerList)remoteListenersByTarget.get(target);
        if (targetList == null)
            return null;
        return targetList.getEventListenersAsArray(type,useCapture);
    }    
    
    public void processExpunged(Object value)
    {
        DOMBasedEventTargetListenerList targetList = (DOMBasedEventTargetListenerList)value;
        
        LinkedList listeners = targetList.getAllEventListeners();
        if (listeners == null) 
            return;
        
        for(Iterator it = listeners.iterator(); it.hasNext(); )
        {
            Pair pair = (Pair)it.next();
            String id = pair.getId();            
            removeDOMBasedEventListenerByIdOnly(id,false);
            
            // Pasamos updateClient = false para evitar llamar getJSRender().removeEventListenerCode(listenerWrapper);
            // precisamente porque este mtodo se llama cuando nadie sujeta el nodo
            // y por tanto no pertenece al Document.
            // Al menos evitamos que haya memory leaks en el servidor
            // aunque podr haber en el cliente, para evitarlo han de desregistrarse
            // explcitamente los listeners cuando no se necesitan o el nodo DOM se va a perder
        }
    }    
    
    public abstract DOMBasedEventTargetListenerList newDOMBasedEventTargetListenerList(boolean concurrentAllowed);    
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.