Package org.richfaces.renderkit

Source Code of org.richfaces.renderkit.DropzoneRendererContributor$DraggableDecoderContextCallback

/**
* 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.text.MessageFormat;
import java.util.Map;
import java.util.Set;

import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import org.ajax4jsf.component.ContextCallbackWrapper;
import org.ajax4jsf.javascript.DnDScript;
import org.ajax4jsf.javascript.JSFunction;
import org.ajax4jsf.javascript.JSFunctionDefinition;
import org.ajax4jsf.javascript.JSReference;
import org.ajax4jsf.javascript.PrototypeScript;
import org.ajax4jsf.javascript.ScriptUtils;
import org.ajax4jsf.renderkit.AjaxRendererUtils;
import org.richfaces.component.Draggable;
import org.richfaces.component.Dropzone;
import org.richfaces.component.util.MessageUtil;
import org.richfaces.event.DragEvent;
import org.richfaces.event.DropEvent;
import org.richfaces.json.JSONCollection;
import org.richfaces.json.JSONException;
import org.richfaces.json.JSONMap;

/**
* @author shura
*
*/
public class DropzoneRendererContributor implements RendererContributor {

  public static final String DROP_TARGET_ID = "dropTargetId";

  private DropzoneRendererContributor() {
    super();
  }

  private static RendererContributor instance;

  public static synchronized RendererContributor getInstance() {
    if (instance == null) {
      instance = new DropzoneRendererContributor();
    }

    return instance;
  }

  /**
   * Utility class for building scripting options
   * @author Maksim Kaszynski
   *
   */
  public class DropZoneOptions extends ScriptOptions {

    public DropZoneOptions(Dropzone zone) {
      //TODO by nick - change this cast
      super((UIComponent) zone);

      Object acceptedTypes = zone.getAcceptedTypes();
      if(acceptedTypes instanceof String) {
        try {
          String typesString = ((String) acceptedTypes).trim();
          if (!typesString.startsWith("[")) {
            typesString = "[" + typesString + "]";
          }

          acceptedTypes = new JSONCollection(typesString);
        } catch (JSONException e) {
          throw new FacesException(e);
        }
      }
      addOption("acceptedTypes", acceptedTypes);

      Object typeMapping = zone.getTypeMapping();
      if(typeMapping instanceof String) {
        try {
          typeMapping = new JSONMap((String)typeMapping);
        } catch (JSONException e) {
          throw new FacesException(e);
        }
      }
      addOption("typeMapping", typeMapping);
     
      Object cursorTypeMapping = zone.getCursorTypeMapping();
      if (cursorTypeMapping instanceof String) {
        try {
          cursorTypeMapping = new JSONMap((String)cursorTypeMapping);
        } catch (JSONException e) {
          throw new FacesException(e)
        }
      }
     
      addOption("cursorTypeMapping", cursorTypeMapping);
     
      String acceptCursors = zone.getAcceptCursors();
      if (!acceptCursors.equals("")) {
        addOption("acceptCursor", acceptCursors);
      }
       
      String rejectCursors = zone.getRejectCursors();
      if (!rejectCursors.equals("")) {
        addOption("rejectCursor", rejectCursors);
      }
             
      addEventHandler("ondragenter", zone.getOndragenter());
      addEventHandler("ondragexit", zone.getOndragexit());
      addEventHandler("onafterdrag");
      addEventHandler("ondrop");
      addEventHandler("ondropend");
    }
  }
 
  public ScriptOptions buildOptions(FacesContext context, UIComponent drop) {
    if (drop instanceof Dropzone) {
      return new DropZoneOptions((Dropzone) drop);
    }

    return null;
  }

  private static final class DraggableDecoderContextCallback implements ContextCallback {

    private Dropzone dropzone;
   
    private Draggable draggable;
   
    private String dragType;
   
    private Object dragValue;
   
    private Object acceptedTypes;
   
    private Object dropValue;
   
    private boolean valid = true;

    private Object draggableLabel;
   
    public DraggableDecoderContextCallback(Dropzone dropzone, Object acceptedTypes, Object dropValue) {
      super();
     
      this.dropzone = dropzone;
      this.acceptedTypes = acceptedTypes;
      this.dropValue = dropValue;
    }

    private boolean validateAcceptTypes(String dragType, Object acceptedTypes) {
      Set<String> set = AjaxRendererUtils.asSet(acceptedTypes);
      return (set != null && set.contains(dragType));
    }
   
