/**
* 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.Map;
import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
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.event.DnDEvent;
import org.richfaces.event.DropEvent;
import org.richfaces.json.JSONCollection;
import org.richfaces.json.JSONException;
import org.richfaces.json.JSONMap;
import org.richfaces.renderkit.DnDEventsExchangeMailer.EventCallback;
/**
* @author shura
*
*/
public class DropzoneRendererContributor implements RendererContributor {
public static final String DROP_TARGET_ID = "dropTargetId";
private static final EventCallback dropEventsCallback = new EventCallback() {
void processEvent(DnDEvent dndEvent, UIComponent source,
FacesContext facesContext, Object type, Object value) {
DropEvent dropEvent = (DropEvent) dndEvent;
Draggable draggable = (Draggable) source;
dropEvent.setDraggableSource(draggable);
dropEvent.setDragType((String) type);
dropEvent.setDragValue(value);
}
};
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;
}
public void decode(FacesContext context, UIComponent component, CompositeRenderer compositeRenderer) {
DnDEventsExchangeMailer eventsExchanger = DnDEventsExchangeMailer.getInstance(context);
String clientId = component.getClientId(context);
Map paramMap = context.getExternalContext().getRequestParameterMap();
if(clientId.equals(paramMap.get(DROP_TARGET_ID))){
String dragSourceId = (String) paramMap.get(DraggableRendererContributor.DRAG_SOURCE_ID);
if (compositeRenderer != null) {
compositeRenderer.contributorDecodeCallback(component, context, this, dragSourceId);
}
Dropzone dropzone = (Dropzone) component;
eventsExchanger.mailEvent(dragSourceId, component,
context, new DropEvent(component), dropEventsCallback,
dropzone.getAcceptedTypes(),
dropzone.getDropValue(), false
);
}
}
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;
}
}