/***************************************************************************** * Copyright (c) 2010 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: * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation *****************************************************************************/ package org.eclipse.papyrus.customization.properties.generation.generators; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.m2m.qvt.oml.BasicModelExtent; import org.eclipse.m2m.qvt.oml.ModelExtent; import org.eclipse.papyrus.customization.properties.generation.Activator; import org.eclipse.papyrus.customization.properties.generation.messages.Messages; import org.eclipse.papyrus.customization.properties.generation.wizard.widget.FileChooser; import org.eclipse.papyrus.views.properties.contexts.Context; import org.eclipse.papyrus.views.properties.contexts.DataContextElement; import org.eclipse.papyrus.views.properties.contexts.Property; import org.eclipse.papyrus.views.properties.root.PropertiesRoot; import org.eclipse.papyrus.views.properties.runtime.ConfigurationManager; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.uml2.uml.Classifier; import org.eclipse.uml2.uml.Enumeration; import org.eclipse.uml2.uml.NamedElement; import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.PrimitiveType; import org.eclipse.uml2.uml.Profile; /** * An IGenerator for building Contexts from a UML Profile * * @author Camille Letavernier */ public class ProfileGenerator extends AbstractQVTGenerator { private FileChooser sourceFileChooser; private Profile umlProfile; public void createControls(Composite parent) { Composite root = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; root.setLayout(layout); Label sourceLabel = new Label(root, SWT.NONE); sourceLabel.setText(Messages.ProfileGenerator_source); GridData data = new GridData(); data.widthHint = 100; sourceLabel.setLayoutData(data); sourceFileChooser = new FileChooser(root, false); sourceFileChooser.setFilterExtensions(new String[]{ "profile.uml" }); //$NON-NLS-1$ sourceFileChooser.addListener(this); } public String getDescription() { return Messages.ProfileGenerator_description; } public boolean isReady() { return sourceFileChooser.getFilePath() != null; } public String getName() { return Messages.ProfileGenerator_name; } @Override protected List<ModelExtent> getModelExtents() { try { URI profileURI = URI.createPlatformResourceURI(sourceFileChooser.getFilePath(), true); umlProfile = (Profile)loadEMFModel(profileURI); ModelExtent inProfile = new BasicModelExtent(Collections.singletonList(umlProfile)); URI umlURI = URI.createURI("ppe:/context/org.eclipse.papyrus.uml.properties/Model/UML/UML.ctx", true); Context umlContext = (Context)loadEMFModel(umlURI); if(umlContext == null) { Activator.log.warn("Cannot find the UML Property View configuration"); } ModelExtent inUml = new BasicModelExtent(Collections.singletonList(umlContext)); PropertiesRoot root = ConfigurationManager.instance.getPropertiesRoot(); ModelExtent inRoot = new BasicModelExtent(Collections.singletonList(root)); LinkedList<ModelExtent> result = new LinkedList<ModelExtent>(); result.add(inProfile); result.add(getOutContextExtent()); result.add(inUml); result.add(inRoot); return result; } catch (Exception ex) { Activator.log.error(ex); } return null; } @Override protected URI getTransformationURI() { return URI.createPlatformPluginURI("org.eclipse.papyrus.customization.properties.generation/transforms/profile2datacontext.qvto", true); //$NON-NLS-1$ } /** * Retrieve the Classifier corresponding to the given path, in the given Package * * @param path * The list of package and subpackages names, and the classifier name, i.e. * the list of segments in the classifier qualified name * e.g. : SysML::Blocks::Block : ["SysML", "Blocks", "Block"] * @param rootPackage * The root Package in which the stereotype should be retrieved * @return * The corresponding Classifier, or null if it couldn't be retrieved */ protected Classifier findClassifier(List<String> path, Package rootPackage) { NamedElement element = rootPackage.getOwnedMember(path.get(0)); path.remove(0); if(path.size() == 0) { if(element instanceof Classifier) { return (Classifier)element; } } else { if(element instanceof Package) { return findClassifier(path, (Package)element); } } return null; } private List<String> getPath(Property property) { List<String> result = getPath(property.getContextElement()); return result; } private List<String> getPath(DataContextElement element) { List<String> result; if(element.getPackage() == null) { result = new LinkedList<String>(); } else { result = getPath(element.getPackage()); } result.add(element.getName()); return result; } /** * Retrieve the UML Property corresponding to the given Property view context Property * * @param property * @return */ public org.eclipse.uml2.uml.Property getAttribute(Property property) { List<String> path = getPath(property); Package propertyRootPackage = findPackage(path.remove(0)); if(propertyRootPackage == null) { return null; } Classifier classifier = findClassifier(path, propertyRootPackage); if(classifier == null) { return null; } org.eclipse.uml2.uml.Property attribute = classifier.getAttribute(property.getName(), null); return attribute; } public Package findPackage(String name) { for(Resource resource : umlProfile.eResource().getResourceSet().getResources()) { for(Object rootElement : resource.getContents()) { if(rootElement instanceof Package) { Package rootPackage = (Package)rootElement; if(name.equals(rootPackage.getName())) { return rootPackage; } } } } return null; } public boolean isSelectedSingle(Property property) { org.eclipse.uml2.uml.Property attribute = getAttribute(property); if(attribute == null) { Activator.log.warn("Cannot find the Property corresponding to " + getPath(property)); //$NON-NLS-1$ return false; } if(attribute.isDerived()) { return false; } if(attribute.isReadOnly()) { return false; } return true; } public boolean isSelectedMultiple(Property property) { if(!isSelectedSingle(property)) { return false; } org.eclipse.uml2.uml.Property attribute = getAttribute(property); Set<String> validDataTypes = new HashSet<String>(Arrays.asList(new String[]{ "Integer", "Boolean", "Float", "Double" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ if(attribute.getType() instanceof PrimitiveType) { return validDataTypes.contains(((PrimitiveType)attribute.getType()).getName()); } if(attribute.getType() instanceof Enumeration) { return true; } return false; } public boolean isSelectedSingle(Property property, DataContextElement element) { return isSelectedSingle(property); } public boolean isSelectedMultiple(Property property, DataContextElement element) { return isSelectedMultiple(property); } }