[438074] Creation of a command for Class Diagram Pattern

This is a Class/Entity Diagram Description Initializer command. It
creates
a skeleton with Package, Class as list, Attributes, Inheritance and
Reference mappings and a set of default tools. The created skeleton
corresponds to the Bug 438074 attachment.

Bug: 438074
Change-Id: I593973b788b4c14a11e2c4905ffc295fd0411b29
Signed-off-by: João Martins <joaomartins27396@gmail.com>
diff --git a/plugins/org.eclipse.sirius.editor.diagram/plugin.xml b/plugins/org.eclipse.sirius.editor.diagram/plugin.xml
index 43ef7c5..f1b3a14 100644
--- a/plugins/org.eclipse.sirius.editor.diagram/plugin.xml
+++ b/plugins/org.eclipse.sirius.editor.diagram/plugin.xml
@@ -2,7 +2,7 @@
 <?eclipse version="3.0"?>
 <!-- Start of user code plugin.xml start specifics  -->
 <!--
-   Copyright (c) 2007, 2014 THALES GLOBAL SERVICES.
+   Copyright (c) 2007, 2014 THALES GLOBAL SERVICES 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
@@ -10,6 +10,7 @@
 
    Contributors:
       Obeo - initial API and implementation
+      Joao Martins <joaomartins27396@gmail.com> - Bug 438074
 
 -->
 
@@ -22,6 +23,9 @@
            class="org.eclipse.sirius.diagram.editor.tools.internal.menu.refactoring.DiagramRefactoringMenu">
      </builder>
      <builder
+           class="org.eclipse.sirius.diagram.editor.tools.internal.menu.initializer.DiagramInitializerMenu">
+     </builder>
+     <builder
            class="org.eclipse.sirius.diagram.editor.tools.internal.menu.child.ElementCreationMenuBuilder">
      </builder>
      <builder
