/* * 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.wizards; import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.progress.IProgressConstants; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.core.designer.util.I18nUtil; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.relational.ui.textimport.RelationalTableLocationSelectionValidator; import org.teiid.designer.tools.textimport.ui.wizards.AbstractObjectProcessor; import org.teiid.designer.transformation.materialization.MaterializationModelGenerator; import org.teiid.designer.transformation.ui.UiPlugin; import org.teiid.designer.transformation.util.TransformationHelper; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.common.InternalUiConstants; import org.teiid.designer.ui.common.eventsupport.SelectionUtilities; import org.teiid.designer.ui.common.util.WidgetFactory; import org.teiid.designer.ui.common.util.WidgetUtil; import org.teiid.designer.ui.common.viewsupport.ListContentProvider; import org.teiid.designer.ui.common.wizard.AbstractWizard; import org.teiid.designer.ui.editors.ModelEditorManager; import org.teiid.designer.ui.explorer.ModelExplorerLabelProvider; import org.teiid.designer.ui.viewsupport.ModelIdentifier; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * @since 8.0 */ public class CreateMaterializedViewWizard extends AbstractWizard implements INewWizard, InternalUiConstants.Widgets, CoreStringUtil.Constants, UiConstants { private static final String I18N_PREFIX = I18nUtil.getPropertyPrefix(CreateMaterializedViewWizard.class); private static final String TITLE = UiPlugin.getDefault().getString(I18N_PREFIX, "title"); //$NON-NLS-1$ private static final String PAGE_TITLE = UiPlugin.getDefault().getString(I18N_PREFIX, "pageTitle"); //$NON-NLS-1$ private static final String UNDEFINED = UiPlugin.getDefault().getString(I18N_PREFIX, "undefined"); //$NON-NLS-1$ private static final int COLUMN_COUNT = 3; private WizardPage wizardPage; private Text mvModelText, mvLocationText; private Button btnBrowse; IStructuredSelection initialSelection; Object mvTableLocation; private MaterializationModelGenerator generator; /** * @since 4.0 */ public CreateMaterializedViewWizard() { super(UiPlugin.getDefault(), TITLE, null); } /** * @see org.eclipse.jface.wizard.IWizard#performFinish() * @since 4.0 */ @Override public boolean finish() { final IRunnableWithProgress op = new IRunnableWithProgress() { @Override @SuppressWarnings("unchecked") public void run( final IProgressMonitor monitor ) throws InvocationTargetException { try { runAsJob(); } catch (final Exception err) { throw new InvocationTargetException(err); } finally { monitor.done(); } } }; try { new ProgressMonitorDialog(getShell()).run(false, true, op); return true; } catch (Throwable err) { if (err instanceof InvocationTargetException) { err = ((InvocationTargetException)err).getTargetException(); } Util.log(err); WidgetUtil.showError(UiPlugin.getDefault().getString(I18N_PREFIX, "errorCreatingMaterializedViews")); //$NON-NLS-1$ return false; } } /** * @see org.eclipse.ui.IWorkbenchWizard#init(org.eclipse.ui.IWorkbench, org.eclipse.jface.viewers.IStructuredSelection) * @since 4.0 */ @Override public void init( final IWorkbench workbench, final IStructuredSelection selection ) { if (isAllVirtualTablesSelected(selection)) { initialSelection = new StructuredSelection(selection.toArray()); } this.wizardPage = new WizardPage(CreateMaterializedViewWizard.class.getSimpleName(), PAGE_TITLE, null) { @Override public void createControl( final Composite parent ) { setControl(createPageControl(parent)); } }; this.wizardPage.setPageComplete(false); this.wizardPage.setMessage(UiPlugin.getDefault().getString(I18N_PREFIX, "initialMessage")); //$NON-NLS-1$ addPage(wizardPage); this.generator = new MaterializationModelGenerator(); this.generator.setVirtualTables(initialSelection.toList()); validatePage(); } /** * @see org.eclipse.jface.wizard.IWizard#canFinish() * @since 4.0 */ @Override public boolean canFinish() { // defect 16154 -- Finish can be enabled even if errors on page. // check the page's isComplete status (in super) -- just follow its advice. return super.canFinish(); } Composite createEmptyPageControl( final Composite parent ) { return new Composite(parent, SWT.NONE); } /** * @param parent * @return composite the page * @since 4.0 */ @SuppressWarnings("unchecked") Composite createPageControl( final Composite parent ) { // Create page final Composite pg = new Composite(parent, SWT.NONE); pg.setLayout(new GridLayout(COLUMN_COUNT, false)); // Add widgets to page WidgetFactory.createLabel(pg, UiPlugin.getDefault().getString(I18N_PREFIX, "modelLabel")); //$NON-NLS-1$ this.mvModelText = WidgetFactory.createTextField(pg, GridData.FILL_HORIZONTAL, 1, UNDEFINED, SWT.READ_ONLY); btnBrowse = WidgetFactory.createButton(pg, BROWSE_BUTTON); btnBrowse.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( final SelectionEvent event ) { browseForModelSelected(); } }); WidgetFactory.createLabel(pg, UiPlugin.getDefault().getString(I18N_PREFIX, "targetLocationLabel")); //$NON-NLS-1$ this.mvLocationText = WidgetFactory.createTextField(pg, GridData.HORIZONTAL_ALIGN_FILL, COLUMN_COUNT - 1); this.mvLocationText.setText(UNDEFINED); btnBrowse.setFocus(); if( isAllVirtualTablesSelected() ) { Group group = WidgetFactory.createGroup(pg, UiPlugin.getDefault().getString(I18N_PREFIX, "virtualTablesGroup"), //$NON-NLS-1$ GridData.FILL_BOTH, COLUMN_COUNT, COLUMN_COUNT); TableViewer viewer = new TableViewer(group); GridData gdv = new GridData(GridData.FILL_BOTH); //gdv.horizontalSpan = COLUMN_COUNT; viewer.getControl().setLayoutData(gdv); viewer.setContentProvider(new ListContentProvider()); viewer.setLabelProvider(new ModelExplorerLabelProvider()); List selectedModels = SelectionUtilities.getSelectedEObjects(initialSelection); viewer.setInput(selectedModels); } return pg; } private boolean isAllVirtualTablesSelected( final ISelection selection ) { boolean isValid = true; if (SelectionUtilities.isEmptySelection(selection) || !SelectionUtilities.isAllEObjects(selection)) isValid = false; if (isValid ) { final Collection objs = SelectionUtilities.getSelectedEObjects(selection); final Iterator selections = objs.iterator(); while (selections.hasNext() && isValid) { final EObject next = (EObject)selections.next(); if ( isRelationalVirtualTable(next) && TransformationHelper.isVirtualSqlTable(next) ) { isValid = true; } else isValid = false; // stop processing if no longer valid: if (!isValid) break; } // endwhile -- all selected } else isValid = false; return isValid; } private boolean isAllVirtualTablesSelected( ) { return isAllVirtualTablesSelected(this.initialSelection); } private boolean isRelationalVirtualTable( EObject eObject ) { // Do a quick object check if( TransformationHelper.isVirtualSqlTable(eObject)) { // make sure it's a virtual relational model final Resource resource = eObject.eResource(); if (resource != null ) { ModelResource mr = ModelUtilities.getModelResource(resource, true); return ModelIdentifier.isRelationalViewModel(mr); } } return false; } void browseForModelSelected() { Object result = null; RelationalModelSelectorDialog mwdDialog = new RelationalModelSelectorDialog( UiPlugin.getDefault().getCurrentWorkbenchWindow().getShell()); mwdDialog.setValidator(new RelationalTableLocationSelectionValidator()); mwdDialog.setAllowMultiple(false); mwdDialog.open(); if (mwdDialog.getReturnCode() == Window.OK) { Object[] oSelectedObjects = mwdDialog.getResult(); // add the selected location to this Relationship if (oSelectedObjects.length > 0) { result = oSelectedObjects[0]; } } this.generator.setTargetLocation(result); validatePage(); updateWidgetValues(); } private void updateWidgetValues() { this.mvModelText.setText(this.generator.getModelName()); this.mvLocationText.setText(this.generator.getLocationName()); } private void validatePage() { // For materialized views to be created we'll need // 1) Valid Relational model, so query user for existing or to create new // 2) Valid container within that model. Could be schema OR just the model // 3) Maybe other validation checks? Already a materialized view? IStatus currentStatus = this.generator.getExecuteStatus(); if( currentStatus.isOK() ) { this.wizardPage.setErrorMessage(null); this.wizardPage.setMessage(currentStatus.getMessage()); this.wizardPage.setPageComplete(true); } else if( currentStatus.getSeverity() == IStatus.WARNING){ this.wizardPage.setMessage("WARNING: " + currentStatus.getMessage()); //$NON-NLS-1$ this.wizardPage.setPageComplete(true); } else { this.wizardPage.setErrorMessage(currentStatus.getMessage()); this.wizardPage.setPageComplete(false); } } private boolean runAsJob() { final String message = UiPlugin.getDefault().getString(I18N_PREFIX, "progressMonitorTitle"); //$NON-NLS-1$ final Job job = new Job(message) { @Override protected IStatus run( IProgressMonitor monitor ) { try { monitor.beginTask(message, generator.getVirtualTables().size()); if (!monitor.isCanceled()) { execute(monitor); } monitor.done(); if (monitor.isCanceled()) { return Status.CANCEL_STATUS; } return new Status(IStatus.OK, UiConstants.PLUGIN_ID, IStatus.OK, AbstractObjectProcessor.FINISHED, null); } catch (Exception e) { UiConstants.Util.log(e); return new Status(IStatus.ERROR, UiConstants.PLUGIN_ID, IStatus.ERROR, UiPlugin.getDefault().getString(I18N_PREFIX, "errorCreatingMaterializedViews"), e); //$NON-NLS-1$ } finally { } } }; job.setSystem(false); job.setUser(true); job.setProperty(IProgressConstants.KEEP_PROPERTY, Boolean.TRUE); // start as soon as possible job.schedule(); return true; } private boolean execute(IProgressMonitor monitor ) { boolean requiredStart = ModelerCore.startTxn(false, false, "Create Materialized View Model", this); //$NON-NLS-1$ boolean succeeded = false; try { generator.execute(); succeeded = true; } catch (Exception ex) { UiConstants.Util.log(IStatus.ERROR, ex, UiPlugin.getDefault().getString(I18N_PREFIX, "errorCreatingMaterializedViews")); //$NON-NLS-1$ } finally { // if we started the txn, commit it. if (requiredStart) { if (succeeded && !monitor.isCanceled()) { ModelerCore.commitTxn(); } else { ModelerCore.rollbackTxn(); } } } if (succeeded) { ModelEditorManager.activate(this.generator.getMaterializedViewModel(), true); } return succeeded; } }