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

Java Open Source » Ajax » ItsNat 
ItsNat » org » itsnat » impl » core » listener » AsyncTaskRegistry.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.HashMap;
import java.util.Map;
import org.itsnat.core.ItsNatException;
import org.itsnat.impl.core.ItsNatDocumentImpl;
import org.itsnat.impl.core.event.client2serv.*;
import org.itsnat.impl.core.js.listener.EventListenerJSRenderImpl;
import org.itsnat.impl.core.js.listener.AsyncTaskEventListenerJSRenderImpl;

/**
 *
 * @author jmarranz
 */
public class AsyncTaskRegistry
{
    protected Map tasks = new HashMap();
    protected ItsNatDocumentImpl itsNatDoc;
    
    /**
     * Creates a new instance of AsyncTaskRegistry
     */
    public AsyncTaskRegistry(ItsNatDocumentImpl itsNatDoc)
    {
        this.itsNatDoc = itsNatDoc;        
    }    

    public AsyncTaskEventListenerWrapperImpl createAsyncTaskEventListenerWrapper(AsyncTask taskContainer,long ajaxTimeout)
    {
        return new AsyncTaskEventListenerWrapperImpl((AsyncTask)taskContainer,ajaxTimeout,itsNatDoc);
    }
    
    public EventListenerJSRenderImpl getJSRender()
    {
        return AsyncTaskEventListenerJSRenderImpl.SINGLETON;
    }    
    
    public void addAsynchronousTask(Runnable task,boolean lockDoc,long maxWait,long ajaxTimeout)
    {    
        // Usar por ejemplo cuando una tarea
        // va a ser muy larga pero no es deseable que est bloqueado durante la tarea (lockDoc = false)
        // y dicha tarea modifica el documento 
        // por lo que hay que recoger los cambios, dichos cambios se recogern
        // a travs de un evento generado automticamente al volver al cliente y asncrono.
        
        AsyncTask taskContainer = new AsyncTask(task,lockDoc,maxWait,itsNatDoc);
        AsyncTaskEventListenerWrapperImpl listener = createAsyncTaskEventListenerWrapper(taskContainer,ajaxTimeout);
        
        EventListenerWrapperImpl evtListener = (EventListenerWrapperImpl)listener;
        
        String id = evtListener.getId();
        
        tasks.put(id,listener);
        
        taskContainer.start();  
        
        getJSRender().addEventListenerCode(evtListener);        
    }
    
    public AsyncTaskEventListenerWrapperImpl removeAsynchronousTask(String id)
    {    
        // Mtodo no pblico, es llamado por el framework
        // En este contexto hay que recordar que el ItsNatDocument est bloqueado
        // por el hilo actual.

        AsyncTaskEventListenerWrapperImpl listener = (AsyncTaskEventListenerWrapperImpl)tasks.get(id);
        if (listener == null) 
            throw new ItsNatException("Asynchronous Task with id " + id + " does not exist");

        AsyncTask task = listener.getAsyncTask();
        
        if (!task.isAlive())
        {
            task.dispose();
            tasks.remove(id);
        }

        // El hilo-tarea est vivo todava, si locksDocument() es true no debera estar vivo
        // todava pues no podramos llegar aqu si el documento est bloqueado por la tarea
        // (o bien acaba de salir del synchronized y todava no se ha marcado el hilo como finalizado) 
        // El problema ms bien es cuando locksDocument() devuelve false, en ese caso
        // la tarea puede ser muy larga y el programador tiene la obligacin
        // de bloquear el ItsNatDocument en el momento que vaya a acceder al mismo (resultados, cambios en el DOM etc),
        // esto supone que como ahora el ItsNatDocument est bloqueado por el hilo 
        // actual NO podemos esperar al hilo-tarea a que acabe (con un join())
        // pues ste en *cualquier momento* puede intentar bloquear el ItsNatDocument
        // por lo que entraramos en un bloqueo mutuo.
        // Para resolver el problema hay que obtener el Thread que no ha terminado todava, esto implica
        // que se ha de intentar de nuevo pero antes desbloqueando el ItsNatDocument
        // para que el hilo-tarea pueda bloquear el ItsNatDocument si lo necesita
        // o bien otros request puedan hacer su trabajo. Con el Thread
        // podremos hacer un join() fuera del documento sincronizado, de esa manera
        // el hilo podr esperar "dormido" hasta que termine el hilo 

        return listener;
    }        
}
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.