diff --git a/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/DiagramInitializerMenu.java b/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/DiagramInitializerMenu.java
new file mode 100644
index 0000000..c9aff4e
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/DiagramInitializerMenu.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2014 - Joao Martins 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:
+ *   Joao Martins <joaomartins27396@gmail.com>  - initial API and implementation
+ *   Maxime Porhel <maxime.porhel@obeo.fr> Obeo - Bug 438074, remarks and correction during review.
+ *******************************************************************************/
+
+package org.eclipse.sirius.diagram.editor.tools.internal.menu.initializer;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.sirius.editor.tools.api.menu.AbstractEObjectRefactoringAction;
+import org.eclipse.sirius.editor.tools.api.menu.AbstractMenuBuilder;
+import org.eclipse.ui.IEditorPart;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+
+/**
+ * Menu of the Initializer.
+ * 
+ * @author Joao Martins
+ * 
+ */
+public class DiagramInitializerMenu extends AbstractMenuBuilder {
+
+    /**
+     * Initializer menu label.
+     */
+    public static final String INITIALIZER_MENU_LABEL = "Initializer";
+
+    @Override
+    public String getLabel() {
+        return INITIALIZER_MENU_LABEL;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void update(final Collection newChildDescriptors, final ISelection selection, final IEditorPart editor) {
+        depopulate();
+        advancedChildActions = generateInitializerActions(selection, editor);
+    }
+
+    private Collection generateInitializerActions(final ISelection selection, final IEditorPart editor) {
+
+        // We first build all candidate Actions
+        Set<AbstractEObjectRefactoringAction> allActions = Sets.newLinkedHashSet();
+        allActions.add(new InitializerAction(editor, selection));
+
+        // We only add to the menu the actions that have a valid selection
+        return Sets.filter(allActions, new Predicate<AbstractEObjectRefactoringAction>() {
+
+            public boolean apply(AbstractEObjectRefactoringAction candidateAction) {
+                return candidateAction.isSelectionValid();
+            }
+        });
+    }
+
+    @Override
+    protected boolean isMine(CommandParameter object) {
+        return false;
+    }
+
+}
diff --git a/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/InitializerAction.java b/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/InitializerAction.java
new file mode 100644
index 0000000..8268287
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/InitializerAction.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2014 - Joao Martins 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:
+ *   Joao Martins <joaomartins27396@gmail.com>  - initial API and implementation 
+ *   Maxime Porhel <maxime.porhel@obeo.fr> Obeo - Bug 438074, remarks and correction during review.
+ *******************************************************************************/
+
+package org.eclipse.sirius.diagram.editor.tools.internal.menu.initializer;
+
+import java.util.Collection;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.sirius.editor.tools.api.menu.AbstractEObjectRefactoringAction;
+import org.eclipse.sirius.viewpoint.description.Viewpoint;
+import org.eclipse.ui.IEditorPart;
+
+/**
+ * Action to launch the Intializer, it is valid only when the selection contains
+ * one Viewpoint.
+ * 
+ * 
+ * @author Joao Martins.
+ * 
+ */
+public class InitializerAction extends AbstractEObjectRefactoringAction {
+
+    /**
+     * Create the action.
+     * 
+     * @param editor
+     *            the current editor.
+     * @param selection
+     *            the current selection.
+     */
+    public InitializerAction(final IEditorPart editor, final ISelection selection) {
+        super(editor, selection);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected Command buildActionCommand(final EditingDomain arg0, final Collection<EObject> selection) {
+        Command result = UnexecutableCommand.INSTANCE;
+        setSelectionValid(false);
+        if (selection.size() == 1 && selection.iterator().next() instanceof Viewpoint) {
+            setSelectionValid(true);
+            result = new InitializerCommand(arg0.getResourceSet(), selection);
+        }
+
+        return result;
+    }
+
+}
diff --git a/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/InitializerCommand.java b/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/InitializerCommand.java
new file mode 100644
index 0000000..b130911
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor.diagram/src/org/eclipse/sirius/diagram/editor/tools/internal/menu/initializer/InitializerCommand.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2014 - Joao Martins 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:
+ *   Joao Martins <joaomartins27396@gmail.com>  - initial API and implementation
+ *   Maxime Porhel <maxime.porhel@obeo.fr> Obeo - Bug 438074, remarks and correction during review.
+ *******************************************************************************/
+
+package org.eclipse.sirius.diagram.editor.tools.internal.menu.initializer;
+
+import java.util.Collection;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.sirius.diagram.ContainerLayout;
+import org.eclipse.sirius.diagram.description.ContainerMapping;
+import org.eclipse.sirius.diagram.description.DescriptionFactory;
+import org.eclipse.sirius.diagram.description.DiagramDescription;
+import org.eclipse.sirius.diagram.description.DiagramElementMapping;
+import org.eclipse.sirius.diagram.description.EdgeMapping;
+import org.eclipse.sirius.diagram.description.Layer;
+import org.eclipse.sirius.diagram.description.NodeMapping;
+import org.eclipse.sirius.diagram.description.style.EdgeStyleDescription;
+import org.eclipse.sirius.diagram.description.style.StyleFactory;
+import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.DeleteElementDescription;
+import org.eclipse.sirius.diagram.description.tool.DirectEditLabel;
+import org.eclipse.sirius.diagram.description.tool.EdgeCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
+import org.eclipse.sirius.diagram.description.tool.ToolFactory;
+import org.eclipse.sirius.diagram.description.tool.ToolSection;
+import org.eclipse.sirius.editor.tools.api.menu.AbstractUndoRecordingCommand;
+import org.eclipse.sirius.viewpoint.description.Viewpoint;
+
+/**
+ * This is a command to create a skeleton of a Class/Entity diagram.
+ * 
+ * @author Joao Martins
+ * 
+ */
+public class InitializerCommand extends AbstractUndoRecordingCommand {
+
+    /**
+     * Command Label.
+     */
+    public static final String TEXT = "Class diagram skeleton creation command";
+
+    /**
+     * Default ID.
+     */
+    private static final String BASE_ID = "pattern.class.diagram";
+
+    private final Viewpoint viewpoint;
+
+    /**
+     * Constructor.
+     * 
+     * @param set
+     *            set.
+     * @param selection
+     *            selection.
+     */
+    public InitializerCommand(ResourceSet set, final Collection<EObject> selection) {
+        super(set);
+        this.viewpoint = (Viewpoint) selection.iterator().next();
+        this.setLabel(TEXT);
+    }
+
+    @Override
+    protected void doExecute() {
+        // Create the Pattern Elements
+        DiagramDescription diagramdesc = DescriptionFactory.eINSTANCE.createDiagramDescription();
+        diagramdesc.setName(BASE_ID + ".default.layer");
+        viewpoint.getOwnedRepresentations().add(diagramdesc);
+
+        Layer layer = DescriptionFactory.eINSTANCE.createLayer();
+        diagramdesc.setDefaultLayer(layer);
+        ToolSection toolSection = createToolSection(layer);
+
+        ContainerMapping packageMapping = createPackageMapping(layer, toolSection);
+        ContainerMapping classMapping = createClassMapping(layer, toolSection);
+
+        NodeMapping attribute = createAttribute(classMapping, toolSection);
+
+        EdgeMapping edgeMappingInheritance = createEdgeMappingInheritance(layer, toolSection, classMapping);
+        EdgeMapping edgeMappingReference = createEdgeMappingReference(layer, toolSection, classMapping);
+
+        createDeleteTool(toolSection, classMapping, packageMapping, attribute, edgeMappingInheritance, edgeMappingReference);
+        createEditTool(toolSection, classMapping, packageMapping, attribute, edgeMappingInheritance, edgeMappingReference);
+    }
+
+    private ContainerMapping createPackageMapping(Layer layer, ToolSection toolSection) {
+        ContainerMapping packageMapping = DescriptionFactory.eINSTANCE.createContainerMapping();
+        packageMapping.setLabel("packageMapping");
+        packageMapping.setName(BASE_ID + ".package.container");
+        packageMapping.setStyle(StyleFactory.eINSTANCE.createFlatContainerStyleDescription());
+        layer.getContainerMappings().add(packageMapping);
+        packageMapping.setSemanticCandidatesExpression("feature:eContents");
+
+        ContainerCreationDescription containerPackageMapping = ToolFactory.eINSTANCE.createContainerCreationDescription();
+        containerPackageMapping.setName(BASE_ID + ".package.container.creation");
+        containerPackageMapping.setLabel("Package");
+        toolSection.getOwnedTools().add(containerPackageMapping);
+        containerPackageMapping.getContainerMappings().add(packageMapping);
+
+        return packageMapping;
+    }
+
+    private NodeMapping createAttribute(ContainerMapping classMapping, ToolSection toolSection) {
+        NodeMapping attribute = DescriptionFactory.eINSTANCE.createNodeMapping();
+        attribute.setLabel("Attribute");
+        attribute.setName(BASE_ID + "class.list.attribute");
+
+        NodeCreationDescription nodeCreation = ToolFactory.eINSTANCE.createNodeCreationDescription();
+        nodeCreation.setName(BASE_ID + ".class.list.attribute.creation");
+        nodeCreation.setLabel("Attribute");
+        toolSection.getOwnedTools().add(nodeCreation);
+        nodeCreation.getNodeMappings().add(attribute);
+
+        classMapping.getSubNodeMappings().add(attribute);
+        return attribute;
+    }
+
+    private ContainerMapping createClassMapping(Layer layer, ToolSection toolSection) {
+        ContainerMapping classMapping = DescriptionFactory.eINSTANCE.createContainerMapping();
+        classMapping.setChildrenPresentation(ContainerLayout.LIST);
+
+        classMapping.setLabel("classMapping");
+        classMapping.setName(BASE_ID + ".class.list");
+        layer.getContainerMappings().add(classMapping);
+        classMapping.setSemanticCandidatesExpression("feature:eContents");
+
+        ContainerCreationDescription containerClassMapping = ToolFactory.eINSTANCE.createContainerCreationDescription();
+        containerClassMapping.setName(BASE_ID + ".class.list.creation");
+        containerClassMapping.setLabel("Class");
+        toolSection.getOwnedTools().add(containerClassMapping);
+        containerClassMapping.getContainerMappings().add(classMapping);
+        return classMapping;
+    }
+
+    private EdgeMapping createEdgeMappingInheritance(Layer layer, ToolSection toolSection, ContainerMapping classMapping) {
+        EdgeMapping edgeMappingInheritance = DescriptionFactory.eINSTANCE.createEdgeMapping();
+        EdgeStyleDescription edgeStyleI = StyleFactory.eINSTANCE.createEdgeStyleDescription();
+
+        edgeMappingInheritance.setName(BASE_ID + ".edge.inheritance");
+        edgeMappingInheritance.setLabel("Inheritance");
+
+        edgeStyleI.setCenterLabelStyleDescription(StyleFactory.eINSTANCE.createCenterLabelStyleDescription());
+
+        edgeMappingInheritance.setStyle(edgeStyleI);
+
+        edgeMappingInheritance.getSourceMapping().add(classMapping);
+        edgeMappingInheritance.getTargetMapping().add(classMapping);
+
+        layer.getEdgeMappings().add(edgeMappingInheritance);
+
+        EdgeCreationDescription edgeCreationDescription = ToolFactory.eINSTANCE.createEdgeCreationDescription();
+        edgeCreationDescription.setName(BASE_ID + ".edge.inheritance.creation");
+        edgeCreationDescription.setLabel("Inheritance");
+        
+        edgeCreationDescription.getEdgeMappings().add(edgeMappingInheritance);
+        toolSection.getOwnedTools().add(edgeCreationDescription);
+
+        return edgeMappingInheritance;
+    }
+
+    private EdgeMapping createEdgeMappingReference(Layer layer, ToolSection toolSection, ContainerMapping classMapping) {
+        EdgeMapping edgeMappingReference = DescriptionFactory.eINSTANCE.createEdgeMapping();
+        EdgeStyleDescription edgeStyleR = StyleFactory.eINSTANCE.createEdgeStyleDescription();
+
+        edgeMappingReference.setName(BASE_ID + ".edge.reference");
+        edgeMappingReference.setLabel("Reference");
+
+        edgeMappingReference.setUseDomainElement(true);
+
+        edgeStyleR.setCenterLabelStyleDescription(StyleFactory.eINSTANCE.createCenterLabelStyleDescription());
+
+        edgeMappingReference.setStyle(edgeStyleR);
+
+        edgeMappingReference.getSourceMapping().add(classMapping);
+        edgeMappingReference.getTargetMapping().add(classMapping);
+
+        layer.getEdgeMappings().add(edgeMappingReference);
+
+        EdgeCreationDescription edgeCreationDescription = ToolFactory.eINSTANCE.createEdgeCreationDescription();
+        edgeCreationDescription.setName(BASE_ID + ".edge.reference.creation");
+        edgeCreationDescription.setLabel("Reference");
+        
+        edgeCreationDescription.getEdgeMappings().add(edgeMappingReference);
+        toolSection.getOwnedTools().add(edgeCreationDescription);
+
+        return edgeMappingReference;
+    }
+
+    private ToolSection createToolSection(Layer layer) {
+        ToolSection toolSection = ToolFactory.eINSTANCE.createToolSection();
+        toolSection.setLabel("Tool Section");
+        toolSection.setName(BASE_ID + ".package.toolsection");
+        layer.getToolSections().add(toolSection);
+        return toolSection;
+    }
+
+    private void createDeleteTool(ToolSection toolSection, DiagramElementMapping... mappings) {
+        DeleteElementDescription deleteElement = ToolFactory.eINSTANCE.createDeleteElementDescription();
+        deleteElement.setName(BASE_ID + "global.delete");
+        deleteElement.setLabel("Delete Tool");
+        toolSection.getOwnedTools().add(deleteElement);
+
+        for (DiagramElementMapping dem : mappings) {
+            deleteElement.getMappings().add(dem);
+        }
+    }
+
+    private void createEditTool(ToolSection toolSection, DiagramElementMapping... mappings) {
+        DirectEditLabel directEditElement = ToolFactory.eINSTANCE.createDirectEditLabel();
+        directEditElement.setName(BASE_ID + ".global.directedit");
+        directEditElement.setLabel("Edit Tool");
+        toolSection.getOwnedTools().add(directEditElement);
+
+        for (DiagramElementMapping dem : mappings) {
+            directEditElement.getMapping().add(dem);
+        }
+    }
+
+    @Override
+    public boolean canExecute() {
+        return true;
+    }
+
+    @Override
+    protected String getText() {
+        return TEXT;
+    }
+
+}
diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/menu/initializer/InitializerMenu.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/menu/initializer/InitializerMenu.java
new file mode 100644
index 0000000..7755908
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/menu/initializer/InitializerMenu.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2014 - Joao Martins 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:
+ *   Joao Martins <joaomartins27396@gmail.com> - initial API and implementation 
+ *   Maxime Porhel <maxime.porhel@obeo.fr> Obeo - Bug 438074, remarks and correction during review.
+ *******************************************************************************/
+
+package org.eclipse.sirius.editor.tools.internal.menu.initializer;
+
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.sirius.editor.tools.api.menu.AbstractMenuBuilder;
+
+/**
+ * Specific menu builder to create an Initializer menu.
+ * 
+ * @author Joao Martins
+ * 
+ */
+public class InitializerMenu extends AbstractMenuBuilder {
+
+    /**
+     * Initializer menu label.
+     */
+    public static final String INITIALIZER_MENU_LABEL = "Initializer";
+
+    @Override
+    public String getLabel() {
+        return INITIALIZER_MENU_LABEL;
+    }
+
+    @Override
+    protected boolean isMine(CommandParameter object) {
+        return false;
+    }
+
+}
diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/presentation/CustomSiriusActionBarContributor.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/presentation/CustomSiriusActionBarContributor.java
index 1660cff..1a60419 100644
--- a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/presentation/CustomSiriusActionBarContributor.java
+++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/presentation/CustomSiriusActionBarContributor.java
@@ -8,6 +8,7 @@
  * Contributors:
  *    Obeo - initial API and implementation
  *    Joao Martins <joaomartins27396@gmail.com> - Bug 434698
+ *    Joao Martins <joaomartins27396@gmail.com> - Bug 438074
  *******************************************************************************/
 package org.eclipse.sirius.editor.tools.internal.presentation;
 
@@ -63,6 +64,7 @@
 import org.eclipse.sirius.editor.tools.internal.menu.child.StyleMenuBuilder;
 import org.eclipse.sirius.editor.tools.internal.menu.child.ValidationMenuBuilder;
 import org.eclipse.sirius.editor.tools.internal.menu.child.VariablesMenuBuilder;
+import org.eclipse.sirius.editor.tools.internal.menu.initializer.InitializerMenu;
 import org.eclipse.sirius.editor.tools.internal.menu.refactoring.RefactoringMenu;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.PartInitException;
@@ -440,8 +442,8 @@
 
     private void insertInParentMenu(final IMenuManager menuManager) {
         for (final AbstractMenuBuilder builder : builders) {
-            if (RefactoringMenu.REFACTORING_MENU_LABEL.equals(builder.getLabel())) {
-                // Refactoring menu should be added after the edit group
+            if (RefactoringMenu.REFACTORING_MENU_LABEL.equals(builder.getLabel()) || InitializerMenu.INITIALIZER_MENU_LABEL.equals(builder.getLabel())) {
+                //Refactoring and Initializer menu should be added after the edit group.
                 builder.insertAfterInContainer(menuManager);
             } else {
                 builder.insertBeforeInContainer(menuManager);