// ============================================================================ // // 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.dq.analysis; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.talend.core.model.metadata.builder.connection.Connection; import org.talend.cwm.helper.ColumnHelper; import org.talend.cwm.helper.ColumnSetHelper; import org.talend.cwm.helper.ConnectionHelper; import org.talend.cwm.helper.ResourceHelper; import org.talend.cwm.helper.SwitchHelpers; import org.talend.cwm.management.i18n.Messages; import org.talend.cwm.relational.TdColumn; import org.talend.dataquality.PluginConstant; import org.talend.dataquality.analysis.Analysis; import org.talend.dataquality.analysis.AnalysisContext; import org.talend.dataquality.helpers.RowCountIndicatorsAdapter; import org.talend.dataquality.indicators.Indicator; import org.talend.dq.dbms.GenericSQLHandler; import org.talend.dq.helper.EObjectHelper; import org.talend.dq.indicators.IndicatorEvaluator; import org.talend.utils.sugars.ReturnCode; import orgomg.cwm.objectmodel.core.Classifier; import orgomg.cwm.objectmodel.core.ModelElement; import orgomg.cwm.objectmodel.core.Package; import orgomg.cwm.resource.relational.ColumnSet; /** * @author scorreia * * Run analysis on columns. */ public class ColumnAnalysisExecutor extends AnalysisExecutor { private Connection dataprovider; private static Logger log = Logger.getLogger(ColumnAnalysisExecutor.class); protected Map<ModelElement, Package> schemata = new HashMap<ModelElement, Package>(); protected boolean isAccessWith(Connection dp) { if (dataprovider == null) { dataprovider = dp; return true; } // else compare return ResourceHelper.areSame(dataprovider, dp); } @Override protected ReturnCode evaluate(Analysis analysis, java.sql.Connection connection, String sqlStatement) { IndicatorEvaluator eval = CreateIndicatorEvaluator(analysis); // MOD xqliu 2009-02-09 bug 6237 eval.setMonitor(getMonitor()); // set it into the evaluator eval.setConnection(connection); // use pooled connection eval.setPooledConnection(POOLED_CONNECTION); // --- add indicators EList<Indicator> indicators = analysis.getResults().getIndicators(); RowCountIndicatorsAdapter.getInstance().clear(); for (Indicator indicator : indicators) { assert indicator != null; TdColumn tdColumn = SwitchHelpers.COLUMN_SWITCH.doSwitch(indicator.getAnalyzedElement()); if (tdColumn == null) { continue; } // --- get the schema owner if (!belongToSameSchemata(tdColumn)) { setError(Messages.getString("ColumnAnalysisExecutor.GivenColumn", tdColumn.getName())); //$NON-NLS-1$ return new ReturnCode(getErrorMessage(), Boolean.FALSE); } String columnName = ColumnHelper.getFullName(tdColumn); eval.storeIndicator(columnName, indicator); } // when to close connection boolean closeAtTheEnd = true; Package catalog = schemata.values().iterator().next(); if (!eval.selectCatalog(catalog.getName())) { log.warn(Messages.getString("ColumnAnalysisExecutor.FAILEDTOSELECTCATALOG", catalog.getName()));//$NON-NLS-1$ } return eval.evaluateIndicators(sqlStatement, closeAtTheEnd); } /** * DOC zshen Comment method "CreateIndicatorEvaluator". * * @param analysis * @return */ protected IndicatorEvaluator CreateIndicatorEvaluator(Analysis analysis) { IndicatorEvaluator eval = new IndicatorEvaluator(analysis); return eval; } /** * Method "belongToSameSchemata" fills in the map this{@link #schemata}. * * @param tdColumn a column * @return false when the given column has an owner different from the one registered in the map. */ protected boolean belongToSameSchemata(final ModelElement tdColumn) { assert tdColumn != null; if (schemata.get(tdColumn) != null) { return true; } // get table or view ColumnSet owner = ColumnHelper.getColumnOwnerAsColumnSet(tdColumn); if (owner == null) { setError(Messages.getString("ColumnAnalysisExecutor.NotFoundColumn", tdColumn.getName())); //$NON-NLS-1$ return false; } // get catalog or schema Package schema = ColumnSetHelper.getParentCatalogOrSchema(owner); if (schema == null) { setError(Messages.getString("ColumnAnalysisExecutor.NoSchemaOrCatalogFound", owner.getName(), tdColumn.getName())); //$NON-NLS-1$ return false; } schemata.put(tdColumn, schema); return true; } /* * (non-Javadoc) * * @see org.talend.dq.analysis.AnalysisExecutor#createSqlStatement(org.talend.dataquality.analysis.Analysis) */ @Override public String createSqlStatement(Analysis analysis) { this.cachedAnalysis = analysis; // CwmZQuery query = new CwmZQuery(); StringBuilder sql = new StringBuilder("SELECT ");//$NON-NLS-1$ EList<ModelElement> analysedElements = analysis.getContext().getAnalysedElements(); // From here to the end of the method is as same as the part in ColumnSetAnalysisExecutor(line 184), // so if you modify the code here, please also modify the same part. if (analysedElements.isEmpty()) { setError(Messages.getString("ColumnAnalysisExecutor.CannotCreateSQLStatement",//$NON-NLS-1$ analysis.getName())); return null; } Set<ColumnSet> fromPart = new HashSet<ColumnSet>(); final Iterator<ModelElement> iterator = analysedElements.iterator(); while (iterator.hasNext()) { // for (ModelElement modelElement : analysedElements) { ModelElement modelElement = iterator.next(); // --- preconditions TdColumn col = SwitchHelpers.COLUMN_SWITCH.doSwitch(modelElement); if (col == null) { setError(Messages.getString("ColumnAnalysisExecutor.GivenElementIsNotColumn", modelElement)); //$NON-NLS-1$ return null; } Classifier owner = col.getOwner(); if (owner == null) { setError(Messages.getString("ColumnAnalysisExecutor.NoOwnerFound", col.getName())); //$NON-NLS-1$ } ColumnSet colSet = SwitchHelpers.COLUMN_SET_SWITCH.doSwitch(owner); if (colSet == null) { setError(Messages.getString("ColumnAnalysisExecutor.NoContainerFound", col.getName())); //$NON-NLS-1$ return null; } // else add into select // MOD zshen feature 12919 select all the column to be prepare for drill down when user need. if (!analysis.getParameters().isStoreData()) { sql.append(this.quote(col.getName())); // append comma if more columns exist if (iterator.hasNext()) { sql.append(','); } } // add from fromPart.add(colSet); } if (fromPart.size() != 1) { log.error(Messages.getString("ColumnAnalysisExecutor.ANALYSISMUSTRUNONONETABLE") + fromPart.size() + PluginConstant.DOT_STRING);//$NON-NLS-1$ setError(Messages.getString("ColumnAnalysisExecutor.ANALYSISMUSTRUNONONETABLEERRORMESSAGE")); //$NON-NLS-1$ return null; } TdColumn firstColumn = SwitchHelpers.COLUMN_SWITCH.doSwitch(analysedElements.get(0)); // MOD zshen feature 12919 select all the column to be prepare for drill down. if (analysis.getParameters().isStoreData()) { // MOD klliu 2011-06-30 bug 22523 whichever is Table or View,that finds columns should ues columnset EObject eContainer = firstColumn.eContainer(); List<TdColumn> columnList = ColumnSetHelper.getColumns(SwitchHelpers.COLUMN_SET_SWITCH.doSwitch(eContainer)); // ~ Iterator<TdColumn> iter = columnList.iterator(); while (iter.hasNext()) { TdColumn column = iter.next(); sql.append(this.quote(column.getName())); // append comma if more columns exist if (iter.hasNext()) { sql.append(','); } } } // add from clause sql.append(dbms().from()); sql.append(dbms().getQueryColumnSetWithPrefix(firstColumn)); // add where clause // --- get data filter ModelElementAnalysisHandler handler = new ModelElementAnalysisHandler(); handler.setAnalysis(analysis); String stringDataFilter = handler.getStringDataFilter(); if (!(stringDataFilter == null || "".equals(stringDataFilter))) { //$NON-NLS-1$ sql.append(GenericSQLHandler.WHERE_CLAUSE); } String sqlStatement = sql.toString(); sqlStatement = dbms().addWhereToStatement(sqlStatement, stringDataFilter); return sqlStatement; } @Override protected boolean check(final Analysis analysis) { if (analysis == null) { setError(Messages.getString("ColumnAnalysisExecutor.AnalysisIsNull")); //$NON-NLS-1$ return false; } if (!super.check(analysis)) { // error message already set in super method. return false; } // --- check that there exists at least on element to analyze AnalysisContext context = analysis.getContext(); if (context.getAnalysedElements().size() == 0) { setError(Messages.getString("ColumnAnalysisExecutor.AnalysisHaveAtLeastOneColumn")); //$NON-NLS-1$ return false; } return checkAnalyzedElements(analysis, context); } /** * DOC scorreia Comment method "checkAnalyzedElements". * * @param analysis * @param context */ protected boolean checkAnalyzedElements(final Analysis analysis, AnalysisContext context) { ModelElementAnalysisHandler analysisHandler = new ModelElementAnalysisHandler(); analysisHandler.setAnalysis(analysis); for (ModelElement node : context.getAnalysedElements()) { TdColumn column = SwitchHelpers.COLUMN_SWITCH.doSwitch(node); // --- Check that each analyzed element has at least one indicator if (analysisHandler.getIndicators(column).size() == 0) { setError(Messages.getString("ColumnAnalysisExecutor.EachColumnHaveOneIndicator")); //$NON-NLS-1$ return false; } // --- get the data provider Connection dp = ConnectionHelper.getTdDataProvider(column); if (!isAccessWith(dp)) { setError(Messages.getString("ColumnAnalysisExecutor.AllColumnsBelongSameConnection", //$NON-NLS-1$ column.getName(), dataprovider.getName())); return false; } } return true; } /** * Method "getQuotedColumnName". * * @param column a column * @return the quoted column name */ protected String getQuotedColumnName(ModelElement column) { if (column != null && column.eIsProxy()) { column = (ModelElement) EObjectHelper.resolveObject(column); } assert column != null; String quotedColName = quote(column.getName()); return quotedColName; } /** * Method "getQuotedTableName". * * @param column * @return the quoted table name */ protected String getQuotedTableName(TdColumn column) { if (column != null && column.eIsProxy()) { column = (TdColumn) EObjectHelper.resolveObject(column); } String table = quote(ColumnHelper.getTableFullName(column)); return table; } protected boolean isSchemataProxy() { for (Package pckg : schemata.values()) { if (pckg != null && pckg.eIsProxy()) { return true; } } return false; } }