/* * Copyright (C) 2006-2016 DLR, Germany * * All rights reserved * * http://www.rcenvironment.de/ */ package de.rcenvironment.core.gui.workflow.editor.handlers; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import org.apache.commons.logging.LogFactory; import org.codehaus.jackson.JsonEncoding; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.JsonGenerator; import org.codehaus.jackson.util.DefaultPrettyPrinter; import de.rcenvironment.core.component.workflow.model.api.Connection; import de.rcenvironment.core.component.workflow.model.api.WorkflowDescription; import de.rcenvironment.core.component.workflow.model.api.WorkflowDescriptionPersistenceHandler; import de.rcenvironment.core.component.workflow.model.api.WorkflowLabel; import de.rcenvironment.core.component.workflow.model.api.WorkflowNode; import de.rcenvironment.core.gui.utils.common.ClipboardHelper; import de.rcenvironment.core.gui.workflow.parts.WorkflowLabelPart; import de.rcenvironment.core.gui.workflow.parts.WorkflowNodePart; /** * Handle copy part of copy&paste for {@link WorkflowNode}s, {@link Connection}s and {@link WorkflowLabel}s. * * @author Doreen Seider * @author Oliver Seebach * @author Marc Stammerjohann */ // TODO fix class name, it is not longer only a copy handler for WorkflowNodes public class WorkflowNodeCopyHandler extends AbstractWorkflowNodeEditHandler { private WorkflowDescriptionPersistenceHandler descriptionHandler = new WorkflowDescriptionPersistenceHandler(); @Override void edit() { WorkflowDescription model = (WorkflowDescription) viewer.getContents().getModel(); List<?> selection = viewer.getSelectedEditParts(); List<WorkflowNodePart> nodes = new ArrayList<WorkflowNodePart>(); List<Connection> connections = new ArrayList<Connection>(); List<WorkflowLabelPart> labels = new ArrayList<WorkflowLabelPart>(); // check whether there are connections between the selected nodes; if yes, add them to clipboard, too. for (Object selectedObject : selection) { if (selectedObject instanceof WorkflowNodePart) { WorkflowNodePart workflowNodePart = (WorkflowNodePart) selectedObject; nodes.add(workflowNodePart); WorkflowNode workflowNode = (WorkflowNode) workflowNodePart.getModel(); for (Object comparisonObject : selection) { if (comparisonObject instanceof WorkflowNodePart) { WorkflowNodePart comparisonWorkflowNodePart = ((WorkflowNodePart) comparisonObject); WorkflowNode comparisonWorkflowNode = (WorkflowNode) comparisonWorkflowNodePart.getModel(); for (Connection connection : model.getConnections()) { if ((connection.getSourceNode().getIdentifier().equals(workflowNode.getIdentifier()) && connection.getTargetNode().getIdentifier().equals(comparisonWorkflowNode.getIdentifier()))) { connections.add(connection); } } } } } else if (selectedObject instanceof WorkflowLabelPart) { WorkflowLabelPart workflowLabelPart = (WorkflowLabelPart) selectedObject; labels.add(workflowLabelPart); } } Collections.sort(labels, new WorkflowLabelpartComparator()); try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); JsonFactory f = new JsonFactory(); JsonGenerator generator = null; generator = f.createJsonGenerator(outputStream, JsonEncoding.UTF8); generator.setPrettyPrinter(new DefaultPrettyPrinter()); generator.writeStartObject(); if (!nodes.isEmpty()) { writeComponent(generator, nodes); } if (!connections.isEmpty()) { writeConnection(generator, connections); } if (!labels.isEmpty()) { writeLabel(generator, labels); } if (!connections.isEmpty()) { writeBendpoints(generator, connections); } generator.writeEndObject(); generator.close(); ClipboardHelper.setContent(outputStream.toString()); } catch (IOException e) { LogFactory.getLog(getClass()).debug("Error when writing components to JSON: " + e.getMessage()); } } private void writeComponent(JsonGenerator generator, List<WorkflowNodePart> nodes) throws JsonGenerationException, IOException { generator.writeArrayFieldStart(WorkflowDescriptionPersistenceHandler.NODES); for (WorkflowNodePart workflowNodePart : nodes) { WorkflowNode workflowNode = (WorkflowNode) workflowNodePart.getModel(); descriptionHandler.writeWorkflowNode(generator, workflowNode); } generator.writeEndArray(); } private void writeConnection(JsonGenerator generator, List<Connection> connections) throws JsonGenerationException, IOException { generator.writeArrayFieldStart(WorkflowDescriptionPersistenceHandler.CONNECTIONS); for (Connection connection : connections) { descriptionHandler.writeConnection(generator, connection); } generator.writeEndArray(); } private void writeBendpoints(JsonGenerator generator, List<Connection> connections) throws JsonGenerationException, IOException { generator.writeArrayFieldStart(WorkflowDescriptionPersistenceHandler.BENDPOINTS); Map<String, String> uniqueConnectionBendpointMapping = descriptionHandler.calculateUniqueBendpointList(connections); descriptionHandler.writeBendpoints(generator, uniqueConnectionBendpointMapping); generator.writeEndArray(); } private void writeLabel(JsonGenerator generator, List<WorkflowLabelPart> labels) throws JsonGenerationException, IOException { generator.writeArrayFieldStart(WorkflowDescriptionPersistenceHandler.LABELS); for (WorkflowLabelPart workflowLabelPart : labels) { WorkflowLabel workflowLabel = (WorkflowLabel) workflowLabelPart.getModel(); descriptionHandler.writeLabel(generator, workflowLabel); } generator.writeEndArray(); } /** * Comparing two {@link WorkflowLabelPart}s, depending on the Y-Position of the {@link WorkflowLabel}. * * @author Marc Stammerjohann */ private class WorkflowLabelpartComparator implements Comparator<WorkflowLabelPart> { @Override public int compare(WorkflowLabelPart part1, WorkflowLabelPart part2) { int y1 = getYPosition(part1); int y2 = getYPosition(part2); if (y1 == y2) { return 0; } else if (y1 < y2) { return 0 - 1; } else { return 1; } } private int getYPosition(WorkflowLabelPart part) { int y = 0; Object model = part.getModel(); if (model instanceof WorkflowLabel) { WorkflowLabel label = (WorkflowLabel) model; y = label.getY(); } return y; } } }