/******************************************************************************* * 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.graph.utility; import hydrograph.ui.common.util.Constants; import hydrograph.ui.datastructure.property.ComponentsOutputSchema; import hydrograph.ui.graph.model.Component; import hydrograph.ui.graph.model.Container; import hydrograph.ui.graph.model.Link; import hydrograph.ui.graph.model.components.CloneComponent; import hydrograph.ui.graph.model.components.InputSubjobComponent; import hydrograph.ui.graph.model.components.OutputSubjobComponent; import hydrograph.ui.graph.model.components.UnionallComponent; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.Point; /** * Class SubJobPortLinkUtilty has business logic to link the port in sub graph component. * @author Bitwise * */ public class SubJobPortLinkUtilty { /** * Adds the input sub graph component and link. * * @param container the container * @param cacheInputSubjobComp map of component and number of port. * @param clipboardList the clipboard list * @return the component */ public static Component addInputSubJobComponentAndLink(Container container,Map<Component,Integer> cacheInputSubjobComp,List clipboardList){ int outPort=0; InputSubjobComponent inputSubComponent=new InputSubjobComponent(); for (Map.Entry<Component,Integer> entry : cacheInputSubjobComp.entrySet()) { inputSubComponent.setProperties(new LinkedHashMap<String,Object>()); List<Link> linkedList = entry.getKey().getTargetConnections(); int inputLinksCountForEntry = linkedList.size(); if(inputLinksCountForEntry == 0){ for(int j=0;j<entry.getValue();j++) { createNewLink(entry, inputSubComponent, outPort, j); outPort++; } }else if(inputLinksCountForEntry < entry.getValue()){ for(int j=0;j<entry.getValue();j++) { for (int i = 0; i < inputLinksCountForEntry; i++){ if(!linkedList.get(i).getTargetTerminal().equalsIgnoreCase(Constants.INPUT_SOCKET_TYPE + j)){ createNewLink(entry, inputSubComponent, outPort, j); outPort++; } } } } inputSubComponent.getProperties().put(Constants.TYPE, Constants.INPUT_SUBJOB); container.addSubJobChild((Component) entry.getKey()); clipboardList.remove(entry.getKey()); } if(cacheInputSubjobComp.size()>0){ inputSubComponent.getProperties().put(Constants.NAME, Constants.INPUT_SUBJOB); inputSubComponent.setComponentId(Constants.INPUT_SUBJOB); inputSubComponent.setComponentLabel(Constants.INPUT_SUBJOB); inputSubComponent.setType(Constants.INPUT_SUBJOB_TYPE); inputSubComponent.setCategory(Constants.SUBJOB_COMPONENT_CATEGORY); inputSubComponent.completeOutputPortSettings(outPort); fixComponentSize(inputSubComponent, outPort); setXYCoordinate(inputSubComponent,0 , 0); inputSubComponent.setParent(container); container.addSubJobChild(inputSubComponent); } return inputSubComponent; } private static void createNewLink(Entry<Component, Integer> entry, InputSubjobComponent inputSubComponent, int outPort, int j) { Link linkNew = new Link(); linkNew.setTarget(entry.getKey()); linkNew.setSource(inputSubComponent); if(entry.getKey() instanceof UnionallComponent){ linkNew.setTargetTerminal(Constants.FIXED_INSOCKET_ID); }else{ linkNew.setTargetTerminal(Constants.INPUT_SOCKET_TYPE + j); } linkNew.setSourceTerminal(Constants.OUTPUT_SOCKET_TYPE + outPort); entry.getKey().connectInput(linkNew); inputSubComponent.connectOutput(linkNew); } /** * Adds the output sub graph component and link. * * @param container the container * @param cacheInputSubjobComp the cache input subjob comp * @param cacheOutSubjobComp the cache out subjob comp * @param clipboardList the clipboard list * @return the component */ public static Component addOutputSubJobComponentAndLink(Container container,Map<Component,Integer> cacheInputSubjobComp,Map<Component,List<String>> cacheOutSubjobComp,List clipboardList){ int inPort=0; OutputSubjobComponent outSubComponent=new OutputSubjobComponent(); Map<String, ComponentsOutputSchema> schemaMap = new HashMap<String, ComponentsOutputSchema>(); for (Map.Entry<Component,List<String>> entry : cacheOutSubjobComp.entrySet()) { outSubComponent.setProperties(new LinkedHashMap<String,Object>()); for (String sourceTerminal : entry.getValue()) { Link linkNew = new Link(); linkNew.setSource(entry.getKey()); linkNew.setTarget(outSubComponent); linkNew.setSourceTerminal(sourceTerminal); linkNew.setTargetTerminal(Constants.INPUT_SOCKET_TYPE+inPort); entry.getKey().connectOutput(linkNew); outSubComponent.connectInput(linkNew); if(entry.getKey() instanceof CloneComponent){ rearrangeLinkNumbers(entry.getKey()); } outSubComponent.getProperties().put(Constants.TYPE, Constants.OUTPUT_SUBJOB); inPort++; } if(cacheInputSubjobComp.get(entry.getKey())==null){ container.addSubJobChild(entry.getKey()); clipboardList.remove(entry.getKey()); } } if(cacheOutSubjobComp.size()>0){ outSubComponent.getProperties().put(Constants.NAME,Constants.OUTPUT_SUBJOB); outSubComponent.setComponentLabel(Constants.OUTPUT_SUBJOB); outSubComponent.setComponentId(Constants.OUTPUT_SUBJOB); outSubComponent.setType(Constants.OUTPUT_SUBJOB_TYPE); outSubComponent.setCategory(Constants.SUBJOB_COMPONENT_CATEGORY); outSubComponent.completeInputPortSettings(inPort); fixComponentSize(outSubComponent, inPort); setXYCoordinate(outSubComponent,getMaxXCoordinate(container)+300 , 0); outSubComponent.getProperties().put(Constants.SCHEMA_TO_PROPAGATE,schemaMap); outSubComponent.setParent(container); container.addSubJobChild(outSubComponent); } return outSubComponent; } private static void rearrangeLinkNumbers(Component component) { for(Link link:component.getSourceConnections()){ link.setLinkNumber(component.getSourceConnections().indexOf(link)); } } /** * Gets the max x coordinate. * * @param container the container * @return the max x coordinate */ public static int getMaxXCoordinate(Container container){ int maxXCoordinate=Integer.MIN_VALUE; for (Object object : container.getChildren()) { if(object instanceof Component){ Component component = (Component)object; if(component.getLocation().x > maxXCoordinate){ maxXCoordinate = component.getLocation().x ; } } } return maxXCoordinate; } /** * Fix component size. * * @param component the component * @param portCount the port count */ public static void fixComponentSize(Component component,int portCount){ Dimension newSize = component.getSize(); component.setSize(newSize.expand(0, portCount * 15)); } /** * Sets the xy coordinate. * * @param component the component * @param x the x Coordinate * @param y the y Coordinate */ public static void setXYCoordinate(Component component,int x ,int y){ Point point = new Point(); point.x = x; point.y = y; component.setLocation(point); } }