/******************************************************************************* * 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.propertywindow.widgets.utility; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import hydrograph.ui.common.util.Constants; import hydrograph.ui.common.validator.Validator; import hydrograph.ui.datastructure.property.ComponentsOutputSchema; import hydrograph.ui.datastructure.property.GridRow; import hydrograph.ui.datastructure.property.Schema; import hydrograph.ui.graph.model.Component; import hydrograph.ui.graph.model.Container; import hydrograph.ui.graph.model.Link; import hydrograph.ui.graph.model.components.InputSubjobComponent; import hydrograph.ui.graph.model.components.OutputSubjobComponent; import hydrograph.ui.graph.model.components.SubjobComponent; import hydrograph.ui.graph.schema.propagation.SchemaPropagation; import hydrograph.ui.propertywindow.schema.propagation.helper.SchemaPropagationHelper; public class SubjobUtility { public static final SubjobUtility INSTANCE= new SubjobUtility(); /** * This method set continuousSchema propagation flag to true until it encounters transform or union All component. * @param component through which continuous propagation starts. */ public void setFlagForContinuousSchemaPropogation(Component component) { for(Link link:component.getSourceConnections()) { Component nextComponent=link.getTarget(); if (nextComponent != null) { Schema schema=(Schema)nextComponent.getProperties().get(Constants.SCHEMA_PROPERTY_NAME); while(StringUtils.equalsIgnoreCase(nextComponent.getCategory(), Constants.STRAIGHTPULL) ||StringUtils.equalsIgnoreCase(nextComponent.getComponentName(),Constants.FILTER) ||StringUtils.equalsIgnoreCase(nextComponent.getComponentName(),Constants.UNIQUE_SEQUENCE) ||StringUtils.equalsIgnoreCase(nextComponent.getComponentName(),Constants.PARTITION_BY_EXPRESSION) ||nextComponent instanceof SubjobComponent ||nextComponent instanceof OutputSubjobComponent ) { if(StringUtils.equalsIgnoreCase(Constants.UNION_ALL,nextComponent.getComponentName())) { if(!isUnionAllInputSchemaInSync(nextComponent)) { nextComponent.getProperties().put(Constants.IS_UNION_ALL_COMPONENT_SYNC,Constants.FALSE); ((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure().repaint(); break; } else { nextComponent.getProperties().put(Constants.IS_UNION_ALL_COMPONENT_SYNC,Constants.TRUE); ((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure().repaint(); } } if(schema==null) schema=new Schema(); ComponentsOutputSchema outputSchema=SchemaPropagation.INSTANCE.getComponentsOutputSchema(link); if(schema.getGridRow()==null) { List<GridRow> gridRows=new ArrayList<>(); schema.setGridRow(gridRows); } schema.getGridRow().clear(); if(outputSchema!=null) schema.getGridRow().addAll(outputSchema.getBasicGridRowsOutputFields()); if(!StringUtils.equalsIgnoreCase(Constants.SUBJOB_COMPONENT_CATEGORY, nextComponent.getCategory())) { nextComponent.getProperties().put(Constants.SCHEMA_PROPERTY_NAME,schema); nextComponent.validateComponentProperties(false); Validator validator=(Validator)((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure(); validator.setPropertyStatus((String)nextComponent.getProperties().get(Constants.VALIDITY_STATUS)); ((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure().repaint(); } nextComponent.setContinuousSchemaPropogationAllow(true); if(nextComponent instanceof SubjobComponent) { Container container=(Container)nextComponent.getProperties().get(Constants.SUBJOB_CONTAINER); for(Component subjobComponent:container.getUIComponentList()) { if(subjobComponent instanceof InputSubjobComponent) { initializeSchemaMapForInputSubJobComponent(subjobComponent,nextComponent); setFlagForContinuousSchemaPropogation(subjobComponent); break; } } showOrHideErrorSymbolOnComponent(container,nextComponent); Validator validator=(Validator)((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure(); validator.setPropertyStatus((String)nextComponent.getProperties().get(Constants.VALIDITY_STATUS)); ((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure().repaint(); } else if(nextComponent instanceof OutputSubjobComponent) { Component subJobComponent=(Component)nextComponent.getProperties().get(Constants.SUBJOB_COMPONENT); if(subJobComponent!=null) SubjobUtility.INSTANCE.initializeSchemaMapForInputSubJobComponent(subJobComponent, nextComponent); setFlagForContinuousSchemaPropogation(subJobComponent); } if(!nextComponent.getSourceConnections().isEmpty()) { if(nextComponent.getSourceConnections().size()==1) { if(nextComponent instanceof SubjobComponent) { if(!checkIfSubJobHasTransformOrUnionAllComponent(nextComponent)) { nextComponent=nextComponent.getSourceConnections().get(0).getTarget(); } else { ((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure().repaint(); break; } } else { nextComponent=nextComponent.getSourceConnections().get(0).getTarget(); } } else { setFlagForContinuousSchemaPropogation(nextComponent); break; } } else break; } } if(StringUtils.equalsIgnoreCase(nextComponent.getCategory(),Constants.TRANSFORM)) { nextComponent.setContinuousSchemaPropogationAllow(true); ((AbstractGraphicalEditPart)nextComponent.getComponentEditPart()).getFigure().repaint(); } nextComponent.getProperties().put(Constants.PREVIOUS_COMPONENT_OLD_SCHEMA, component.getProperties().get(Constants.PREVIOUS_COMPONENT_OLD_SCHEMA)); } } /** * check whether union compoent's input schema are in sync or not * @param union All component * @return true if input schema are in sync otherwise false */ public boolean isUnionAllInputSchemaInSync(Component component) { Schema previousSchema=null; if(component.getTargetConnections()!=null && component.getTargetConnections().size()>=2){ for(Link link:component.getTargetConnections()){ Schema currentComponentSchema=getSchemaFromPreviousComponentSchema(component,link); if(previousSchema!=null && !isSameSchema(previousSchema,currentComponentSchema)){ return false; } previousSchema=currentComponentSchema; } } return true; } private boolean isSameSchema(Schema previousSchema, Schema currentComponentSchema) { if( (previousSchema!=null && currentComponentSchema!=null) && (previousSchema.getIsExternal() == currentComponentSchema.getIsExternal()) && (StringUtils.equals(previousSchema.getExternalSchemaPath(), currentComponentSchema.getExternalSchemaPath())) && (previousSchema.getGridRow()!=null && currentComponentSchema.getGridRow()!=null) && (previousSchema.getGridRow().size()==currentComponentSchema.getGridRow().size())){ for(int index=0;index<previousSchema.getGridRow().size();index++){ if(!SchemaPropagationHelper.INSTANCE.isGridRowEqual(previousSchema.getGridRow().get(index), currentComponentSchema.getGridRow().get(index))){ return false; } } return true; } return false; } /** * check if sub job contains transform or union All component * * @param Subjob component * @return true if Sub job contains transform or union all component otherwise false */ public boolean checkIfSubJobHasTransformOrUnionAllComponent(Component component) { boolean containsTransformOrUnionAllComponent=false; Container container=(Container)component.getProperties().get(Constants.SUBJOB_CONTAINER); if(container!=null) { for(Object object:container.getChildren()) { if(object instanceof Component) { Component component1=(Component)object; if((StringUtils.equalsIgnoreCase(component1.getCategory(), Constants.TRANSFORM) &&!StringUtils.equalsIgnoreCase(component1.getComponentName(), Constants.FILTER) &&!StringUtils.equalsIgnoreCase(component1.getComponentName(), Constants.UNIQUE_SEQUENCE) &&!StringUtils.equalsIgnoreCase(component1.getComponentName(),Constants.PARTITION_BY_EXPRESSION)) && component1.isContinuousSchemaPropogationAllow() ) { containsTransformOrUnionAllComponent=true; break; } else if((StringUtils.equalsIgnoreCase( Constants.UNION_ALL, component1.getComponentName()))) { if(!isUnionAllInputSchemaInSync(component1)) { containsTransformOrUnionAllComponent=true; break; } } else if(component1 instanceof SubjobComponent) { containsTransformOrUnionAllComponent=checkIfSubJobHasTransformOrUnionAllComponent(component1); if(containsTransformOrUnionAllComponent) break; } } } } return containsTransformOrUnionAllComponent; } /** * * initialize SchemaMap for inputSubjobComponent. * @param inputSubJobComponent * @param subjobComponent */ public void initializeSchemaMapForInputSubJobComponent(Component inputSubJobComponent,Component subjobComponent) { Map<String,Schema> inputSubJobComponentHashMap=new HashMap<>(); for(int i=0;i<subjobComponent.getTargetConnections().size();i++) { Component previousComponentToSubJobComponenet=subjobComponent.getTargetConnections().get(i).getSource(); if(previousComponentToSubJobComponenet instanceof SubjobComponent) { inputSubJobComponentHashMap =(Map<String,Schema>)previousComponentToSubJobComponenet.getProperties() .get(Constants.SCHEMA_FOR_INPUTSUBJOBCOMPONENT); } else { inputSubJobComponentHashMap.put(Constants.INPUT_SOCKET_TYPE+i,((Schema)previousComponentToSubJobComponenet .getProperties().get(Constants.SCHEMA))); } } inputSubJobComponent.getProperties().put(Constants.SCHEMA_FOR_INPUTSUBJOBCOMPONENT, inputSubJobComponentHashMap); } /** * This method shows or hides error icon on component * @param subJobContainer * @param uiComponent */ public void showOrHideErrorSymbolOnComponent(Container subJobContainer, Component uiComponent) { if (subJobContainer == null) { uiComponent.setValidityStatus(Constants.ERROR); } else { for (int i = 0; i < subJobContainer.getUIComponentList().size(); i++) { if(subJobContainer.getUIComponentList().get(i) instanceof Component){ Component component = (Component)subJobContainer.getUIComponentList().get(i); if (!(component instanceof InputSubjobComponent || component instanceof OutputSubjobComponent)) { if (StringUtils.equalsIgnoreCase(Constants.ERROR, component.getProperties().get(Constants.VALIDITY_STATUS).toString()) || StringUtils.equalsIgnoreCase( Constants.WARN, component.getProperties() .get(Constants.VALIDITY_STATUS).toString())) { uiComponent.getProperties().put(Constants.VALIDITY_STATUS, Constants.ERROR); uiComponent.setValidityStatus(Constants.ERROR); break; } else { uiComponent.getProperties().put(Constants.VALIDITY_STATUS, Constants.VALID); uiComponent.setValidityStatus(Constants.VALID); } } } } } } /** * * gets the schema of previous component * @param present component * @param link * @return */ public Schema getSchemaFromPreviousComponentSchema(Component component,Link link) { Schema previousComponentSchema=null; if(StringUtils.equalsIgnoreCase(Constants.INPUT_SUBJOB_COMPONENT_NAME, link.getSource().getComponentName()) ||StringUtils.equalsIgnoreCase(Constants.SUBJOB_COMPONENT, link.getSource().getComponentName()) ) { Map<String,Schema> inputSchemaMap=(HashMap<String,Schema>)link.getSource().getProperties(). get(Constants.SCHEMA_FOR_INPUTSUBJOBCOMPONENT); if(inputSchemaMap!=null) previousComponentSchema=inputSchemaMap.get(Constants.INPUT_SOCKET_TYPE+getPortIndex(link)); } else { previousComponentSchema=SchemaPropagation.INSTANCE.getSchema(link); } return previousComponentSchema; } private String getPortIndex(Link link) { if(StringUtils.startsWithIgnoreCase(link.getSourceTerminal(), Constants.INPUT_SOCKET_TYPE)){ return StringUtils.remove(link.getSourceTerminal(), Constants.INPUT_SOCKET_TYPE); }else { return StringUtils.remove(link.getSourceTerminal(), Constants.OUTPUT_SOCKET_TYPE); } } }