/******************************************************************************* * Copyright (c) 2008 Obeo, CEA LIST. * 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 * Tatiana Fesenko(CEA) - [313179] Refactor CreateModelWizard * Saadia Dhouib (CEA LIST) - Implementation of loading diagrams from template files (.uml, .di , .notation) *******************************************************************************/ package org.eclipse.papyrus.uml.diagram.wizards; import static org.eclipse.papyrus.uml.diagram.wizards.Activator.log; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.emf.common.command.CommandStack; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.transaction.RecordingCommand; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.Wizard; import org.eclipse.papyrus.infra.core.editor.BackboneException; import org.eclipse.papyrus.infra.core.extension.commands.ICreationCommand; import org.eclipse.papyrus.infra.core.extension.commands.IModelCreationCommand; import org.eclipse.papyrus.infra.core.utils.DiResourceSet; import org.eclipse.papyrus.infra.core.utils.EditorUtils; import org.eclipse.papyrus.uml.diagram.wizards.category.DiagramCategoryDescriptor; import org.eclipse.papyrus.uml.diagram.wizards.category.DiagramCategoryRegistry; import org.eclipse.papyrus.uml.diagram.wizards.category.NewPapyrusModelCommand; import org.eclipse.papyrus.uml.diagram.wizards.pages.NewModelFilePage; import org.eclipse.papyrus.uml.diagram.wizards.pages.SelectDiagramCategoryPage; import org.eclipse.papyrus.uml.diagram.wizards.pages.SelectDiagramKindPage; import org.eclipse.papyrus.uml.diagram.wizards.pages.SelectDiagramKindPage.CategoryProvider; import org.eclipse.papyrus.uml.diagram.wizards.template.InitFromTemplateCommand; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.ide.IDE; /** * Create new model file and initialize a selected diagram. This wizard create * several files : * <li>*.di : the DI file to store Di diagrams and references all * external diagrams like GMF diagrams.</li> * <li>*.notation : the file to store pure GMF * diagrams</li> * <li>*.uml : the standard UML file to store UML semantics elements. * (Model, Package, Class,...)</li> * * Those files can be used with the PapyrusEditor (see plugin.xml). */ public class CreateModelWizard extends Wizard implements INewWizard { /** The Constant WIZARD_ID. */ public static final String WIZARD_ID = "org.eclipse.papyrus.uml.diagram.wizards.createmodel"; //$NON-NLS-1$ /** The Constant NEW_MODEL_SETTINGS. */ public static final String NEW_MODEL_SETTINGS = "NewModelWizard"; //$NON-NLS-1$ /** New model file page for the file. */ private NewModelFilePage newModelFilePage; /** Select kind of new diagram the wizard must create. */ private SelectDiagramKindPage selectDiagramKindPage; /** The select diagram category page. */ private SelectDiagramCategoryPage selectDiagramCategoryPage; /** Current workbench. */ private IWorkbench workbench; /** * Instantiates a new creates the model wizard. */ public CreateModelWizard() { super(); setWindowTitle(Messages.CreateModelWizard_new_papyrus_model_title); } /** * Adds the pages. * * {@inheritDoc} */ @Override public void addPages() { addPageIfNotNull(newModelFilePage); addPageIfNotNull(selectDiagramCategoryPage); addPageIfNotNull(selectDiagramKindPage); } /** * Adds the page if not null. * * @param page the page */ protected final void addPageIfNotNull(IWizardPage page) { if(page != null) { addPage(page); } } /** * Inits the. * * @param workbench the workbench * @param selection the selection * {@inheritDoc} */ public void init(IWorkbench workbench, IStructuredSelection selection) { this.workbench = workbench; IDialogSettings workbenchSettings = Activator.getDefault().getDialogSettings(); IDialogSettings section = workbenchSettings.getSection(NEW_MODEL_SETTINGS); if(section == null) { section = workbenchSettings.addNewSection(NEW_MODEL_SETTINGS); } setDialogSettings(section); newModelFilePage = createNewModelFilePage(selection); selectDiagramCategoryPage = createSelectDiagramCategoryPage(); selectDiagramKindPage = createSelectDiagramKindPage(); } /** * Perform finish. * * @return true, if successful * {@inheritDoc} */ @Override public boolean performFinish() { DiResourceSet diResourceSet = new DiResourceSetExt(); String[] diagramCategoryIds = getDiagramCategoryIds(); if(diagramCategoryIds.length == 0) { return false; } String diagramCategoryId = diagramCategoryIds[0]; final IFile newFile = createNewModelFile(diagramCategoryId); createAndOpenPapyrusModel(diResourceSet, newFile, diagramCategoryId); saveDiagramCategorySettings(); saveDiagramKindSettings(); return true; } /** * Creates the and open papyrus model. * * @param diResourceSet the di resource set * @param newFile the new file * @param diagramCategoryId the diagram category id * @return true, if successful */ protected boolean createAndOpenPapyrusModel(DiResourceSet diResourceSet, IFile newFile, String diagramCategoryId) { if(newFile == null) { return false; } createPapyrusModels(diResourceSet, newFile); initDomainModel(diResourceSet, newFile, diagramCategoryId); initDiagramModel(diResourceSet, diagramCategoryId); openDiagram(newFile); return true; } /** * Gets the diagram category ids. * * @return the diagram category ids */ protected String[] getDiagramCategoryIds() { if(selectDiagramCategoryPage != null) { return selectDiagramCategoryPage.getDiagramCategories(); } return null; } /** * Gets the diagram file extension. * * @param diagramCategoryId the diagram category id * @return the diagram file extension */ protected String getDiagramFileExtension(String diagramCategoryId) { return getDiagramFileExtension(diagramCategoryId, NewModelFilePage.DEFAULT_DIAGRAM_EXTENSION); } /** * Gets the diagram file extension. * * @param categoryId the category id * @param defaultExtension the default extension * @return the diagram file extension */ protected String getDiagramFileExtension(String categoryId, String defaultExtension) { DiagramCategoryDescriptor diagramCategory = getDiagramCategoryMap().get(categoryId); String extensionPrefix = diagramCategory != null ? diagramCategory.getExtensionPrefix() : null; return (extensionPrefix != null) ? extensionPrefix + "." + defaultExtension : defaultExtension; //$NON-NLS-1$ } /** * Creates the new model file page. * * @param selection the selection * @return the new model file page */ protected NewModelFilePage createNewModelFilePage(IStructuredSelection selection) { return new NewModelFilePage(selection); } /** * Creates the select diagram category page. * * @return the select diagram category page */ protected SelectDiagramCategoryPage createSelectDiagramCategoryPage() { return new SelectDiagramCategoryPage(); } /** * Creates the select diagram kind page. * * @return the select diagram kind page */ protected SelectDiagramKindPage createSelectDiagramKindPage() { return new SelectDiagramKindPage(new CategoryProvider() { public String[] getCurrentCategories() { return getDiagramCategoryIds(); } }); } /** * Creates the new model file. * * @param categoryId the category id * @return the i file */ protected IFile createNewModelFile(String categoryId) { return newModelFilePage.createNewFile(); } /** * Inits the domain model. * * @param diResourceSet the di resource set * @param newFile the new file * @param diagramCategoryId the diagram category id */ protected void initDomainModel(DiResourceSet diResourceSet, final IFile newFile, String diagramCategoryId) { boolean isToInitFromTemplate = selectDiagramKindPage.getTemplatePath() != null; if(isToInitFromTemplate) { initDomainModelFromTemplate(diResourceSet); } else { createEmptyDomainModel(diResourceSet, diagramCategoryId); } } /** * Inits the domain model from template. * * @param diResourceSet the di resource set */ protected void initDomainModelFromTemplate(DiResourceSet diResourceSet) { //getCommandStack(diResourceSet).execute(new InitFromTemplateCommand(diResourceSet.getTransactionalEditingDomain(), diResourceSet.getModelResource(), diResourceSet.getDiResource(), diResourceSet.getNotationResource(), selectDiagramKindPage.getTemplatePluginId(), selectDiagramKindPage.getTemplatePath(),selectDiagramKindPage.getNotationTemplatePath(),selectDiagramKindPage.getDiTemplatePath())); getCommandStack(diResourceSet).execute(new InitFromTemplateCommand(diResourceSet.getTransactionalEditingDomain(), diResourceSet, selectDiagramKindPage.getTemplatePluginId(), selectDiagramKindPage.getTemplatePath(),selectDiagramKindPage.getNotationTemplatePath(),selectDiagramKindPage.getDiTemplatePath())); } /** * Creates the empty domain model. * * @param diResourceSet the di resource set * @param diagramCategoryId the diagram category id */ protected void createEmptyDomainModel(DiResourceSet diResourceSet, String diagramCategoryId) { try { IModelCreationCommand creationCommand = getDiagramCategoryMap().get(diagramCategoryId).getCommand(); creationCommand.createModel(diResourceSet); } catch (BackboneException e) { log.error(e); } } /** * Creates the papyrus models. * * @param diResourceSet the di resource set * @param newFile the new file */ protected void createPapyrusModels(DiResourceSet diResourceSet, IFile newFile) { RecordingCommand command = new NewPapyrusModelCommand(diResourceSet, newFile); getCommandStack(diResourceSet).execute(command); } /** * Save diagram category settings. */ protected void saveDiagramCategorySettings() { IDialogSettings settings = getDialogSettings(); if(settings != null) { SettingsHelper settingsHelper = new SettingsHelper(settings); settingsHelper.saveDefaultDiagramCategory(getDiagramCategoryIds()); } } /** * Save diagram kind settings. */ protected void saveDiagramKindSettings() { IDialogSettings settings = getDialogSettings(); if(settings == null) { return; } SettingsHelper settingsHelper = new SettingsHelper(settings); for (String category: getDiagramCategoryIds()) { if(selectDiagramKindPage.isRememberCurrentSelection()) { saveDefaultDiagramKinds(settingsHelper, category); saveDefaultTemplates(settingsHelper, category); } else { settingsHelper.saveDefaultDiagramKinds(category, Collections.<String> emptyList()); settingsHelper.saveDefaultTemplates(category, Collections.<String> emptyList()); } } settingsHelper.saveRememberCurrentSelection(selectDiagramKindPage.isRememberCurrentSelection()); } /** * Save default diagram kinds. * * @param settingsHelper the settings helper * @param category the category */ private void saveDefaultDiagramKinds(SettingsHelper settingsHelper, String category) { String[] selected = selectDiagramKindPage.getSelectedDiagramKinds(category); settingsHelper.saveDefaultDiagramKinds(category, Arrays.asList(selected)); } /** * Save default templates. * * @param settingsHelper the settings helper * @param category the category */ private void saveDefaultTemplates(SettingsHelper settingsHelper, String category) { if(!selectDiagramKindPage.templatesEnabled()) { return; } String path = selectDiagramKindPage.getTemplatePath(); settingsHelper.saveDefaultTemplates(category, Collections.singletonList(path)); } /** * Open diagram. * * @param newFile the new file */ protected void openDiagram(final IFile newFile) { IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); if(page != null) { try { IDE.openEditor(page, newFile, true); } catch (PartInitException e) { log.error(e); } } } /** * Inits the diagram model. * * @param diResourceSet the di resource set * @param categoryId the category id */ protected void initDiagramModel(DiResourceSet diResourceSet, String categoryId) { initDiagrams(diResourceSet, categoryId); saveDiagram(diResourceSet); } /** * Save diagram. * * @param diResourceSet the di resource set */ private void saveDiagram(DiResourceSet diResourceSet) { try { diResourceSet.save(new NullProgressMonitor()); } catch (IOException e) { log.error(e); // return false; } } /** * Inits the diagrams. * * @param diResourceSet the di resource set * @param categoryId the category id */ protected void initDiagrams(DiResourceSet diResourceSet, String categoryId) { initDiagrams(diResourceSet, null, categoryId); } /** * Inits the diagrams. * * @param resourceSet the resource set * @param root the root * @param categoryId the category id */ protected void initDiagrams(DiResourceSet resourceSet, EObject root, String categoryId) { List<ICreationCommand> creationCommands = getDiagramKindsFor(categoryId); String diagramName = selectDiagramKindPage.getDiagramName(); if(creationCommands.isEmpty()) { createEmptyDiagramEditor(resourceSet); } else { for(int i = 0; i < creationCommands.size(); i++) { creationCommands.get(i).createDiagram(resourceSet, root, diagramName); } } } /** * Gets the diagram kinds for. * * @param categoryId the category id * @return the diagram kinds for */ protected List<ICreationCommand> getDiagramKindsFor(String categoryId) { return selectDiagramKindPage.getCreationCommands(categoryId); } /** * Creates the empty diagram editor. * * @param diResourceSet the di resource set */ private void createEmptyDiagramEditor(DiResourceSet diResourceSet) { // Create an empty editor (no diagrams opened) // Geting an IPageMngr is enough to initialize the // SashSystem. EditorUtils.getTransactionalIPageMngr(diResourceSet.getDiResource(), diResourceSet.getTransactionalEditingDomain()); } /** * Gets the command stack. * * @param diResourceSet the di resource set * @return the command stack */ protected final CommandStack getCommandStack(DiResourceSet diResourceSet) { return diResourceSet.getTransactionalEditingDomain().getCommandStack(); } /** * Gets the diagram category map. * * @return the diagram category map */ protected Map<String, DiagramCategoryDescriptor> getDiagramCategoryMap() { return DiagramCategoryRegistry.getInstance().getDiagramCategoryMap(); } /** * Diagram category changed. * * @param newCategories the new categories * @return the i status */ public IStatus diagramCategoryChanged(String... newCategories) { if(newModelFilePage != null) { String firstCategory = newCategories.length > 0 ? newCategories[0] : null; if(newCategories.length > 0) { //316943 - [Wizard] Wrong suffix for file name when creating a profile model return newModelFilePage.diagramExtensionChanged(getDiagramFileExtension(firstCategory)); } } return Status.OK_STATUS; } // Bug 339504 - [Wizard] NPE when init diagram from an existing model /** * The Class DiResourceSetExt. */ public static class DiResourceSetExt extends DiResourceSet { // open access to protected method to be set in PapyrusModelFromExistingDomainModelCommand /* (non-Javadoc) * @see org.eclipse.papyrus.resource.ModelSet#setFilenameWithoutExtension(org.eclipse.core.runtime.IPath) */ @Override public void setFilenameWithoutExtension(IPath filenameWithoutExtension) { super.setFilenameWithoutExtension(filenameWithoutExtension); } } }