/* * 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.ui.actions; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.xsd.XSDSimpleTypeDefinition; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.metamodel.aspect.AspectManager; import org.teiid.designer.core.metamodel.aspect.MetamodelAspect; import org.teiid.designer.core.metamodel.aspect.sql.SqlColumnAspect; import org.teiid.designer.core.metamodel.aspect.sql.SqlProcedureParameterAspect; import org.teiid.designer.metamodels.relational.aspects.sql.ProcedureParameterAspect; import org.teiid.designer.transformation.aspects.validation.InputParameterAspect; import org.teiid.designer.ui.PluginConstants; import org.teiid.designer.ui.UiPlugin; import org.teiid.designer.ui.common.eventsupport.SelectionUtilities; import org.teiid.designer.ui.editors.ModelEditorManager; import org.teiid.designer.ui.viewsupport.DatatypeSelectionDialog; import org.teiid.designer.ui.viewsupport.ModelObjectUtilities; /** * @since 8.0 */ public class SetDatatypeModelingAction extends SortableSelectionAction { private static final String STRING_STRING = "string"; //$NON-NLS-1$ /** * * @since 5.0 */ public SetDatatypeModelingAction() { super(); setImageDescriptor(UiPlugin.getDefault().getImageDescriptor(PluginConstants.Images.BUILTIN_DATATYPE)); } /** * * @see org.teiid.designer.ui.actions.SortableSelectionAction#isValidSelection(org.eclipse.jface.viewers.ISelection) * @since 5.0 */ @Override public boolean isValidSelection(ISelection selection) { boolean isValid = false; if (SelectionUtilities.isAllEObjects(selection) ) { isValid = allSelectedAreSqlColumns(selection); if( !isValid ) { isValid = allSelectedAreProcedureParameters(selection); } if( !isValid ) { isValid = allSelectedAreXmlInputParameters(selection); } if( isValid ) { isValid = allSelectedHaveEditorsOpen(selection); } } return isValid; } /** * @see org.eclipse.jface.action.IAction#run() * @since 5.0 */ @Override public void run() { Collection selectedEObjects = new ArrayList(SelectionUtilities.getSelectedEObjects(getSelection())); if (!selectedEObjects.isEmpty()) { showDialog(selectedEObjects); } } /** * @see org.teiid.designer.ui.actions.ISelectionAction#isApplicable(org.eclipse.jface.viewers.ISelection) * @since 5.0 */ @Override public boolean isApplicable(ISelection selection) { return isValidSelection(selection); } private boolean allSelectedAreSqlColumns(ISelection selection) { boolean result = true; Iterator iter = SelectionUtilities.getSelectedEObjects(selection).iterator(); EObject nextEObj = null; MetamodelAspect mmAspect = null; while( iter.hasNext() && result) { nextEObj = (EObject)iter.next(); if( ModelObjectUtilities.isReadOnly(nextEObj)) result = false; if( result ) { mmAspect = ModelObjectUtilities.getSqlAspect(nextEObj); if( mmAspect != null && mmAspect instanceof SqlColumnAspect ) { result = ((SqlColumnAspect)mmAspect).canSetDatatype(); } else { result = false; } } } return result; } private boolean allSelectedAreProcedureParameters(ISelection selection) { boolean result = true; Iterator iter = SelectionUtilities.getSelectedEObjects(selection).iterator(); EObject nextEObj = null; MetamodelAspect mmAspect = null; while( iter.hasNext() && result) { nextEObj = (EObject)iter.next(); if( ModelObjectUtilities.isReadOnly(nextEObj)) result = false; if( result ) { mmAspect = ModelObjectUtilities.getSqlAspect(nextEObj); if( mmAspect != null && mmAspect instanceof ProcedureParameterAspect ) { result = ((ProcedureParameterAspect)mmAspect).canSetDatatype(); } else { result = false; } } } return result; } private boolean allSelectedAreXmlInputParameters(ISelection selection) { boolean result = true; Iterator iter = SelectionUtilities.getSelectedEObjects(selection).iterator(); EObject nextEObj = null; MetamodelAspect mmAspect = null; while( iter.hasNext() && result) { nextEObj = (EObject)iter.next(); if( ModelObjectUtilities.isReadOnly(nextEObj)) result = false; if( result ) { mmAspect = ModelObjectUtilities.getSqlAspect(nextEObj); if( mmAspect != null && mmAspect instanceof InputParameterAspect) { result = true; } else { result = false; } } } return result; } private boolean allSelectedHaveEditorsOpen(ISelection selection) { boolean result = true; Iterator iter = SelectionUtilities.getSelectedEObjects(selection).iterator(); EObject nextEObj = null; while( iter.hasNext() && result) { nextEObj = (EObject)iter.next(); result = ModelEditorManager.isOpen(nextEObj); } return result; } /** * * @param theEObjects collection of <code>EObject</code>s; cannot be null or empty. * @return * @since 4.2 */ protected void showDialog(Collection theEObjects) { int length = 0; EObject eObj = (EObject)theEObjects.iterator().next(); Shell shell = UiPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell(); // configure dialog DatatypeSelectionDialog dialog = new DatatypeSelectionDialog(shell, eObj); boolean canSetLength = false; // If multiple objects selected, then tell the dialog if( theEObjects.size() > 1 ) { dialog.setMultipleObjects(true); } else { dialog.setMultipleObjects(false); } MetamodelAspect mmAspect = ModelObjectUtilities.getSqlAspect(eObj); if( mmAspect instanceof SqlColumnAspect ) { SqlColumnAspect sqa = (SqlColumnAspect)mmAspect; Object originalValue = sqa.getDatatype(eObj); Object[] selection = new Object[] { originalValue }; dialog.setInitialSelections(selection); canSetLength = sqa.canSetLength(); // show length panel if necessary if (canSetLength) { int initialLength = sqa.getLength(eObj); if( initialLength >= 0 ) dialog.setInitialLength(initialLength); dialog.setEditLength(true); } // show dialog int status = dialog.open(); // process dialog if (status == Window.OK) { Object newType = null; Object[] result = dialog.getResult(); // return the selected value if (result.length > 0) { if (canSetLength) { length = dialog.getLength(); } newType = result[0]; } setDatatypesForSqlColumns(theEObjects, (EObject)newType, length, dialog.overrideAllLengths()); } } else if( mmAspect instanceof SqlProcedureParameterAspect ) { SqlProcedureParameterAspect ppa = (SqlProcedureParameterAspect)mmAspect; Object originalValue = ppa.getDatatype(eObj); Object[] selection = new Object[] { originalValue }; dialog.setInitialSelections(selection); canSetLength = ppa.canSetLength(); // show length panel if necessary if (canSetLength) { int initialLength = ppa.getLength(eObj); if( initialLength >= 0 ) dialog.setInitialLength(initialLength); dialog.setEditLength(true); } // show dialog int status = dialog.open(); // process dialog if (status == Window.OK) { Object newType = null; Object[] result = dialog.getResult(); // return the selected value if (result.length > 0) { if (canSetLength) { length = dialog.getLength(); } newType = result[0]; } setDatatypesForProcedureParameters(theEObjects, (EObject)newType, length, dialog.overrideAllLengths() ); } } } /** * Set the datatype for the supplied sqlColumn eobject. * @param eObject the supplied EObject * @param datatype the Datatype */ private void setDatatypesForSqlColumns(Collection columns, EObject datatype, int theLength, boolean overrideAllLengths) { SqlColumnAspect columnAspect = null; EObject nextEObj = null; Iterator iter = columns.iterator(); int length = 0; if( typeIsString(datatype) ) length = theLength; boolean requiredStart = ModelerCore.startTxn(true,true,"Set Datatype For Columns",this); //$NON-NLS-1$ boolean succeeded = false; try { while( iter.hasNext() ) { nextEObj = (EObject)iter.next(); columnAspect = (SqlColumnAspect)AspectManager.getSqlAspect(nextEObj); boolean hasLength = columnAspect.canSetLength() && columnAspect.getLength(nextEObj) > 0; if (columnAspect.canSetDatatype()) { columnAspect.setDatatype(nextEObj,datatype); } if ( overrideAllLengths && columnAspect.canSetLength()) { columnAspect.setLength(nextEObj, length); } else if( !overrideAllLengths && !hasLength && columnAspect.canSetLength() ) { columnAspect.setLength(nextEObj, length); } } succeeded = true; } finally { //if we started the txn, commit it. if(requiredStart){ if(succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } } /** * Set the datatype for the supplied sqlColumn eobject. * @param eObject the supplied EObject * @param datatype the Datatype */ private void setDatatypesForProcedureParameters(Collection columns, EObject datatype, int length, boolean overrideAllLengths) { SqlProcedureParameterAspect procedureAspect = null; EObject nextEObj = null; Iterator iter = columns.iterator(); boolean requiredStart = ModelerCore.startTxn(true,true,"Set Datatype For Columns",this); //$NON-NLS-1$ boolean succeeded = false; try { while( iter.hasNext() ) { nextEObj = (EObject)iter.next(); procedureAspect = (SqlProcedureParameterAspect)AspectManager.getSqlAspect(nextEObj); boolean hasLength = procedureAspect.canSetLength() && procedureAspect.getLength(nextEObj) > 0; if (procedureAspect.canSetDatatype()) { procedureAspect.setDatatype(nextEObj,datatype); } if ( overrideAllLengths && procedureAspect.canSetLength() && procedureAspect.canSetLength()) { procedureAspect.setLength(nextEObj, length); } else if( !overrideAllLengths && !hasLength ) { procedureAspect.setLength(nextEObj, length); } } succeeded = true; } finally { //if we started the txn, commit it. if(requiredStart){ if(succeeded) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } } private boolean typeIsString(Object type) { if( type != null && type instanceof XSDSimpleTypeDefinition ) { String simpleType = ModelerCore.getWorkspaceDatatypeManager().getRuntimeTypeName((EObject)type); if( simpleType.equalsIgnoreCase(STRING_STRING) ) { return true; } } return false; } }