Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators')
-rw-r--r--plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/AbstractQVTGenerator.java284
-rw-r--r--plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EcoreGenerator.java379
-rw-r--r--plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EditContextGenerator.java121
-rw-r--r--plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/IGenerator.java149
-rw-r--r--plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/ProfileGenerator.java361
5 files changed, 1294 insertions, 0 deletions
diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/AbstractQVTGenerator.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/AbstractQVTGenerator.java
new file mode 100644
index 00000000000..7e664840de4
--- /dev/null
+++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/AbstractQVTGenerator.java
@@ -0,0 +1,284 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Strategy improvement of generated files
+ * Christian W. Damus (CEA) - bug 422257
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.customization.properties.generation.generators;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+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.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.m2m.qvt.oml.BasicModelExtent;
+import org.eclipse.m2m.qvt.oml.ExecutionContextImpl;
+import org.eclipse.m2m.qvt.oml.ExecutionDiagnostic;
+import org.eclipse.m2m.qvt.oml.ModelExtent;
+import org.eclipse.m2m.qvt.oml.TransformationExecutor;
+import org.eclipse.papyrus.customization.properties.generation.Activator;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+import org.eclipse.papyrus.infra.properties.contexts.Context;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * An Abstract generator based on QVTO transformations.
+ * Subclasses should specify the .qvto file and ModelExtents, as well as the
+ * SWT widgets allowing the user to chose the input models.
+ *
+ * @author Camille Letavernier
+ */
+public abstract class AbstractQVTGenerator implements IGenerator, Listener {
+
+ /**
+ * The Contexts created by the transformation.
+ */
+ protected List<Context> generatedContexts;
+
+ /**
+ * The output ModelExtent
+ */
+ protected ModelExtent out;
+
+ private Set<Listener> listeners = new HashSet<Listener>();
+
+ private int strategy;
+
+ private Collection<ResourceSet> scratchResourceSets;
+
+ public List<Context> generate(List<URI> targetURI) {
+
+ switch (strategy) {
+ case 0:
+ generatedContexts = generateSameFile(targetURI);
+ break;
+ case 1:
+ generatedContexts = generateSameFile(targetURI);
+ break;
+ case 2:
+ generatedContexts = generateDifferentFile(targetURI);
+ break;
+ default:
+ generatedContexts = null;
+ }
+ return generatedContexts;
+ }
+
+ public void dispose() {
+ if (scratchResourceSets != null) {
+ for (ResourceSet next : scratchResourceSets) {
+ EMFHelper.unload(next);
+ }
+ scratchResourceSets = null;
+ }
+ }
+
+
+
+ /**
+ * @return the list of in/out/inout ModelExtents (including the OutContextExtent)
+ * Implementors should ensure they add the outContextExtent to the list.
+ */
+ abstract protected List<ModelExtent> getModelExtents();
+
+ /**
+ * @return the ModelExtent containing the generated context
+ */
+ protected ModelExtent getOutContextExtent() {
+ if (out == null) {
+ out = new BasicModelExtent();
+ }
+
+ return out;
+ }
+
+ /**
+ * @return the URI of the QVTO transformation file.
+ */
+ abstract protected URI getTransformationURI();
+
+ /**
+ * Loads the EObject from the given URI.
+ *
+ * @param uri
+ * The URI from which the EObject is loaded
+ * @return
+ * The loaded EObject, or null if an error occured
+ * @throws IOException
+ * If the URI isn't a valid EObject
+ */
+ protected EObject loadEMFModel(URI uri) throws IOException {
+ ResourceSet resourceSet = createResourceSet();
+ try {
+ Resource resource = resourceSet.getResource(uri, true);
+ if (resource != null) {
+ if (!resource.getContents().isEmpty()) {
+ return resource.getContents().get(0);
+ }
+ }
+ } catch (Exception ex) {
+ throw new IOException(ex.toString());
+ }
+
+ return null;
+ }
+
+ protected final ResourceSet createResourceSet() {
+ ResourceSet result = new ResourceSetImpl();
+ if (scratchResourceSets == null) {
+ scratchResourceSets = new ArrayList<ResourceSet>();
+ }
+ scratchResourceSets.add(result);
+ return result;
+ }
+
+ public void addListener(Listener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(Listener listener) {
+ listeners.remove(listener);
+ }
+
+ public void handleEvent(Event event) {
+ for (Listener listener : listeners) {
+ listener.handleEvent(event);
+ }
+ }
+
+ /**
+ * Return the generated Context from a list of EObjects
+ *
+ * @param outObjects
+ * The list of EObjects from which the context will be retrieved
+ * @return
+ * The main generated context
+ */
+ protected List<Context> getContexts(List<EObject> outObjects) {
+ List<Context> result = new LinkedList<Context>();
+
+ for (Object objectResult : outObjects) {
+ if (objectResult instanceof Context) {
+ result.add((Context) objectResult);
+ }
+ }
+
+ return result;
+ }
+
+
+ public abstract IObservableValue getObservableValue();
+
+ public void setStrategy(int strategy) {
+ this.strategy = strategy;
+ }
+
+ private List<Context> generateSameFile(List<URI> targetURI) {
+
+ URI transformationURI = getTransformationURI();
+
+ TransformationExecutor executor = new TransformationExecutor(transformationURI);
+ Diagnostic diagnostic = executor.loadTransformation();
+ if (diagnostic.getSeverity() != Diagnostic.OK) {
+ Activator.log.warn("Cannot load the transformation : " + transformationURI);
+ return generatedContexts = null;
+ }
+ List<ModelExtent> extents = getModelExtents();
+
+
+ ExecutionContextImpl context = new ExecutionContextImpl();
+ context.setConfigProperty("keepModeling", true); //$NON-NLS-1$
+
+ // context.setLog(new WriterLog(new OutputStreamWriter(System.out)));
+
+ ExecutionDiagnostic result = executor.execute(context, extents.toArray(new ModelExtent[0]));
+
+ if (result.getSeverity() == org.eclipse.emf.common.util.Diagnostic.OK) {
+ List<EObject> outObjects = getOutContextExtent().getContents();
+ Object objectResult = outObjects.get(0);
+ if (!(objectResult instanceof Context)) {
+ return null;
+ }
+
+ ResourceSet resourceSet = createResourceSet();
+ Resource contextResource = resourceSet.createResource(targetURI.get(0));
+ contextResource.getContents().addAll(outObjects);
+
+ return generatedContexts = getContexts(outObjects);
+ } else {
+ IStatus status = BasicDiagnostic.toIStatus(result);
+ Activator.log.warn(String.format("%s : %s", status.getPlugin(), status.getMessage()));
+ }
+ return generatedContexts = null;
+ }
+
+ protected abstract List<ModelExtent> getModelExtents(int i);
+
+ private List<Context> generateDifferentFile(List<URI> targetURI) {
+
+ URI transformationURI = getTransformationURI();
+
+ TransformationExecutor executor = new TransformationExecutor(transformationURI);
+ Diagnostic diagnostic = executor.loadTransformation();
+ if (diagnostic.getSeverity() != Diagnostic.OK) {
+ Activator.log.warn("Cannot load the transformation : " + transformationURI);
+ return generatedContexts = null;
+ }
+ List<ModelExtent> extents = null;
+ ExecutionContextImpl context = new ExecutionContextImpl();
+ context.setConfigProperty("keepModeling", true); //$NON-NLS-1$
+ // context.setLog(new WriterLog(new OutputStreamWriter(System.out)));
+ List<Context> temp = new LinkedList<Context>();
+
+ for (int i = 0; i < targetURI.size(); i++) {
+ extents = getModelExtents(i);
+
+
+
+ ExecutionDiagnostic result = executor.execute(context, extents.toArray(new ModelExtent[0]));
+
+ if (result.getSeverity() == org.eclipse.emf.common.util.Diagnostic.OK) {
+ List<EObject> outObjects = getOutContextExtent().getContents();
+ Object objectResult = outObjects.get(0);
+ if (!(objectResult instanceof Context)) {
+ return null;
+ }
+ ResourceSet resourceSet = createResourceSet();
+ Resource contextResource = resourceSet.createResource(targetURI.get(i));
+ contextResource.getContents().addAll(outObjects);
+ temp.addAll(getContexts(outObjects));
+
+ } else {
+ IStatus status = BasicDiagnostic.toIStatus(result);
+ Activator.log.warn(String.format("%s : %s", status.getPlugin(), status.getMessage()));
+ }
+ }
+
+ return temp;
+
+ }
+
+
+
+}
diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EcoreGenerator.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EcoreGenerator.java
new file mode 100644
index 00000000000..c9d1b229e7a
--- /dev/null
+++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EcoreGenerator.java
@@ -0,0 +1,379 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Strategy improvement of generated files
+ *****************************************************************************/
+package org.eclipse.papyrus.customization.properties.generation.generators;
+
+import java.io.IOException;
+import java.util.ArrayList;
+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.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EDataType;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+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.infra.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.infra.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;
+
+/**
+ * An IGenerator to create Property view contexts from an Ecore metamodel FIXME
+ * : The generator doesn't seem to keep the Metaclass inheritance
+ *
+ * @author Camille Letavernier
+ */
+public class EcoreGenerator extends AbstractQVTGenerator {
+
+ private FileChooser sourceFileChooser;
+
+ protected EPackage ecorePackage;
+
+ protected List<EPackage> listEPackages;
+
+ 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.EcoreGenerator_source);
+ GridData data = new GridData();
+ data.widthHint = 100;
+ sourceLabel.setLayoutData(data);
+
+ sourceFileChooser = new FileChooser(root, false);
+ sourceFileChooser.setFilterExtensions(new String[] { "ecore" }); //$NON-NLS-1$
+ sourceFileChooser.addListener(this);
+
+ listEPackages = new ArrayList<EPackage>();
+
+ }
+
+ public String getDescription() {
+ return Messages.EcoreGenerator_ecoreGeneratorDescription;
+ }
+
+ public boolean isReady() {
+ return sourceFileChooser.getFilePath() != null;
+ }
+
+ public String getName() {
+ return Messages.EcoreGenerator_ecoreGeneratorName;
+ }
+
+ public boolean isSelectedSingle(Property property) {
+ EStructuralFeature feature = getFeature(property);
+ if (feature == null) {
+ return false;
+ }
+
+ if (feature.isDerived()) {
+ return false;
+ }
+
+ if (!feature.isChangeable()) {
+ return false;
+ }
+
+ if (feature instanceof EReference) {
+ EReference reference = (EReference) feature;
+ if (reference.isContainer() || reference.isContainment()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Retrieve the EStructuralFeature corresponding to the given property
+ *
+ * @param property
+ * @return The EStructuralFeature corresponding to the given property
+ */
+ protected EStructuralFeature getFeature(Property property) {
+ List<String> path = getPath(property);
+ path.remove(0); // Root = EPackage
+
+ EPackage currentPackage = ecorePackage;
+
+ EClassifier classifier = findClassifier(path, currentPackage);
+ if (classifier == null) {
+ return null;
+ }
+
+ if (!(classifier instanceof EClass)) {
+ return null;
+ }
+
+ EClass eClass = (EClass) classifier;
+ return eClass.getEStructuralFeature(property.getName());
+ }
+
+ /**
+ * Retrieve the Classifier corresponding to the given path, in the given
+ * EPackage
+ *
+ * @param path
+ * The list of package and subpackages names, and the classifier
+ * name, i.e. the list of segments in the classifier's qualified
+ * name
+ * @param source
+ * The root EPackage in which the classifier should be retrieved
+ * @return The corresponding EClassifier, or null if it couldn't be
+ * retrieved
+ */
+ protected EClassifier findClassifier(List<String> path, EPackage source) {
+ String qualifier = path.get(0);
+ EClassifier classifier = source.getEClassifier(qualifier);
+ if (classifier == null) {
+ source = findSubPackage(source, qualifier);
+ if (source == null) {
+ return null;
+ }
+ path.remove(0);
+ return findClassifier(path, source);
+ } else {
+ return classifier;
+ }
+ }
+
+ /**
+ * Retrieve the subpackage corresponding to the given packageName, in the
+ * given package
+ *
+ * @param currentPackage
+ * The EPackage in which the subpackage should be found
+ * @param packageName
+ * The name of the EPackage to find
+ * @return The corresponding EPackage, or null if it couldn't be found
+ */
+ protected EPackage findSubPackage(EPackage currentPackage, String packageName) {
+ for (EPackage pack : currentPackage.getESubpackages()) {
+ if (pack.getName().equals(packageName)) {
+ return pack;
+ }
+ }
+ 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;
+ }
+
+ public boolean isSelectedMultiple(Property property) {
+ if (!isSelectedSingle(property)) {
+ return false;
+ }
+
+ EStructuralFeature feature = getFeature(property);
+
+ Set<String> validDataTypes = new HashSet<String>(Arrays.asList(new String[] { "int", "boolean", "float", "double" })); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+ if (feature.getEType() instanceof EDataType) {
+ if (validDataTypes.contains(((EDataType) feature.getEType()).getInstanceTypeName())) {
+ return true;
+ }
+ }
+
+ if (feature.getEType() instanceof EEnum) {
+ return true;
+ }
+
+ return false;
+ }
+
+ public boolean isSelectedSingle(Property property, DataContextElement element) {
+ return isSelectedSingle(property);
+ }
+
+ public boolean isSelectedMultiple(Property property, DataContextElement element) {
+ return isSelectedMultiple(property);
+ }
+
+ @Override
+ protected URI getTransformationURI() {
+ return URI.createPlatformPluginURI(Activator.PLUGIN_ID + "/transforms/ecore2datacontext.qvto", true); //$NON-NLS-1$
+ }
+
+
+ @Override
+ protected List<ModelExtent> getModelExtents() {
+ LinkedList<ModelExtent> result = new LinkedList<ModelExtent>();
+ ModelExtent temp = new BasicModelExtent();
+ ModelExtent inPackage = new BasicModelExtent(Collections.singletonList(ecorePackage));
+
+
+
+ PropertiesRoot root = ConfigurationManager.getInstance().getPropertiesRoot();
+ ModelExtent inRoot = new BasicModelExtent(Collections.singletonList(root));
+ if (!listEPackages.isEmpty()) {
+ temp.setContents(listEPackages);
+ if (!listEPackages.contains(ecorePackage)) {
+ result.add(temp); // if the root package isnt selected
+ } else {
+ result.add(inPackage);
+ }
+ result.add(temp);
+
+ } else {
+ // Basic Method
+ result.add(inPackage);
+ result.add(inPackage);
+ }
+
+ result.add(inRoot);
+ result.add(getOutContextExtent());
+ return result;
+
+ }
+
+ @Override
+ public IObservableValue getObservableValue() {
+ return sourceFileChooser.getObservableValue();
+ }
+
+ public List<Object> getExternalReference() {
+
+ URI packageURI = URI.createPlatformResourceURI(sourceFileChooser.getFilePath(), true);
+
+ try {
+ ecorePackage = (EPackage) loadEMFModel(packageURI);
+ } catch (IOException e) {
+ // nothing
+ }
+
+ EcoreUtil.resolveAll(ecorePackage);
+
+ List<Object> listePackage = new ArrayList<Object>();
+ if (!listePackage.contains(ecorePackage)) {
+ listePackage.add(ecorePackage);
+ }
+
+ TreeIterator<Notifier> tree = ecorePackage.eResource().getResourceSet().getAllContents();
+ while (tree.hasNext()) {
+ Notifier next = tree.next();
+ if (!(next instanceof EObject)) {
+ continue;
+ }
+
+ EObject object = (EObject) next;
+ if (object instanceof EStructuralFeature) {
+ EStructuralFeature feature = (EStructuralFeature) object;
+ EClass eClass = feature.getEContainingClass();
+ if (eClass != null) {
+ EClassifier classifier = feature.getEType();
+ EPackage targetPackage = null;
+ if (classifier != null) {
+ targetPackage = classifier.getEPackage();
+ }
+ if (targetPackage != null) {
+ if (!ecorePackage.equals(targetPackage)) {
+ if (!listePackage.contains(targetPackage)) {
+ listePackage.add(targetPackage);
+ }
+
+ }
+ }
+ }
+ }
+ if (object instanceof EClass) {
+
+ EClass eclass = (EClass) object;
+ List<EClass> liste = eclass.getESuperTypes();
+ for (EClass item : liste) {
+ if (!listePackage.contains(item.getEPackage())) {
+ listePackage.add(item.getEPackage());
+ }
+
+ }
+ }
+
+ }
+
+ return listePackage;
+ }
+
+ public void addCheckElement(Object obj) {
+
+ if (obj instanceof EPackage) {
+ EPackage pack = (EPackage) obj;
+ listEPackages.add(pack);
+ }
+
+ }
+
+
+ @Override
+ protected List<ModelExtent> getModelExtents(int i) {
+ EPackage currentPackage = listEPackages.get(i);
+ try {
+
+ ModelExtent inPackage = new BasicModelExtent(Collections.singletonList(currentPackage));
+ PropertiesRoot root = ConfigurationManager.getInstance().getPropertiesRoot();
+ ModelExtent inRoot = new BasicModelExtent(Collections.singletonList(root));
+ LinkedList<ModelExtent> result = new LinkedList<ModelExtent>();
+ result.add(inPackage);
+ result.add(inPackage);
+ result.add(inRoot);
+ result.add(getOutContextExtent());
+
+ return result;
+
+ } catch (Exception ex) {
+ return null;
+
+ }
+
+ }
+
+
+
+}
diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EditContextGenerator.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EditContextGenerator.java
new file mode 100644
index 00000000000..7c23a341749
--- /dev/null
+++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/EditContextGenerator.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com
+ * Christian W. Damus (CEA) - bug 422257
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.customization.properties.generation.generators;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.customization.properties.generation.messages.Messages;
+import org.eclipse.papyrus.infra.properties.contexts.Context;
+import org.eclipse.papyrus.infra.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.infra.properties.contexts.Property;
+import org.eclipse.papyrus.infra.properties.contexts.View;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * Incubation
+ *
+ * An implementation of IGenerator used to re-generate a Context from an existing one
+ *
+ * @author Camille Letavernier
+ */
+public class EditContextGenerator implements IGenerator {
+
+ public void dispose() {
+ // TODO Auto-generated method stub
+
+ }
+
+ public List<Context> generate(List<URI> targetURI) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void createControls(Composite parent) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public String getDescription() {
+ return Messages.EditContextGenerator_generateNewContext;
+ }
+
+ public boolean isReady() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public String getName() {
+ return Messages.EditContextGenerator_importExistingContext;
+ }
+
+ public boolean isSelectedSingle(Property property) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSelectedMultiple(Property property) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSelectedSingle(Property property, DataContextElement element) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isSelectedMultiple(Property property, DataContextElement element) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void addListener(Listener listener) {
+ // TODO Auto-generated method stub
+ }
+
+ public List<DataContextElement> getContextElementsFor(Collection<Context> contexts, View view) {
+ // TODO Auto-generated method stub
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeListener(Listener listener) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public IObservableValue getObservableValue() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public List<Object> getExternalReference() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setStrategy(int strategy) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void addCheckElement(Object obj) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/IGenerator.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/IGenerator.java
new file mode 100644
index 00000000000..683ab418956
--- /dev/null
+++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/IGenerator.java
@@ -0,0 +1,149 @@
+/*****************************************************************************
+ * Copyright (c) 2010, 2014 CEA LIST 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:
+ * Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Strategy improvement of generated files
+ * Christian W. Damus (CEA) - bug 422257
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.customization.properties.generation.generators;
+
+import java.util.List;
+
+import org.eclipse.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.papyrus.infra.properties.contexts.Context;
+import org.eclipse.papyrus.infra.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.infra.properties.contexts.Property;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Listener;
+
+/**
+ * A Generator is intended to output a partial Context model.
+ * This context model should only contain DataContextElements and Properties
+ * (i.e. it should not contain any View or Tabs)
+ * The Generator should also implement an heuristic, which will determine
+ * for each Property if it should be displayed in the Property view or not,
+ * for both Single and Multiple selection
+ *
+ * @author Camille Letavernier
+ *
+ */
+public interface IGenerator {
+
+ /**
+ * Generates the partial context, and persists it to the given target URI
+ *
+ * @param targetURI
+ * @return The generated Context
+ */
+ public List<Context> generate(List<URI> targetURI);
+
+ /**
+ * Creates the controls for this Generator. The generator is responsible
+ * for displaying any Control useful for editing its options, and listening
+ * for changes on them.
+ *
+ * @param parent
+ * The Composite in which the controls will be displayed
+ */
+ public void createControls(Composite parent);
+
+ /**
+ * Gets the description for this Generator
+ *
+ * @return The description
+ */
+ public String getDescription();
+
+ /**
+ * Tests if this Generator's settings are all set and valid
+ *
+ * @return true if all options are set and valid
+ */
+ public boolean isReady();
+
+ /**
+ * Gets the name for this Generator
+ *
+ * @return The name
+ */
+ public String getName();
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * exactly one instance of this property's parent element is selected.
+ *
+ * @param property
+ * @return
+ */
+ public boolean isSelectedSingle(Property property);
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * at least two instances of this property's parent element are selected.
+ *
+ * @param property
+ * @return
+ */
+ public boolean isSelectedMultiple(Property property);
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * exactly one instance of the given element is selected. The difference
+ * with {@link #isSelectedSingle(Property)} is that this method takes the inheritance
+ * into account, i.e. the property belongs to a Superclass of the given DataContextElement
+ *
+ * @param property
+ * @param element
+ * @return
+ */
+ public boolean isSelectedSingle(Property property, DataContextElement element);
+
+ /**
+ * Tests if a field should be displayed for this Property when
+ * at least two instances of the given element are selected. The difference
+ * with {@link #isSelectedMultiple(Property)} is that this method takes the inheritance
+ * into account, i.e. the property belongs to a Superclass of the given DataContextElement
+ *
+ * @param property
+ * @param element
+ * @return
+ */
+ public boolean isSelectedMultiple(Property property, DataContextElement element);
+
+ /**
+ * Adds a Change Listener to this generator. The Listener should be notified
+ * each time the generator's {@link #isReady()} value changes
+ *
+ * @param listener
+ */
+ public void addListener(Listener listener);
+
+ /**
+ * Removes a Change Listener from this generator.
+ *
+ * @param listener
+ */
+ public void removeListener(Listener listener);
+
+ public List<Object> getExternalReference();
+
+ public IObservableValue getObservableValue();
+
+ public void setStrategy(int strategy);
+
+ public void addCheckElement(Object obj);
+
+ /**
+ * Disposes of any resources allocated by me when I am no longer needed.
+ */
+ public void dispose();
+
+}
diff --git a/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/ProfileGenerator.java b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/ProfileGenerator.java
new file mode 100644
index 00000000000..92066951805
--- /dev/null
+++ b/plugins/uml/properties/org.eclipse.papyrus.uml.properties.generation/src/org/eclipse/papyrus/customization/properties/generation/generators/ProfileGenerator.java
@@ -0,0 +1,361 @@
+/*****************************************************************************
+ * 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
+ * Thibault Le Ouay t.leouay@sherpa-eng.com - Strategy improvement of generated files
+ *****************************************************************************/
+package org.eclipse.papyrus.customization.properties.generation.generators;
+
+import java.io.IOException;
+import java.util.ArrayList;
+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.core.databinding.observable.value.IObservableValue;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+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.infra.properties.contexts.Context;
+import org.eclipse.papyrus.infra.properties.contexts.DataContextElement;
+import org.eclipse.papyrus.infra.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.PackageImport;
+import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.Profile;
+
+/**
+ * An IGenerator for building Contexts from a UML Profile
+ *
+ * @author Camille Letavernier
+ */
+
+// FIXME warning if all profiles have the same name overwrite the same file
+public class ProfileGenerator extends AbstractQVTGenerator {
+
+ private FileChooser sourceFileChooser;
+
+ private Profile umlProfile;
+
+ private List<Object> list;
+
+ private List<EObject> listEObject;
+
+
+ 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);
+ listEObject = new ArrayList<EObject>();
+ }
+
+ 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() {
+ LinkedList<ModelExtent> result = new LinkedList<ModelExtent>();
+ ModelExtent inPackage = new BasicModelExtent();
+ List<EObject> liste = new ArrayList<EObject>();
+ if (!listEObject.isEmpty()) {
+ for (EObject currentEObject : listEObject) {
+ EObject tempEObject = null;
+ try {
+ tempEObject = loadEMFModel(currentEObject.eResource().getURI());
+ liste.add(tempEObject);
+
+ } catch (IOException e) {
+ }
+ }
+ } else {
+ liste.add(umlProfile);
+
+
+ }
+ inPackage.setContents(liste);
+
+ URI umlURI = URI.createURI("ppe:/context/org.eclipse.papyrus.uml.properties/Model/UML/UML.ctx", true);
+ Context umlContext = null;
+ try {
+ umlContext = (Context) loadEMFModel(umlURI);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (umlContext == null) {
+ Activator.log.warn("Cannot find the UML Property View configuration");
+ }
+
+ ModelExtent inUml = new BasicModelExtent(Collections.singletonList(umlContext));
+
+ PropertiesRoot root = ConfigurationManager.getInstance().getPropertiesRoot();
+ ModelExtent inRoot = new BasicModelExtent(Collections.singletonList(root));
+
+ result.add(inPackage);
+ result.add(getOutContextExtent());
+ result.add(inUml);
+ result.add(inRoot);
+
+ return result;
+ }
+
+
+ @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);
+ }
+
+ @Override
+ public IObservableValue getObservableValue() {
+ return sourceFileChooser.getObservableValue();
+ }
+
+ public List<Object> getExternalReference() {
+ URI packageURI = URI.createPlatformResourceURI(sourceFileChooser.getFilePath(), true);
+ try {
+ umlProfile = (Profile) loadEMFModel(packageURI);
+ } catch (IOException e) {
+ // nothing
+ }
+ list = new ArrayList<Object>();
+ list.add(umlProfile);
+
+ TreeIterator<EObject> tree = umlProfile.eAllContents();
+ while (tree.hasNext()) {
+ Object obj = tree.next();
+ if (obj instanceof PackageImport) {
+ PackageImport currentPackage = (PackageImport) obj;
+ if (!list.contains(currentPackage.getImportedPackage())) {
+ list.add(currentPackage.getImportedPackage());
+ }
+ }
+
+
+ }
+
+ return list;
+ }
+
+
+ public void addCheckElement(Object obj) {
+ if (obj instanceof EObject) {
+ EObject current = (EObject) obj;
+ if (!listEObject.contains(current)) {
+ listEObject.add(current);
+ }
+ }
+
+ }
+
+
+
+
+ @Override
+ protected List<ModelExtent> getModelExtents(int i) {
+ try {
+ ModelExtent inProfile = null;
+
+ if (listEObject.get(i) instanceof Package) {
+ Package currentPackage = (Package) listEObject.get(i);
+ umlProfile = (Profile) loadEMFModel(currentPackage.eResource().getURI());
+ 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.getInstance().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;
+
+ }
+}

Back to the top