// ============================================================================
//
// 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.dataprofiler.core.ui.editor.analysis;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.Section;
import org.talend.core.model.metadata.builder.connection.Connection;
import org.talend.core.model.properties.ConnectionItem;
import org.talend.core.model.repository.IRepositoryViewObject;
import org.talend.core.repository.model.repositoryObject.MetadataColumnRepositoryObject;
import org.talend.cwm.dependencies.DependenciesHandler;
import org.talend.cwm.helper.ColumnHelper;
import org.talend.cwm.helper.ColumnSetHelper;
import org.talend.cwm.helper.ResourceHelper;
import org.talend.cwm.relational.TdColumn;
import org.talend.dataprofiler.core.PluginConstant;
import org.talend.dataprofiler.core.i18n.internal.DefaultMessagesImpl;
import org.talend.dataprofiler.core.ui.editor.composite.AnalysisColumnCompareTreeViewer;
import org.talend.dataquality.domain.Domain;
import org.talend.dataquality.exception.DataprofilerCoreException;
import org.talend.dataquality.helpers.AnalysisHelper;
import org.talend.dataquality.indicators.Indicator;
import org.talend.dataquality.indicators.columnset.ColumnDependencyIndicator;
import org.talend.dataquality.indicators.columnset.ColumnsetFactory;
import org.talend.dataquality.indicators.columnset.ColumnsetPackage;
import org.talend.dq.analysis.AnalysisBuilder;
import org.talend.dq.analysis.AnalysisHandler;
import org.talend.dq.analysis.ModelElementAnalysisHandler;
import org.talend.dq.helper.RepositoryNodeHelper;
import org.talend.dq.indicators.definitions.DefinitionHandler;
import org.talend.dq.nodes.DBColumnRepNode;
import org.talend.dq.writer.impl.ElementWriterFactory;
import org.talend.repository.model.IRepositoryNode;
import org.talend.repository.model.RepositoryNode;
import org.talend.utils.sugars.ReturnCode;
import org.talend.utils.sugars.TypedReturnCode;
import orgomg.cwm.objectmodel.core.Dependency;
import orgomg.cwm.objectmodel.core.ModelElement;
import orgomg.cwm.resource.relational.ColumnSet;
/**
* This is a Master Detail Page for <a href="http://www.talendforge.org/bugs/view.php?id=8134">Functional Dependency
* Analysis</a>.
*
* @author jet
*/
public class FunctionalDependencyAnalysisDetailsPage extends AbstractAnalysisMetadataPage implements PropertyChangeListener {
private static Logger log = Logger.getLogger(FunctionalDependencyAnalysisDetailsPage.class);
private Section columnsComparisonSection = null;
List<RepositoryNode> columnListA = null;
List<RepositoryNode> columnListB = null;
private AnalysisColumnCompareTreeViewer anaColumnCompareViewer;
ModelElementAnalysisHandler analysisHandler;
/**
* @param editor
* @param id
* @param title
*/
public FunctionalDependencyAnalysisDetailsPage(FormEditor editor, String id, String title) {
super(editor, id, title);
}
public Section getColumnsComparisonSection() {
return this.columnsComparisonSection;
}
public void setColumnsComparisonSection(Section columnsComparisonSection) {
this.columnsComparisonSection = columnsComparisonSection;
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataprofiler.core.ui.editor.AbstractMetadataFormPage#initialize(org.eclipse.ui.forms.editor.FormEditor
* )
*/
@Override
public void initialize(FormEditor editor) {
super.initialize(editor);
analysisHandler = new ModelElementAnalysisHandler();
analysisHandler.setAnalysis(getCurrentModelElement());
stringDataFilter = analysisHandler.getStringDataFilterwithContext();
}
@Override
protected void createFormContent(IManagedForm managedForm) {
setFormTitle(DefaultMessagesImpl.getString("ColumnDependencyMasterDetailsPage.ColumnDependencyAnalysis")); //$NON-NLS-1$
setMetadataSectionTitle(DefaultMessagesImpl.getString("ColumnDependencyMasterDetailsPage.analysisMeta")); //$NON-NLS-1$
setMetadataSectionDescription(DefaultMessagesImpl.getString("ColumnsComparisonMasterDetailsPage.setAnalysisProperties")); //$NON-NLS-1$
super.createFormContent(managedForm);
createDataPreviewSection(form, topComp, false, false, false);
anaColumnCompareViewer = new AnalysisColumnCompareTreeViewer(this, topComp, getColumnLeftSet(), getColumnRightSet(),
DefaultMessagesImpl.getString("FunctionalDependencyMasterDetailsPage.Title"), DefaultMessagesImpl //$NON-NLS-1$
.getString("FunctionalDependencyMasterDetailsPage.Description"), false, true); //$NON-NLS-1$
anaColumnCompareViewer.addPropertyChangeListener(this);
// the sampletable only observer the viewer
anaColumnCompareViewer.addObserver(sampleTable);
createDataFilterSection(form, topComp);
dataFilterComp.addPropertyChangeListener(this);
dataFilterComp.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
AnalysisHelper.setStringDataFilter(getCurrentModelElement(), dataFilterComp.getDataFilterString());
}
});
createAnalysisParamSection(form, topComp);
createContextGroupSection(form, topComp);
columnListA = anaColumnCompareViewer.getColumnListA();
columnListB = anaColumnCompareViewer.getColumnListB();
columnsComparisonSection = anaColumnCompareViewer.getColumnsComparisonSection();
anaColumnCompareViewer.addPropertyChangeListener(this);
form.reflow(true);
}
@Override
public ScrolledForm getScrolledForm() {
return form;
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#canRun()
*/
@Override
protected ReturnCode canRun() {
return columnListA.size() > 0 ? new ReturnCode(true) : new ReturnCode(
DefaultMessagesImpl.getString("ColumnDependencyMasterDetailsPage.columnsBlankRunMessage"), false); //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#canSave()
*/
@Override
public ReturnCode canSave() {
// do some validator.
return validator(columnListA, columnListB);
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#refresh()
*/
@Override
public void refreshGraphicsInSettingsPage() {
// do nothing
}
@Override
public AnalysisHandler getAnalysisHandler() {
return analysisHandler;
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#saveAnalysis()
*/
@Override
protected void saveAnalysis() throws DataprofilerCoreException {
analysisHandler.changeDefaultRowLoaded(rowLoadedText.getText());
analysisHandler.changeSampleDataShowWay(sampleDataShowWayCombo.getText());
for (Domain domain : getCurrentModelElement().getParameters().getDataFilter()) {
domain.setName(getCurrentModelElement().getName());
}
IRepositoryViewObject reposObject = null;
getAnalysisHandler().clearAnalysis();
List<RepositoryNode> columnListAANode = anaColumnCompareViewer.getColumnListA();
List<RepositoryNode> columnListBBNode = anaColumnCompareViewer.getColumnListB();
AnalysisBuilder anaBuilder = new AnalysisBuilder();
anaBuilder.setAnalysis(getCurrentModelElement());
Connection tdDataProvider = null;
for (int i = 0; i < columnListAANode.size(); i++) {
if (columnListBBNode.size() > i) {
ColumnDependencyIndicator indicator = ColumnsetFactory.eINSTANCE.createColumnDependencyIndicator();
TdColumn columnA = (TdColumn) ((MetadataColumnRepositoryObject) columnListAANode.get(i).getObject())
.getTdColumn();
TdColumn columnB = (TdColumn) ((MetadataColumnRepositoryObject) columnListBBNode.get(i).getObject())
.getTdColumn();
indicator.setColumnA(columnA);
indicator.setColumnB(columnB);
indicator.setIndicatorDefinition(DefinitionHandler.getInstance().getFDRuleDefaultIndicatorDefinition());
getCurrentModelElement().getResults().getIndicators().add(indicator);
anaBuilder.addElementToAnalyze(columnA, indicator);
// ADD this line qiongli 2010-6-8
anaBuilder.addElementToAnalyze(columnB, indicator);
}
}
if (columnListAANode.size() > 0) {
reposObject = columnListAANode.get(0).getObject();
tdDataProvider = ((ConnectionItem) reposObject.getProperty().getItem()).getConnection();
// MOD qiongli bug 14437:Add dependency
getCurrentModelElement().getContext().setConnection(tdDataProvider);
TypedReturnCode<Dependency> rc = DependenciesHandler.getInstance().setDependencyOn(getCurrentModelElement(),
tdDataProvider);
if (!rc.isOk()) {
log.info("fail to save dependency analysis:" + getCurrentModelElement().getFileName());//$NON-NLS-1$
}
} else {
getCurrentModelElement().getContext().setConnection(null);
}
// save the number of connections per analysis
this.saveNumberOfConnectionsPerAnalysis();
// 2011.1.12 MOD by zhsne to unify anlysis and connection id when saving.
this.nameText.setText(getCurrentModelElement().getName());
// MOD yyi 2012-02-08 TDQ-4621:Explicitly set true for updating dependencies.
ReturnCode saved = ElementWriterFactory.getInstance().createAnalysisWrite()
.save(getCurrentRepNode().getObject().getProperty().getItem(), true);
// MOD yyi 2012-02-03 TDQ-3602:Avoid to rewriting all analyzes after saving, no reason to update all analyzes
// which is depended in the referred connection.
// Extract saving log function.
// @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#logSaved(ReturnCode)
logSaved(saved);
anaColumnCompareViewer.setDirty(false);
dataFilterComp.setDirty(false);
}
/*
* (non-Javadoc)
*
* @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent evt) {
if (PluginConstant.ISDIRTY_PROPERTY.equals(evt.getPropertyName())) {
((AnalysisEditor) currentEditor).firePropertyChange(IEditorPart.PROP_DIRTY);
((AnalysisEditor) currentEditor).setRefreshResultPage(true);
} else if (PluginConstant.DATAFILTER_PROPERTY.equals(evt.getPropertyName())) {
this.setDirty(true);
}
}
private List<RepositoryNode> getColumnLeftSet() {
return getColumnSet(ColumnsetPackage.Literals.COLUMN_DEPENDENCY_INDICATOR__COLUMN_A);
}
private List<RepositoryNode> getColumnRightSet() {
return getColumnSet(ColumnsetPackage.Literals.COLUMN_DEPENDENCY_INDICATOR__COLUMN_B);
}
private List<RepositoryNode> getColumnSet(EReference reference) {
List<RepositoryNode> columns = new ArrayList<RepositoryNode>();
EList<Indicator> indicators = getCurrentModelElement().getResults().getIndicators();
for (Indicator indicator : indicators) {
TdColumn findColumn = (TdColumn) indicator.eGet(reference);
RepositoryNode recursiveFind = RepositoryNodeHelper.recursiveFind(findColumn);
if (recursiveFind == null) {
recursiveFind = RepositoryNodeHelper.createRepositoryNode(findColumn);
}
if (recursiveFind != null) {
columns.add(recursiveFind);
}
}
return columns;
}
private ReturnCode validator(List<RepositoryNode> columnASet, List<RepositoryNode> columnBSet) {
// MOD by gdbu 2011-3-21 bug 19179
ReturnCode canModRetCode = super.canSave();
if (!canModRetCode.isOk()) {
return canModRetCode;
}
// ~19179
if (columnASet.isEmpty() || columnBSet.isEmpty()) {
return new ReturnCode(DefaultMessagesImpl.getString("ColumnDependencyMasterDetailsPage.columnsBlankMessag"), false); //$NON-NLS-1$
}
if (columnASet.size() != columnBSet.size()) {
// two set must have equal number.
return new ReturnCode(DefaultMessagesImpl.getString("ColumnsComparisonMasterDetailsPage.columnsSameMessage"), false); //$NON-NLS-1$
}
for (int i = 0; i < columnASet.size(); i++) {
RepositoryNode columnANode = columnASet.get(i);
RepositoryNode columnBNode = columnBSet.get(i);
TdColumn tdColumnA = ((DBColumnRepNode) columnANode).getTdColumn();
TdColumn tdColumnB = ((DBColumnRepNode) columnBNode).getTdColumn();
ColumnSet ownerA = ColumnHelper.getColumnOwnerAsColumnSet(tdColumnA);
ColumnSet ownerB = ColumnHelper.getColumnOwnerAsColumnSet(tdColumnB);
String uuidA = ResourceHelper.getUUID(ownerA);
String uuidB = ResourceHelper.getUUID(ownerB);
if (!uuidA.equals(uuidB)) {
// must come from one table
return new ReturnCode(DefaultMessagesImpl.getString("ColumnDependencyMasterDetailsPage.tableMessage"), false); //$NON-NLS-1$
}
}
return new ReturnCode(true);
}
/**
*
* DOC zshen DOC mzhao Open column selection dialog for left column set. this method is intended to use from cheat
* sheets.
*/
public void openColumnsSetASelectionDialog() {
anaColumnCompareViewer.openColumnsSetASelectionDialog();
}
/**
*
* DOC zshen DOC mzhao Open column selection dialog for right column set. this method is intended to use from cheat
* sheets.
*/
public void openColumnsSetBSelectionDialog() {
anaColumnCompareViewer.openColumnsSetBSelectionDialog();
}
/**
* ADD xqliu 2012-04-19 TDQ-5005.
*/
@Override
public boolean isDirty() {
if (anaColumnCompareViewer == null ? false : anaColumnCompareViewer.isDirty()) {
this.setDirty(anaColumnCompareViewer.isDirty());
}
if (dataFilterComp == null ? false : dataFilterComp.isDirty()) {
this.setDirty(dataFilterComp.isDirty());
}
return super.isDirty();
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#updateTreeView()
*/
@Override
protected void updateAnalysisTree() {
if (anaColumnCompareViewer != null) {
boolean beforeUpdateDirty = anaColumnCompareViewer.isDirty();
anaColumnCompareViewer.updateModelViewer();
if (!beforeUpdateDirty) {
anaColumnCompareViewer.setDirty(false);
}
}
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#getConnectionsWithoutDeleted()
*/
@Override
protected List<IRepositoryNode> getConnectionsWithoutDeleted() {
return RepositoryNodeHelper.getConnectionRepositoryNodes(false, false);
}
/*
* (non-Javadoc)
*
* @see org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#getSelectedColumns()
*/
@Override
protected ModelElement[] getSelectedColumns() {
ColumnSet previewDataColumnOwner = anaColumnCompareViewer.getPreviewDataColumnOwner();
if (previewDataColumnOwner == null) {
return null;
}
List<TdColumn> columns = ColumnSetHelper.getColumns(previewDataColumnOwner);
return columns.toArray(new TdColumn[columns.size()]);
}
@Override
protected boolean isDataTableCompVisible() {
if (anaColumnCompareViewer == null) {
EList<ModelElement> analyzedColumns = analysisHandler.getAnalyzedColumns();
return analyzedColumns != null && !analyzedColumns.isEmpty();
} else {
return anaColumnCompareViewer.getPreviewDataColumnOwner() != null;
}
}
/*
* (non-Javadoc)
*
* @see
* org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisMetadataPage#createRunSampleDataButton(org.eclipse.swt.
* widgets.Composite)
*/
@Override
protected void createRunSampleDataButton(Composite buttonComposite) {
// here no need to implement anything override this method just to hide the checkbox.
// anytime we want to reuse the checkbox just remove this override method
}
}