/******************************************************************************* * Copyright 2017 Capital One Services, LLC and Bitwise, Inc. * 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 hydrograph.ui.engine.ui.xygenration; import hydrograph.ui.engine.ui.converter.LinkingData; import hydrograph.ui.engine.ui.exceptions.ComponentNotFoundException; import hydrograph.ui.engine.ui.repository.UIComponentRepo; import hydrograph.ui.graph.model.Component; import hydrograph.ui.logging.factory.LogFactory; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.draw2d.geometry.Point; import org.slf4j.Logger; /** * The class CoordinateProcessor * * @author Bitwise * */ public class CoordinateProcessor { private static final Logger LOGGER = LogFactory.INSTANCE.getLogger(CoordinateProcessor.class); private List<Node> nodeList = new ArrayList<>(); private Map<String, Node> nodeMap = new LinkedHashMap<>(); private Map<String, Component> tempUiComponentFactory = new LinkedHashMap<>(); private UIComponentRepo componentRepo; private static final int HORIZONTAL_SPACING = 200; private static final int VERTICAL_SPACING = 200; public CoordinateProcessor(UIComponentRepo componentRepo) { this.componentRepo=componentRepo; } /** * Initiate X-Y coordinate generation process and creates node structure for each component. */ public void initiateCoordinateGenration() throws ComponentNotFoundException{ LOGGER.debug("Processing link-data for creating individual nodes"); Node sourceNode = null; Node destinationNode = null; tempUiComponentFactory.putAll(componentRepo.getComponentUiFactory()); for (LinkingData linkingData : componentRepo.getComponentLinkList()) { if (nodeMap.get(linkingData.getSourceComponentId()) == null) { sourceNode = new Node(linkingData.getSourceComponentId()); nodeMap.put(linkingData.getSourceComponentId(), sourceNode); nodeList.add(sourceNode); tempUiComponentFactory.remove(linkingData.getSourceComponentId()); } if (nodeMap.get(linkingData.getTargetComponentId()) == null) { destinationNode = new Node(linkingData.getTargetComponentId()); nodeMap.put(linkingData.getTargetComponentId(), destinationNode); nodeList.add(destinationNode); tempUiComponentFactory.remove(linkingData.getTargetComponentId()); } nodeMap.get(linkingData.getSourceComponentId()).getDestinationNodes() .add(nodeMap.get(linkingData.getTargetComponentId())); nodeMap.get(linkingData.getTargetComponentId()).getSourceNodes() .add(nodeMap.get(linkingData.getSourceComponentId())); } genrateUnlinkedComponents(); caculateXY(); processNodes(); } private void genrateUnlinkedComponents() { LOGGER.debug("Generating nodes of non-connected UI-Components"); for (Entry<String, Component> entry : tempUiComponentFactory.entrySet()) { nodeList.add(new Node(entry.getKey())); } } private void processNodes() { LOGGER.debug("Process individual links"); genrateYCoordinate(); for (Node node : nodeList) { Point point = new Point(); point.x = node.gethPosition(); point.y = node.getvPosition(); componentRepo.getComponentUiFactory().get(node.name).setLocation(point); } } private void genrateYCoordinate() { LOGGER.debug("Generating Y coordinates for all UI-Components"); int height = 0; LinkedHashMap<Integer, Integer> ycoordinate = new LinkedHashMap<>(); LinkedHashMap<Integer, Node> upperNodeDetails = new LinkedHashMap<>(); for (Node node : nodeList) { if (ycoordinate.get(node.gethPosition()) == null) { ycoordinate.put(node.gethPosition(), 1); upperNodeDetails.put(node.gethPosition(), node); node.setvPosition(1); } else { height = ycoordinate.get(node.gethPosition()) + VERTICAL_SPACING + incrementYPosition(upperNodeDetails.get(node.gethPosition())); upperNodeDetails.put(node.gethPosition(), node); ycoordinate.put(node.gethPosition(), height); node.setvPosition(ycoordinate.get(node.gethPosition())); } } } private void caculateXY()throws ComponentNotFoundException { LOGGER.debug("Calculating logical Linking and positioning of Nodes"); int position = 1; List<Node> noSource = new ArrayList<>(); List<Node> noDestination = new ArrayList<>(); for (Node node : nodeList) { if (node.getSourceNodes().isEmpty()) { node.sethPosition(position); noSource.add(node); } if (node.getDestinationNodes().isEmpty()) { noDestination.add(node); } } for (Node node : noSource) { calculate(node, position); } } private void calculate(Node node, int position) throws ComponentNotFoundException{ LOGGER.debug("Applying X coordinates for UI-Components"); node.sethPosition(position); position = incrementXPosition(node, position); if (node.getDestinationNodes().isEmpty()) { return; } for (Node destinationNode : node.getDestinationNodes()) { if (destinationNode.gethPosition() == 0 && destinationNode.getvPosition() == 0) calculate(destinationNode, position + HORIZONTAL_SPACING); } } private int incrementXPosition(Node node, int position)throws ComponentNotFoundException { LOGGER.debug("Applying X cordinate for component:{}" + node.getName()); if (componentRepo.getComponentUiFactory().get(node.getName()) != null) { int width = componentRepo.getComponentUiFactory().get(node.getName()).getSize().width(); if (width > 100) position = position + (width - 100); return position; } else throw new ComponentNotFoundException(node.getName(), null); } private int incrementYPosition(Node node) { int height = componentRepo.getComponentUiFactory().get(node.getName()).getSize().height(); if (height > 75) height = height - 75; else height = 0; return height; } }