// ============================================================================ // // 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 org.apache.commons.lang.StringUtils; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.Action; import org.eclipse.jface.dialogs.MessageDialogWithToggle; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.part.FileEditorInput; import org.talend.commons.emf.FactoriesUtil; import org.talend.commons.exception.ExceptionHandler; import org.talend.core.model.context.JobContextManager; import org.talend.core.repository.model.IRepositoryFactory; import org.talend.core.repository.model.ProxyRepositoryFactory; import org.talend.core.repository.model.RepositoryFactoryProvider; import org.talend.dataprofiler.core.i18n.internal.DefaultMessagesImpl; import org.talend.dataprofiler.core.ui.IRuningStatusListener; import org.talend.dataprofiler.core.ui.action.actions.DefaultSaveAction; import org.talend.dataprofiler.core.ui.action.actions.RunAnalysisAction; import org.talend.dataprofiler.core.ui.editor.SupportContextEditor; import org.talend.dataprofiler.core.ui.editor.TdEditorToolBar; import org.talend.dataprofiler.core.ui.events.EventEnum; import org.talend.dataprofiler.core.ui.events.EventManager; import org.talend.dataprofiler.core.ui.events.EventReceiver; import org.talend.dataprofiler.core.ui.utils.WorkbenchUtils; import org.talend.dataquality.analysis.Analysis; import org.talend.dataquality.analysis.AnalysisType; import org.talend.dataquality.analysis.ExecutionLanguage; import org.talend.dataquality.helpers.AnalysisHelper; import org.talend.dataquality.properties.TDQAnalysisItem; import org.talend.dq.helper.resourcehelper.AnaResourceFileHelper; import org.talend.dq.nodes.AnalysisRepNode; import org.talend.dq.nodes.ReportAnalysisRepNode; import org.talend.repository.model.IRepositoryNode; import org.talend.repository.model.RepositoryConstants; import org.talend.utils.sugars.ReturnCode; /** * @author rli * */ public class AnalysisEditor extends SupportContextEditor { private static Logger log = Logger.getLogger(AnalysisEditor.class); public static final String RESULT_PAGE = "SecondPage";//$NON-NLS-1$ public static final String MASTER_PAGE = "MasterPage";//$NON-NLS-1$ private static final String ANALYSIS_RESULTS = DefaultMessagesImpl.getString("AnalysisEditor.analysisResult"); //$NON-NLS-1$ private static final String ANALYSIS_SETTINGS = DefaultMessagesImpl.getString("AnalysisEditor.analysisSettings"); //$NON-NLS-1$ private static final int RESULT_PAGE_INDEX = 1; private AbstractAnalysisResultPage resultPage; private AnalysisType analysisType; private RunAnalysisAction runAction; // MOD xqliu 2009-07-02 bug 7687 private DefaultSaveAction saveAction; // ~ // Added 20130725 TDQ-7639 yyin private EventReceiver refreshReceiver = null; private EventReceiver checkBeforeRunReceiver = null; private EventReceiver refresh2ShowMatchIndicator = null; private EventReceiver reopenEditor = null; // Added TDQ-8787 2014-06-16 yyin private EventReceiver registerDynamicEvent = null; private EventReceiver unRegisterDynamicEvent = null; private boolean isRefreshResultPage = false; /** * */ public AnalysisEditor() { } @Override protected void addPages() { TdEditorToolBar toolbar = getToolBar(); if (toolbar != null) { saveAction = new DefaultSaveAction(this); runAction = new RunAnalysisAction(); toolbar.addActions(saveAction, runAction); } switch (analysisType) { case COLUMN_CORRELATION: masterPage = new CorrelationAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new CorrelationAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case MULTIPLE_COLUMN: masterPage = new ColumnAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new ColumnAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case CONNECTION: masterPage = new ConnectionAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new OverviewResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case CATALOG: masterPage = new CatalogAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new OverviewResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case SCHEMA: masterPage = new SchemaAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new OverviewResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case COLUMNS_COMPARISON: masterPage = new RedundancyAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new RedundancyAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case TABLE: masterPage = new BusinessRuleAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new BusinessRuleAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case TABLE_FUNCTIONAL_DEPENDENCY: masterPage = new FunctionalDependencyAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new FunctionalDependencyAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case COLUMN_SET: masterPage = new ColumnSetAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new ColumnSetAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; case MATCH_ANALYSIS:// Added 20130724 TDQ-7504 masterPage = new MatchAnalysisDetailsPage(this, MASTER_PAGE, ANALYSIS_SETTINGS); resultPage = new MatchAnalysisResultPage(this, RESULT_PAGE, ANALYSIS_RESULTS); break; default: } try { if (masterPage != null) { addPage(masterPage); setPartName(masterPage.getIntactElemenetName()); initContext(); // Added 20130930 TDQ-8117, yyin // init the run analysis action, to give it the analysis item and listener this.runAction.setAnalysisItems(new TDQAnalysisItem[] { (TDQAnalysisItem) getMasterPage().getCurrentRepNode() .getObject().getProperty().getItem() }); } if (resultPage != null) { addPage(resultPage); } } catch (PartInitException e) { ExceptionHandler.process(e, Level.ERROR); } // Added 20130725 TDQ-7639 yyin : register the run analysis event, which need to refresh the pages registerUpdateExecutionEvent(); } /** * init the context for the analysis. */ private void initContext() { Analysis analysis = getMasterPage().getCurrentModelElement(); contextManager = new JobContextManager(analysis.getContextType(), analysis.getDefaultContext()); this.setLastRunContextGroupName(AnalysisHelper.getContextGroupName(analysis)); } @Override public void doSave(IProgressMonitor monitor) { if (masterPage != null && masterPage.isDirty()) { masterPage.doSave(monitor); setPartName(masterPage.getIntactElemenetName()); // TDQ-11312 if (this.getEditorInput() instanceof FileEditorInput) { this.setInput(masterPage.getEditorInput()); } // reset the modified status of ContextManager according to the masterPage if (contextManager instanceof JobContextManager) { JobContextManager jobContextManager = (JobContextManager) contextManager; jobContextManager.setModified(masterPage.isDirty()); } } setEditorObject(getMasterPage().getCurrentRepNode()); super.doSave(monitor); masterPage.setOldDataproviderName(masterPage.getCurrentModelElement().getName()); } @Override protected void firePropertyChange(final int propertyId) { if (masterPage.isActive()) { setRunActionButtonState(true); } // MOD klliu 2011-04-08 if masterPage is dirty,then button of SaveAction can been used. setSaveActionButtonState(masterPage.isDirty()); super.firePropertyChange(propertyId); } @Override protected void translateInput(IEditorInput input) { // MOD klliu 2010-12-10 Analysis findAnalysis = null; String label = "";//$NON-NLS-1$ if (input instanceof AnalysisItemEditorInput) { AnalysisItemEditorInput fileEditorInput = (AnalysisItemEditorInput) input; findAnalysis = (Analysis) fileEditorInput.getModel(); label = fileEditorInput.getName(); } else if (input instanceof FileEditorInput) { FileEditorInput fileEditorInput = (FileEditorInput) input; IFile file = fileEditorInput.getFile(); label = file.getFullPath().toString(); if (FactoriesUtil.isAnalysisFile(file.getFileExtension())) { findAnalysis = AnaResourceFileHelper.getInstance().findAnalysis(file); } } if (findAnalysis != null) { analysisType = findAnalysis.getParameters().getAnalysisType(); } else { log.error("Could not find an analysis in file: " + label);//$NON-NLS-1$ } } @Override protected void pageChange(int newPageIndex) { // TDQ-11422 msjian: we should do save first when turn to result page if (newPageIndex == RESULT_PAGE_INDEX) { if (masterPage.isDirty()) { masterPage.doSave(null); } setSaveActionButtonState(false); } // TDQ-11422~ changeListener(); super.pageChange(newPageIndex); if (isRefreshResultPage) { resultPage.refresh(getMasterPage()); isRefreshResultPage = false; } else { // Added TDQ-9241 if (resultPage != null) { EventManager.getInstance().publish(resultPage.getAnalysisHandler().getAnalysis(), EventEnum.DQ_DYNAMIC_SWITCH_MASTER_RESULT_PAGE, null); } } } /** * Getter for masterPage. * * @return the masterPage */ @Override public AbstractAnalysisMetadataPage getMasterPage() { return (AbstractAnalysisMetadataPage) masterPage; } /** * Getter for resultPage. * * @return the resultPage */ public AbstractAnalysisResultPage getResultPage() { return resultPage; } public void performGlobalAction(String id) { if (id.equals(RunAnalysisAction.ID)) { // TDQ-10748: make the ref project analysis can not run when press F6 IRepositoryNode currentRepNode = this.getMasterPage().getCurrentRepNode(); boolean isMainProject = false; if (currentRepNode instanceof ReportAnalysisRepNode) { isMainProject = ((ReportAnalysisRepNode) currentRepNode).getProject().isMainProject(); } else if (currentRepNode instanceof AnalysisRepNode) { isMainProject = ((AnalysisRepNode) currentRepNode).getProject().isMainProject(); } if (isMainProject) { runAction.run(); } // TDQ-10748~ return; } if (analysisType == AnalysisType.MULTIPLE_COLUMN) { ((ColumnAnalysisDetailsPage) masterPage).performGlobalAction(id); } if (analysisType == AnalysisType.TABLE) { ((BusinessRuleAnalysisDetailsPage) masterPage).performGlobalAction(id); } } public void setRefreshResultPage(boolean isRefreshRP) { this.isRefreshResultPage = isRefreshRP; } public AnalysisType getAnalysisType() { return analysisType; } /** * DOC bZhou Comment method "setRunActionButtonState". * * @param state */ public void setRunActionButtonState(boolean state) { if (runAction != null) { runAction.setEnabled(state); } } /** * DOC bZhou Comment method "setSaveActionButtonState". * * @param state */ public void setSaveActionButtonState(boolean state) { if (saveAction != null) { saveAction.setEnabled(state); } } /** * * DOC mzhao Comment method "getRunAnalysisAction". * * @return */ public Action getRunAnalysisAction() { return runAction; } /** * DOC yyi Comment method "canRun". * * @return */ public ReturnCode canRun() { return getMasterPage().canRun(); } @Override public void setFocus() { super.setFocus(); // don't invoke this method here, invoke it in IPartListener.partBroughtToTop() // WorkbenchUtils.autoChange2DataProfilerPerspective(); } public ExecutionLanguage getUIExecuteEngin() { return this.getMasterPage().getUIExecuteEngin(); } IFormPage activePageInstance; private void changeListener() { activePageInstance = getActivePageInstance(); if (activePageInstance instanceof IRuningStatusListener) { runAction.setListener((IRuningStatusListener) activePageInstance); } } /** * currently will not open the editor of the analysis when running from menu, so, if the editor is opened and not * the current active one, the page will not know that the result is changed. so we need to add the event/listener * to them to handle this. Added 20130725 TDQ-7639 * * @param analysis */ private void registerUpdateExecutionEvent() { // register: check if the analysis need to be saved or if it can run before running it(from menu's RUN) checkBeforeRunReceiver = new EventReceiver() { @Override public boolean handle(Object data) { if (isDirty()) { ReturnCode canSave = masterPage.canSave(); if (canSave.isOk()) { // save the analysis before running // MOD msjian TDQ-8225 : This save action won't invoke any remote repository action such as svn // commit. TDQ-7508 IRepositoryFactory localRepository = RepositoryFactoryProvider .getRepositoriyById(RepositoryConstants.REPOSITORY_LOCAL_ID); IRepositoryFactory oldRepository = ProxyRepositoryFactory.getInstance() .getRepositoryFactoryFromProvider(); ProxyRepositoryFactory.getInstance().setRepositoryFactoryFromProvider(localRepository); try { doSave(null); } catch (Exception e) { log.error(e, e); } finally { ProxyRepositoryFactory.getInstance().setRepositoryFactoryFromProvider(oldRepository); } // TDQ-8225~ setDirty(false); } else { if (canSave.getMessage() != null && !canSave.getMessage().equals(StringUtils.EMPTY)) { MessageDialogWithToggle .openError( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), DefaultMessagesImpl.getString("AbstractAnalysisMetadataPage.SaveAnalysis"), canSave.getMessage()); //$NON-NLS-1$ } return false; } } ReturnCode canRun = canRun(); if (!canRun.isOk()) { MessageDialogWithToggle.openError(null, DefaultMessagesImpl.getString("RunAnalysisAction.runAnalysis"), canRun//$NON-NLS-1$ .getMessage()); return false; } // TDQ-8220 change the listener every time( master page or result page) changeListener(); return true; } }; EventManager.getInstance().register(getMasterPage().getCurrentModelElement(), EventEnum.DQ_ANALYSIS_CHECK_BEFORERUN, checkBeforeRunReceiver); // register: refresh the result page after running it from menu refreshReceiver = new EventReceiver() { @Override public boolean handle(Object data) { // MOD TDQ-7816: when the result page are not created, no need to refresh, only refresh master page is // enough;TDQ-8270 resultpage is null for overview type if (resultPage != null && resultPage.getManagedForm() != null) { resultPage.refresh(getMasterPage()); } else { getMasterPage().refreshGraphicsInSettingsPage(); } return true; } }; EventManager.getInstance().register(getMasterPage().getCurrentModelElement(), EventEnum.DQ_ANALYSIS_RUN_FROM_MENU, refreshReceiver); // register: reopen this editor after reload its depended connection reopenEditor = new EventReceiver() { @Override public boolean handle(Object data) { Display.getDefault().asyncExec(new Runnable() { public void run() { WorkbenchUtils.refreshCurrentAnalysisEditor(getMasterPage().getCurrentModelElement().getName()); } }); return true; } }; EventManager.getInstance().register(getMasterPage().getCurrentModelElement().getName(), EventEnum.DQ_ANALYSIS_REOPEN_EDITOR, reopenEditor); // ADD msjian TDQ-8860 2014-4-30:only for column set analysis, when there have pattern(s) when java engine,show // all match indicator in the Indicators section. if (analysisType.equals(AnalysisType.COLUMN_SET)) { // register: refresh the dataprovider combobox when the name of the data provider is changed. refresh2ShowMatchIndicator = new EventReceiver() { @Override public boolean handle(Object data) { ((ColumnSetAnalysisDetailsPage) getMasterPage()).refreshIndicatorsSection(); return true; } }; EventManager.getInstance().register(getMasterPage().getCurrentModelElement(), EventEnum.DQ_COLUMNSET_SHOW_MATCH_INDICATORS, refresh2ShowMatchIndicator); } // TDQ-8860~ // Added TDQ8787 2014-06-16 yyin: for dynamic chart, create all charts before execute the analysis if (masterPage instanceof DynamicAnalysisMasterPage) { registerDynamicEvent = new EventReceiver() { @Override public boolean handle(Object data) { if (masterPage.equals(activePageInstance)) { ((DynamicAnalysisMasterPage) masterPage).registerDynamicEvent(); } else { // register result page if (resultPage != null) { if (resultPage instanceof ColumnAnalysisResultPage) { ((ColumnAnalysisResultPage) resultPage).registerDynamicEvent(); } else if (resultPage instanceof BusinessRuleAnalysisResultPage) { ((BusinessRuleAnalysisResultPage) resultPage).registerDynamicEvent(); } } } return true; } }; EventManager.getInstance().register(getMasterPage().getCurrentModelElement(), EventEnum.DQ_DYNAMIC_REGISTER_DYNAMIC_CHART, registerDynamicEvent); unRegisterDynamicEvent = new EventReceiver() { @Override public boolean handle(Object data) { if (masterPage.equals(activePageInstance)) { ((DynamicAnalysisMasterPage) masterPage).unRegisterDynamicEvent(); } else { // register result page if (resultPage != null) { if (resultPage instanceof ColumnAnalysisResultPage) { ((ColumnAnalysisResultPage) resultPage).unRegisterDynamicEvent(); } else if (resultPage instanceof BusinessRuleAnalysisResultPage) { ((BusinessRuleAnalysisResultPage) resultPage).unRegisterDynamicEvent(); } } } return true; } }; EventManager.getInstance().register(getMasterPage().getCurrentModelElement(), EventEnum.DQ_DYNAMIC_UNREGISTER_DYNAMIC_CHART, unRegisterDynamicEvent); } } /** * unregister the update execution event Added 20130725 TDQ-7639 */ @Override public void dispose() { EventManager.getInstance().clearEvent(getMasterPage().getCurrentModelElement(), EventEnum.DQ_ANALYSIS_CHECK_BEFORERUN); EventManager.getInstance().clearEvent(getMasterPage().getCurrentModelElement(), EventEnum.DQ_ANALYSIS_RUN_FROM_MENU); EventManager.getInstance().clearEvent(getMasterPage().getCurrentModelElement().getName(), EventEnum.DQ_ANALYSIS_REOPEN_EDITOR); // ADD msjian TDQ-8860 2014-4-30:only for column set analysis, when there have pattern(s) when java engine,show // all match indicator in the Indicators section. if (analysisType.equals(AnalysisType.COLUMN_SET)) { EventManager.getInstance().clearEvent(getMasterPage().getCurrentModelElement(), EventEnum.DQ_COLUMNSET_SHOW_MATCH_INDICATORS); } // TDQ-8860~ // Added TDQ8787 2014-06-16 yyin: for dynamic chart, unregister the create all chart event if (masterPage instanceof DynamicAnalysisMasterPage) { EventManager.getInstance().clearEvent(getMasterPage().getCurrentModelElement(), EventEnum.DQ_DYNAMIC_REGISTER_DYNAMIC_CHART); EventManager.getInstance().clearEvent(getMasterPage().getCurrentModelElement(), EventEnum.DQ_DYNAMIC_UNREGISTER_DYNAMIC_CHART); }// ~ super.dispose(); } }