Commit 375648f8 authored by Vincent Aravantinos's avatar Vincent Aravantinos
Browse files

unique signal constraint

refs 2721
parent 8150ba8f
......@@ -20,8 +20,10 @@ package org.fortiss.af3.mira.ui;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.fortiss.af3.mira.constraints.AuthorConstraint;
import org.fortiss.af3.mira.constraints.RequirementContainsTestSuiteConstraint;
import org.fortiss.af3.mira.constraints.SignalConstraints.UniqueSignalNameConstraint;
import org.fortiss.af3.mira.ui.constraints.AuthorConstraintUI;
import org.fortiss.af3.mira.ui.constraints.RequirementContainsTestSuiteConstraintUI;
import org.fortiss.af3.mira.ui.constraints.SignalConstraintsUI.UniqueSignalNameConstraintUI;
import org.fortiss.af3.mira.ui.constraints.TraceConstraint;
import org.fortiss.af3.mira.ui.constraints.TraceConstraintUI;
import org.fortiss.tooling.kernel.service.IConstraintService;
......@@ -31,7 +33,7 @@ import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*
* @ConQAT.Rating YELLOW Hash: D48B67A9A6B7CF8CBB10E52775199353
* @ConQAT.Rating YELLOW Hash: 132ADAD76FFDBA3E342BCB2855C79D4E
*/
public class AF3MiraUIActivator extends AbstractUIPlugin {
......@@ -60,6 +62,8 @@ public class AF3MiraUIActivator extends AbstractUIPlugin {
TraceConstraint.class);
IConstraintUIService.getInstance().registerConstraintUI(AuthorConstraintUI.class,
AuthorConstraint.class);
IConstraintUIService.getInstance().registerConstraintUI(UniqueSignalNameConstraintUI.class,
UniqueSignalNameConstraint.class);
IConstraintUIService.getInstance().registerConstraintUI(
RequirementContainsTestSuiteConstraintUI.class,
RequirementContainsTestSuiteConstraint.class);
......
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2016 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mira.ui.constraints;
import static org.apache.commons.lang.StringUtils.join;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.eclipse.emf.common.util.EList;
import org.fortiss.af3.mira.model.functional.DuplicatedSignalsStatus;
import org.fortiss.af3.mira.model.functional.SignalDuplicates;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
import org.fortiss.tooling.kernel.ui.extension.base.ConstraintUIBases.ConstraintUIBaseAutocheck;
import org.fortiss.tooling.kernel.ui.service.IModelElementHandlerService;
/**
* UI part of {@link org.fortiss.af3.mira.constraints.AuthorConstraint}
*
* @author aravantinos
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 142024C164EB27D185E3A304B4BF5203
*/
public class SignalConstraintsUI {
/** A signal should have a unique name among all the signals. */
public static class UniqueSignalNameConstraintUI extends ConstraintUIBaseAutocheck {
/** {@inheritDoc} */
@Override
public String getDescription() {
return "All signals are uniquely defined";
}
/** {@inheritDoc} */
@Override
public boolean canOpen(ConstraintInstance ci, IConstraintInstanceStatus status) {
return status instanceof DuplicatedSignalsStatus;
}
/** {@inheritDoc} */
@Override
public String getMessage(ConstraintInstance ci, IConstraintInstanceStatus status) {
if(status instanceof DuplicatedSignalsStatus) {
EList<SignalDuplicates> dups =
((DuplicatedSignalsStatus)status).getDuplicatedSignals();
List<String> sigNames = new ArrayList<String>();
for(SignalDuplicates dup : dups) {
// get(0) cause all signals there should have the same name, so we take randomly
// the first one.
String sig = dup.getSignals().get(0).getName();
IModelElementHandlerService hs = IModelElementHandlerService.getInstance();
List<String> containers =
dup.getSignals().stream().map(s -> hs.getName(s.eContainer()))
.collect(Collectors.toList());
String str;
if(containers.size() == 2) {
// get(0) because we want here explicitly the two first elements
str = containers.get(0) + " and " + containers.get(1);
} else {
str = join(containers, ", ");
}
sigNames.add(sig + " in " + str);
}
String isAre = sigNames.size() == 1 ? " is" : "s are";
String res = "The following signal" + isAre + " defined more than once:\n\t";
return res + StringUtils.join(sigNames, "\n\t");
}
return super.getMessage(ci, status);
}
/** {@inheritDoc} */
@Override
public boolean shouldBeManuallyActivated() {
return true;
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="model" nsURI="http://www.fortiss.org/af3/mira" nsPrefix="org-fortiss-af3-mira">
<eClassifiers xsi:type="ecore:EClass" name="Analysis" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//IProjectRootElement platform:/resource/org.fortiss.tooling.base/model/base.ecore#//element/IHierarchicElement">
<eClassifiers xsi:type="ecore:EClass" name="Analysis" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//IProjectRootElement platform:/resource/org.fortiss.tooling.base/model/base.ecore#//element/IHierarchicElement platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//constraints/IConstrained">
<eOperations name="getRequirementsList">
<eAnnotations source="http://www.eclipse.org/emf/2002/GenModel">
<details key="body" value="return AnalysisStaticImpl.getRequirementsList(this);"/>
......@@ -476,6 +476,14 @@
eType="#//functional/Signal" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="SignalRequirement" eSuperTypes="#//Requirement #//functional/ISignalsContainer"/>
<eClassifiers xsi:type="ecore:EClass" name="DuplicatedSignalsStatus" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//constraints/FailedConstraintInstanceStatus">
<eStructuralFeatures xsi:type="ecore:EReference" name="duplicatedSignals" upperBound="-1"
eType="#//functional/SignalDuplicates" containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="SignalDuplicates">
<eStructuralFeatures xsi:type="ecore:EReference" name="signals" upperBound="-1"
eType="#//functional/Signal"/>
</eClassifiers>
</eSubpackages>
<eSubpackages name="glossary" nsURI="http://www.fortiss.org/af3/mira/glossary" nsPrefix="org-fortiss-af3-mira-glossary">
<eClassifiers xsi:type="ecore:EClass" name="Glossary" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement platform:/resource/org.fortiss.tooling.base/model/base.ecore#//element/IHierarchicElement">
......
......@@ -246,6 +246,14 @@
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference mira.ecore#//functional/ISignalsContainer/signals"/>
</genClasses>
<genClasses ecoreClass="mira.ecore#//functional/SignalRequirement"/>
<genClasses ecoreClass="mira.ecore#//functional/DuplicatedSignalsStatus">
<genFeatures notify="false" createChild="false" propertySortChoices="true"
ecoreFeature="ecore:EReference mira.ecore#//functional/DuplicatedSignalsStatus/duplicatedSignals"/>
</genClasses>
<genClasses ecoreClass="mira.ecore#//functional/SignalDuplicates">
<genFeatures notify="false" createChild="false" propertySortChoices="true"
ecoreFeature="ecore:EReference mira.ecore#//functional/SignalDuplicates/signals"/>
</genClasses>
</nestedGenPackages>
<nestedGenPackages prefix="Glossary" basePackage="org.fortiss.af3.mira.model"
disposableProviderFactory="true" ecorePackage="mira.ecore#//glossary">
......
......@@ -20,6 +20,7 @@ package org.fortiss.af3.mira;
import org.eclipse.core.runtime.Plugin;
import org.fortiss.af3.mira.constraints.AuthorConstraint;
import org.fortiss.af3.mira.constraints.RequirementContainsTestSuiteConstraint;
import org.fortiss.af3.mira.constraints.SignalConstraints.UniqueSignalNameConstraint;
import org.fortiss.af3.mira.relation.IRelationTypeService;
import org.fortiss.af3.mira.relation.RelationTypeService;
import org.fortiss.tooling.kernel.service.IConstraintService;
......@@ -28,7 +29,7 @@ import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle.
*
* @ConQAT.Rating YELLOW Hash: 3FDF1EA15F22AC9F07CF5ED7EEB4A077
* @ConQAT.Rating YELLOW Hash: 84FB4D5E378AEAEA0314DE99F093A111
*/
public class AF3MiraActivator extends Plugin {
......@@ -54,6 +55,7 @@ public class AF3MiraActivator extends Plugin {
IConstraintService.getInstance().registerConstraint(AuthorConstraint.class);
IConstraintService.getInstance().registerConstraint(
RequirementContainsTestSuiteConstraint.class);
IConstraintService.getInstance().registerConstraint(UniqueSignalNameConstraint.class);
}
/** {@inheritDoc} */
......
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2016 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mira.constraints;
import static org.fortiss.af3.mira.utils.SignalsUtils.getDoubleDefinedSignals;
import static org.fortiss.af3.mira.utils.SignalsUtils.getSignalsPerName;
import static org.fortiss.tooling.kernel.utils.ConstraintsUtils.createSuccessStatus;
import java.util.List;
import org.fortiss.af3.mira.model.Analysis;
import org.fortiss.af3.mira.model.functional.DuplicatedSignalsStatus;
import org.fortiss.af3.mira.model.functional.FunctionalFactory;
import org.fortiss.af3.mira.model.functional.Signal;
import org.fortiss.af3.mira.model.functional.SignalDuplicates;
import org.fortiss.af3.project.utils.ConstraintsProjectUtils.AF3ProjectConstraintCheckerBase;
import org.fortiss.tooling.kernel.model.constraints.IConstrained;
import org.fortiss.tooling.kernel.model.constraints.IConstraintInstanceStatus;
/**
* Constraints related to signals.
*
* @author aravantinos
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: 6B72386790D562B95571479913AF0584
*/
public class SignalConstraints {
/** A signal should have a unique name among all the signals. */
public static class UniqueSignalNameConstraint extends AF3ProjectConstraintCheckerBase {
/** {@inheritDoc} */
@Override
public IConstraintInstanceStatus verify(IConstrained constrained) {
List<List<Signal>> dblDefineds =
getDoubleDefinedSignals(getSignalsPerName((Analysis)constrained));
if(dblDefineds.isEmpty()) {
return createSuccessStatus();
}
DuplicatedSignalsStatus status =
FunctionalFactory.eINSTANCE.createDuplicatedSignalsStatus();
for(List<Signal> dblDefined : dblDefineds) {
SignalDuplicates dup = FunctionalFactory.eINSTANCE.createSignalDuplicates();
dup.getSignals().addAll(dblDefined);
status.getDuplicatedSignals().add(dup);
}
return status;
}
/** {@inheritDoc} */
@Override
public boolean isApplicable(IConstrained constrained) {
return constrained instanceof Analysis;
}
}
}
/*--------------------------------------------------------------------------+
$Id$
| |
| Copyright 2016 fortiss GmbH |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mira.utils;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.fortiss.af3.mira.model.Analysis;
import org.fortiss.af3.mira.model.functional.ISignalsContainer;
import org.fortiss.af3.mira.model.functional.Signal;
import org.fortiss.af3.mira.model.functional.SignalRequirement;
import org.fortiss.af3.mira.model.requirementSource.RequirementSource;
/**
* Utility methods w.r.t. signals.
*
* @author aravantinos
* @author $Author$
* @version $Rev$
* @ConQAT.Rating YELLOW Hash: DF49A7D72F83AF30D2916845FF2917FD
*/
public class SignalsUtils {
/** Returns a map returning the number of occurrences of a signal in the given context. */
public static Map<String, List<Signal>> getSignalsPerName(Analysis a) {
List<ISignalsContainer> containers = new ArrayList<ISignalsContainer>();
for(RequirementSource src : a.getRequirementSourceList()) {
containers.addAll(src.getExternalSystem());
}
containers.addAll(pickInstanceOf(SignalRequirement.class, a.getRequirementsList()));
HashMap<String, List<Signal>> map = new HashMap<String, List<Signal>>();
for(ISignalsContainer container : containers) {
for(Signal s : container.getSignals()) {
List<Signal> existingSigs = map.get(s.getName());
if(existingSigs == null) {
map.put(s.getName(), new ArrayList<>(Arrays.asList(s)));
} else {
existingSigs.add(s);
}
}
}
return map;
}
/** True iff the given signal is defined (at least) twice in the given context. */
public static List<List<Signal>> getDoubleDefinedSignals(Map<String, List<Signal>> sigCount) {
return sigCount.entrySet().stream().filter(p -> p.getValue().size() > 1)
.map(p -> p.getValue()).collect(Collectors.toList());
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment