/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.transformation.ui.actions; import java.util.Iterator; import java.util.List; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.teiid.designer.metamodels.diagram.Diagram; import org.teiid.designer.metamodels.transformation.SqlTransformationMappingRoot; import org.teiid.designer.query.sql.lang.ICommand; import org.teiid.designer.query.sql.lang.ICriteria; import org.teiid.designer.query.sql.lang.IFrom; import org.teiid.designer.query.sql.lang.IFromClause; import org.teiid.designer.query.sql.lang.IGroupBy; import org.teiid.designer.query.sql.lang.IInto; import org.teiid.designer.query.sql.lang.IOption; import org.teiid.designer.query.sql.lang.IOrderBy; import org.teiid.designer.query.sql.lang.IQuery; import org.teiid.designer.query.sql.lang.ISelect; import org.teiid.designer.query.sql.lang.IUnaryFromClause; import org.teiid.designer.transformation.ui.UiPlugin; import org.teiid.designer.transformation.ui.editors.TransformationObjectEditorPage; import org.teiid.designer.transformation.ui.editors.sqleditor.SqlEditorPanel; import org.teiid.designer.transformation.util.SqlAspectHelper; import org.teiid.designer.transformation.util.TransformationHelper; import org.teiid.designer.ui.common.eventsupport.SelectionUtilities; import org.teiid.designer.ui.editors.ModelObjectEditorPage; import org.teiid.designer.ui.editors.MultiPageModelEditor; import org.teiid.designer.ui.viewsupport.ModelObjectUtilities; /** * AddJoinExpressionAction This action will create an inner join on the two selected columns. The action is currently contributed * by the TransformationObjectEditorPage, so that it only appears when the editor is displayed. * * @since 8.0 */ public class AddJoinExpressionAction extends TransformationAction { // ///////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS // ///////////////////////////////////////////////////////////////////////////////////////////// public AddJoinExpressionAction( EObject transformationEObject, Diagram diagram ) { super(transformationEObject, diagram); // setImageDescriptor(UiPlugin.getDefault().getImageDescriptor(UiConstants.Images.CLEAR_TRANSFORMATION)); } // ///////////////////////////////////////////////////////////////////////////////////////////// // METHODS // ///////////////////////////////////////////////////////////////////////////////////////////// /* (non-Javadoc) * @see org.eclipse.ui.ISelectionListener#selectionChanged(IWorkbenchPart, ISelection) */ @Override public void selectionChanged( IWorkbenchPart thePart, ISelection theSelection ) { super.selectionChanged(thePart, theSelection); // Enable the action based on the selection boolean enable = shouldEnable(); setEnabled(enable); } /* (non-Javadoc) * @see org.eclipse.jface.action.IAction#run() */ @Override protected void doRun() { ISelection theSelection = getSelection(); List selectedEObjs = SelectionUtilities.getSelectedEObjects(theSelection); Object selection1 = selectedEObjs.get(0); Object selection2 = selectedEObjs.get(1); if (selection1 != null && selection2 != null && selection1 instanceof EObject && selection2 instanceof EObject) { EObject col1 = (EObject)selection1; EObject col2 = (EObject)selection2; // New clause from selected columns String joinClause = buildJoinFromClause(col1, col2); // // Get the currently active ModelObjectEditorPage, ensure its TransformationObjEditorPage // IEditorPart editor = UiPlugin.getDefault().getCurrentWorkbenchWindow().getActivePage().getActiveEditor(); if (editor instanceof MultiPageModelEditor) { ModelObjectEditorPage moep = ((MultiPageModelEditor)editor).getActiveObjectEditor(); if (moep != null && moep instanceof TransformationObjectEditorPage) { TransformationObjectEditorPage transOEP = (TransformationObjectEditorPage)moep; // TransformationObjectEditorPage // Get the sqlEditor SqlEditorPanel sqlEditor = transOEP.getCurrentSqlEditor(); ICommand command = sqlEditor.getCommand(); if (command instanceof IQuery) { IQuery query = (IQuery)command; ISelect select = query.getSelect(); String newQuery = "SELECT " + select.toString() + joinClause; //$NON-NLS-1$ sqlEditor.setText(newQuery); } } } } } /* * this method builds the inner join string, given the column selections */ private String buildJoinFromClause( EObject col1, EObject col2 ) { EObject col1Parent = col1.eContainer(); EObject col2Parent = col2.eContainer(); // Object fullnames String col1Name = TransformationHelper.getSqlEObjectFullName(col1); String col1ParentName = TransformationHelper.getSqlEObjectFullName(col1Parent); String col2Name = TransformationHelper.getSqlEObjectFullName(col2); String col2ParentName = TransformationHelper.getSqlEObjectFullName(col2Parent); StringBuffer sb = new StringBuffer(" FROM "); //$NON-NLS-1$ sb.append(col1ParentName); sb.append(" INNER JOIN "); //$NON-NLS-1$ sb.append(col2ParentName); sb.append(" ON "); //$NON-NLS-1$ sb.append(col1Name); sb.append(" = "); //$NON-NLS-1$ sb.append(col2Name); return sb.toString(); } /* * method to determine if this action should be enabled, based on the current selection * @param theSelection the current selection * @return 'true' if the action should be enabled, 'false' if not. */ private boolean shouldEnable() { boolean enable = false; List selectedEObjs = SelectionUtilities.getSelectedEObjects(getSelection()); // ---------------------------------------------- // Two columns must be selected // ---------------------------------------------- if (!selectedEObjs.isEmpty() && selectedEObjs.size() == 2 && !ModelObjectUtilities.isReadOnly(getTransformation()) && !isDependencyDiagram() && getTransformation() != null && areEObjectsSelected()) { // // Get the currently active ModelObjectEditorPage, ensure its TransformationObjEditorPage // Transformation Editor must be open for this action to enable // boolean editorOpen = false; SqlEditorPanel sqlEditor = null; IEditorPart editor = UiPlugin.getDefault().getCurrentWorkbenchWindow().getActivePage().getActiveEditor(); if (editor instanceof MultiPageModelEditor) { ModelObjectEditorPage moep = ((MultiPageModelEditor)editor).getActiveObjectEditor(); if (moep instanceof TransformationObjectEditorPage) { TransformationObjectEditorPage transOEP = (TransformationObjectEditorPage)moep; // TransformationObjectEditorPage // Get the sqlEditor sqlEditor = transOEP.getCurrentSqlEditor(); if (sqlEditor != null) editorOpen = true; } } // Check Editor open and is Simple Query if (editorOpen && isSimpleQuery(sqlEditor)) { // Selected Eobjects Object selection1 = selectedEObjs.get(0); Object selection2 = selectedEObjs.get(1); if (selection1 instanceof EObject && selection2 instanceof EObject) { EObject eObj1 = (EObject)selection1; EObject eObj2 = (EObject)selection2; EObject eObj1Parent = eObj1.eContainer(); EObject eObj2Parent = eObj2.eContainer(); // Both selections must be non null columns if (eObj1Parent != null && eObj2Parent != null && org.teiid.designer.core.metamodel.aspect.sql.SqlAspectHelper.isColumn(eObj1) && org.teiid.designer.core.metamodel.aspect.sql.SqlAspectHelper.isColumn(eObj2) && !SqlAspectHelper.isInputParameter(eObj1) && !SqlAspectHelper.isInputParameter(eObj2)) { // Dont enable if any output columns are selected List transOutputs = ((SqlTransformationMappingRoot)getTransformation()).getOutputs(); if (transOutputs.contains(eObj1Parent) || transOutputs.contains(eObj2Parent)) { return false; } if (eObj1Parent.equals(eObj2Parent)) { return false; } enable = true; } } } } return enable; } // This action can currently only work on simple two-source queries. This means that the // query must be of the form "SELECT xxx FROM Source1, Source2" without any other clauses. // Future enhancement would be to support updating more complex queries. private boolean isSimpleQuery( SqlEditorPanel sqlEditor ) { boolean isSimpleQuery = false; ICommand command = sqlEditor.getCommand(); if (command != null && command instanceof IQuery) { // Get all of the query components IQuery query = (IQuery)command; ISelect select = query.getSelect(); IFrom from = query.getFrom(); ICriteria criteria = query.getCriteria(); IGroupBy groupBy = query.getGroupBy(); ICriteria having = query.getHaving(); IInto into = query.getInto(); IOption option = query.getOption(); IOrderBy orderBy = query.getOrderBy(); // Select and From must be non-null. All others must be null if (select != null && from != null && criteria == null && groupBy == null && having == null && into == null && option == null && orderBy == null) { // All FROM clauses must be UnaryFromClause. And there can only be two. List fromClauses = from.getClauses(); if (fromClauses.size() == 2) { boolean allUnary = true; Iterator fromIter = fromClauses.iterator(); while (fromIter.hasNext()) { IFromClause fromClause = (IFromClause)fromIter.next(); if (!(fromClause instanceof IUnaryFromClause)) { allUnary = false; break; } } if (allUnary) isSimpleQuery = true; } } } return isSimpleQuery; } }