// ============================================================================ // // 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.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.Section; import org.talend.dataprofiler.common.ui.editor.preview.ICustomerDataset; import org.talend.dataprofiler.core.PluginConstant; import org.talend.dataprofiler.core.i18n.internal.DefaultMessagesImpl; import org.talend.dataprofiler.core.model.TableIndicator; import org.talend.dataprofiler.core.model.dynamic.DynamicIndicatorModel; import org.talend.dataprofiler.core.ui.editor.composite.AbstractPagePart; import org.talend.dataprofiler.core.ui.editor.composite.AnalysisTableTreeViewer; import org.talend.dataprofiler.core.ui.editor.preview.CompositeIndicator; import org.talend.dataprofiler.core.ui.editor.preview.TableIndicatorUnit; import org.talend.dataprofiler.core.ui.editor.preview.model.ChartTableFactory; import org.talend.dataprofiler.core.ui.editor.preview.model.ChartTypeStatesFactory; import org.talend.dataprofiler.core.ui.editor.preview.model.TableTypeStatesFactory; import org.talend.dataprofiler.core.ui.editor.preview.model.TableWithData; import org.talend.dataprofiler.core.ui.editor.preview.model.states.IChartTypeStates; import org.talend.dataprofiler.core.ui.editor.preview.model.states.WhereRuleStatisticsStateTable; import org.talend.dataprofiler.core.ui.editor.preview.model.states.table.ITableTypeStates; import org.talend.dataprofiler.core.ui.editor.preview.model.states.table.WhereRuleStatisticsTableState; import org.talend.dataprofiler.core.ui.events.DynamicChartEventReceiver; 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.events.IEventReceiver; import org.talend.dataprofiler.core.ui.events.TableDynamicChartEventReceiver; import org.talend.dataprofiler.core.ui.pref.EditorPreferencePage; import org.talend.dataprofiler.core.ui.utils.AnalysisUtils; import org.talend.dataprofiler.core.ui.utils.TOPChartUtils; import org.talend.dataquality.analysis.Analysis; import org.talend.dataquality.indicators.Indicator; import org.talend.dq.analysis.AnalysisHandler; import org.talend.dq.indicators.preview.EIndicatorChartType; import org.talend.dq.nodes.indicator.type.IndicatorEnum; import orgomg.cwm.resource.relational.NamedColumnSet; /** * DOC xqliu class global comment. Detailled comment */ public class BusinessRuleAnalysisResultPage extends AbstractAnalysisResultPageWithChart implements PropertyChangeListener { protected static Logger log = Logger.getLogger(BusinessRuleAnalysisResultPage.class); private Composite resultComp; BusinessRuleAnalysisDetailsPage masterPage; AnalysisTableTreeViewer tableTreeViewer; private Section resultSection = null; // Added TDQ-8787 20140617 yyin : store the temp indicator and its related dataset between one running private List<DynamicIndicatorModel> dynamicList = new ArrayList<DynamicIndicatorModel>(); private Map<Indicator, EventReceiver> eventReceivers = new IdentityHashMap<Indicator, EventReceiver>(); private EventReceiver registerDynamicRefreshEvent; private Composite sectionClient; // Added TDQ-9241 private EventReceiver switchBetweenPageEvent; /** * DOC xqliu TableAnalysisResultPage constructor comment. * * @param editor * @param id * @param title */ public BusinessRuleAnalysisResultPage(FormEditor editor, String id, String title) { super(editor, id, title); AnalysisEditor analysisEditor = (AnalysisEditor) editor; this.masterPage = (BusinessRuleAnalysisDetailsPage) analysisEditor.getMasterPage(); } @Override protected void createFormContent(IManagedForm managedForm) { super.createFormContent(managedForm); if (topComposite != null && !topComposite.isDisposed()) { resultComp = toolkit.createComposite(topComposite); resultComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING)); resultComp.setLayout(new GridLayout()); createResultSection(resultComp); form.reflow(true); } } @Override protected AnalysisHandler getAnalysisHandler() { return this.masterPage.getAnalysisHandler(); } @Override protected void createResultSection(Composite parent) { // ADD gdbu 2011-3-4 bug 19242 AbstractPagePart treeViewer = masterPage.getTreeViewer(); if (treeViewer != null && treeViewer instanceof AnalysisTableTreeViewer) { tableTreeViewer = (AnalysisTableTreeViewer) treeViewer; } // ~ resultSection = createSection(form, parent, DefaultMessagesImpl.getString("TableAnalysisResultPage.analysisResult"), null); //$NON-NLS-1$ sectionClient = toolkit.createComposite(resultSection); sectionClient.setLayout(new GridLayout()); sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH)); dynamicList.clear(); for (final TableIndicator tableIndicator : tableTreeViewer.getTableIndicator()) { ExpandableComposite exComp = toolkit.createExpandableComposite(sectionClient, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT | ExpandableComposite.EXPANDED); // bug 10541 fix by zshen,Change some character set to be proper to add view in the table anasys if (tableIndicator.isTable()) { exComp.setText(DefaultMessagesImpl.getString( "TableAnalysisResultPage.table", tableIndicator.getColumnSet().getName())); //$NON-NLS-1$ } else { exComp.setText(DefaultMessagesImpl.getString( "TableAnalysisResultPage.view", tableIndicator.getColumnSet().getName())); //$NON-NLS-1$ } exComp.setLayout(new GridLayout()); exComp.setLayoutData(new GridData(GridData.FILL_BOTH)); // MOD xqliu 2009-06-23 bug 7481 exComp.setExpanded(EditorPreferencePage.isUnfoldingAnalyzedEelementsResultPage()); // ~ final Composite comp = toolkit.createComposite(exComp); comp.setLayout(new GridLayout()); comp.setLayoutData(new GridData(GridData.FILL_BOTH)); exComp.setClient(comp); createResultDataComposite(comp, tableIndicator); exComp.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { form.reflow(true); } }); } resultSection.setClient(sectionClient); } private void createResultDataComposite(final Composite comp, final TableIndicator tableIndicator) { if (tableIndicator.getIndicators().length != 0) { final NamedColumnSet set = tableIndicator.getColumnSet(); IRunnableWithProgress rwp = new IRunnableWithProgress() { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask( DefaultMessagesImpl.getString("TableAnalysisResultPage.createPreview", set.getName()), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ Display.getDefault().asyncExec(new Runnable() { public void run() { Map<EIndicatorChartType, List<TableIndicatorUnit>> indicatorComposite = CompositeIndicator .getInstance().getTableIndicatorComposite(tableIndicator); for (EIndicatorChartType chartType : indicatorComposite.keySet()) { List<TableIndicatorUnit> units = indicatorComposite.get(chartType); if (!units.isEmpty()) { // create UI ExpandableComposite subComp = createSubWholeComposite(comp, chartType); final Composite composite = createCompositeForTableAndChart(subComp); Composite tableTopComp = createTableComposite(composite); Analysis analysis = masterPage.getAnalysisHandler().getAnalysis(); ITableTypeStates tableTypeState = TableTypeStatesFactory.getInstance().getTableStateForRule( chartType, units, tableIndicator); // create table for RownCountIndicator createTableViewerForRowCount(chartType, units, tableTopComp, analysis, tableTypeState); // create table for WhereRuleIndicator createTableForWhereRule(chartType, tableTopComp, analysis, tableTypeState, units); Composite chartTopComp = createTableComposite(composite); if (canShowChartForResultPage()) { createChartsForRules(tableIndicator, chartType, units, analysis, chartTopComp); } subComp.setClient(composite); subComp.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { form.reflow(true); } }); } } } /** * DOC yyin Comment method "createChartsForRules". * * @param tableIndicator * @param chartType * @param units * @param analysis * @param chartTopComp */ private void createChartsForRules(final TableIndicator tableIndicator, EIndicatorChartType chartType, List<TableIndicatorUnit> units, Analysis analysis, Composite chartTopComp) { IChartTypeStates chartTypeState = ChartTypeStatesFactory.getChartStateOfTableAna(chartType, units, tableIndicator); // get all indicator lists separated by chart, and only // WhereRuleStatisticsStateTable can get not-null charts List<List<Indicator>> pagedIndicators = ((WhereRuleStatisticsStateTable) chartTypeState) .getPagedIndicators(); // Added TDQ-9241: for each list(for each chart), check if the current // list has been registered dynamic event List<Object> datasets = new ArrayList<Object>(); for (List<Indicator> oneChart : pagedIndicators) { IEventReceiver event = EventManager.getInstance().findRegisteredEvent(oneChart.get(0), EventEnum.DQ_DYMANIC_CHART, 0); if (event != null) { // get the dataset from the event Object dataset = ((TableDynamicChartEventReceiver) event).getDataset(); // if there has the dataset for the current rule, use it to replace, // (only happen when first switch from master to result page, during // one running) if (dataset != null) { datasets.add(dataset); } }// ~ } // create chart List<Object> charts = null; if (datasets.size() > 0) { charts = chartTypeState.getChartList(datasets); } else { charts = chartTypeState.getChartList(); datasets = ((WhereRuleStatisticsStateTable) chartTypeState).getTempDatasetList(); } if (charts != null) { int index = 0; for (int i = 0; i < charts.size(); i++) { Object chart2 = charts.get(i); Object chartComp = TOPChartUtils.getInstance().createChartCompositeWithSpecialSize( chartTopComp, SWT.NONE, chart2, true, 250, 550); // Added TDQ-8787 20140707 yyin: create and store the dynamic model for // each chart DynamicIndicatorModel dyModel = AnalysisUtils.createDynamicModel(chartType, pagedIndicators.get(index++), chart2); dynamicList.add(dyModel); // ~ // one dataset <--> one chart addMenuToChartComp(chartComp, chartTypeState.getDataExplorer(), analysis, ((ICustomerDataset) datasets.get(i)).getDataEntities()); } } } /** * DOC yyin Comment method "createTableForWhereRule". * * @param chartType * @param tableTopComp * @param analysis * @param tableTypeState * @param units * @return */ private void createTableForWhereRule(EIndicatorChartType chartType, Composite tableTopComp, Analysis analysis, ITableTypeStates tableTypeState, List<TableIndicatorUnit> units) { TableWithData chartData = new TableWithData(chartType, tableTypeState.getDataEntity()); TableViewer tableviewer = tableTypeState.getTableForm(tableTopComp); tableviewer.setInput(chartData); ChartTableFactory.addMenuAndTip(tableviewer, tableTypeState.getDataExplorer(), analysis); // Added TDQ-8787 20140707 yyin: create and store the dynamic model List<Indicator> allRules = new ArrayList<Indicator>(); List<TableIndicatorUnit> removeRowCountUnit = ((WhereRuleStatisticsTableState) tableTypeState) .removeRowCountUnit(units); for (TableIndicatorUnit indUnit : removeRowCountUnit) { allRules.add(indUnit.getIndicator()); } DynamicIndicatorModel dyModel = AnalysisUtils.createDynamicModel(chartType, allRules, null); dyModel.setTableViewer(tableviewer); dynamicList.add(dyModel); } /** * DOC yyin Comment method "createTableViewerForRowCount". * * @param chartType * @param units * @param tableTopComp * @param analysis * @param tableTypeState */ private void createTableViewerForRowCount(EIndicatorChartType chartType, List<TableIndicatorUnit> units, Composite tableTopComp, Analysis analysis, ITableTypeStates tableTypeState) { WhereRuleStatisticsTableState tableWhereRule = (WhereRuleStatisticsTableState) tableTypeState; TableWithData chartDataRowCount = new TableWithData(chartType, tableWhereRule .getDataEntityOfRowCount()); TableViewer tableviewerRowCount = tableWhereRule.getTableFormRowCount(tableTopComp); tableviewerRowCount.setInput(chartDataRowCount); ChartTableFactory.addMenuAndTip(tableviewerRowCount, tableTypeState.getDataExplorer(), analysis); // Added TDQ-8787 20140707 yyin: create and store the dynamic model for row // count's table List<Indicator> rowCount = new ArrayList<Indicator>(); rowCount.add(tableWhereRule.getRownCountUnit(units).getIndicator()); DynamicIndicatorModel dyModel = AnalysisUtils.createDynamicModel(chartType, rowCount, null); dyModel.setTableViewer(tableviewerRowCount); dynamicList.add(dyModel); } /** * DOC yyin Comment method "createTableComposite". * * @param composite * @return */ private Composite createTableComposite(final Composite composite) { Composite tableTopComp = toolkit.createComposite(composite, SWT.NULL); tableTopComp.setLayout(new GridLayout(1, false)); tableTopComp.setLayoutData(new GridData(GridData.FILL_BOTH)); return tableTopComp; } /** * DOC yyin Comment method "createCompositeForTableAndChart". * * @param subComp * @return */ private Composite createCompositeForTableAndChart(ExpandableComposite subComp) { final Composite composite = toolkit.createComposite(subComp, SWT.NULL); composite.setLayout(new GridLayout(2, false)); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); return composite; } /** * DOC yyin Comment method "createSubWholeComposite". * * @param comp * @param chartType * @return */ private ExpandableComposite createSubWholeComposite(final Composite comp, EIndicatorChartType chartType) { ExpandableComposite subComp = toolkit.createExpandableComposite(comp, ExpandableComposite.TWISTIE | ExpandableComposite.CLIENT_INDENT | ExpandableComposite.EXPANDED); subComp.setText(chartType.getLiteral()); subComp.setLayoutData(new GridData(GridData.FILL_BOTH)); subComp.setExpanded(EditorPreferencePage.isUnfoldingIndicatorsResultPage()); return subComp; } }); monitor.done(); } }; try { new ProgressMonitorDialog(this.getEditorSite().getShell()).run(true, false, rwp); } catch (Exception ex) { log.error(ex, ex); } } } @Override public void setDirty(boolean isDirty) { // no implementation } public void propertyChange(PropertyChangeEvent evt) { if (PluginConstant.ISDIRTY_PROPERTY.equals(evt.getPropertyName())) { ((AnalysisEditor) this.getEditor()).firePropertyChange(IEditorPart.PROP_DIRTY); } } /* * (non-Javadoc) * * @see * org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisResultPage#refresh(org.talend.dataprofiler.core * .ui.editor.analysis.AbstractAnalysisMetadataPage) */ @Override public void refresh(AbstractAnalysisMetadataPage masterPage1) { this.masterPage = (BusinessRuleAnalysisDetailsPage) masterPage1; disposeComposite(); createFormContent(getManagedForm()); } /** * DOC yyin Comment method "disposeComposite". */ private void disposeComposite() { if (summaryComp != null && !summaryComp.isDisposed()) { summaryComp.dispose(); } if (resultComp != null && !resultComp.isDisposed()) { resultComp.dispose(); } } /** * Added TDQ-8787 20140613 yyin: create all charts before running, register each chart with its related indicator. */ public void registerDynamicEvent() { // register dynamic event,for the indicator (for each column) for (DynamicIndicatorModel oneCategoryIndicatorModel : dynamicList) { Object categoryDataset = oneCategoryIndicatorModel.getDataset(); TableViewer tableViewer = oneCategoryIndicatorModel.getTableViewer(); int index = 0; for (Indicator oneIndicator : oneCategoryIndicatorModel.getIndicatorList()) { TableDynamicChartEventReceiver eReceiver = new TableDynamicChartEventReceiver(); eReceiver.setDataset(categoryDataset); eReceiver.setIndexInDataset(index++); eReceiver.setIndicatorName(oneIndicator.getName()); eReceiver.setIndicator(oneIndicator); eReceiver.setIndicatorType(IndicatorEnum.findIndicatorEnum(oneIndicator.eClass())); eReceiver.setChartComposite(sectionClient); eReceiver.setTableViewer(tableViewer); // clear data eReceiver.clearValue(); registerIndicatorEvent(oneIndicator, eReceiver); } } reLayoutChartComposite(); registerRefreshDynamicChartEvent(); } private void registerIndicatorEvent(Indicator oneIndicator, DynamicChartEventReceiver eReceiver) { eventReceivers.put(oneIndicator, eReceiver); EventManager.getInstance().register(oneIndicator, EventEnum.DQ_DYMANIC_CHART, eReceiver); } public void reLayoutChartComposite() { sectionClient.getParent().layout(); sectionClient.layout(); } /** * refresh the composite of the chart, to show the changes on the chart. */ private void registerRefreshDynamicChartEvent() { registerDynamicRefreshEvent = new EventReceiver() { @Override public boolean handle(Object data) { reLayoutChartComposite(); return true; } }; EventManager.getInstance().register(sectionClient, EventEnum.DQ_DYNAMIC_REFRESH_DYNAMIC_CHART, registerDynamicRefreshEvent); // register a event to handle switch between master and result page switchBetweenPageEvent = new EventReceiver() { int times = 0; @Override public boolean handle(Object data) { if (times == 0) { times++; masterPage.refreshGraphicsInSettingsPage(); } return true; } }; EventManager.getInstance().register(masterPage.getCurrentModelElement(), EventEnum.DQ_DYNAMIC_SWITCH_MASTER_RESULT_PAGE, switchBetweenPageEvent); } /** * unregister every dynamic events which registered before executing analysis * * @param eventReceivers */ public void unRegisterDynamicEvent() { // Added TDQ-9241 EventManager.getInstance() .clearEvent(masterPage.getCurrentModelElement(), EventEnum.DQ_DYNAMIC_SWITCH_MASTER_RESULT_PAGE); for (Indicator oneIndicator : eventReceivers.keySet()) { DynamicChartEventReceiver eventReceiver = (DynamicChartEventReceiver) eventReceivers.get(oneIndicator); eventReceiver.clear(); EventManager.getInstance().clearEvent(oneIndicator, EventEnum.DQ_DYMANIC_CHART); } eventReceivers.clear(); EventManager.getInstance().clearEvent(sectionClient, EventEnum.DQ_DYNAMIC_REFRESH_DYNAMIC_CHART); for (DynamicIndicatorModel dyModel : dynamicList) { dyModel.clear(); } dynamicList.clear(); masterPage.clearDynamicDatasets(); } }