Commit d2023e0b authored by Rakshit Mittal's avatar Rakshit Mittal
Browse files

Preference page and property page implemented

parent 784e90af
......@@ -27,6 +27,7 @@
</buildCommand>
</buildSpec>
<natures>
<nature>org.osate.core.aadlnature</nature>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
......
......@@ -38,4 +38,5 @@ Import-Package: com.google.inject,
Require-Bundle: org.junit,
fr.mem4csd.osatedim.viatra,
org.eclipse.core.resources,
org.junit.jupiter.api
org.junit.jupiter.api,
fr.mem4csd.osatedim.ui
......@@ -498,7 +498,7 @@ end ReceiveInputProcessorPort;
data ResourceType extends RuntimeDataType
properties
Source_Name => "resource_t";
end ResoureType;
end ResourceType;
data LockAccessProtocolType extends RuntimeDataType
properties
......
......@@ -6,7 +6,8 @@ import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.junit.jupiter.api.Test;
import org.osate.aadl2.AadlPackage;
import fr.mem4csd.osatedim.ui.DeinstantiationUtils;
import fr.mem4csd.osatedim.ui.utils.DeinstantiationUtils;
import fr.mem4csd.osatedim.viatra.utils.PackageUtils;
import fr.mem4csd.osatedim.viatra.utils.TransformationUtils;
......
......@@ -22,6 +22,7 @@ Import-Package: org.eclipse.core.commands,
org.osate.aadl2.modelsupport,
org.osate.aadl2.modelsupport.resources
Export-Package: fr.mem4csd.osatedim.ui,
fr.mem4csd.osatedim.ui.handlers
fr.mem4csd.osatedim.ui.handlers,
fr.mem4csd.osatedim.ui.utils
Bundle-ActivationPolicy: lazy
Bundle-Vendor: MEM4CSD Telecom Paris
......@@ -237,7 +237,25 @@
category="org.osate.internal.ui.preferences.OsatePreferencePage"
class="fr.mem4csd.osatedim.ui.DeinstantiationPreferencePage"
id="fr.mem4csd.osatedim.ui.preferencePage"
name="Deinstantiation">
name="DIM: Deinstantiation">
</page>
</extension>
<extension
point="org.eclipse.ui.propertyPages">
<page
category="org.osate.ui.properties.OSATE"
class="fr.mem4csd.osatedim.ui.DeinstantiationPropertyPage"
id="fr.mem4csd.osatedim.ui.propertyPage"
name="DIM: Deinstantiation">
<enabledWhen>
<adapt
type="org.eclipse.core.resources.IProject">
<test
property="org.eclipse.core.resources.projectNature"
value="org.osate.core.aadlnature">
</test>
</adapt>
</enabledWhen>
</page>
</extension>
</plugin>
......@@ -10,7 +10,6 @@ import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorReference;
......@@ -22,16 +21,17 @@ import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
import org.eclipse.viatra.query.runtime.emf.EMFScope;
import org.osate.aadl2.instance.SystemInstance;
import org.osate.aadl2.modelsupport.FileNameConstants;
import org.osate.aadl2.modelsupport.resources.OsateResourceUtil;
import fr.mem4csd.osatedim.ui.utils.DeinstantiationUtils;
import fr.mem4csd.osatedim.ui.utils.EditorUtils;
import fr.mem4csd.osatedim.viatra.preference.DeinstantiationPreference;
import fr.mem4csd.osatedim.viatra.transformations.DIMTransformationDeltaInplace;
public class DIMStartup extends AbstractUIPlugin implements IStartup, IPartListener {
public class DIMStartup implements IStartup, IPartListener {
private static DIMStartup instance = null;
......@@ -39,6 +39,7 @@ public class DIMStartup extends AbstractUIPlugin implements IStartup, IPartListe
private final QualifiedName syncPropQualName;
private final Map<URI, DIMTransformationDeltaInplace> transformationMap;
private final DeinstantiationPreference preferenceStore;
public static DIMStartup getInstance() {
return instance;
......@@ -46,9 +47,8 @@ public class DIMStartup extends AbstractUIPlugin implements IStartup, IPartListe
public DIMStartup() {
super();
instance = this;
preferenceStore = new DeinstantiationPreference();
transformationMap = new HashMap<URI, DIMTransformationDeltaInplace>();
syncPropQualName = new QualifiedName( getClass().getPackageName(), "synchronized" );
}
......@@ -229,17 +229,5 @@ public class DIMStartup extends AbstractUIPlugin implements IStartup, IPartListe
return null;
}
public static final String propertyInheritanceUtilityPreference = null;
public static final String deleteUnusedClassifierPreference = null;
public static final String classifierExtensionPreference = null;
public static final Boolean propertyInheritanceUtilityPreferenceDefault = true;
public static final Boolean collapseUnusedClassifierPreferenceDefault = false;
public static final Integer classifierExtensionPreferenceDefault = 0;
protected void initializeDefaultPreferences(IPreferenceStore store) {
store.setDefault(propertyInheritanceUtilityPreference,propertyInheritanceUtilityPreferenceDefault);
}
}
......@@ -19,12 +19,15 @@ import org.eclipse.ui.IWorkbenchPreferencePage;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.osate.core.AadlNature;
import org.osate.ui.dialogs.ProjectSelectionDialog;
import fr.mem4csd.osatedim.ui.utils.SpacerFieldEditor;
import fr.mem4csd.osatedim.viatra.preference.ClassifierExtensionPreference;
import fr.mem4csd.osatedim.viatra.preference.DeinstantiationPreference;
public class DeinstantiationPreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
private static final String LABEL = "Configure Project Specific Settings...";
private static final String TITLE = "Project Specific Configuration";
private static final String MESSAGE = "Select the project to configure:";
private static final String ID = "fr.mem4csd.osatedim.ui.DeinstantiationPropertyPage";
private static final String ID = "fr.mem4csd.osatedim.ui.propertyPage";
private static final String[] ID_LIST = { ID };
private static final Object DUMMY_DATA = new Object();
......@@ -32,8 +35,8 @@ public class DeinstantiationPreferencePage extends FieldEditorPreferencePage imp
public DeinstantiationPreferencePage() {
super(GRID);
setPreferenceStore(DIMStartup.getInstance().getPreferenceStore());
setDescription("OSATE-DIM: AADL model deinstantiation preferences");
setPreferenceStore(DeinstantiationPreference.getInstance().getPreferenceStore());
setDescription("OSATE-DIM: Deinstantiation Preferences");
}
@Override
......@@ -66,11 +69,31 @@ public class DeinstantiationPreferencePage extends FieldEditorPreferencePage imp
*/
@Override
public void createFieldEditors() {
final BooleanFieldEditor propertyInheritanceUtilityField = new BooleanFieldEditor(DIMStartup.propertyInheritanceUtilityPreference,"Automatically add inherited properties to newly created instance elements", getFieldEditorParent());
SpacerFieldEditor spacer0 = new SpacerFieldEditor(
getFieldEditorParent());
addField(spacer0);
final BooleanFieldEditor propertyInheritanceUtilityField = new BooleanFieldEditor(
DeinstantiationPreference.INHERIT_PROPERTY_PREFERENCE,"AUTO-ADD INHERITED PROPERTIES to new instance elements", getFieldEditorParent());
addField(propertyInheritanceUtilityField);
final BooleanFieldEditor deleteUnusuedClassifierField = new BooleanFieldEditor(DIMStartup.deleteUnusedClassifierPreference,"Delete all unused classifiers created by OSATE-DIM (loss of delta information!)", getFieldEditorParent());
SpacerFieldEditor spacer1 = new SpacerFieldEditor(
getFieldEditorParent());
addField(spacer1);
final BooleanFieldEditor deleteUnusuedClassifierField = new BooleanFieldEditor(
DeinstantiationPreference.DELETE_CLASSIFIER_PREFERENCE,"DELETE UNUSED CLASSIFIERS created by OSATE-DIM (loss of delta information!)", getFieldEditorParent());
addField(deleteUnusuedClassifierField);
final RadioGroupFieldEditor classifierExtensionField = new RadioGroupFieldEditor(DIMStartup.classifierExtensionPreference,"Classifier extension preference",1, new String[][] {{"NONE",ComponentExtensionPreference.NONE_EXTENSION.getLiteral()},{"Structural changes",ComponentExtensionPreference.REQUIRED_EXTENSION.getLiteral()},{"Always",ComponentExtensionPreference.ALWAYS_EXTENSION.getLiteral()}},getFieldEditorParent());
SpacerFieldEditor spacer2 = new SpacerFieldEditor(
getFieldEditorParent());
addField(spacer2);
final RadioGroupFieldEditor classifierExtensionField = new RadioGroupFieldEditor(
DeinstantiationPreference.EXTEND_CLASSIFIER_PREFERENCE,"Classifier extension preference:",1,
new String[][] {{"NONE",ClassifierExtensionPreference.NONE_EXTENSION.getLiteral()},
{"ONLY REQUIRED (Structural changes)",ClassifierExtensionPreference.REQUIRED_EXTENSION.getLiteral()},
{"ALWAYS (Recommended DELETE_UNUSED_CLASSIFIERS = true)",ClassifierExtensionPreference.ALWAYS_EXTENSION.getLiteral()}},getFieldEditorParent());
addField(classifierExtensionField);
}
......@@ -87,8 +110,7 @@ public class DeinstantiationPreferencePage extends FieldEditorPreferencePage imp
}
}
final ProjectSelectionDialog dialog = new ProjectSelectionDialog(getShell(), projectsWithSpecifics, TITLE,
MESSAGE);
final ProjectSelectionDialog dialog = new ProjectSelectionDialog(getShell(), projectsWithSpecifics, TITLE, MESSAGE);
if (dialog.open() == Window.OK) {
final IProject project = dialog.getSelectedProject();
PreferencesUtil.createPropertyDialogOn(getShell(), project, ID, ID_LIST, DUMMY_DATA).open();
......
package fr.mem4csd.osatedim.ui;
public class DeinstantiationPropertyPage {
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.Adapters;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.jface.preference.IPreferenceNode;
import org.eclipse.jface.preference.IPreferencePage;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferenceManager;
import org.eclipse.jface.preference.PreferenceNode;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.ui.dialogs.PropertyPage;
import org.osate.ui.internal.preferences.InstantiationPreferencePage;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
import fr.mem4csd.osatedim.viatra.preference.ClassifierExtensionPreference;
import fr.mem4csd.osatedim.viatra.preference.DeinstantiationPreference;
import fr.mem4csd.osatedim.viatra.transformations.DIMTransformationRules;
public class DeinstantiationPropertyPage extends PropertyPage {
private Button inheritProperty;
private Button deleteClassifier;
private Preferences preferences;
private Button noClassifierExtension, requiredClassifierExtension, alwaysClassifierExtension;
Button useWorkspaceSettingsButton;
Button useProjectSettingsButton;
Button configureButton;
@Override
protected Control createContents(Composite parent) {
// Get the project
IProject project = Adapters.adapt(getElement(), IProject.class);
if (project == null) {
IResource resource = Adapters.adapt(getElement(), IResource.class);
Assert.isNotNull(resource, "unable to adapt element to a project");
project = resource.getProject();
}
// Get the project's preferences
final IScopeContext context = new ProjectScope(project);
preferences = context.getNode(DIMTransformationRules.PREFS_QUALIFIER);
// Create the overall composite to fill up
final Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2, false));
// Create the buttons for choosing between workspace and project preferences
final Composite selectionGroup = new Composite(composite, SWT.NONE);
final GridLayout sgLayout = new GridLayout(2, false);
sgLayout.marginHeight = 0;
sgLayout.marginWidth = 0;
selectionGroup.setLayout(sgLayout);
selectionGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 2, 1));
final Composite radioGroup = new Composite(selectionGroup, SWT.NONE);
radioGroup.setLayout(new GridLayout());
radioGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
useWorkspaceSettingsButton = new Button(radioGroup, SWT.RADIO);
useWorkspaceSettingsButton.setText("Use workspace settings");
useProjectSettingsButton = new Button(radioGroup, SWT.RADIO);
useProjectSettingsButton.setText("Use project settings");
configureButton = new Button(selectionGroup, SWT.PUSH);
configureButton.setText("Configure Workspace Settings ...");
// Create the actual property fields that we want to edit
inheritProperty = new Button(composite, SWT.CHECK);
inheritProperty.setSelection(getInherentProperty());
inheritProperty.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 1, 1));
final Label label0 = new Label(composite, SWT.NONE);
label0.setText("AUTO-ADD INHERITED PROPERTIES to new instance elements");
label0.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
deleteClassifier = new Button(composite, SWT.CHECK);
deleteClassifier.setSelection(getDeleteClassifier());
deleteClassifier.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false, 1, 1));
final Label label1 = new Label(composite, SWT.NONE);
label1.setText("DELETE UNUSED CLASSIFIERS created by OSATE-DIM (loss of delta information!)");
label1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));
final Composite radioGroup1 = new Composite(composite, SWT.NONE);
radioGroup1.setLayout(new GridLayout());
radioGroup1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
noClassifierExtension = new Button(radioGroup1, SWT.RADIO);
noClassifierExtension.setText("NONE");
requiredClassifierExtension = new Button(radioGroup1, SWT.RADIO);
requiredClassifierExtension.setText("ONLY REQUIRED (Structural changes)");
alwaysClassifierExtension = new Button(radioGroup1, SWT.RADIO);
alwaysClassifierExtension.setText("ALWAYS (Recommended DELETE_UNUSED_CLASSIFIERS = true)");
if (getExtendClassifier() == "none") {
noClassifierExtension.setSelection(true);
} else if (getExtendClassifier() == "required") {
requiredClassifierExtension.setSelection(true);
} else {
alwaysClassifierExtension.setSelection(true);
}
// Configure button status
if (useWorkspacePreferences()) {
useWorkspaceSettingsButton.setSelection(true);
useProjectSettingsButton.setSelection(false);
configureButton.setEnabled(true);
inheritProperty.setEnabled(false);
deleteClassifier.setEnabled(false);
radioGroup1.setEnabled(false);
} else {
useWorkspaceSettingsButton.setSelection(false);
useProjectSettingsButton.setSelection(true);
configureButton.setEnabled(false);
inheritProperty.setEnabled(true);
deleteClassifier.setEnabled(true);
radioGroup1.setEnabled(true);
}
// Add listeners
useWorkspaceSettingsButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
configureButton.setEnabled(true);
inheritProperty.setEnabled(false);
deleteClassifier.setEnabled(false);
radioGroup1.setEnabled(false);
}
});
useProjectSettingsButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
configureButton.setEnabled(false);
inheritProperty.setEnabled(true);
deleteClassifier.setEnabled(true);
radioGroup1.setEnabled(true);
}
});
configureButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
configureWorkspaceSettings();
}
});
// return the whole thing
return composite;
}
private boolean getInherentProperty() {
return preferences.getBoolean(DIMTransformationRules.PREF_INHERIT_PROPERTY, DeinstantiationPreference.getInstance().getInheritProperty());
}
private boolean getDeleteClassifier() {
return preferences.getBoolean(DIMTransformationRules.PREF_DELETE_CLASSIFIER, DeinstantiationPreference.getInstance().getDeleteClassifier());
}
private String getExtendClassifier() {
return preferences.get(DIMTransformationRules.PREF_EXTEND_CLASSIFIER, DeinstantiationPreference.getInstance().getExtendClassifier());
}
private boolean useWorkspacePreferences() {
return preferences.getBoolean(DIMTransformationRules.PREF_USE_WORKSPACE, true);
}
@Override
public boolean performOk() {
preferences.putBoolean(DIMTransformationRules.PREF_USE_WORKSPACE, useWorkspaceSettingsButton.getSelection());
preferences.putBoolean(DIMTransformationRules.PREF_INHERIT_PROPERTY, inheritProperty.getSelection());
preferences.putBoolean(DIMTransformationRules.PREF_DELETE_CLASSIFIER, deleteClassifier.getSelection());
if (noClassifierExtension.getSelection()) {
preferences.put(DIMTransformationRules.PREF_EXTEND_CLASSIFIER, ClassifierExtensionPreference.NONE_EXTENSION.getLiteral());
} else if (requiredClassifierExtension.getSelection()) {
preferences.put(DIMTransformationRules.PREF_EXTEND_CLASSIFIER, ClassifierExtensionPreference.REQUIRED_EXTENSION.getLiteral());
} else {
preferences.put(DIMTransformationRules.PREF_EXTEND_CLASSIFIER, ClassifierExtensionPreference.ALWAYS_EXTENSION.getLiteral());
}
try {
preferences.flush();
} catch (final BackingStoreException e) {
e.printStackTrace();
}
return true;
}
@Override
protected void performDefaults() {
useWorkspaceSettingsButton.setSelection(true);
useProjectSettingsButton.setSelection(false);
configureButton.setEnabled(true);
inheritProperty.setSelection(true);
inheritProperty.setEnabled(false);
deleteClassifier.setSelection(false);
deleteClassifier.setEnabled(false);
noClassifierExtension.setSelection(false);
requiredClassifierExtension.setSelection(true);
alwaysClassifierExtension.setSelection(false);
noClassifierExtension.setEnabled(false);
requiredClassifierExtension.setEnabled(false);
alwaysClassifierExtension.setEnabled(false);
// Why? Because the default implementation does this
updateApplyButton();
}
private void configureWorkspaceSettings() {
final IPreferencePage page = new InstantiationPreferencePage();
page.setTitle(getTitle());
final IPreferenceNode targetNode = new PreferenceNode("fr.mem4csd.osatedim.ui.preferencePage", page);
final PreferenceManager manager = new PreferenceManager();
manager.addToRoot(targetNode);
final PreferenceDialog dialog = new PreferenceDialog(getControl().getShell(), manager);
BusyIndicator.showWhile(getControl().getDisplay(), () -> {
dialog.create();
dialog.setMessage(targetNode.getLabelText());
dialog.open();
});
}
}
......@@ -11,7 +11,7 @@ import org.eclipse.ui.handlers.HandlerUtil;
import org.osate.aadl2.instance.SystemInstance;
import fr.mem4csd.osatedim.ui.DIMStartup;
import fr.mem4csd.osatedim.ui.DeinstantiationUtils;
import fr.mem4csd.osatedim.ui.utils.DeinstantiationUtils;
public class DeltaInPlaceDeinstatiationHandler extends AbstractHandler {
......
......@@ -12,7 +12,8 @@ import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.viatra.query.runtime.exception.ViatraQueryException;
import org.osate.aadl2.AadlPackage;
import org.osate.aadl2.instance.SystemInstance;
import fr.mem4csd.osatedim.ui.DeinstantiationUtils;
import fr.mem4csd.osatedim.ui.utils.DeinstantiationUtils;
import fr.mem4csd.osatedim.viatra.utils.PackageUtils;
import fr.mem4csd.osatedim.viatra.utils.TransformationUtils;
......
......@@ -9,7 +9,7 @@ import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
import fr.mem4csd.osatedim.ui.DIMStartup;
import fr.mem4csd.osatedim.ui.DeinstantiationUtils;
import fr.mem4csd.osatedim.ui.utils.DeinstantiationUtils;
public class StopInPlaceDeinstatiationHandler extends AbstractHandler {
......
package fr.mem4csd.osatedim.ui;
package fr.mem4csd.osatedim.ui.utils;
import org.eclipse.core.resources.IFile;
import org.eclipse.emf.common.util.URI;
......
package fr.mem4csd.osatedim.ui;
package fr.mem4csd.osatedim.ui.utils;
import java.util.ArrayList;
import java.util.List;
......
package fr.mem4csd.osatedim.ui.utils;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
/**
* A field editor for displaying labels not associated with other widgets.
*/
class LabelFieldEditor extends FieldEditor {
private Label label;
// All labels can use the same preference name since they don't
// store any preference.
public LabelFieldEditor(String value, Composite parent) {
super("label", value, parent);
}
// Adjusts the field editor to be displayed correctly
// for the given number of columns.
protected void adjustForNumColumns(int numColumns) {
((GridData) label.getLayoutData()).horizontalSpan = numColumns;
}
// Fills the field editor's controls into the given parent.
protected void doFillIntoGrid(Composite parent, int numColumns) {
label = getLabelControl(parent);
GridData gridData = new GridData();
gridData.horizontalSpan = numColumns;
gridData.horizontalAlignment = GridData.FILL;
gridData.grabExcessHorizontalSpace = false;
gridData.verticalAlignment = GridData.CENTER;
gridData.grabExcessVerticalSpace = false;
label.setLayoutData(gridData);
}
// Returns the number of controls in the field editor.
public int getNumberOfControls() {
return 1;
}
// Labels do not persist any preferences, so these methods are empty.
protected void doLoad() {
}
protected void doLoadDefault() {
}
protected void doStore() {
}
}
\ No newline at end of file
package fr.mem4csd.osatedim.ui.utils;
import org.eclipse.swt.widgets.Composite;
/**
* A field editor for adding space to a preference page.
*/
public class SpacerFieldEditor extends LabelFieldEditor {
// Implemented as an empty label field editor.
public SpacerFieldEditor(Composite parent) {
super("", parent);
}
}
\ No newline at end of file
......@@ -4,7 +4,8 @@ Bundle-Name: OSATE-DIM VIATRA Transformations
Bundle-SymbolicName: fr.mem4csd.osatedim.viatra;singleton:=true
Bundle-Version: 0.0.1.qualifier
Bundle-Vendor: MEM4CSD Telecom Paris