Bug 569586 - [PrivacyDesigner] customize the model explorer to
distinguish GDPR requirements

Change-Id: I71c7e8be64057216ede753e700c954b35bc5f555
diff --git a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/META-INF/MANIFEST.MF b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/META-INF/MANIFEST.MF
index 87e6ba4..e3dce35 100644
--- a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/META-INF/MANIFEST.MF
+++ b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/META-INF/MANIFEST.MF
@@ -15,7 +15,8 @@
  org.eclipse.ui.workbench;bundle-version="[3.119.0,4.0.0)",
  org.eclipse.papyrus.infra.gmfdiag.css;bundle-version="[2.4.0,3.0.0)",
  org.eclipse.papyrus.pdp4eng.req.profile;bundle-version="[1.0.0,2.0.0)",
- org.eclipse.papyrus.sysml14;bundle-version="[1.3.0,2.0.0)"
+ org.eclipse.papyrus.sysml14;bundle-version="[1.3.0,2.0.0)",
+ org.eclipse.papyrus.uml.tools;bundle-version="[4.3.0,5.0.0)"
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.papyrus.pdp4eng.req.ui
 Bundle-Activator: org.eclipse.papyrus.pdp4eng.req.ui.Activator
diff --git a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/build.properties b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/build.properties
index 36f7a94..ca1cfd4 100644
--- a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/build.properties
+++ b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/build.properties
@@ -5,4 +5,5 @@
                plugin.xml,\
                icons/,\
                build.properties,\
-               styles/
+               styles/,\
+               models/
diff --git a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/models/pdp4eng.custom b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/models/pdp4eng.custom
new file mode 100644
index 0000000..f276838
--- /dev/null
+++ b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/models/pdp4eng.custom
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<custom:Customization xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:custom="http://www.eclipse.org/papyrus/emf/facet/custom/0.2.incubation/custom" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:efacet="http://www.eclipse.org/papyrus/emf/facet/efacet/0.2.incubation/efacet" xmlns:javaQuery="http://www.eclipse.org/papyrus/emf/facet/query/java/0.2.incubation/javaquery" name="pdp4eng" documentation="Used to Requirements" mustBeLoadedByDefault="true" rank="0">
+  <eClassifiers xsi:type="custom:EClassCustomization" name="NamedElement">
+    <extendedMetaclass href="http://www.eclipse.org/uml2/5.0.0/UML#//NamedElement"/>
+    <facetOperations name="getForeground">
+      <eType xsi:type="ecore:EDataType" href="http://www.eclipse.org/papyrus/emf/facet/custom/0.2.incubation/custom_primitive_types#//Color"/>
+      <eParameters name="eObject">
+        <eType xsi:type="ecore:EClass" href="http://www.eclipse.org/emf/2002/Ecore#//EObject"/>
+      </eParameters>
+      <query xsi:type="javaQuery:JavaQuery" implementationClassName="org.eclipse.papyrus.pdp4eng.req.ui.queries.DisplayGDPRRequirement"/>
+      <override xsi:type="efacet:FacetOperation" href="platform:/plugin/org.eclipse.papyrus.emf.facet.custom.ui/resources/customproperties.efacet#//CustomizedEObject/foreground"/>
+    </facetOperations>
+    <facetOperations name="DisplayLabel">
+      <eType xsi:type="ecore:EDataType" href="http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eParameters name="eReference">
+        <eType xsi:type="ecore:EClass" href="http://www.eclipse.org/emf/2002/Ecore#//EReference"/>
+      </eParameters>
+      <query xsi:type="javaQuery:JavaQuery" implementationClassName="org.eclipse.papyrus.pdp4eng.req.ui.queries.DisplayReqAndGDRPInfo"/>
+      <override xsi:type="efacet:FacetOperation" href="platform:/plugin/org.eclipse.papyrus.emf.facet.custom.ui/resources/customproperties.efacet#//CustomizedEObject/label"/>
+    </facetOperations>
+    <extendedFacets href="platform:/plugin/org.eclipse.papyrus.emf.facet.custom.ui/resources/customproperties.efacet#//CustomizedEObject"/>
+  </eClassifiers>
+</custom:Customization>
diff --git a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/plugin.xml b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/plugin.xml
index 279f196..11db9f3 100644
--- a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/plugin.xml
+++ b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/plugin.xml
@@ -96,6 +96,12 @@
             restorable="true">
       </view>
    </extension>
