package org.teiid.designer.teiidimporter.ui.wizard; import java.util.Collection; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.osgi.util.NLS; 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.graphics.Font; 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.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Text; import org.teiid.core.designer.util.CoreStringUtil; import org.teiid.core.designer.util.StringConstants; import org.teiid.core.designer.util.StringUtilities; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.workspace.DotProjectUtils; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelUtil; import org.teiid.designer.metamodels.relational.RelationalPackage; import org.teiid.designer.runtime.DqpPlugin; import org.teiid.designer.runtime.PreferenceConstants; import org.teiid.designer.teiidimporter.ui.Messages; import org.teiid.designer.teiidimporter.ui.UiConstants; import org.teiid.designer.ui.common.product.ProductCustomizerMgr; import org.teiid.designer.ui.common.text.StyledTextEditor; import org.teiid.designer.ui.common.util.WidgetFactory; import org.teiid.designer.ui.common.util.WidgetUtil; import org.teiid.designer.ui.common.util.WizardUtil; import org.teiid.designer.ui.common.widget.DefaultScrolledComposite; import org.teiid.designer.ui.common.wizard.AbstractWizardPage; import org.teiid.designer.ui.viewsupport.ModelIdentifier; import org.teiid.designer.ui.viewsupport.ModelNameUtil; import org.teiid.designer.ui.viewsupport.ModelProjectSelectionStatusValidator; import org.teiid.designer.ui.viewsupport.ModelWorkspaceViewerFilter; import org.teiid.designer.ui.viewsupport.ModelingResourceFilter; /** * SelectTargetPage * TeiidImportWizard page - for selection of the target model * * @since 8.5 */ public class SelectTargetPage extends AbstractWizardPage implements UiConstants { private static final String UNKNOWN = "Unknown"; //$NON-NLS-1$ private TeiidImportManager importManager; private Text targetModelContainerText; private Text targetModelFileText; private Text targetModelInfoText; private Text timeoutText; private Button filterRedundantUCsCB; private Button createConnProfileCB; private StyledTextEditor vdbTextEditor; /** * SelectedTranslatorAndTargetPage Constructor * @param importManager the TeiidImportManager for the wizard */ public SelectTargetPage( TeiidImportManager importManager ) { super(SelectTargetPage.class.getSimpleName(), Messages.SelectTargetPage_title); this.importManager = importManager; } @Override public void createControl( Composite theParent ) { final Composite basePanel = new Composite(theParent, SWT.NONE); basePanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); basePanel.setLayout(new GridLayout(1, false)); // Create page DefaultScrolledComposite scrolledComposite = new DefaultScrolledComposite(basePanel, SWT.H_SCROLL | SWT.V_SCROLL); scrolledComposite.setExpandHorizontal(true); scrolledComposite.setExpandVertical(true); GridLayoutFactory.fillDefaults().equalWidth(false).applyTo(scrolledComposite); GridDataFactory.fillDefaults().grab(true, false); final Composite pnl = scrolledComposite.getPanel(); pnl.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); pnl.setLayout(new GridLayout(1, false)); setControl(pnl); Label serverNameLabel = new Label(pnl,SWT.NONE); String serverString; try { serverString = importManager.getDisplayName(); } catch (Exception ex) { serverString = UNKNOWN; } serverNameLabel.setText(Messages.SelectTargetPage_defaultServerPrefix + StringConstants.SPACE + serverString); serverNameLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE)); Font bannerFont = JFaceResources.getBannerFont(); serverNameLabel.setFont(bannerFont); // TabFolder - one tab contains Target Model info, other tab contains VDB deployment info createTabPanel(pnl); scrolledComposite.sizeScrolledPanel(); setControl(basePanel); // Validate the page validatePage(); } /** * Create the tab panel containing the Target Model Definition tab and VDB Details tab * @param parent the parent composite */ private void createTabPanel(Composite parent) { final TabFolder tabFolder = new TabFolder(parent, SWT.TOP | SWT.BORDER | SWT.NO_SCROLL); GridDataFactory.fillDefaults().grab(true, true).applyTo(tabFolder); // The Target Model Definition tab Composite modelDefnPanel = createTargetModelDefnPanel(tabFolder); TabItem modelDefinitionTab = new TabItem(tabFolder, SWT.NONE); modelDefinitionTab.setControl(modelDefnPanel); modelDefinitionTab.setText(Messages.SelectTargetPage_TgtModelDefnTab); // The VDB details tab Composite vdbDetailsPanel = createVdbDetailsPanel(tabFolder); TabItem vdbTab = new TabItem(tabFolder, SWT.NONE); vdbTab.setControl(vdbDetailsPanel); vdbTab.setText(Messages.SelectTargetPage_AdvancedTab); } private int getTimeoutPrefSecs() { return DqpPlugin.getInstance().getPreferences().getInt(PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC, PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC_DEFAULT); } private void setTimeoutPrefSecs(int timeoutSecs) { DqpPlugin.getInstance().getPreferences().putInt(PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC, timeoutSecs); } @Override public void setVisible( boolean visible ) { if (visible) { // Set source model location if( importManager.getTargetModelLocation() != null ) { this.targetModelContainerText.setText(this.importManager.getTargetModelLocation().makeRelative().toString()); } vdbTextEditor.setText(importManager.getDynamicVdbString()); timeoutText.setText(Integer.toString(getTimeoutPrefSecs())); validatePage(); getControl().setVisible(visible); } else { super.setVisible(visible); } } /* * Create Group for definition of the target relational model * @parent the parent Composite * @return the target model definition composite */ private Composite createTargetModelDefnPanel(Composite parent) { new Label(parent,SWT.NULL); // For spacing // ------------------------------------- // Create the Model Definition Group // ------------------------------------- Group modelDefnPanel = WidgetFactory.createGroup(parent, StringConstants.EMPTY_STRING, SWT.NONE, 1, 3); modelDefnPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); ((GridData)modelDefnPanel.getLayoutData()).widthHint = 400; // ----------------------- // Location controls // ----------------------- // Location Label Label locationLabel = new Label(modelDefnPanel, SWT.NULL); locationLabel.setText(Messages.SelectTargetPage_Location); // Location Text box targetModelContainerText = new Text(modelDefnPanel, SWT.BORDER | SWT.SINGLE); String targetContainerText = null; if( this.importManager.getTargetModelLocation() != null ) { targetContainerText = this.importManager.getTargetModelLocation().toOSString(); } if(targetContainerText!=null) targetModelContainerText.setText(targetContainerText); GridData gridData = new GridData(GridData.FILL_HORIZONTAL); targetModelContainerText.setLayoutData(gridData); targetModelContainerText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); targetModelContainerText.setEditable(false); // Browse button for Location Definition Button browseButton = new Button(modelDefnPanel, SWT.PUSH); gridData = new GridData(); browseButton.setLayoutData(gridData); browseButton.setText(Messages.SelectTargetPage_Browse); browseButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected( SelectionEvent e ) { handleTargetModelLocationBrowse(); } }); // ----------------------- // Model Name controls // ----------------------- // Name label Label fileLabel = new Label(modelDefnPanel, SWT.NULL); fileLabel.setText(Messages.SelectTargetPage_Name); // Name Text box targetModelFileText = new Text(modelDefnPanel, SWT.BORDER | SWT.SINGLE); gridData = new GridData(GridData.FILL_HORIZONTAL); targetModelFileText.setLayoutData(gridData); targetModelFileText.addModifyListener(new ModifyListener() { @Override public void modifyText( ModifyEvent e ) { handleTargetModelTextChanged(); } }); new Label(modelDefnPanel, SWT.NONE); // For spacing new Label(modelDefnPanel, SWT.NONE); // For spacing // Info area - shows model selection status Group infoGroup = WidgetFactory.createGroup(modelDefnPanel, Messages.SelectTargetPage_ModelStatus, SWT.NONE | SWT.BORDER_DASH,2); infoGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Text box for info message targetModelInfoText = new Text(infoGroup, SWT.WRAP | SWT.READ_ONLY); setTargetModelInfoText(); targetModelInfoText.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); targetModelInfoText.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE)); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.heightHint = 35; gd.horizontalSpan=3; targetModelInfoText.setLayoutData(gd); // CheckBox for FilterRedundantUniqueConstraints DDL Import property filterRedundantUCsCB = WidgetFactory.createCheckBox(modelDefnPanel, Messages.SelectTargetPage_FilterRedundantUCsCB_Label, SWT.NONE, 3); filterRedundantUCsCB.setToolTipText(Messages.SelectTargetPage_FilterRedundantUCsCB_ToolTip); filterRedundantUCsCB.setSelection(true); this.importManager.setDdlImportOptionFilterConstraints(true); // Toggling the checkbox toggles the import property filterRedundantUCsCB.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { importManager.setDdlImportOptionFilterConstraints(filterRedundantUCsCB.getSelection()); } }); // CheckBox for Connection Profile - defaults to checked createConnProfileCB = WidgetFactory.createCheckBox(modelDefnPanel, Messages.SelectTargetPage_CreateConnectionProfileCB_Label, SWT.NONE, 3); createConnProfileCB.setToolTipText(Messages.SelectTargetPage_CreateConnectionProfileCB_ToolTip); createConnProfileCB.setSelection(true); return modelDefnPanel; } /* * Create panel containing the import VDB details (content and deployment timeout) * @parent the parent Composite * @return the vdb details composite */ private Composite createVdbDetailsPanel(Composite parent) { // Overall panel containing VDB Details final Composite vdbPanel = new Composite(parent, SWT.NONE); vdbPanel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); vdbPanel.setLayout(new GridLayout(2, false)); // VDB Deployment timeout preference Label timeoutLabel = new Label(vdbPanel,SWT.NULL); timeoutLabel.setText(Messages.SelectTargetPage_TimeoutLabelText); timeoutText = new Text(vdbPanel,SWT.BORDER | SWT.SINGLE); GridDataFactory.fillDefaults().minSize(40,SWT.DEFAULT).applyTo(timeoutText); timeoutText.addModifyListener(new ModifyListener() { @Override public void modifyText( ModifyEvent e ) { validatePage(); } }); timeoutLabel.setToolTipText(Messages.SelectTargetPage_TimeoutTooltip); timeoutText.setToolTipText(Messages.SelectTargetPage_TimeoutTooltip); // Dynamic VDB content Group vdbContentGroup = WidgetFactory.createGroup(vdbPanel, Messages.SelectTargetPage_dynamic_vdb_text, SWT.NONE); GridData gd = new GridData(GridData.FILL_BOTH); gd.horizontalSpan = 2; vdbContentGroup.setLayoutData(gd); vdbContentGroup.setToolTipText(Messages.SelectTargetPage_dynamic_vdb_tooltip); Composite innerPanel = new Composite(vdbContentGroup, SWT.NONE); innerPanel.setLayout(new GridLayout()); GridData pgd = new GridData(GridData.FILL_BOTH); pgd.minimumWidth = 400; pgd.minimumHeight = 400; pgd.grabExcessVerticalSpace = true; pgd.grabExcessHorizontalSpace = true; innerPanel.setLayoutData(pgd); vdbTextEditor = new StyledTextEditor(innerPanel, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER); GridData gdt = new GridData(GridData.FILL_BOTH); gdt.widthHint = 400; gdt.heightHint = 400; vdbTextEditor.setLayoutData(gdt); vdbTextEditor.setEditable(false); vdbTextEditor.setAllowFind(false); vdbTextEditor.getTextWidget().setWordWrap(false); vdbTextEditor.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW)); vdbTextEditor.getTextWidget().setToolTipText(Messages.SelectTargetPage_dynamic_vdb_tooltip); return vdbPanel; } /** * Handler for choosing the Target Model Location */ void handleTargetModelLocationBrowse() { final IContainer folder = WidgetUtil.showFolderSelectionDialog(ModelerCore.getWorkspace().getRoot(), new ModelingResourceFilter(), new ModelProjectSelectionStatusValidator()); if( folder == null ) { return; // do nothing } if (targetModelContainerText != null) { this.importManager.setTargetModelLocation(folder.getFullPath().makeRelative()); this.targetModelContainerText.setText(this.importManager.getTargetModelLocation().makeRelative().toString()); } else { this.importManager.setTargetModelLocation(new Path(StringConstants.EMPTY_STRING)); this.targetModelContainerText.setText(StringConstants.EMPTY_STRING); } validatePage(); } // Handler for ModelText changes void handleTargetModelTextChanged() { String mdlText = this.targetModelFileText.getText(); if( !CoreStringUtil.isEmpty(mdlText) && !matchingModelOfWrongTypeExists(mdlText) ) { this.importManager.setTargetModelName(this.targetModelFileText.getText()); } validatePage(); } /** * Check if the supplied modelName already exists, but is a different type * @param modelName the proposed model Name * @return 'true' if model of different type exists, otherwise 'false' */ private boolean matchingModelOfWrongTypeExists(String modelName ) { IPath modelLocation = importManager.getTargetModelLocation(); if(modelLocation==null) return false; IWorkspaceRoot root = ModelerCore.getWorkspace().getRoot(); IResource containerResource = root.findMember(modelLocation); if(containerResource==null || !(containerResource instanceof IContainer) ) { return false; } IContainer container = (IContainer)containerResource; if(!container.exists()) return false; IPath modelPath = container.getFullPath().append(modelName); if (!modelName.endsWith(ModelerCore.MODEL_FILE_EXTENSION)) modelPath = modelPath.addFileExtension(ModelerCore.MODEL_FILE_EXTENSION.substring(1)); IResource modelResource = root.findMember(modelPath); if( modelResource==null || !ModelUtil.isModelFile(modelResource) ) { return false; } // See if model is non-relational if (!RelationalPackage.eNS_URI.equals(ModelUtil.getXmiHeader(modelResource).getPrimaryMetamodelURI())) { return true; } return false; } /* * Page Validation * @return 'true' if the page is valid, 'false' if not */ private boolean validatePage() { //--------------------------------------------------- // Timeout preference value - validation //--------------------------------------------------- boolean timeoutTextValid = validateTimeoutText(); if(!timeoutTextValid) return false; //--------------------------------------------------- // Target Model Section - validation //--------------------------------------------------- boolean modelSelectionValid = validateTargetModelSelection(); if(!modelSelectionValid) return false; setThisPageComplete(StringConstants.EMPTY_STRING, NONE); return true; } /* * This method validates the target model section of this page * @return 'true' if the target model section is valid, 'false' if not. */ private boolean validateTargetModelSelection() { // Sets info about the current model selection setTargetModelInfoText(); // Check for at least ONE open non-hidden Model Project Collection<IProject> openModelProjects = DotProjectUtils.getOpenModelProjects(); // No open projects if (openModelProjects.size() == 0) { setThisPageComplete(Messages.SelectTargetPage_NoOpenProjMsg, ERROR); return false; } // Check for a selected container String container = targetModelContainerText.getText(); if (CoreStringUtil.isEmpty(container)) { setThisPageComplete(Messages.SelectTargetPage_SrcLocationNotSpecified, ERROR); return false; } // Check for the target project IProject project = getTargetProject(); if (project == null) { setThisPageComplete(Messages.SelectTargetPage_SrcLocationNotSpecified, ERROR); return false; } // Validate the target model name String fileText = targetModelFileText.getText().trim(); if(StringUtilities.isEmpty(fileText)) { setThisPageComplete(Messages.SelectTargetPage_EnterModelNameMsg, ERROR); return false; } IStatus status = ModelNameUtil.validate(fileText, ModelerCore.MODEL_FILE_EXTENSION, null, ModelNameUtil.IGNORE_CASE ); if( status.getSeverity() == IStatus.ERROR ) { setThisPageComplete(ModelNameUtil.MESSAGES.INVALID_MODEL_NAME + status.getMessage(), ERROR); return false; } // Valid target model - now compare it's connection profile vs the selected profile if( importManager.targetModelExists() ) { setThisPageComplete(NLS.bind(Messages.SelectTargetPage_ModelExistsWithThisNameMsg, fileText), ERROR); return false; } return true; } /* * This method validates the timeout textbox. If valid, the preference is updated. * @return 'true' if the timeout textbox is valid, 'false' if not. */ private boolean validateTimeoutText() { // Make sure the timeout text entered is parsable String timeoutValue = timeoutText.getText(); try { // Check for empty value if(StringUtilities.isEmpty(timeoutValue)) { setThisPageComplete(Messages.SelectTargetPage_TimeoutEmptyMsg, ERROR); return false; } int timeoutInt = Integer.parseInt(timeoutValue.trim()); // Make sure the timeout is not less than min value if(timeoutInt < PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC_MIN) { setThisPageComplete(NLS.bind(Messages.SelectTargetPage_TimeoutLessThanMinAllowedMsg, timeoutValue, PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC_MIN), ERROR); return false; } // Make sure the timeout is not greater than max value if(timeoutInt > PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC_MAX) { setThisPageComplete(NLS.bind(Messages.SelectTargetPage_TimeoutGreaterThanMaxAllowedMsg, timeoutValue, PreferenceConstants.TEIID_IMPORTER_TIMEOUT_SEC_MAX), ERROR); return false; } // If valid, update the preference setTimeoutPrefSecs(timeoutInt); } catch (NumberFormatException ex) { setThisPageComplete(NLS.bind(Messages.SelectTargetPage_TimeoutTextNotParsableMsg, timeoutValue), ERROR); return false; } return true; } private void setThisPageComplete( String message, int severity) { WizardUtil.setPageComplete(this, message, severity); } /* * Get workspace target Project * @return the target project */ private IProject getTargetProject() { IProject result = null; String containerName = getTargetContainerName(); if (!CoreStringUtil.isEmpty(containerName)) { IWorkspaceRoot root = ModelerCore.getWorkspace().getRoot(); IResource resource = root.findMember(new Path(containerName)); if (resource.exists()) { result = resource.getProject(); } } return result; } /* * Get the Target Container name */ private String getTargetContainerName() { String result = null; if (ProductCustomizerMgr.getInstance().getProductCharacteristics().isHiddenProjectCentric()) { result = getHiddenProjectPath(); } else { result = targetModelContainerText.getText().trim(); } return result; } private String getHiddenProjectPath() { String result = null; IProject hiddenProj = ProductCustomizerMgr.getInstance().getProductCharacteristics().getHiddenProject(false); if (hiddenProj != null) { result = hiddenProj.getFullPath().makeRelative().toString(); } return result; } /* * Sets target model info section */ private void setTargetModelInfoText() { String targetModelName = this.targetModelFileText.getText(); if(targetModelName==null || targetModelName.trim().length()==0) { this.targetModelInfoText.setText(Messages.SelectTargetPage_SrcModelUndefined); } else { this.targetModelInfoText.setText(Messages.SelectTargetPage_SrcModelSelected+": "+targetModelName); //$NON-NLS-1$ } } /** * Gets the Create Connection Profile status * @return 'true' if the create checkbox is checked, 'false' if not. */ public boolean isCreateConnectionProfile() { boolean isChecked = false; if(this.createConnProfileCB != null) { isChecked = this.createConnProfileCB.getSelection(); } return isChecked; } /* * Filter for Model Selection */ final ViewerFilter sourceModelFilter = new ModelWorkspaceViewerFilter(true) { @Override public boolean select( final Viewer viewer, final Object parent, final Object element ) { boolean doSelect = false; if (element instanceof IResource) { // If the project is closed, dont show boolean projectOpen = ((IResource)element).getProject().isOpen(); if (projectOpen) { // Show open projects if (element instanceof IProject ) { try { doSelect = ((IProject)element).hasNature(ModelerCore.NATURE_ID); } catch (CoreException e) { UTIL.log(e); } } else if (element instanceof IContainer) { doSelect = true; // Show webservice model files, and not .xsd files } else if (element instanceof IFile && ModelUtil.isModelFile((IFile)element)) { ModelResource theModel = null; try { theModel = ModelUtil.getModelResource((IFile)element, true); } catch (Exception ex) { ModelerCore.Util.log(ex); } if (theModel != null && ModelIdentifier.isRelationalSourceModel(theModel)) { doSelect = true; } } } } else if (element instanceof IContainer) { doSelect = true; } return doSelect; } }; }