// ============================================================================
//
// Copyright (C) 2006-2016 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.dataquality.record.linkage.ui.section;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.talend.dataquality.analysis.Analysis;
import org.talend.dataquality.record.linkage.grouping.swoosh.SurvivorshipUtils;
import org.talend.dataquality.record.linkage.ui.composite.AbsMatchAnalysisTableComposite;
import org.talend.dataquality.record.linkage.ui.composite.MatchKeyAndSurvivorTableComposite;
import org.talend.dataquality.record.linkage.ui.composite.tableviewer.definition.MatchKeyAndSurvivorDefinition;
import org.talend.dataquality.record.linkage.ui.composite.tableviewer.sorter.KeyDefinitionTableViewerSorter;
import org.talend.dataquality.record.linkage.ui.i18n.internal.DefaultMessagesImpl;
import org.talend.dataquality.record.linkage.utils.MatchAnalysisConstant;
import org.talend.dataquality.record.linkage.utils.SurvivorShipAlgorithmEnum;
import org.talend.dataquality.rules.AlgorithmDefinition;
import org.talend.dataquality.rules.MatchKeyDefinition;
import org.talend.dataquality.rules.MatchRule;
import org.talend.dataquality.rules.MatchRuleDefinition;
import org.talend.dataquality.rules.RulesFactory;
import org.talend.dataquality.rules.SurvivorshipKeyDefinition;
/**
*
* Match survivorship key table section specific to match analysis editor.
*
*/
public class AnaMatchSurvivorSection extends MatchingKeySection {
protected MatchRuleDefinition matchRuleDef = null;
protected Map<MatchRule, List<MatchKeyAndSurvivorDefinition>> matchRuleWithSurvMap = new HashMap<MatchRule, List<MatchKeyAndSurvivorDefinition>>();
/**
* DOC zhao AnaMatchSurvivorSection constructor comment.
*
* @param form
* @param parent
* @param style
* @param toolkit
* @param analysis
*/
public AnaMatchSurvivorSection(ScrolledForm form, Composite parent, int style, FormToolkit toolkit, Analysis analysis) {
super(form, parent, style, toolkit, analysis);
}
/*
* (non-Javadoc)
*
* @see org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#getSectionName()
*/
@Override
protected String getSectionName() {
return MatchAnalysisConstant.MATCHING_KEY_AND_SURVIVOR_DEFINITION_SECTION_NAME;
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#createTableComposite(org.eclipse.swt.widgets
* .Composite, org.talend.dataquality.rules.MatchRule)
*/
@Override
protected AbsMatchAnalysisTableComposite<?> createTableComposite(Composite ruleComp, MatchRule matchRule) {
MatchKeyAndSurvivorTableComposite tableComp = new MatchKeyAndSurvivorTableComposite(ruleComp, SWT.NO_FOCUS, matchRule);
// In case of the section in analysis editor, need to show the input column in matching key table.
tableComp.setShowInputColumn(true);
return tableComp;
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#setInput(org.talend.dataquality.rules.MatchRule
* , org.talend.dataquality.record.linkage.ui.composite.AbsMatchAnalysisTableComposite)
*/
@Override
protected void setInput(MatchRule matchRule, AbsMatchAnalysisTableComposite<?> matchRuleComposite) {
List<MatchKeyAndSurvivorDefinition> generatedSurvivorKeyList = generateSurvivorKeyByMatchKey(matchRule, Boolean.FALSE);
((MatchKeyAndSurvivorTableComposite) matchRuleComposite).setInput(generatedSurvivorKeyList);
}
protected List<MatchKeyAndSurvivorDefinition> generateSurvivorKeyByMatchKey(MatchRule matchRule, boolean isMustCreateSurvivor) {
List<MatchKeyAndSurvivorDefinition> matchAndSurvivorKeyList = matchRuleWithSurvMap.get(matchRule);
if (matchAndSurvivorKeyList == null) {
matchAndSurvivorKeyList = new ArrayList<MatchKeyAndSurvivorDefinition>();
matchRuleWithSurvMap.put(matchRule, matchAndSurvivorKeyList);
}
EList<MatchKeyDefinition> matchKeys = matchRule.getMatchKeys();
int index = 0;
for (MatchKeyDefinition matchKey : matchKeys) {
// first, find the current matchKey in MatchAndSurvivorKeyList
if (matchAndSurvivorKeyList.size() > index) {
MatchKeyAndSurvivorDefinition definition = matchAndSurvivorKeyList.get(index);
// check if the position of the match key moved or not
if (StringUtils.equals(matchKey.getName(), definition.getMatchKey().getName())) {
// update the current match key
definition.setMatchKey(matchKey);
updateSurvivorKey(isMustCreateSurvivor, matchKey.getName(), definition);
} else {
// the position of the current match key moved, need to find its related mAndS key in list,
MatchKeyAndSurvivorDefinition oldDefinition = findPositionOfCurrentMatchkey(matchKey, matchAndSurvivorKeyList);
// if can't find, means that it is a new one
if (oldDefinition == null) {
createMatchAndSurvivorKey(matchKey, isMustCreateSurvivor, matchAndSurvivorKeyList);
} else {
// delete the old definition in current list
matchAndSurvivorKeyList.remove(oldDefinition);
// set new match key to it
oldDefinition.setMatchKey(matchKey);
updateSurvivorKey(isMustCreateSurvivor, matchKey.getName(), oldDefinition);
// insert it in the new position
matchAndSurvivorKeyList.add(index, oldDefinition);
}
}
} else {
// need to create a MatchAndSurvivorKey
createMatchAndSurvivorKey(matchKey, isMustCreateSurvivor, matchAndSurvivorKeyList);
}
index++;
}
return matchAndSurvivorKeyList;
}
@Override
public void createMatchKeyFromCurrentMatchRule(String column) {
MatchKeyAndSurvivorTableComposite matchRuleTableComp = (MatchKeyAndSurvivorTableComposite) getCurrentMatchRuleTableComposite();
List<MatchKeyAndSurvivorDefinition> matchAndSurvKeyList = matchRuleWithSurvMap.get(matchRuleTableComp.getMatchRule());
matchRuleTableComp.addKeyDefinition(column, matchAndSurvKeyList);
}
private void updateSurvivorKey(boolean isCreateNewOne, String name, MatchKeyAndSurvivorDefinition definition) {
EList<SurvivorshipKeyDefinition> survivorshipKeys = matchRuleDef.getSurvivorshipKeys();
// set the survivor key: if clear, use a new one , if not clear, use the one in model
boolean isSurvKeyFound = false;
if (!isCreateNewOne) {
// Use the key name to find the appropriate survivor key definition.
for (SurvivorshipKeyDefinition survKey : survivorshipKeys) {
if (survKey.getName().equals(name)) {
definition.setSurvivorShipKey(survKey);
isSurvKeyFound = true;
break;
}
}
}
if (isCreateNewOne || !isSurvKeyFound) {
SurvivorshipKeyDefinition survivorshipKeyDefinition = createNewSurvivorshipKeyDefinition(name);
definition.setSurvivorShipKey(survivorshipKeyDefinition);
survivorshipKeys.add(survivorshipKeyDefinition);
}
}
private SurvivorshipKeyDefinition createNewSurvivorshipKeyDefinition(String matchKeyName) {
SurvivorshipKeyDefinition skd = RulesFactory.eINSTANCE.createSurvivorshipKeyDefinition();
skd.setName(matchKeyName);
AlgorithmDefinition createAlgorithmDefinition = RulesFactory.eINSTANCE.createAlgorithmDefinition();
createAlgorithmDefinition.setAlgorithmType(SurvivorShipAlgorithmEnum.getTypeByIndex(0).getValue());
// MOD TDQ-11774 set a default value for parameter
createAlgorithmDefinition.setAlgorithmParameters(SurvivorshipUtils.DEFAULT_CONCATENATE_PARAMETER);
skd.setFunction(createAlgorithmDefinition);
skd.setAllowManualResolution(true);
return skd;
}
/**
* DOC yyin Comment method "findPositionOfCurrentMatchkey".
*
* @param matchKey
* @return
*/
private MatchKeyAndSurvivorDefinition findPositionOfCurrentMatchkey(MatchKeyDefinition matchKey,
List<MatchKeyAndSurvivorDefinition> matchAndSurvivorKeyList) {
// find the definition by match key's name
for (MatchKeyAndSurvivorDefinition definition : matchAndSurvivorKeyList) {
if (StringUtils.equals(matchKey.getName(), definition.getMatchKey().getName())) {
return definition;
}
}
return null;
}
/**
* DOC yyin Comment method "createMatchAndSurvivorKey".
*
* @param matchKey
* @param isClearSurvivor
* @param isClearSurvivor
* @param index
*/
private void createMatchAndSurvivorKey(MatchKeyDefinition matchKey, boolean isClearSurvivor,
List<MatchKeyAndSurvivorDefinition> matchAndSurvivorKeyList) {
MatchKeyAndSurvivorDefinition mAnds = new MatchKeyAndSurvivorDefinition();
mAnds.setMatchKey(matchKey);
// create a new survivor key
updateSurvivorKey(isClearSurvivor, matchKey.getName(), mAnds);
matchAndSurvivorKeyList.add(mAnds);
}
public void removeAllSurvivorship() {
matchRuleDef.getSurvivorshipKeys().clear();
}
/*
* (non-Javadoc)
*
* @see org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#removeTableItem()
*/
@Override
public void removeTableItem() {
boolean success = false;
ISelection selectItems = getCurrentMatchRuleTableComposite().getSelectItems();
if (selectItems instanceof StructuredSelection) {
Iterator<MatchKeyAndSurvivorDefinition> iterator = ((StructuredSelection) selectItems).iterator();
while (iterator.hasNext()) {
MatchKeyAndSurvivorDefinition next = iterator.next();
removeMatchKeyFromCurrentMatchRule(next);
success = true;
}
if (success) {
listeners.firePropertyChange(MatchAnalysisConstant.ISDIRTY_PROPERTY, true, false);
listeners.firePropertyChange(MatchAnalysisConstant.MATCH_RULE_TAB_SWITCH, true, false);
}
}
}
public void removeMatchKeyFromCurrentMatchRule(MatchKeyAndSurvivorDefinition mAndSDefition) {
MatchKeyAndSurvivorTableComposite matchRuleTableComp = (MatchKeyAndSurvivorTableComposite) getCurrentMatchRuleTableComposite();
matchRuleTableComp.removeKeyDefinition(mAndSDefition, matchRuleWithSurvMap.get(matchRuleTableComp.getMatchRule()));
}
public void setMatchRuleDef(MatchRuleDefinition matchRuleDef) {
this.matchRuleDef = matchRuleDef;
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#deleteMatchRuleTab(org.eclipse.swt.custom
* .CTabItem)
*/
@Override
protected void deleteMatchRuleTab(CTabItem tabItem) {
MatchRule matchRule = getMatchRule(tabItem);
List<MatchKeyAndSurvivorDefinition> matchAndSurvDefList = matchRuleWithSurvMap.get(matchRule);
MatchRuleDefinition matchRuleDefinition = getMatchRuleDefinition();
for (MatchKeyAndSurvivorDefinition matchAndSurvDef : matchAndSurvDefList) {
matchRuleDefinition.getSurvivorshipKeys().remove(matchAndSurvDef.getSurvivorShipKey());
}
matchRuleWithSurvMap.remove(matchRule);
super.deleteMatchRuleTab(tabItem);
}
/*
* (non-Javadoc)
*
* @see org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#remoteKeyDefinition(java.lang.String,
* org.eclipse.swt.custom.CTabItem)
*/
@Override
protected void remoteKeyDefinition(String column, CTabItem oneTab) {
MatchKeyAndSurvivorTableComposite matchRuleTableComp = (MatchKeyAndSurvivorTableComposite) getMatchRuleComposite(oneTab);
List<MatchKeyAndSurvivorDefinition> matchAndSurvDefList = matchRuleWithSurvMap.get(getMatchRule(oneTab));
matchRuleTableComp.removeKeyDefinition(column, matchAndSurvDefList);
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#checkAndRemoveEmptyMatchRule(org.eclipse.
* swt.custom.CTabItem)
*/
@Override
protected void checkAndRemoveEmptyMatchRule(CTabItem theTab) {
MatchRule matchRule = getMatchRule(theTab);
List<MatchKeyAndSurvivorDefinition> matchAndSurvDefList = matchRuleWithSurvMap.get(matchRule);
if (matchAndSurvDefList.size() <= 0) {
MatchRuleDefinition matchRuleDefinition = getMatchRuleDefinition();
matchRuleDefinition.getMatchRules().remove(matchRule);
for (MatchKeyAndSurvivorDefinition matchAndSurvDef : matchAndSurvDefList) {
matchRuleDefinition.getSurvivorshipKeys().remove(matchAndSurvDef.getSurvivorShipKey());
}
}
}
/*
* (non-Javadoc)
*
* @see org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#getCurrentTabDefinitions()
*/
@Override
protected List<?> getCurrentTabDefinitions() {
MatchKeyAndSurvivorTableComposite matchRuleTableComp = (MatchKeyAndSurvivorTableComposite) getCurrentMatchRuleTableComposite();
MatchRule matchRule = matchRuleTableComp.getMatchRule();
List<MatchKeyAndSurvivorDefinition> matchAndSurvDefList = matchRuleWithSurvMap.get(matchRule);
return matchAndSurvDefList;
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#getMatchRule(org.eclipse.swt.custom.CTabItem)
*/
@Override
protected MatchRule getMatchRule(CTabItem tabItem) {
MatchKeyAndSurvivorTableComposite matchRuleTableComp = (MatchKeyAndSurvivorTableComposite) getMatchRuleComposite(tabItem);
MatchRule matchRule = matchRuleTableComp.getMatchRule();
return matchRule;
}
@Override
protected MatchRule getCurrentMatchRule() throws Exception {
CTabItem currentTabItem = ruleFolder.getSelection();
if (currentTabItem == null) {
throw new Exception(DefaultMessagesImpl.getString("MatchingKeySection.ONE_MATCH_RULE_REQUIRED")); //$NON-NLS-1$
}
return getMatchRule(currentTabItem);
}
@Override
public void removeMatchKeyFromCurrentMatchRule(String column) {
MatchKeyAndSurvivorTableComposite matchRuleTableComp = (MatchKeyAndSurvivorTableComposite) getCurrentMatchRuleTableComposite();
MatchRule matchRule = matchRuleTableComp.getMatchRule();
List<MatchKeyAndSurvivorDefinition> matchAndSurvDefList = matchRuleWithSurvMap.get(matchRule);
matchRuleTableComp.removeKeyDefinition(column, matchAndSurvDefList);
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataquality.record.linkage.ui.section.MatchingKeySection#getTableViewerSorter(org.talend.dataquality
* .rules.MatchRule)
*/
@Override
protected KeyDefinitionTableViewerSorter<?> getTableViewerSorter(MatchRule matchRule) {
List<MatchKeyAndSurvivorDefinition> matchAndSurvDefList = matchRuleWithSurvMap.get(matchRule);
return new KeyDefinitionTableViewerSorter<MatchKeyAndSurvivorDefinition>(matchAndSurvDefList);
}
}