+  <extension
+        point="org.eclipse.papyrus.emf.facet.util.emf.core.modeldeclaration">
+     <modeldeclaration
+           file="models/pdp4eng.custom">
+     </modeldeclaration>
+  </extension>
 
 </plugin>
    
diff --git a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/src/org/eclipse/papyrus/pdp4eng/req/ui/queries/DisplayGDPRRequirement.java b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/src/org/eclipse/papyrus/pdp4eng/req/ui/queries/DisplayGDPRRequirement.java
new file mode 100644
index 0000000..6bf614c
--- /dev/null
+++ b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/src/org/eclipse/papyrus/pdp4eng/req/ui/queries/DisplayGDPRRequirement.java
@@ -0,0 +1,50 @@
+/**
+ *  Copyright (c)2020 CEA LIST, Committer Name, and others.
+ *
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License 2.0
+ *  which accompanies this distribution, and is available at
+ *  https://www.eclipse.org/legal/epl-2.0/
+ *
+ *  SPDX-License-Identifier: EPL-2.0
+ *
+ *  Contributors:
+ *  Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr   - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.pdp4eng.req.ui.queries;
+
+import org.eclipse.papyrus.emf.facet.custom.metamodel.custompt.IColor;
+import org.eclipse.papyrus.emf.facet.custom.ui.internal.custompt.Color;
+import org.eclipse.papyrus.emf.facet.efacet.core.IFacetManager;
+import org.eclipse.papyrus.emf.facet.efacet.core.exception.DerivedTypedElementException;
+import org.eclipse.papyrus.emf.facet.query.java.core.IJavaQuery2;
+import org.eclipse.papyrus.emf.facet.query.java.core.IParameterValueList2;
+import org.eclipse.papyrus.pdp4eng.req.profile.constraints.GDPRRequiementHelper;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Stereotype;
+
+/**
+ * this class is use to set in blue the color of GDPR requirements
+ *
+ */
+public class DisplayGDPRRequirement implements  IJavaQuery2<NamedElement, IColor> {
+
+	
+
+	public IColor evaluate(final NamedElement context, final IParameterValueList2 parameterValues, final IFacetManager facetManager)
+			throws DerivedTypedElementException {
+
+
+		Stereotype appStereotype = null;
+		if (context.getAppliedStereotypes().size() > 0) {
+			appStereotype = context.getAppliedStereotypes().get(0);
+		}
+
+		if ((context instanceof org.eclipse.uml2.uml.Class) && (appStereotype != null) && (GDPRRequiementHelper.isGDPR_Requirement(context))) {
+				return new Color( 51, 204, 255);
+		}
+		return new Color(0, 0, 0);
+	}
+}
+
diff --git a/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/src/org/eclipse/papyrus/pdp4eng/req/ui/queries/DisplayReqAndGDRPInfo.java b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/src/org/eclipse/papyrus/pdp4eng/req/ui/queries/DisplayReqAndGDRPInfo.java
new file mode 100644
index 0000000..538d7b9
--- /dev/null
+++ b/plugins/req/org.eclipse.papyrus.pdp4eng.req.ui/src/org/eclipse/papyrus/pdp4eng/req/ui/queries/DisplayReqAndGDRPInfo.java
@@ -0,0 +1,106 @@
+/**
+ *  Copyright (c)2020 CEA LIST, Committer Name, and others.
+ *
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License 2.0
+ *  which accompanies this distribution, and is available at
+ *  https://www.eclipse.org/legal/epl-2.0/
+ *
+ *  SPDX-License-Identifier: EPL-2.0
+ *
+ *  Contributors:
+ *  Patrick Tessier (CEA LIST) Patrick.tessier@cea.fr   - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.pdp4eng.req.ui.queries;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.papyrus.emf.facet.efacet.core.IFacetManager;
+import org.eclipse.papyrus.emf.facet.efacet.core.exception.DerivedTypedElementException;
+import org.eclipse.papyrus.emf.facet.efacet.metamodel.v0_2_0.efacet.ParameterValue;
+import org.eclipse.papyrus.emf.facet.query.java.core.IJavaQuery2;
+import org.eclipse.papyrus.emf.facet.query.java.core.IParameterValueList2;
+import org.eclipse.papyrus.pdp4eng.req.profile.constraints.GDPRRequiementHelper;
+import org.eclipse.papyrus.pdp4eng.req.profile.constraints.TraceabilityIndexer;
+import org.eclipse.papyrus.requirements.sysml14.common.I_SysMLStereotype;
+import org.eclipse.papyrus.uml.tools.providers.DelegatingItemLabelProvider;
+import org.eclipse.uml2.uml.DirectedRelationship;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Stereotype;
+
+/** A requirement should be displayed as ID [nb]: text  , nvb is the number of sub GDPR requirements*/
+public class DisplayReqAndGDRPInfo implements IJavaQuery2<NamedElement, String> {
+
+	/**
+	 * test if the stereotype is a SysML Requirement Stereotype
+	 * 
+	 * @param stereotype
+	 *            a given stereotype
+	 * @return return true if this is a SysML stereotype or inherits directly or indirectly from requirement
+	 */
+	protected boolean isRequirementStereotype(Stereotype stereotype) {
+		if (I_SysMLStereotype.REQUIREMENT_STEREOTYPE.equals(stereotype.getQualifiedName())) {
+			return true;
+		}
+		for (org.eclipse.uml2.uml.Class superStereotype : stereotype.getSuperClasses()) {
+			if (superStereotype instanceof Stereotype) {
+				if (isRequirementStereotype((Stereotype) superStereotype)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private static final IItemLabelProvider labelProvider = new DelegatingItemLabelProvider();
+
+	public String evaluate(NamedElement source, IParameterValueList2 parameterValues, IFacetManager facetManager) throws DerivedTypedElementException {
+		ParameterValue parameterValue = parameterValues.getParameterValueByName("eReference"); //$NON-NLS-1$
+		if (parameterValue.getValue() instanceof EStructuralFeature) {
+			return ((EStructuralFeature) parameterValue.getValue()).getName();
+		}
+		
+		Stereotype appStereotype = null;
+		if (source.getAppliedStereotypes().size() > 0) {
+			appStereotype = source.getAppliedStereotypes().get(0);
+		}
+		
+		if ((source instanceof org.eclipse.uml2.uml.Class) && (appStereotype != null) && (isRequirementStereotype(appStereotype))) {
+			TraceabilityIndexer.getInstance().loadTraceability(source);
+			int nb=getNumberOfGDRPR_SubRequirement(source);
+			return "" + source.getValue(appStereotype, I_SysMLStereotype.REQUIREMENT_ID_ATT) + " ["+nb+"]: " +  source.getValue(appStereotype, I_SysMLStereotype.REQUIREMENT_TEXT_ATT);
+		}
+		// Delegate to UML2 Edit providers to get localized and inferred names where applicable
+		return labelProvider.getText(source);
+	}
+
+
+	public int getNumberOfGDRPR_SubRequirement(Element element) {
+		int number=0;
+		ArrayList<Element> children= new ArrayList<Element>();
+		if(TraceabilityIndexer.getInstance().getDownwardTraceabiltiy(element)!=null) {
+			ArrayList<DirectedRelationship> links = TraceabilityIndexer.getInstance().getDownwardTraceabiltiy(element);
+			for (Iterator<DirectedRelationship> iterator = links.iterator(); iterator.hasNext();) {
+				DirectedRelationship directedRelationship = iterator.next();
+				children.addAll(directedRelationship.getSources());
+
+			}
+		}
+		if (TraceabilityIndexer.getInstance().getsubRequirements(element)!=null) {
+			children.addAll(TraceabilityIndexer.getInstance().getsubRequirements(element));
+		}
+		if (GDPRRequiementHelper.isGDPR_Requirement(element)) {
+			number=1;
+		}
+		for (Iterator<Element> iterator = children.iterator(); iterator.hasNext();) {
+			Element currentElement = (Element) iterator.next();
+			number = number+getNumberOfGDRPR_SubRequirement(currentElement);
+		}
+		return number;
+	}
+}