/* * 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.textimport; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; 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.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; 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.uml.UmlPackage; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.metamodels.core.ModelType; import org.teiid.designer.relational.ui.wizards.RelationalObjectProcessor; import org.teiid.designer.transformation.ui.UiConstants; import org.teiid.designer.ui.common.util.WidgetFactory; import org.teiid.designer.ui.common.util.WidgetUtil; import org.teiid.designer.ui.common.viewsupport.StatusInfo; import org.teiid.designer.ui.explorer.ModelExplorerContentProvider; import org.teiid.designer.ui.explorer.ModelExplorerLabelProvider; import org.teiid.designer.ui.viewsupport.ModelIdentifier; import org.teiid.designer.ui.viewsupport.ModelNameUtil; import org.teiid.designer.ui.viewsupport.ModelUtilities; import org.teiid.designer.ui.viewsupport.ModelWorkspaceDialog; /** * @since 8.0 */ public class VirtualModelSelectorDialog extends ModelWorkspaceDialog implements UiConstants { private Label lblVirtualModelName; private Text txtVirtualModelName; private IContainer newModelParent; private IPath targetVirtualFilePath; private ModelResource mrVirtualModel; private EObject selectedEObject; private SelectionAdapter saCreateCbxAdapter; private String sNewVirtualModelName; boolean createNewModel = false; private final static String FILE_EXT = ".xmi"; //$NON-NLS-1$ private final static int MODEL_NAME_TEXT_WIDTH = (int)(Display.getCurrent().getBounds().width * .25); private static final String I18N_PREFIX = "VirtualModelSelectorDialog"; //$NON-NLS-1$ private static final String SEPARATOR = "."; //$NON-NLS-1$ private static final String TITLE = getString("title"); //$NON-NLS-1$ private final static String MODEL_CREATE_ERROR_IS_VALID = getString("isValid.message"); //$NON-NLS-1$ private static String MODEL_CREATE_INSTRUCTION = getString("modelCreateInstruction.message"); //$NON-NLS-1$ private static String EXISTING_MODEL_FOLDER_SELECTED = getString("existingModelFolderLocationSelected.message"); //$NON-NLS-1$ private final static String VIRTUAL_LABEL = getString("virtualModelName.text"); //$NON-NLS-1$ private final static String SELECTED_MODEL_NOT_VIRTUAL_MODEL = getString("selModelNotVirtual.message"); //$NON-NLS-1$ private final static String SELECTED_RESOURCE_NOT_VIRTUAL_MODEL = getString("selResrcNotVirtual.message"); //$NON-NLS-1$ private static String getString( final String id ) { return Util.getString(I18N_PREFIX + SEPARATOR + id); } /** * Construct an instance of ModelWorkspaceDialog. This constructor defaults to the resource root. * * @param parent */ public VirtualModelSelectorDialog( Shell parent ) { this(parent, new ModelExplorerLabelProvider(), new ModelExplorerContentProvider()); } /** * Construct an instance of ModelWorkspaceDialog. This constructor defaults to the resource root. * * @param parent * @param labelProvider an ILabelProvider for the tree * @param contentProvider an ITreeContentProvider for the tree */ public VirtualModelSelectorDialog( Shell parent, ILabelProvider labelProvider, ITreeContentProvider contentProvider ) { super(parent, TITLE, labelProvider, contentProvider); } /* * @see Dialog#createDialogArea(Composite) */ @Override protected Control createDialogArea( Composite parent ) { Composite composite = (Composite)super.createDialogArea(parent); // add code here to include new virtual model panel: createModelCreationComposite(composite); return composite; } /** * Create the controls for creating a new virtual Model. * * @param parent the parent composite * @return the created composite */ private Composite createModelCreationComposite( Composite parent ) { // Set up Composite Composite nameComposite = new Composite(parent, SWT.NONE); GridLayout nameCompositeLayout = new GridLayout(); nameComposite.setLayout(nameCompositeLayout); nameCompositeLayout.numColumns = 3; nameCompositeLayout.marginWidth = 0; GridData nameCompositeGridData = new GridData(GridData.FILL_HORIZONTAL); nameCompositeGridData.horizontalIndent = 20; nameComposite.setLayoutData(nameCompositeGridData); // Enter Model name label - col 1 VIRTUAL_LABEL lblVirtualModelName = new Label(nameComposite, SWT.NONE); lblVirtualModelName.setText(VIRTUAL_LABEL); lblVirtualModelName.getAlignment(); // Model name entry field - col 2 txtVirtualModelName = WidgetFactory.createTextField(nameComposite, GridData.HORIZONTAL_ALIGN_FILL); GridData modelNameTextGridData = new GridData(); modelNameTextGridData.widthHint = MODEL_NAME_TEXT_WIDTH; txtVirtualModelName.setLayoutData(modelNameTextGridData); // listener for typing changes txtVirtualModelName.addModifyListener(new ModifyListener() { @Override public void modifyText( final ModifyEvent event ) { handleSetVirtualModelName(); } }); // This initializes the status label handleSetVirtualModelName(); setCreateControlsEnabled(false); return nameComposite; } /** * handler for Create Virtual Model Button pressed */ void createVirtualModel() { mrVirtualModel = constructVirtualModel(newModelParent, sNewVirtualModelName); // Save Virtual Model try { if (mrVirtualModel != null) { mrVirtualModel.save(null, false); } } catch (ModelWorkspaceException mwe) { Util.log(mwe); } } @Override public Object[] getResult() { // if they created a new relational model, return it if (mrVirtualModel != null) { return new Object[] {mrVirtualModel}; } else if (selectedEObject != null) { return new Object[] {selectedEObject}; } // if they selected an existing relational model, return it return super.getResult(); } private SelectionAdapter getOKSelectionListener() { // establish the selection adapter for the OK button if (saCreateCbxAdapter == null) { saCreateCbxAdapter = new SelectionAdapter() { @Override public void widgetSelected( final SelectionEvent event ) { if (createNewModel) { // create the new Virtual Model createVirtualModel(); } } }; } return saCreateCbxAdapter; } private void updateDialogMessage( String sMessage, boolean bIsError ) { int iStatusCode = IStatus.OK; if (bIsError) { iStatusCode = IStatus.ERROR; } IStatus status = new StatusInfo(PLUGIN_ID, iStatusCode, sMessage); updateStatus(status); } protected void registerControls() { // System.out.println("VirtualModelSelectorDialog.registerControls() adding as selection changed listener to tree viewer...."); getTreeViewer().addSelectionChangedListener(this); } @Override public void selectionChanged( SelectionChangedEvent event ) { super.selectionChanged(event); // set default: null the selected project var newModelParent = null; IStructuredSelection sel = (IStructuredSelection)getTreeViewer().getSelection(); Object oSelection = sel.getFirstElement(); // assume we are creating a new model createNewModel = true; // Selection is a Virtual Relational Model if (isVirtualModelResource(oSelection)) { // null the selected project var newModelParent = null; selectedEObject = null; createNewModel = false; String instruction = Util.getString("VirtualModelSelectorDialog.useExistingModelInstruction.message", //$NON-NLS-1$ ((IResource)oSelection).getName()); updateDialogMessage(instruction, false); setCreateControlsEnabled(false); enableOKButton(); // Selection is a Model, but not a Relational Model } else if (isModelResource(oSelection)) { newModelParent = null; selectedEObject = null; setCreateControlsEnabled(false); disableOKButton(); updateDialogMessage(SELECTED_MODEL_NOT_VIRTUAL_MODEL, true); // Selection is a Container } else if (isContainer(oSelection)) { // capture the selected project newModelParent = (IContainer)oSelection; selectedEObject = null; setCreateControlsEnabled(true); // this will validate the model name handleSetVirtualModelName(); } else if (isPackageInVirtualModel(oSelection)) { selectedEObject = (EObject)oSelection; newModelParent = null; createNewModel = false; setCreateControlsEnabled(false); enableOKButton(); updateDialogMessage(EXISTING_MODEL_FOLDER_SELECTED, false); // Resource, not a Relational Model } else if (oSelection instanceof IResource) { newModelParent = null; selectedEObject = null; setCreateControlsEnabled(false); disableOKButton(); updateDialogMessage(SELECTED_RESOURCE_NOT_VIRTUAL_MODEL, true); } } /** * handler when the virtual Model name field changes. This updates the status label under the modelName entry field */ void handleSetVirtualModelName() { // get the text from the Text field String nameText = txtVirtualModelName.getText(); // validate it if (isValidVirtualModelName(nameText)) { sNewVirtualModelName = nameText; enableOKButton(); String message = getVirtualModelNameStatus(nameText); updateDialogMessage(message, false); } else { disableOKButton(); // if the name has zero length, reapply the 'create' message if (nameText.trim().length() == 0) { if (newModelParent != null) { MODEL_CREATE_INSTRUCTION = Util.getString("VirtualModelSelectorDialog.modelCreateInstruction.message", //$NON-NLS-1$ newModelParent.getName()); updateDialogMessage(MODEL_CREATE_INSTRUCTION, true); } } else { // use the message from the character validation String message = getVirtualModelNameStatus(nameText); updateDialogMessage(message, true); } } } /** * Create a Virtual Model with the supplied name, in the desired project * * @param targetProj the project resource under which to create the model * @param modelName the model name to create * @return the newly-created ModelResource */ public ModelResource constructVirtualModel( IResource targetRes, String sModelName ) { String sFileName = getFileName(sModelName); IPath relativeModelPath = targetRes.getProjectRelativePath().append(sFileName); final IFile modelFile = targetRes.getProject().getFile(relativeModelPath); final ModelResource resrc = ModelerCore.create(modelFile); try { resrc.getModelAnnotation().setPrimaryMetamodelUri(RelationalObjectProcessor.RELATIONAL_PACKAGE_URI); resrc.getModelAnnotation().setModelType(ModelType.VIRTUAL_LITERAL); } catch (ModelWorkspaceException mwe) { mwe.printStackTrace(); } return resrc; } /** * get a string status indicator for the modelName status label, given the modelName * * @param modelName the model name to test * @return the status of the supplied model name */ private String getVirtualModelNameStatus( String sModelName ) { IStatus status = ModelNameUtil.validate(sModelName, ModelerCore.MODEL_FILE_EXTENSION, newModelParent, ModelNameUtil.IGNORE_CASE | ModelNameUtil.NO_DUPLICATE_MODEL_NAMES_OTHER_THAN_LOCATION | ModelNameUtil.NO_DUPLICATE_MODEL_NAMES); if( status.getSeverity() == IStatus.ERROR ) { return ModelNameUtil.MESSAGES.INVALID_MODEL_NAME + status.getMessage(); } // success return MODEL_CREATE_ERROR_IS_VALID; } /** * test whether the supplied modelName is valid * * @param modelName the model name to test * @return 'true' if the name is valid, 'false' if not. */ private boolean isValidVirtualModelName( String sModelName ) { IStatus status = ModelNameUtil.validate(sModelName, ModelerCore.MODEL_FILE_EXTENSION, newModelParent, ModelNameUtil.IGNORE_CASE | ModelNameUtil.NO_DUPLICATE_MODEL_NAMES_OTHER_THAN_LOCATION | ModelNameUtil.NO_DUPLICATE_MODEL_NAMES); if( status.getSeverity() == IStatus.ERROR ) { return false; } // success return true; } private void setCreateControlsEnabled( boolean b ) { txtVirtualModelName.setEnabled(b); lblVirtualModelName.setEnabled(b); } private void disableOKButton() { if (getOkButton() != null) { getOkButton().removeSelectionListener(getOKSelectionListener()); getOkButton().setEnabled(false); } } private void enableOKButton() { if (getOkButton() != null) { getOkButton().addSelectionListener(getOKSelectionListener()); getOkButton().setEnabled(true); } } private boolean isVirtualModelResource( Object oSelection ) { boolean bResult = false; if (oSelection instanceof IResource) { IResource resource = (IResource)oSelection; if (ModelUtilities.isModelFile(resource)) { ModelResource mr = null; try { mr = ModelUtil.getModelResource((IFile)resource, true); } catch (ModelWorkspaceException theException) { ModelerCore.Util.log(IStatus.ERROR, theException, theException.getMessage()); WidgetUtil.showError(theException); } if (ModelIdentifier.isVirtualModelType(mr)) { try { if (mr.getPrimaryMetamodelDescriptor() != null) { if (mr.getPrimaryMetamodelDescriptor().getNamespaceURI().equals(RelationalObjectProcessor.RELATIONAL_PACKAGE_URI)) { bResult = true; } } } catch (ModelWorkspaceException mwe) { ModelerCore.Util.log(IStatus.ERROR, mwe, mwe.getMessage()); WidgetUtil.showError(mwe); } } } } return bResult; } private boolean isModelResource( Object oSelection ) { boolean bResult = false; if (oSelection instanceof IResource) { try { IResource resource = (IResource)oSelection; if (ModelUtilities.isModelFile(resource)) { ModelResource mr = ModelUtil.getModelResource((IFile)resource, true); if (mr.getPrimaryMetamodelDescriptor() != null) { bResult = true; } } } catch (ModelWorkspaceException mwe) { ModelerCore.Util.log(IStatus.ERROR, mwe, mwe.getMessage()); } } return bResult; } private boolean isContainer( Object oSelection ) { return (oSelection instanceof IContainer || oSelection instanceof IFolder); } private boolean isPackageInVirtualModel( Object oSelection ) { if (oSelection instanceof EObject) { MetamodelAspect mmAspect = AspectManager.getUmlDiagramAspect((EObject)oSelection); if (mmAspect != null && mmAspect instanceof UmlPackage) return true; } return false; } /* (non-Javadoc) * @see org.eclipse.ui.dialogs.ElementTreeSelectionDialog#createTreeViewer(org.eclipse.swt.widgets.Composite) */ @Override protected TreeViewer createTreeViewer( Composite parent ) { TreeViewer result = super.createTreeViewer(parent); // add a filter to remove closed projects result.addFilter(new ViewerFilter() { @Override public boolean select( Viewer viewer, Object parentElement, Object element ) { boolean result = true; if (element instanceof IProject) { IProject project = (IProject)element; if (!project.isOpen()) { result = false; } else { try { if (!project.hasNature(ModelerCore.NATURE_ID)) { result = false; } else { String name = project.getName(); if (name != null && (org.teiid.designer.ui.PluginConstants.HIDDEN_PROJECTS.contains(name)) ) { return false; } } } catch (CoreException theException) { ModelerCore.Util.log(theException); result = false; } } } return result; } }); result.expandToLevel(2); return result; } /** * get the full file name, given a modelName string * * @param modelName the model name * @return the full model name, including extension */ private String getFileName( String sModelName ) { String sResult = sModelName.trim(); if (!sResult.endsWith(FILE_EXT)) { sResult += FILE_EXT; } return sResult; } @Override public boolean close() { getTreeViewer().removeSelectionChangedListener(this); return super.close(); } }