Package org.richfaces.renderkit

Source Code of org.richfaces.renderkit.DnDEventsExchangeMailer$EventCallback

/**
* License Agreement.
*
*  JBoss RichFaces - Ajax4jsf Component Library
*
* Copyright (C) 2007  Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/

package org.richfaces.renderkit;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.apache.commons.collections.MultiHashMap;
import org.richfaces.component.Draggable;
import org.richfaces.component.Dropzone;
import org.richfaces.event.DnDEvent;

/**
* @author Nick Belaevski - nbelaevski@exadel.com
* created 27.12.2006
*
*/
final class DnDEventsExchangeMailer {
  private DnDEventsExchangeMailer() {

  }

  private static class EventInfoStructure {
    private DnDEvent dndEvent;
    private EventCallback eventCallback;
   
    private Object type;
    private Object value;
   
    public EventInfoStructure(DnDEvent dndEvent,
        EventCallback eventCallback, Object type, Object value) {
      super();
      this.dndEvent = dndEvent;
      this.eventCallback = eventCallback;
      this.type = type;
      this.value = value;
    }

  }

  static abstract class EventCallback {
    abstract void processEvent(DnDEvent dndEvent, UIComponent source, FacesContext facesContext, Object type, Object value);
  }

  static DnDEventsExchangeMailer getInstance(FacesContext facesContext) {
    synchronized (facesContext) {
      Map requestMap = facesContext.getExternalContext().getRequestMap();

      String attrName = DnDEventsExchangeMailer.class.getName();
      DnDEventsExchangeMailer instance;
      if ((instance = (DnDEventsExchangeMailer) requestMap.get(attrName)) == null) {
        instance = new DnDEventsExchangeMailer();

        requestMap.put(attrName, instance);
      }

      return instance;
    }
  }

  private Map<String, EventInfoStructure> queuedMap = new HashMap<String, EventInfoStructure>();

  private Map<String, UIComponent> components = new HashMap<String, UIComponent>();

  private void processEvent(UIComponent source, FacesContext facesContext, DnDEvent dndEvent, EventCallback callback, Object type, Object value) {
    if (callback != null) {
      callback.processEvent(dndEvent, source, facesContext, type, value);
    }
  }
 
  /**
   * Decode drag & drop events. Collect pairs of correspondent drag & drop events and send them
   * together where OnDrag becomes always before OnDrop.  
   *
   * @param sourceId Id of element event come from
   * @param target component that receive event
   * @param facesContext Faces context
   * @param dndEvent drag & drop event descriptor
   * @param callback call back method
   * @param type type of dragged/dropped value
   * @param value dragged/dropped value
   * @param isDraggable whether the event related draggable component or dropzone one.
   */
  public void mailEvent(String sourceId, UIComponent target, FacesContext facesContext, final DnDEvent dndEvent,
      final EventCallback callback, final Object type, final Object value, boolean isDraggable) {
   
    final UIComponent component = components.get(sourceId);
    String targetId = target.getClientId(facesContext);
   
    if (component == null) {
      //component with that sourceId have never mailed anything before - wait
      if (queuedMap.containsKey(sourceId)) {
        throw new IllegalStateException("Drag source with id '" + sourceId + "' already specified.");
      }
      queuedMap.put(sourceId, new EventInfoStructure(dndEvent, callback, type, value));
      components.put(targetId, target);
    } else {
      //check queued mail lists for current component
      final EventInfoStructure eventInfo = (EventInfoStructure) queuedMap.get(targetId);
      if (eventInfo != null) {
        Draggable draggable;
        Dropzone dropzone;
       
        final EventInfoStructure dragEventInfo = isDraggable ? eventInfo : new EventInfoStructure(dndEvent, callback, type, value);
        final EventInfoStructure dropEventInfo = isDraggable ? new EventInfoStructure(dndEvent, callback, type, value) : eventInfo;
       
        Object acceptedTypes;
        Object dragType;

        if (isDraggable) {
          draggable = (Draggable) target;
          dropzone = (Dropzone) component;
         
          acceptedTypes = eventInfo.type;
          dragType = type;
        } else {
          draggable = (Draggable) component;
          dropzone = (Dropzone) target;
         
          acceptedTypes = type;
          dragType = eventInfo.type;
        }

        if (DnDValidator.validateAcceptTypes(facesContext,
            draggable, dropzone,
            dragType, acceptedTypes)) {
         
          // Make sure that we will have OnDrag event occur first
          facesContext.getViewRoot().invokeOnComponent(facesContext, isDraggable ? targetId : sourceId, new ContextCallback() {
            public void invokeContextCallback(FacesContext fc,
                      UIComponent targetComponent) {
             
              processEvent(targetComponent, fc, dragEventInfo.dndEvent, dragEventInfo.eventCallback,
                  dropEventInfo.type, dropEventInfo.value);
             
              dropEventInfo.dndEvent.queue();
            }
          });
         
          facesContext.getViewRoot().invokeOnComponent(facesContext, isDraggable ? sourceId : targetId, new ContextCallback() {
            public void invokeContextCallback(FacesContext fc,
                      UIComponent targetComponent) {
             
              processEvent(targetComponent, fc, dropEventInfo.dndEvent, dropEventInfo.eventCallback,
                  dragEventInfo.type, dragEventInfo.value);
             
              dragEventInfo.dndEvent.queue();
            }
          });
        }
         
        queuedMap.remove(targetId);
      }
    }
  }

}

TOP

Related Classes of org.richfaces.renderkit.DnDEventsExchangeMailer$EventCallback

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.