    public void invokeContextCallback(FacesContext context,
        UIComponent target) {

      this.draggable = (Draggable) target;

      this.dragType = draggable.getDragType();
      this.dragValue = draggable.getDragValue();
     
      if (validateAcceptTypes(dragType, acceptedTypes)) {

        DragEvent dragEvent = new DragEvent((UIComponent) draggable);
        dragEvent.setDropTarget(dropzone);
        dragEvent.setAcceptedTypes(acceptedTypes);
        dragEvent.setDropValue(dropValue);

        dragEvent.queue();
      } else {
        //invalidate
        this.valid = false;
        //store label for message output
        this.draggableLabel = MessageUtil.getLabel(context, (UIComponent) draggable);
      }
    }
   
    public Draggable getDraggable() {
      return draggable;
    }
   
    public String getDragType() {
      return dragType;
    }
   
    public Object getDragValue() {
      return dragValue;
    }
   
    public boolean isValid() {
      return valid;
    }
   
    public Object getDraggableLabel() {
      return draggableLabel;
    }
  }

  private final static String MISTYPED_DND_MESSAGE = "Dropzone [{0}] with accepted types {1} cannot accept Draggable [{2}] with dragType [{3}]";
 
  public void decode(FacesContext context, UIComponent component, CompositeRenderer compositeRenderer) {
    String clientId = component.getClientId(context);
    Map<String, String> paramMap = context.getExternalContext().getRequestParameterMap();

    if(clientId.equals(paramMap.get(DROP_TARGET_ID))){
      String dragSourceId = (String) paramMap.get(DraggableRendererContributor.DRAG_SOURCE_ID);

      if (dragSourceId != null && dragSourceId.length() != 0) {
        Dropzone dropzone = (Dropzone) component;
        Object acceptedTypes = dropzone.getAcceptedTypes();
        Object dropValue = dropzone.getDropValue();

        DraggableDecoderContextCallback draggableDecoderContextCallback =
          new DraggableDecoderContextCallback(dropzone,
              acceptedTypes, dropValue);
       
        context.getViewRoot().invokeOnComponent(context, dragSourceId,
          new ContextCallbackWrapper(draggableDecoderContextCallback));
     
        Draggable draggable = draggableDecoderContextCallback.getDraggable();
        if (draggable != null) {
          if (draggableDecoderContextCallback.isValid()) {
            DropEvent dropEvent = new DropEvent(component);
            dropEvent.setDraggableSource(draggable);
            dropEvent.setDragType(draggableDecoderContextCallback.getDragType());
            dropEvent.setDragValue(draggableDecoderContextCallback.getDragValue());

            dropEvent.queue();
          } else {
            String text = MessageFormat.format(
                MISTYPED_DND_MESSAGE,
                new Object[] {
                    MessageUtil.getLabel(context, component),
                    acceptedTypes,
                    draggableDecoderContextCallback.getDraggableLabel(),
                    draggableDecoderContextCallback.getDragType()});

            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, text, text);

            context.addMessage(component.getClientId(context), message);

            context.renderResponse();
          }
        }
      }
    }
  }
 
  public String getScriptContribution(FacesContext context, UIComponent component) {
    StringBuffer result = new StringBuffer();

    result.append(".drop = ");

    JSFunctionDefinition definition = new JSFunctionDefinition();
    definition.addParameter("event");
    definition.addParameter("drag");

    Map requestOpts = AjaxRendererUtils.buildEventOptions(context, component);
    definition.addToBody("var options = ").addToBody(ScriptUtils.toScript(requestOpts)).addToBody(";");
    definition.addToBody("options.parameters['" + DROP_TARGET_ID + "'] = '" + component.getClientId(context) + "';");
    //TODO nick - remove as legacy
    definition.addToBody("Object.extend(options.parameters, drag.getParameters());");
    definition.addToBody("var dzOptions = this.getDropzoneOptions(); if (dzOptions.ondrop) { if (!dzOptions.ondrop.call(this, event)) return; };");
   
    JSFunction dropFunction = AjaxRendererUtils.buildAjaxFunction(component, context);
    dropFunction.addParameter(new JSReference("options"));
   
    definition.addToBody(dropFunction.toScript()).addToBody(";");
    definition.appendScript(result);
    result.append(";");

    return result.toString();
  }

  public String[] getStyleDependencies() {
    return null;
  }
 
  public String[] getScriptDependencies() {
    return new String[] {
      PrototypeScript.class.getName(),
      "/org/richfaces/renderkit/html/scripts/json/json-mini.js",
      DnDScript.class.getName(),
      "/org/richfaces/renderkit/html/scripts/utils.js",
      "/org/richfaces/renderkit/html/scripts/json/json-dom.js",
      "/org/richfaces/renderkit/html/scripts/dnd/dnd-common.js",
      "/org/richfaces/renderkit/html/scripts/dnd/dnd-dropzone.js"
    };
  }

  public Class getAcceptableClass() {
    return Dropzone.class;
  }

}
TOP

Related Classes of org.richfaces.renderkit.DropzoneRendererContributor$DraggableDecoderContextCallback

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.