| /******************************************************************************* |
| * Copyright (c) 2016 ALL4TEC & CEA LIST. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * ALL4TEC & CEA LIST - initial API and implementation |
| ******************************************************************************/ |
| package org.polarsys.esf.core.importmodel.common.commands; |
| |
| import java.io.IOException; |
| import java.sql.Timestamp; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.GregorianCalendar; |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.edit.command.ChangeCommand; |
| import org.eclipse.emf.transaction.TransactionalEditingDomain; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.papyrus.infra.core.resource.ModelMultiException; |
| import org.eclipse.papyrus.infra.core.resource.ModelSet; |
| import org.eclipse.papyrus.infra.core.resource.ModelsReader; |
| import org.eclipse.papyrus.infra.core.sashwindows.di.util.DiResourceImpl; |
| import org.eclipse.papyrus.infra.emf.utils.EMFHelper; |
| import org.eclipse.papyrus.uml.profile.ui.dialogs.ElementImportTreeSelectionDialog.ImportAction; |
| import org.eclipse.papyrus.uml.profile.ui.dialogs.ElementImportTreeSelectionDialog.ImportSpec; |
| import org.eclipse.papyrus.uml.tools.importsources.PackageImportSourceDialog; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.uml2.uml.Model; |
| import org.eclipse.uml2.uml.Package; |
| import org.eclipse.uml2.uml.PackageImport; |
| import org.eclipse.uml2.uml.UMLFactory; |
| import org.eclipse.uml2.uml.internal.resource.UMLResourceImpl; |
| import org.eclipse.uml2.uml.resource.UMLResource; |
| import org.polarsys.esf.core.importmodel.common.ImportModelCommonActivator; |
| import org.polarsys.esf.core.importmodel.common.dialogs.UMLImportModelDialog; |
| import org.polarsys.esf.core.profile.esfarchitectureconcepts.application.ApplyESFArchitectureConceptsAnnotation; |
| |
| /** |
| * Specific {@link ChangeCommand} that imports models from file. |
| * |
| * @author $Author: ymunoz $ |
| * @version $Revision: 168 $ |
| */ |
| @SuppressWarnings("restriction") |
| public class UMLImportModelFromFileCommand |
| extends AbstractImportModelCommand { |
| |
| /** Default title of the dialog for selecting models to import. */ |
| private static final String SELECT_MODELS_TO_IMPORT_TITLE = ImportModelCommonActivator.getMessages().getString("UMLImportModelFromFileCommand.dialog.title"); //$NON-NLS-1$ |
| |
| /** Default label of the command Import Models to import. */ |
| private static final String IMPORT_MODELS_LABLE = ImportModelCommonActivator.getMessages().getString("UMLImportModelFromFileCommand.command.label"); //$NON-NLS-1$ |
| |
| /** Default description of the command Import Models to import. */ |
| private static final String IMPORT_MODELS_DESCRIPTION = ImportModelCommonActivator.getMessages().getString( |
| "UMLImportModelFromFileCommand.command.description"); //$NON-NLS-1$ |
| |
| /** UML extension key. */ |
| private static final String UML_EXTENSION_KEY = "*.uml"; //$NON-NLS-1$ |
| |
| /** UML extension value. */ |
| private static final String UML_EXTENSION_VALUE = "UML (*.uml)"; //$NON-NLS-1$ |
| |
| /** Underscore. */ |
| private static final String UNDERSCORE = "_"; //$NON-NLS-1$ |
| |
| /** |
| * Default constructor. |
| * |
| * @param pEditingDomain |
| * The editing domain |
| * @param pSelectedElements |
| * The selected elements |
| * @param pSelection |
| * The selection |
| */ |
| public UMLImportModelFromFileCommand( |
| final TransactionalEditingDomain pEditingDomain, |
| final List<EObject> pSelectedElements, |
| final List<?> pSelection) { |
| |
| super( |
| pEditingDomain, |
| pSelectedElements, |
| new UMLImportModelRunnable(pSelection, pSelectedElements), |
| IMPORT_MODELS_LABLE, |
| IMPORT_MODELS_DESCRIPTION); |
| } |
| |
| /** |
| * The inner class which provides the dialog and operation for importing UML models. |
| * |
| * @author $Author: ymunoz $ |
| * @version $Revision: 168 $ |
| */ |
| private static class UMLImportModelRunnable |
| implements Runnable { |
| |
| /** The selection of elements. */ |
| private Collection<?> mSelection = null; |
| |
| /** The model where the others models will be imported. */ |
| private Model mModelTarget = null; |
| |
| /** |
| * Default constructor. |
| * |
| * @param pSelection |
| * The selection |
| * @param pSelectedElements |
| * The selected Elements |
| */ |
| UMLImportModelRunnable(final List<?> pSelection, final List<EObject> pSelectedElements) { |
| mSelection = pSelection; |
| |
| if (pSelectedElements.isEmpty()) { |
| throw new IllegalArgumentException("Selected element is empty"); |
| } else if (!(pSelectedElements.get(0) instanceof Model)) { |
| throw new IllegalArgumentException("Selected element is not a Model object"); |
| } else { |
| mModelTarget = (Model) pSelectedElements.get(0); |
| } |
| } |
| |
| /** |
| * Open dialog for selecting the UML models. And in the end, they are duplicated and imported. |
| */ |
| @Override |
| public void run() { |
| Shell vShell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); |
| Map<String, String> vExtensionFilters = new LinkedHashMap<String, String>(); |
| vExtensionFilters.put(UML_EXTENSION_KEY, UML_EXTENSION_VALUE); |
| Collection<?> vSelection = mSelection; |
| Collection<Package> vModels = PackageImportSourceDialog.open(vShell, SELECT_MODELS_TO_IMPORT_TITLE, vSelection, vExtensionFilters); |
| |
| // Remove self-import |
| vModels = removeSelfImport(vModels); |
| |
| if ((vModels != null) && (!vModels.isEmpty())) { |
| if (!vModels.isEmpty()) { |
| UMLImportModelDialog vDialog = new UMLImportModelDialog( |
| PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), |
| vModels); |
| |
| if (Window.OK == vDialog.open()) { |
| // Get the selected packages from UML model to import |
| Collection<ImportSpec<Package>> vResult = vDialog.getResult(); |
| |
| for (ImportSpec<Package> vResultElement : vResult) { |
| Package vSelectedPackage = vResultElement.getElement(); |
| if (ImportAction.IMPORT == vResultElement.getAction()) { |
| Package vImportedPackage = importPackage(vSelectedPackage); |
| ApplyESFArchitectureConceptsAnnotation |
| .applyAnnotationOnUMLModel((Model) vImportedPackage); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Remove the model target where the others models will be imported. |
| * |
| * @param pModels |
| * The models to import |
| * @return The models without itself (model target) |
| */ |
| private Collection<Package> removeSelfImport(final Collection<Package> pModels) { |
| Collection<Package> vUpdatedModels = pModels; |
| if ((pModels != null) && (!pModels.isEmpty())) { |
| URI vModelTargetURI = EcoreUtil.getURI(mModelTarget); |
| Iterator<Package> vModels = pModels.iterator(); |
| Boolean vRemoved = false; |
| |
| while (!vRemoved && vModels.hasNext()) { |
| Package vModel = vModels.next(); |
| if (EcoreUtil.getURI(vModel).equals(vModelTargetURI)) { |
| vUpdatedModels.remove(vModel); |
| vRemoved = true; |
| } |
| } |
| } |
| return vUpdatedModels; |
| } |
| |
| /** |
| * Duplicate the file of each UML model. |
| * |
| * @param pModels |
| * The UML models |
| * @return The UML models of duplicate files |
| * @throws ModelMultiException |
| * This exception is thrown when an operation performed on several Models fails on |
| * one or more of these models. |
| */ |
| private Collection<Package> duplicateModels(final Collection<Package> pModels) throws ModelMultiException { |
| Collection<Package> vDuplicateModels = new ArrayList<Package>(); |
| for (Package vModel : pModels) { |
| // Load the model to be duplicated |
| ModelSet vModelSet = new ModelSet(); |
| ModelsReader vModelsReader = new ModelsReader(); |
| vModelsReader.readModel(vModelSet); |
| vModelSet.loadModels(EcoreUtil.getURI(vModel).trimFragment()); |
| |
| EcoreUtil.resolveAll(vModelSet); |
| |
| /* |
| * Retrieve di resources and get its file's path without |
| * extension for building a new path of the duplicate model |
| */ |
| Resource vDiResource = getSpecificResource(DiResourceImpl.class, vModelSet.getResources()); |
| if (vDiResource != null) { |
| URI vDiURI = vDiResource.getURI(); |
| String vDiExtension = vDiURI.fileExtension(); |
| URI vURIWithoutExtension = vDiURI.trimFileExtension(); |
| Timestamp vTimestamp = new Timestamp(GregorianCalendar.getInstance().getTime().getTime()); |
| String vNewURIString = vURIWithoutExtension.toString() + UNDERSCORE + vTimestamp.getTime(); |
| URI vNewURIWithoutExtension = URI.createURI(vNewURIString); |
| URI vNewDiURI = vNewURIWithoutExtension.appendFileExtension(vDiExtension); |
| try { |
| vModelSet.saveAs(vNewDiURI); |
| } catch (final IOException pException) { |
| ImportModelCommonActivator.logError( |
| "Error during the saving of the new models", pException); //$NON-NLS-1$ |
| } |
| |
| /* |
| * Retrieve the duplicate model to import |
| */ |
| UMLResource vUMLResource = (UMLResource) getSpecificResource(UMLResourceImpl.class, vModelSet.getResources()); |
| if (vUMLResource != null) { |
| EObject vDuplicateModel = vUMLResource.getContents().get(0); |
| vDuplicateModels.add((Package) vDuplicateModel); |
| } |
| } |
| } |
| return vDuplicateModels; |
| } |
| |
| /** |
| * Creates a PackageImport in the current package, which refers to the |
| * selected package. |
| * |
| * @param pPackage |
| * The selected package |
| * @return The imported package |
| */ |
| protected Package importPackage(final Package pPackage) { |
| Package vImportedPackage = null; |
| |
| if (mModelTarget != null) { |
| PackageImport vPackageImport = UMLFactory.eINSTANCE.createPackageImport(); |
| |
| vImportedPackage = EMFHelper.reloadIntoContext(pPackage, mModelTarget); |
| ((Package) mModelTarget).getPackageImports().add(vPackageImport); |
| vPackageImport.setImportedPackage(vImportedPackage); |
| } |
| |
| return vImportedPackage; |
| } |
| |
| /** |
| * Retrieve the resource specified from a resources' list. |
| * |
| * @param pResourceType |
| * The resource type |
| * @param pResources |
| * The list of resources |
| * @return The resource specified |
| */ |
| private Resource getSpecificResource( |
| final Class<? extends Resource> pResourceType, |
| final EList<Resource> pResources) { |
| Resource vSpecificResource = null; |
| for (Resource vResource : pResources) { |
| if (vResource.getClass() == pResourceType) { |
| vSpecificResource = vResource; |
| break; |
| } |
| } |
| return vSpecificResource; |
| } |
| } |
| } |