/* * Copyright 2017 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.kie.workbench.common.stunner.client.lienzo.canvas.controls.connection; import java.util.logging.Level; import java.util.logging.Logger; import javax.enterprise.context.Dependent; import javax.inject.Inject; import com.ait.lienzo.client.core.shape.wires.IConnectionAcceptor; import com.ait.lienzo.client.core.shape.wires.MagnetManager; import com.ait.lienzo.client.core.shape.wires.WiresConnection; import com.ait.lienzo.client.core.shape.wires.WiresMagnet; import com.ait.lienzo.client.core.shape.wires.WiresShape; import com.google.gwt.logging.client.LogConfiguration; import org.kie.workbench.common.stunner.client.lienzo.canvas.wires.WiresCanvas; import org.kie.workbench.common.stunner.client.lienzo.canvas.wires.WiresUtils; import org.kie.workbench.common.stunner.core.client.canvas.AbstractCanvasHandler; import org.kie.workbench.common.stunner.core.client.canvas.controls.connection.ConnectionAcceptorControl; import org.kie.workbench.common.stunner.core.client.canvas.util.CanvasHighlight; import org.kie.workbench.common.stunner.core.client.command.CanvasCommandFactory; import org.kie.workbench.common.stunner.core.client.command.CanvasCommandManager; import org.kie.workbench.common.stunner.core.client.command.CanvasViolation; import org.kie.workbench.common.stunner.core.command.CommandResult; import org.kie.workbench.common.stunner.core.command.util.CommandUtils; import org.kie.workbench.common.stunner.core.graph.Edge; import org.kie.workbench.common.stunner.core.graph.Node; import org.kie.workbench.common.stunner.core.graph.content.view.View; @Dependent public class ConnectionAcceptorControlImpl implements ConnectionAcceptorControl<AbstractCanvasHandler> { private static Logger LOGGER = Logger.getLogger(ConnectionAcceptorControlImpl.class.getName()); CanvasCommandFactory<AbstractCanvasHandler> canvasCommandFactory; private CommandManagerProvider<AbstractCanvasHandler> provider; private AbstractCanvasHandler canvasHandler; private CanvasHighlight canvasHighlight; @Inject public ConnectionAcceptorControlImpl(final CanvasCommandFactory<AbstractCanvasHandler> canvasCommandFactory) { this.canvasCommandFactory = canvasCommandFactory; } @Override public void enable(final AbstractCanvasHandler canvasHandler) { this.canvasHandler = canvasHandler; this.canvasHighlight = new CanvasHighlight(canvasHandler); final WiresCanvas.View canvasView = (WiresCanvas.View) canvasHandler.getAbstractCanvas().getView(); canvasView.setConnectionAcceptor(CONNECTION_ACCEPTOR); } @Override public void disable() { if (null != canvasHandler && null != canvasHandler.getCanvas()) { final WiresCanvas.View canvasView = (WiresCanvas.View) canvasHandler.getAbstractCanvas().getView(); canvasView.setConnectionAcceptor(IConnectionAcceptor.NONE); } this.canvasHighlight.destroy(); this.canvasHighlight = null; this.canvasHandler = null; } @Override @SuppressWarnings("unchecked") public boolean allowSource(final Node source, final Edge<View<?>, Node> connector, final int magnet) { if (null == canvasHandler) { return false; } final boolean eq = eq(source, connector.getSourceNode()); if (!eq) { final CommandResult<CanvasViolation> violations = getCommandManager().allow(canvasHandler, canvasCommandFactory.setSourceNode(source, connector, magnet)); final boolean accepts = isAccept(violations); highlight(source, connector, accepts); return accepts; } return true; } @Override @SuppressWarnings("unchecked") public boolean allowTarget(final Node target, final Edge<View<?>, Node> connector, final int magnet) { if (null == canvasHandler) { return false; } final boolean eq = eq(target, connector.getTargetNode()); if (!eq) { final CommandResult<CanvasViolation> violations = getCommandManager().allow(canvasHandler, canvasCommandFactory.setTargetNode(target, connector, magnet)); final boolean accepts = isAccept(violations); highlight(target, connector, accepts); return accepts; } return true; } @Override @SuppressWarnings("unchecked") public boolean acceptSource(final Node source, final Edge<View<?>, Node> connector, final int magnet) { if (null == canvasHandler) { return false; } final boolean eq = eq(source, connector.getSourceNode()); if (!eq) { ensureUnHighLight(); final CommandResult<CanvasViolation> violations = getCommandManager().execute(canvasHandler, canvasCommandFactory.setSourceNode(source, connector, magnet)); return isAccept(violations); } return true; } @Override @SuppressWarnings("unchecked") public boolean acceptTarget(final Node target, final Edge<View<?>, Node> connector, final int magnet) { if (null == canvasHandler) { return false; } final boolean eq = eq(target, connector.getTargetNode()); if (!eq) { ensureUnHighLight(); final CommandResult<CanvasViolation> violations = getCommandManager().execute(canvasHandler, canvasCommandFactory.setTargetNode(target, connector, magnet)); return isAccept(violations); } return true; } @SuppressWarnings("unchecked") private static boolean eq(final Node n1, final Node n2) { if (n1 == null && n2 == null) { return true; } return null != n1 && n1.equals(n2); } private final IConnectionAcceptor CONNECTION_ACCEPTOR = new IConnectionAcceptor() { // Set the source Node for the connector. @Override @SuppressWarnings("unchecked") public boolean acceptHead(final WiresConnection head, final WiresMagnet magnet) { log(Level.FINE, "## Accept Head ##"); final Edge edge = WiresUtils.getEdge(canvasHandler, head.getConnector()); final Node sourceNode = WiresUtils.getNode(canvasHandler, magnet); final int mIndex = getMagnetIndex(magnet); final String sourceUUID = sourceNode != null ? sourceNode.getUUID() : null; final String message = "Executed SetConnectionSourceNodeCommand [source=" + sourceUUID + ", magnet=" + mIndex + "]"; log(Level.FINE, message); return acceptSource(sourceNode, edge, mIndex); } // Set the target Node for the connector. @Override @SuppressWarnings("unchecked") public boolean acceptTail(final WiresConnection tail, final WiresMagnet magnet) { log(Level.FINE, "## Accept tail ##"); final WiresConnection head = tail.getConnector().getHeadConnection(); final Edge edge = WiresUtils.getEdge(canvasHandler, head.getConnector()); final Node targetNode = WiresUtils.getNode(canvasHandler, magnet); final int mIndex = getMagnetIndex(magnet); final String targetUUID = targetNode != null ? targetNode.getUUID() : null; final String message = "Executed SetConnectionTargetNodeCommand [target=" + targetUUID + ", magnet=" + mIndex + "]"; log(Level.FINE, message); return acceptTarget(targetNode, edge, mIndex); } @Override @SuppressWarnings("unchecked") public boolean headConnectionAllowed(final WiresConnection head, final WiresShape shape) { log(Level.FINE, "## Allow Head ##"); final Edge<View<?>, Node> edge = WiresUtils.getEdge(canvasHandler, head.getConnector()); final Node sourceNode = WiresUtils.getNode(canvasHandler, shape); final boolean b = allowSource(sourceNode, edge, 0); final String nUUID = null != sourceNode ? sourceNode.getUUID() : "null"; log(Level.FINE, " Is head allowed [" + nUUID + "] = " + b); return b; } @Override @SuppressWarnings("unchecked") public boolean tailConnectionAllowed(final WiresConnection tail, final WiresShape shape) { log(Level.FINE, "## Allow tail ##"); final Edge<View<?>, Node> edge = WiresUtils.getEdge(canvasHandler, tail.getConnector()); final Node targetNode = WiresUtils.getNode(canvasHandler, shape); final boolean b = allowTarget(targetNode, edge, 0); final String nUUID = null != targetNode ? targetNode.getUUID() : "null"; log(Level.FINE, " Is tail allowed [" + nUUID + "] = " + b); return b; } private int getMagnetIndex(final WiresMagnet magnet) { if (null != magnet) { MagnetManager.Magnets magnets = magnet.getMagnets(); for (int x = 0; x < magnets.size(); x++) { WiresMagnet _m = magnets.getMagnet(x); if (_m.equals(magnet)) { return x; } } } return -1; } }; private boolean isAccept(final CommandResult<CanvasViolation> result) { return !CommandUtils.isError(result); } private void highlight(final Node node, final Edge<View<?>, Node> connector, final boolean valid) { canvasHighlight.unhighLight(); if (null != node && valid) { canvasHighlight.highLight(node); } else if (null != node) { canvasHighlight.invalid(node); } } private void ensureUnHighLight() { if (null != canvasHighlight) { canvasHighlight.unhighLight(); } } private void log(final Level level, final String message) { if (LogConfiguration.loggingIsEnabled()) { LOGGER.log(level, message); } } @Override public void setCommandManagerProvider(final CommandManagerProvider<AbstractCanvasHandler> provider) { this.provider = provider; } private CanvasCommandManager<AbstractCanvasHandler> getCommandManager() { return provider.getCommandManager(); } }