| /******************************************************************************* |
| * Copyright (c) 2013 THALES GLOBAL SERVICES and Others |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Obeo - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.emf.ecoretools.design.ui.wizard; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.LinkedHashSet; |
| import java.util.Set; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.emf.codegen.ecore.genmodel.provider.GenModelEditPlugin; |
| import org.eclipse.emf.common.util.BasicDiagnostic; |
| import org.eclipse.emf.common.util.Diagnostic; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EPackage; |
| import org.eclipse.emf.ecore.EcoreFactory; |
| import org.eclipse.emf.ecore.EcorePackage; |
| import org.eclipse.emf.ecore.util.EcoreValidator; |
| import org.eclipse.emf.ecoretools.design.service.EcoreToolsDesignPlugin; |
| import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.sirius.business.api.helper.SiriusUtil; |
| import org.eclipse.sirius.business.api.modelingproject.ModelingProject; |
| import org.eclipse.sirius.business.api.query.DViewQuery; |
| import org.eclipse.sirius.business.api.session.Session; |
| import org.eclipse.sirius.common.tools.api.util.ReflectionHelper; |
| import org.eclipse.sirius.common.tools.api.util.StringUtil; |
| import org.eclipse.sirius.common.ui.tools.api.util.EclipseUIUtil; |
| import org.eclipse.sirius.ext.base.Option; |
| import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager; |
| import org.eclipse.sirius.ui.tools.api.wizards.page.ViewpointsSelectionWizardPage; |
| import org.eclipse.sirius.viewpoint.DRepresentation; |
| import org.eclipse.sirius.viewpoint.DView; |
| import org.eclipse.sirius.viewpoint.description.Viewpoint; |
| import org.eclipse.sirius.viewpoint.provider.SiriusEditPlugin; |
| 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.Button; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.IWorkbench; |
| import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; |
| import org.eclipse.ui.part.ISetSelectionTarget; |
| import org.eclipse.ui.plugin.AbstractUIPlugin; |
| import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; |
| import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard; |
| |
| import com.google.common.collect.Lists; |
| import com.google.common.collect.Sets; |
| |
| /** |
| * Wizard to create an EMF project with the {@link ModelingProject} nature, an |
| * Ecore model and its associated genmodel and an aird file. |
| * |
| * @author mporhel |
| */ |
| public class EcoreModelerWizard extends BasicNewProjectResourceWizard { |
| |
| /** The name of the Design viewpoint. */ |
| private static final String DESIGN_VIEWPOINT_NAME = "Design"; //$NON-NLS-1$ |
| |
| private EcoreModelSpecPage modelPage; |
| |
| private ViewpointsSelectionWizardPage viewpointsSelectionWizardPage; |
| |
| private WizardNewProjectCreationPage wizardNewProjectCreationPage; |
| |
| protected IWorkbench workbench; |
| |
| protected IPath genModelProjectLocation; |
| |
| protected IPath genModelContainerPath; |
| |
| protected String initialProjectName; |
| |
| protected IStructuredSelection selection; |
| |
| private IProject createdProject; |
| |
| /** |
| * Constructor. |
| */ |
| public EcoreModelerWizard() { |
| super(); |
| } |
| |
| @Override |
| public void init(IWorkbench workbench, IStructuredSelection selection) { |
| super.init(workbench, selection); |
| this.workbench = workbench; |
| this.selection = selection; |
| setDefaultPageImageDescriptor(ExtendedImageRegistry.INSTANCE.getImageDescriptor(GenModelEditPlugin.INSTANCE.getImage("full/wizban/NewEmptyEMFProject"))); |
| setWindowTitle(GenModelEditPlugin.INSTANCE.getString("_UI_NewEmptyProject_title")); |
| setWindowTitle("New Ecore Modeling Project"); //$NON-NLS-1$ |
| setDefaultPageImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(EcoreToolsDesignPlugin.PLUGIN_ID, "icons/full/wizban/EcoreModelingProject_wizban.png")); |
| setNeedsProgressMonitor(true); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| @Override |
| public void addPages() { |
| wizardNewProjectCreationPage = new WizardNewProjectCreationPage(SiriusEditPlugin.getPlugin().getString("_UI_ModelingProjectWizard_label")) { |
| |
| @Override |
| public void createControl(Composite parent) { |
| super.createControl(parent); |
| |
| Composite control = (Composite) getControl(); |
| GridLayout layout = new GridLayout(); |
| control.setLayout(layout); |
| |
| createWorkingSetGroup(control, new StructuredSelection(), new String[] { "org.eclipse.jdt.ui.JavaWorkingSetPage", //$NON-NLS-1$ |
| "org.eclipse.pde.ui.pluginWorkingSet", "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| Dialog.applyDialogFont(control); |
| } |
| |
| @Override |
| protected boolean validatePage() { |
| if (super.validatePage()) { |
| IPath locationPath = getLocationPath(); |
| genModelProjectLocation = Platform.getLocation().equals(locationPath) ? null : locationPath; |
| IPath projectPath = getProjectHandle().getFullPath(); |
| genModelContainerPath = projectPath.append("src"); //$NON-NLS-1$ |
| |
| updateModelPagePackageName(getProjectName()); |
| return true; |
| } else { |
| return false; |
| } |
| } |
| |
| private void updateModelPagePackageName(String projectName) { |
| if (!StringUtil.isEmpty(projectName)) { |
| String packageName = getPackageName(projectName); |
| if (!StringUtil.isEmpty(packageName)) { |
| modelPage.setPackageNameSilently(packageName); |
| } |
| } |
| } |
| |
| }; |
| |
| wizardNewProjectCreationPage.setInitialProjectName(initialProjectName); |
| wizardNewProjectCreationPage.setTitle("Create a new Ecore Modeling project"); //$NON-NLS-1$ |
| wizardNewProjectCreationPage.setDescription("Enter a project name"); //$NON-NLS-1$ |
| |
| modelPage = new EcoreModelSpecPage("Ecore model parameters"); //$NON-NLS-1$ |
| modelPage.setTitle("Model settings"); //$NON-NLS-1$ |
| modelPage.setDescription("Define the model settings"); //$NON-NLS-1$ |
| |
| viewpointsSelectionWizardPage = new ViewpointsSelectionWizardPage(null, Lists.newArrayList(DESIGN_VIEWPOINT_NAME)) { |
| @Override |
| protected Collection<String> computeSemanticFileExtensions(Session session) { |
| Set<String> fileExtensions = new HashSet<String>(); |
| fileExtensions.add("ecore"); |
| return fileExtensions; |
| } |
| }; |
| |
| // Fix for VP-3711 to avoid a NPE on 3.8 |
| ReflectionHelper.setFieldValueWithoutException(this, "newProjectCreationPage", wizardNewProjectCreationPage); |
| |
| addPage(wizardNewProjectCreationPage); |
| addPage(modelPage); |
| addPage(viewpointsSelectionWizardPage); |
| } |
| |
| /** |
| * {@inheritDoc} |
| * |
| * @see org.eclipse.jface.wizard.Wizard#performFinish() |
| */ |
| @Override |
| public boolean performFinish() { |
| boolean finished = true; |
| |
| updatePerspective(); |
| final EcoreModelingProjectCreationOperation ecoreModelingProjectCreationOperation = new EcoreModelingProjectCreationOperation(modelPage.getEPackage(), modelPage.getEcoreFileName(), |
| modelPage.getGenModelFileName(), modelPage.getRepresentationFileName(), new LinkedHashSet<Viewpoint>(viewpointsSelectionWizardPage.getViewpoints()), workbench, genModelContainerPath, |
| genModelProjectLocation, wizardNewProjectCreationPage.getSelectedWorkingSets()); |
| try { |
| getContainer().run(true, false, ecoreModelingProjectCreationOperation); |
| } catch (InvocationTargetException e) { |
| IStatus status = new Status(IStatus.ERROR, EcoreToolsDesignPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e); |
| EcoreToolsDesignPlugin.INSTANCE.log(status); |
| finished = false; |
| } catch (InterruptedException e) { |
| IStatus status = new Status(IStatus.ERROR, EcoreToolsDesignPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e); |
| EcoreToolsDesignPlugin.INSTANCE.log(status); |
| finished = false; |
| } |
| try { |
| getContainer().run(false, false, new IRunnableWithProgress() { |
| |
| public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| try { |
| monitor.beginTask("Open the diagram metamodel", 2); |
| |
| IFile ecoreModel = ecoreModelingProjectCreationOperation.getEcoreModel(); |
| createdProject = ecoreModelingProjectCreationOperation.getNewProject(); |
| if (ecoreModel != null && ecoreModel.exists()) { |
| selectAndReveal(ecoreModel); |
| } else { |
| selectAndReveal(ecoreModelingProjectCreationOperation.getNewProject()); |
| } |
| monitor.worked(1); |
| |
| // Open the entities diagram, of the root of the |
| // ecore |
| // file, |
| // that is automatically created (because the |
| // Entities |
| // diagram has |
| // the "initialization" to true). |
| // This can fail if the user deselects the "Design" |
| // viewpoint in the second page of the wizard. |
| openFirstRepresentation(ecoreModelingProjectCreationOperation.getNewProject(), new SubProgressMonitor(monitor, 1)); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }); |
| } catch (InvocationTargetException e) { |
| IStatus status = new Status(IStatus.ERROR, EcoreToolsDesignPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e); |
| EcoreToolsDesignPlugin.INSTANCE.log(status); |
| finished = false; |
| } catch (InterruptedException e) { |
| IStatus status = new Status(IStatus.ERROR, EcoreToolsDesignPlugin.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e); |
| EcoreToolsDesignPlugin.INSTANCE.log(status); |
| finished = false; |
| } |
| return finished; |
| } |
| |
| @Override |
| public IProject getNewProject() { |
| return createdProject; |
| } |
| |
| /** |
| * Selects and reveals the newly added resource in all parts of the active |
| * workbench window's active page. |
| * |
| * @see ISetSelectionTarget |
| */ |
| protected void selectAndReveal(IResource newResource) { |
| BasicNewResourceWizard.selectAndReveal(newResource, workbench.getActiveWorkbenchWindow()); |
| EclipseUIUtil.expand(newResource, workbench.getActiveWorkbenchWindow()); |
| } |
| |
| /** |
| * Open the first representation containing in the representation file of |
| * this Modeling project. |
| * |
| * @param project |
| * The modeling project containing the representations file. |
| * @param monitor |
| * a {@link IProgressMonitor} to show progression of first |
| * {@link DRepresentation} opening |
| */ |
| private void openFirstRepresentation(IProject project, IProgressMonitor monitor) { |
| Option<ModelingProject> opionalModelingProject = ModelingProject.asModelingProject(project); |
| if (opionalModelingProject.some()) { |
| Session session = opionalModelingProject.get().getSession(); |
| if (session != null) { |
| if (!session.getSelectedViews().isEmpty()) { |
| Set<DRepresentation> representationsToOpen = Sets.newLinkedHashSet(); |
| for (DView view : session.getSelectedViews()) { |
| for (DRepresentation dRepresentation : new DViewQuery(view).getLoadedRepresentations()) { |
| representationsToOpen.add(dRepresentation); |
| } |
| } |
| for (DRepresentation dRepresentation : representationsToOpen) { |
| DialectUIManager.INSTANCE.openEditor(session, dRepresentation, monitor); |
| } |
| } |
| } |
| } |
| } |
| |
| public void setInitialProjectName(String value) { |
| initialProjectName = value; |
| } |
| |
| private String getPackageName(String projectName) { |
| String packageName = projectName.substring(0, 1).toLowerCase() + projectName.substring(1); |
| int index = packageName.lastIndexOf('.'); |
| if (index != -1) { |
| packageName = packageName.substring(index + 1); |
| } |
| return packageName; |
| } |
| |
| private class EcoreModelSpecPage extends WizardPage { |
| |
| private static final String NAMESPACE_GROUP_LABEL = "Namespace properties";//$NON-NLS-1$ |
| |
| private static final String NS_PREFIX_FIELD_LABEL = "Ns Prefix"; //$NON-NLS-1$ |
| |
| private static final String NS_URI_FIELD_LABEL = "Ns Uri"; //$NON-NLS-1$ |
| |
| private static final String USE_DEFAULT_LABEL = "Use default namespace parameters"; //$NON-NLS-1$ |
| |
| private static final String PACKAGE_FIELD_LABEL = "Main package name"; //$NON-NLS-1$ |
| |
| private static final String DEFAULT_URI_BASE = "http://www.example.org/"; //$NON-NLS-1$ |
| |
| private static final String DEFAULT_COMMON_FILE_NAME = "model"; //$NON-NLS-1$ |
| |
| // widgets |
| private Text packageNameField; |
| |
| private Text nsPrefixField; |
| |
| private Text nsUriField; |
| |
| private Button useDefaultsButton; |
| |
| private EPackage ePackage; |
| |
| private boolean silentModificationEnabled = true; |
| |
| private final ModifyListener nsModifyListener = new ModifyListener() { |
| |
| public void modifyText(ModifyEvent e) { |
| if (!(useDefaultsButton != null && useDefaultsButton.getSelection())) { |
| setPageComplete(validatePage()); |
| } |
| } |
| }; |
| |
| public EcoreModelSpecPage(String name) { |
| super(name); |
| } |
| |
| /** |
| * Allow an other page to set the package name until the user manualy |
| * modify it. |
| * |
| * @param packageName |
| * the package name to set. |
| */ |
| public void setPackageNameSilently(String packageName) { |
| if (packageNameField != null && silentModificationEnabled) { |
| packageNameField.setText(packageName); |
| } |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void createControl(Composite parent) { |
| Composite composite = new Composite(parent, SWT.NULL); |
| composite.setLayout(new GridLayout()); |
| composite.setLayoutData(new GridData(GridData.FILL_BOTH)); |
| |
| createModelGroup(composite); |
| createNamespaceGroup(composite, false); |
| |
| setPageComplete(validatePage()); |
| |
| setControl(composite); |
| Dialog.applyDialogFont(composite); |
| } |
| |
| private void createModelGroup(Composite parent) { |
| packageNameField = createLabelAndText(parent, PACKAGE_FIELD_LABEL, getPackageName()); |
| packageNameField.addModifyListener(new ModifyListener() { |
| |
| public void modifyText(ModifyEvent e) { |
| if (packageNameField.isVisible()) { |
| silentModificationEnabled = false; |
| } |
| updateNamespaceValues(); |
| setPageComplete(validatePage()); |
| } |
| }); |
| |
| } |
| |
| private void createNamespaceGroup(Composite composite, boolean custom) { |
| Group nsGroup = new Group(composite, SWT.NONE); |
| nsGroup.setFont(composite.getFont()); |
| nsGroup.setText(NAMESPACE_GROUP_LABEL); |
| nsGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); |
| nsGroup.setLayout(new GridLayout(1, false)); |
| |
| useDefaultsButton = new Button(nsGroup, SWT.CHECK | SWT.RIGHT); |
| useDefaultsButton.setText(USE_DEFAULT_LABEL); |
| |
| GridData buttonData = new GridData(); |
| buttonData.horizontalSpan = 4; |
| useDefaultsButton.setLayoutData(buttonData); |
| useDefaultsButton.setSelection(!custom); |
| |
| nsUriField = createLabelAndText(nsGroup, NS_URI_FIELD_LABEL, getNsUri()); |
| nsPrefixField = createLabelAndText(nsGroup, NS_PREFIX_FIELD_LABEL, getNsPRefix()); |
| |
| nsUriField.addModifyListener(nsModifyListener); |
| nsPrefixField.addModifyListener(nsModifyListener); |
| setNameSpaceGroupActivation(custom); |
| |
| useDefaultsButton.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| boolean useDefault = useDefaultsButton.getSelection(); |
| if (useDefault) { |
| updateNamespaceValues(); |
| } |
| setNameSpaceGroupActivation(!useDefault); |
| setPageComplete(validatePage()); |
| } |
| }); |
| } |
| |
| private void setNameSpaceGroupActivation(boolean enabled) { |
| if (nsUriField != null) { |
| nsUriField.setEnabled(enabled); |
| } |
| |
| if (nsPrefixField != null) { |
| nsPrefixField.setEnabled(enabled); |
| } |
| } |
| |
| private void updateNamespaceValues() { |
| if (useDefaultsButton != null && useDefaultsButton.getSelection()) { |
| String packageName = getPackageName(); |
| if (nsPrefixField != null) { |
| nsPrefixField.setText(packageName); |
| } |
| |
| if (nsUriField != null) { |
| nsUriField.setText(getDefaultNsUri(packageName)); |
| } |
| } |
| } |
| |
| private Text createLabelAndText(Composite parent, String label, String initialValue) { |
| Composite group = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| group.setLayout(layout); |
| group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| // label |
| Label labelField = new Label(group, SWT.NONE); |
| labelField.setText(label); |
| labelField.setFont(parent.getFont()); |
| |
| // text |
| Text textField = new Text(group, SWT.BORDER); |
| GridData data = new GridData(GridData.FILL_HORIZONTAL); |
| data.widthHint = 250; |
| textField.setLayoutData(data); |
| textField.setFont(parent.getFont()); |
| if (initialValue != null) { |
| textField.setText(initialValue); |
| } |
| return textField; |
| } |
| |
| public EPackage getEPackage() { |
| if (ePackage == null) { |
| initEPackage(); |
| } |
| return ePackage; |
| } |
| |
| private void initEPackage() { |
| EClass eClass = (EClass) EcorePackage.eINSTANCE.getEClassifier("EPackage"); |
| EObject rootObject = EcoreFactory.eINSTANCE.create(eClass); |
| |
| if (rootObject instanceof EPackage) { |
| ePackage = (EPackage) rootObject; |
| updateEPackage(ePackage); |
| } |
| } |
| |
| private void updateEPackage(EPackage p) { |
| p.setName(getPackageName()); |
| p.setNsPrefix(getNsPRefix()); |
| p.setNsURI(getNsUri()); |
| } |
| |
| /** |
| * Returns whether this page's controls currently all contain valid |
| * values. |
| * |
| * @return <code>true</code> if all controls are valid, and |
| * <code>false</code> if at least one is invalid |
| */ |
| protected boolean validatePage() { |
| if (ePackage == null) { |
| initEPackage(); |
| } else { |
| updateEPackage(ePackage); |
| } |
| |
| EcoreValidator validator = new EcoreValidator(); |
| BasicDiagnostic diagnostic = new BasicDiagnostic(); |
| boolean validName = validator.validateENamedElement_WellFormedName(ePackage, diagnostic, null); |
| boolean validNsUri = validator.validateEPackage_WellFormedNsURI(ePackage, diagnostic, null); |
| boolean validNsPrefix = validator.validateEPackage_WellFormedNsPrefix(ePackage, diagnostic, null); |
| |
| boolean validEPackage = validName && validNsUri && validNsPrefix; |
| if (validEPackage) { |
| setErrorMessage(null); |
| } else { |
| StringBuilder sb = new StringBuilder(); |
| buildCompoundMessage(sb, diagnostic); |
| setErrorMessage(sb.toString()); |
| } |
| return validEPackage; |
| } |
| |
| private void buildCompoundMessage(StringBuilder sb, Diagnostic diagnostic) { |
| if (!StringUtil.isEmpty(diagnostic.getMessage()) && diagnostic.getSeverity() != Diagnostic.OK) { |
| sb.append(diagnostic.getMessage()); |
| sb.append("\n"); |
| } |
| |
| for (Diagnostic child : diagnostic.getChildren()) { |
| buildCompoundMessage(sb, child); |
| } |
| } |
| |
| private String getPackageName() { |
| if (packageNameField == null) { |
| return DEFAULT_COMMON_FILE_NAME; |
| } |
| |
| return packageNameField.getText().trim(); |
| } |
| |
| private String getNsUri() { |
| if (nsUriField == null) { |
| return getDefaultNsUri(getPackageName()); |
| } |
| |
| return nsUriField.getText().trim(); |
| } |
| |
| private String getDefaultNsUri(String packageName) { |
| return DEFAULT_URI_BASE + packageName; |
| } |
| |
| private String getNsPRefix() { |
| if (nsPrefixField == null) { |
| return getPackageName(); |
| } |
| |
| return nsPrefixField.getText().trim(); |
| } |
| |
| public String getRepresentationFileName() { |
| return getPackageName() + "." + SiriusUtil.SESSION_RESOURCE_EXTENSION; //$NON-NLS-1$ |
| } |
| |
| public String getEcoreFileName() { |
| return getPackageName() + ".ecore"; //$NON-NLS-1$ |
| } |
| |
| public String getGenModelFileName() { |
| return getPackageName() + ".genmodel"; //$NON-NLS-1$ |
| } |
| } |
| } |