com.vaadin.server.DragAndDropService Maven / Gradle / Ivy
/*
* Copyright (C) 2000-2024 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See for the full
* license.
*/
package com.vaadin.server;
import java.io.IOException;
import java.io.Writer;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.vaadin.event.Transferable;
import com.vaadin.event.TransferableImpl;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DragSource;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.DropTarget;
import com.vaadin.event.dd.TargetDetails;
import com.vaadin.event.dd.TargetDetailsImpl;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.shared.ApplicationConstants;
import com.vaadin.shared.Registration;
import com.vaadin.shared.communication.SharedState;
import com.vaadin.shared.ui.dd.DragEventType;
import com.vaadin.ui.Component;
import com.vaadin.ui.UI;
import com.vaadin.ui.dnd.DragSourceExtension;
import com.vaadin.ui.dnd.DropTargetExtension;
import elemental.json.JsonObject;
/**
*
* @author Vaadin Ltd
* @deprecated Since 8.1, no direct replacement, see {@link DragSourceExtension}
* and {@link DropTargetExtension}.
*/
@Deprecated
public class DragAndDropService implements VariableOwner, ClientConnector {
private int lastVisitId;
private boolean lastVisitAccepted = false;
private DragAndDropEvent dragEvent;
private final VaadinSession session;
private AcceptCriterion acceptCriterion;
private ErrorHandler errorHandler;
public DragAndDropService(VaadinSession session) {
this.session = session;
}
@Override
public void changeVariables(Object source, Map variables) {
Object owner = variables.get("dhowner");
final Component sourceComponent = (Component) variables
.get("component");
if (sourceComponent != null && !sourceComponent.isConnectorEnabled()) {
// source component not supposed to be enabled
getLogger().warning("Client dropped from " + sourceComponent
+ " even though it's disabled");
return;
}
// Validate drop handler owner
if (!(owner instanceof DropTarget)) {
getLogger().severe("DropHandler owner " + owner
+ " must implement DropTarget");
return;
}
// owner cannot be null here
DropTarget dropTarget = (DropTarget) owner;
if (!dropTarget.isConnectorEnabled()) {
getLogger().warning("Client dropped on " + owner
+ " even though it's disabled");
return;
}
lastVisitId = (Integer) variables.get("visitId");
// request may be dropRequest or request during drag operation (commonly
// dragover or dragenter)
boolean dropRequest = isDropRequest(variables);
if (dropRequest) {
handleDropRequest(dropTarget, variables);
} else {
handleDragRequest(dropTarget, variables);
}
}
/**
* Handles a drop request from the VDragAndDropManager.
*
* @param dropTarget
* @param variables
*/
private void handleDropRequest(DropTarget dropTarget,
Map variables) {
DropHandler dropHandler = dropTarget.getDropHandler();
if (dropHandler == null) {
// No dropHandler returned so no drop can be performed.
getLogger().log(Level.FINE,
"DropTarget.getDropHandler() returned null for owner: {0}",
dropTarget);
return;
}
/*
* Construct the Transferable and the DragDropDetails for the drop
* operation based on the info passed from the client widgets (drag
* source for Transferable, drop target for DragDropDetails).
*/
Transferable transferable = constructTransferable(variables);
TargetDetails dropData = constructDragDropDetails(dropTarget,
variables);
DragAndDropEvent dropEvent = new DragAndDropEvent(transferable,
dropData);
if (dropHandler.getAcceptCriterion().accept(dropEvent)) {
dropHandler.drop(dropEvent);
}
}
/**
* Handles a drag/move request from the VDragAndDropManager.
*
* @param dropTarget
* @param variables
*/
private void handleDragRequest(DropTarget dropTarget,
Map variables) {
lastVisitId = (Integer) variables.get("visitId");
acceptCriterion = dropTarget.getDropHandler().getAcceptCriterion();
/*
* Construct the Transferable and the DragDropDetails for the drag
* operation based on the info passed from the client widgets (drag
* source for Transferable, current target for DragDropDetails).
*/
Transferable transferable = constructTransferable(variables);
TargetDetails dragDropDetails = constructDragDropDetails(dropTarget,
variables);
dragEvent = new DragAndDropEvent(transferable, dragDropDetails);
lastVisitAccepted = acceptCriterion.accept(dragEvent);
}
/**
* Construct DragDropDetails based on variables from client drop target.
* Uses DragDropDetailsTranslator if available, otherwise a default
* DragDropDetails implementation is used.
*
* @param dropTarget
* @param variables
* @return
*/
@SuppressWarnings("unchecked")
private TargetDetails constructDragDropDetails(DropTarget dropTarget,
Map variables) {
Map rawDragDropDetails = (Map) variables
.get("evt");
TargetDetails dropData = dropTarget
.translateDropTargetDetails(rawDragDropDetails);
if (dropData == null) {
// Create a default DragDropDetails with all the raw variables
dropData = new TargetDetailsImpl(rawDragDropDetails, dropTarget);
}
return dropData;
}
private boolean isDropRequest(Map variables) {
return getRequestType(variables) == DragEventType.DROP;
}
private DragEventType getRequestType(Map variables) {
int type = (Integer) variables.get("type");
return DragEventType.values()[type];
}
@SuppressWarnings("unchecked")
private Transferable constructTransferable(Map variables) {
final Component sourceComponent = (Component) variables
.get("component");
variables = (Map) variables.get("tra");
Transferable transferable = null;
if (sourceComponent instanceof DragSource) {
transferable = ((DragSource) sourceComponent)
.getTransferable(variables);
}
if (transferable == null) {
transferable = new TransferableImpl(sourceComponent, variables);
}
return transferable;
}
/**
*
* Tests if the variable owner is enabled or not. The terminal should not
* send any variable changes to disabled variable owners.
*
* Implementation detail: this method is originally from the VariableOwner
* class, which has been removed in Vaadin 8.
*
* @return true
if the variable owner is enabled,
* false
if not
*/
@Override
public boolean isEnabled() {
return isConnectorEnabled();
}
public void printJSONResponse(Writer outWriter) throws IOException {
if (isDirty()) {
outWriter.write(", \"dd\":");
JsonPaintTarget jsonPaintTarget = new JsonPaintTarget(
session.getCommunicationManager(), outWriter, false);
jsonPaintTarget.startTag("dd");
jsonPaintTarget.addAttribute("visitId", lastVisitId);
if (acceptCriterion != null) {
jsonPaintTarget.addAttribute("accepted", lastVisitAccepted);
acceptCriterion.paintResponse(jsonPaintTarget);
}
jsonPaintTarget.endTag("dd");
jsonPaintTarget.close();
lastVisitId = -1;
lastVisitAccepted = false;
acceptCriterion = null;
dragEvent = null;
}
}
private boolean isDirty() {
if (lastVisitId > 0) {
return true;
}
return false;
}
@Override
public String getConnectorId() {
return ApplicationConstants.DRAG_AND_DROP_CONNECTOR_ID;
}
@Override
public boolean isConnectorEnabled() {
// Drag'n'drop can't be disabled
return true;
}
@Override
public List retrievePendingRpcCalls() {
return null;
}
@Override
public ServerRpcManager> getRpcManager(String interfaceName) {
// TODO Use rpc for drag'n'drop
return null;
}
@Override
public Class extends SharedState> getStateType() {
return SharedState.class;
}
@Override
@Deprecated
public void requestRepaint() {
markAsDirty();
}
@Override
public void markAsDirty() {
}
@Override
public ClientConnector getParent() {
return null;
}
@Override
@Deprecated
public void requestRepaintAll() {
markAsDirtyRecursive();
}
@Override
public void markAsDirtyRecursive() {
}
@Override
public void attach() {
}
@Override
public void detach() {
}
@Override
public Collection getExtensions() {
return Collections.emptySet();
}
@Override
public void removeExtension(Extension extension) {
}
private Logger getLogger() {
return Logger.getLogger(DragAndDropService.class.getName());
}
@Override
public UI getUI() {
return null;
}
@Override
public void beforeClientResponse(boolean initial) {
// Nothing to do
}
@Override
public JsonObject encodeState() {
return null;
}
@Override
public boolean handleConnectorRequest(VaadinRequest request,
VaadinResponse response, String path) throws IOException {
return false;
}
@Override
public ErrorHandler getErrorHandler() {
return errorHandler;
}
@Override
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
@Override
public Registration addAttachListener(AttachListener listener) {
return () -> {
/* NO-OP */
};
}
@Override
@Deprecated
public void removeAttachListener(AttachListener listener) {
}
@Override
public Registration addDetachListener(DetachListener listener) {
return () -> {
/* NO-OP */
};
}
@Override
@Deprecated
public void removeDetachListener(DetachListener listener) {
}
/*
* (non-Javadoc)
*
* @see com.vaadin.server.ClientConnector#isAttached()
*/
@Override
public boolean isAttached() {
return true;
}
}