Commit 2202c3fa authored by Saad bin Abid's avatar Saad bin Abid
Browse files

This commit have changes that are as follows,

1) Updated the mira.ecore with new classes in order to implement the relationships between the aspects (i.e., functional and non-functional)

2) Implemented constraints for checking the relationships between functional and non-functional aspects

3) Implemented the list in the following editors in order to have a relationships between functional and non-functional aspects
	3.1) FunctionalRequirementEditor
	3.2) InterfaceBehaviourAspect
	3.3) ModeDefinitionEditor
	3.4) TimingRequirementEditor
	3.5) DerivedRequirementEditor
	
parent 33a93586
......@@ -28,12 +28,14 @@ import org.fortiss.af3.mira.constraints.DescriptionAndOrConstraint;
import org.fortiss.af3.mira.constraints.DescriptionConstraint;
import org.fortiss.af3.mira.constraints.EveryDefinedSignalIsUsed;
import org.fortiss.af3.mira.constraints.EverySignalUsedIsDefined;
import org.fortiss.af3.mira.constraints.FunctionalAspectsHaveNonFunctionalAspectsConstraint;
import org.fortiss.af3.mira.constraints.FunctionalReqsHaveOneNonFunctionalReq;
import org.fortiss.af3.mira.constraints.GlossaryTermsDefinitionConstraint;
import org.fortiss.af3.mira.constraints.IDConstraint;
import org.fortiss.af3.mira.constraints.IdentifiedInputOutputDefinedConstraint;
import org.fortiss.af3.mira.constraints.MultipleAspectsConstraint;
import org.fortiss.af3.mira.constraints.NameConstraint;
import org.fortiss.af3.mira.constraints.NonFunctionalAspectsHaveFunctionalAspectsConstraint;
import org.fortiss.af3.mira.constraints.NonFunctionalReqsHaveExactlyOneFunctionalReq;
import org.fortiss.af3.mira.constraints.OnlyOneSILConstraint;
import org.fortiss.af3.mira.constraints.ParameterTypeConstraint;
......@@ -60,12 +62,14 @@ import org.fortiss.af3.mira.ui.constraints.DescriptionAndOrConstraintUI;
import org.fortiss.af3.mira.ui.constraints.DescriptionConstraintUI;
import org.fortiss.af3.mira.ui.constraints.EveryDefinedSignalIsUsedUI;
import org.fortiss.af3.mira.ui.constraints.EverySignalUsedIsDefinedUI;
import org.fortiss.af3.mira.ui.constraints.FunctionalAspectsHaveNonFunctionalAspectsConstraintsUI;
import org.fortiss.af3.mira.ui.constraints.FunctionalReqsHaveOneNonFunctionalReqUI;
import org.fortiss.af3.mira.ui.constraints.GlossaryTermDefinitionConstraintUI;
import org.fortiss.af3.mira.ui.constraints.IDConstraintUI;
import org.fortiss.af3.mira.ui.constraints.IdentifiedInputOutputDefinedConstraintUI;
import org.fortiss.af3.mira.ui.constraints.MultipleAspectsConstraintUI;
import org.fortiss.af3.mira.ui.constraints.NameConstraintUI;
import org.fortiss.af3.mira.ui.constraints.NonFunctionalAspectsHaveFunctionalAspectsConstraintUI;
import org.fortiss.af3.mira.ui.constraints.NonFunctionalReqsHaveExactlyOneFunctionalReqUI;
import org.fortiss.af3.mira.ui.constraints.OnlyOneSILConstraintUI;
import org.fortiss.af3.mira.ui.constraints.ParameterTypeConstraintUI;
......@@ -181,6 +185,12 @@ public class AF3MiraUIActivator extends AbstractUIPlugin {
EverySignalUsedIsDefined.class);
IConstraintUIService.getInstance().registerConstraintUI(
ComponentPackageExistsConstraintUI.class, ComponentPackageExistsConstraint.class);
IConstraintUIService.getInstance().registerConstraintUI(
FunctionalAspectsHaveNonFunctionalAspectsConstraintsUI.class,
FunctionalAspectsHaveNonFunctionalAspectsConstraint.class);
IConstraintUIService.getInstance().registerConstraintUI(
NonFunctionalAspectsHaveFunctionalAspectsConstraintUI.class,
NonFunctionalAspectsHaveFunctionalAspectsConstraint.class);
}
/** {@inheritDoc} */
......
/*-------------------------------------------------------------------------+
| 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.fortiss.tooling.kernel.utils.ConstraintsUtils.getFirstConstrained;
import java.util.Arrays;
import java.util.List;
import org.fortiss.af3.mira.model.Requirement;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.FailedConstraintInstanceStatus;
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.IConstraintUIService.IFix;
import org.fortiss.tooling.kernel.ui.util.ConstraintsUIUtils.FixBase;
/**
* UI part of {@link org.fortiss.af3.mira.constraints.AuthorConstraint}
*
* @author abid
*/
public class FunctionalAspectsHaveNonFunctionalAspectsConstraintsUI extends
ConstraintUIBaseAutocheck {
/** {@inheritDoc} */
@Override
public String getDescription() {
return "All functional aspects should have at least one non-functional aspect defined!!!";
}
/** {@inheritDoc} */
@Override
public boolean shouldBeManuallyActivated() {
return true;
}
/** {@inheritDoc} */
@Override
public List<IFix> fixes(ConstraintInstance ci, IConstraintInstanceStatus status) {
if(status instanceof FailedConstraintInstanceStatus) {
String reqName = ((Requirement)getFirstConstrained(ci)).getName();
if(reqName != null) {
if(reqName.isEmpty() == false) {
String splitFix =
"Please define one non-functional aspect for the requirement: " +
reqName;
return Arrays.asList(new FixBase(splitFix, s -> reqName.toString()));
}
}
}
return super.fixes(ci, status);
}
}
/*-------------------------------------------------------------------------+
| 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.fortiss.tooling.kernel.utils.ConstraintsUtils.getFirstConstrained;
import java.util.Arrays;
import java.util.List;
import org.fortiss.af3.mira.model.Requirement;
import org.fortiss.tooling.kernel.model.constraints.ConstraintInstance;
import org.fortiss.tooling.kernel.model.constraints.FailedConstraintInstanceStatus;
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.IConstraintUIService.IFix;
import org.fortiss.tooling.kernel.ui.util.ConstraintsUIUtils.FixBase;
/**
* UI part of {@link org.fortiss.af3.mira.constraints.AuthorConstraint}
*
* @author abid
*/
public class NonFunctionalAspectsHaveFunctionalAspectsConstraintUI extends
ConstraintUIBaseAutocheck {
/** {@inheritDoc} */
@Override
public String getDescription() {
return "All non-functional aspects should have at least one functional aspect defined!!!";
}
/** {@inheritDoc} */
@Override
public boolean shouldBeManuallyActivated() {
return true;
}
/** {@inheritDoc} */
@Override
public List<IFix> fixes(ConstraintInstance ci, IConstraintInstanceStatus status) {
if(status instanceof FailedConstraintInstanceStatus) {
String reqName = ((Requirement)getFirstConstrained(ci)).getName();
if(reqName != null) {
if(reqName.isEmpty() == false) {
String splitFix =
"Please define one functional aspect for the requirement: " + reqName;
return Arrays.asList(new FixBase(splitFix, s -> reqName.toString()));
}
}
}
return super.fixes(ci, status);
}
}
AnalysisEditor.java a6f697def0b95ccb593c2f202e383ae1dc099ba3 YELLOW
AspectEditorBase.java 63b998056410bd73276a7f3bdfeb3d534c6f7b96 GREEN
CheckListEditor.java b816766819e501396f84f3864ad5904d2fbc1b06 GREEN
......@@ -18,9 +17,9 @@ RequirementsContainerEditor.java d92d66fd2a4216b8c3b775636b89068f4f44965e GREEN
RequirementsPackageEditor.java 66dfe0f4d122572e50c1a4f1b3ed6193f59525ec GREEN
SafetyLevelSectionEditor.java 5736e823649c912a307008e3902134926bbf8831 GREEN
ScenarioEditor.java ca9654613ddcb1504dd0ea6074f55048f50e428e GREEN
SignalDefinitionEditor.java f0f646587874f7484b7220dc008939ef734fb5fb GREEN
SignalDefinitionEditor.java 900da86a6697b22933eb6a13c00775cb38816b10 YELLOW
SignalRequirementEditor.java 1019bb75a095172ea7f7e4fb82ca40ee80d760d7 GREEN
SignalsViewer.java c893a821e09f5e3732bb409bcd82c39c2feaaa5d GREEN
SignalsViewer.java e99408bde79174a49cc949fb8731c0dccc3920d6 YELLOW
StringToIDValidator.java dbad2970db0a8aba3b57f97602b8325bbcc5c14c GREEN
TimingRequirementEditor.java 7379dfce7be2c89c42a435a15e28ecca7dce478a GREEN
TracesEditor.java 3677cbddadf62ae7f09bf063486620901999d9d8 GREEN
......
......@@ -15,14 +15,42 @@
+--------------------------------------------------------------------------*/
package org.fortiss.af3.mira.ui.editor;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.conqat.ide.commons.ui.jface.TreeContentProviderBase;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.fortiss.af3.mira.model.DerivedRequirementSpecification;
import org.fortiss.af3.mira.model.IFunctionalRequirement;
import org.fortiss.af3.mira.model.MiraFactory;
import org.fortiss.af3.mira.model.Requirement;
import org.fortiss.tooling.base.model.element.IModelElementSpecification;
import org.fortiss.tooling.base.ui.editor.StyledTextCellEditor;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.ui.presentation.ModelElementLabelProvider;
/**
* Editor for the parameter definition aspect of a {@link Requirement}.
......@@ -31,11 +59,35 @@ import org.fortiss.tooling.base.model.element.IModelElementSpecification;
*/
public class DerivedRequirementEditor<T extends Requirement> extends AspectEditorBase<T> {
DerivedRequirementSpecification drSpec;
/**
* The tree viewer displaying the modes. Only used as a table, but we use trees because it does
* not cost anything.
*/
private TreeViewer viewer;
/** Top level element for the edited object. */
private ITopLevelElement top;
/**
* The tree viewer for displaying the table that contains the relationships between the
* functional and the non-functional requirement
*/
private TreeViewer reqViewer;
/** The default shell - for functional requirement dialog. */
private Shell shell;
/** {@inheritDoc} */
@Override
protected void createAspectSection() {
toolkit.createLabel(form.getForm().getBody(),
"This requirement is a design choice (in DO178: \"derived requirement\")");
EList<IModelElementSpecification> specs = ((Requirement)editedObject).getSpecifications();
drSpec = pickFirstInstanceOf(DerivedRequirementSpecification.class, specs);
createNonFunctionalRelationshipSection(drSpec);
}
/** {@inheritDoc} */
......@@ -46,4 +98,191 @@ public class DerivedRequirementEditor<T extends Requirement> extends AspectEdito
editedObject.getSpecifications()));
return res;
}
/**
* @return section for relationships between this non-functional requirement and functional
* requirement(s)
*/
private Composite createNonFunctionalRelationshipSection(
DerivedRequirementSpecification drSpecification) {
Composite relatedToSection =
createNewSection("Relationships Section",
"Related to the following functional requirement(s):");
relatedToSection.setLayout(new GridLayout(1, false));
createFunctionalRequirementTable(relatedToSection, drSpecification);
reqViewer.setContentProvider(new TreeContentProviderBase() {
@Override
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof List<?>) {
List<Object> range = new ArrayList<Object>();
range.add(new FakeChild());
range.addAll(IntStream
.rangeClosed(0, drSpecification.getRelatedTo().size() - 1).boxed()
.collect(Collectors.toList()));
return range.toArray();
}
return new Object[0];
}
});
reqViewer.setInput(drSpecification.getRelatedTo());
Button addButton = toolkit.createButton(relatedToSection, "Add", SWT.FLAT);
Button deleteButton = toolkit.createButton(relatedToSection, "Delete", SWT.FLAT);
addButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
// Open dialog of components
ITreeContentProvider tcp = new FormalSpecificationTreeContentProvider();
ElementTreeSelectionDialog dlg =
new ElementTreeSelectionDialog(shell, new ModelElementLabelProvider(), tcp);
dlg.setAllowMultiple(false);
dlg.setTitle("Select the Functional Requirement(s)");
List<Requirement> reqsList =
pickInstanceOf(Requirement.class, ((Requirement)editedObject)
.getContainer().getContainedElements());
List<Requirement> funcReqList = new ArrayList<Requirement>();
for(Requirement req : reqsList) {
if(pickInstanceOf(IFunctionalRequirement.class, req.getSpecifications()).size() > 0) {
funcReqList.add(req);
}
}
dlg.setInput(funcReqList);
if(dlg.open() == 1 || dlg.getResult().length == 0) {
return;
}
modelContext.runAsCommand(new Runnable() {
@Override
public void run() {
drSpecification.getRelatedTo().add((Requirement)dlg.getFirstResult());
reqViewer.refresh();
}
});
}
});
deleteButton.addSelectionListener(new SelectionAdapter() {
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
// Open dialog of components
ITreeContentProvider tcp = new FormalSpecificationTreeContentProvider();
ElementTreeSelectionDialog dlg =
new ElementTreeSelectionDialog(shell, new ModelElementLabelProvider(), tcp);
dlg.setAllowMultiple(false);
dlg.setTitle("Delete Related Functional Requirement(s)");
List<Requirement> nonFuncReqList = new ArrayList<Requirement>();
nonFuncReqList.addAll(pickFirstInstanceOf(DerivedRequirementSpecification.class,
((Requirement)editedObject).getSpecifications()).getRelatedTo());
dlg.setInput(nonFuncReqList);
if(dlg.open() == 1 || dlg.getResult().length == 0) {
return;
}
modelContext.runAsCommand(new Runnable() {
@Override
public void run() {
drSpecification.getRelatedTo().remove(dlg.getFirstResult());
reqViewer.refresh();
}
});
}
});
return relatedToSection;
}
/** Fake child used to add new elements. */
public static class FakeChild {
// Nothing to implement: just a marker class
}
/**
* @param relatedToSection
* section for relating the non-functional requirement to functional requirements
* @param drSpecification
* functional specification of the functional requirement
*/
public void createFunctionalRequirementTable(Composite relatedToSection,
DerivedRequirementSpecification drSpecification) {
reqViewer = new TreeViewer(relatedToSection, SWT.BORDER | SWT.FULL_SELECTION);
Tree tree = reqViewer.getTree();
GridDataFactory.swtDefaults().align(SWT.FILL, SWT.FILL).grab(true, true).minSize(300, 300)
.applyTo(tree);
tree.setLinesVisible(true);
tree.setHeaderVisible(true);
TreeViewerColumn nameColumn = new TreeViewerColumn(reqViewer, SWT.NONE);
TreeColumn trclmnMode = nameColumn.getColumn();
trclmnMode.setWidth(300);
trclmnMode.setText("Functional Requirement Name");
nameColumn.setLabelProvider(new ColumnLabelProvider() {
/** {@inheritDoc} */
@Override
public String getText(Object element) {
if(element instanceof FakeChild) {
return "";
}
return drSpecification.getRelatedTo().get((Integer)element).getReqId() + "-" +
drSpecification.getRelatedTo().get((Integer)element).getName();
}
});
nameColumn.setEditingSupport(createNonFunctionalRequirementNameEditingSupport(reqViewer,
nameColumn));
}
/** {@link EditingSupport} for the name column of the Relationships Table. */
private EditingSupport createNonFunctionalRequirementNameEditingSupport(TreeViewer viewer,
TreeViewerColumn funcCompColumn) {
top = IPersistencyService.getInstance().getTopLevelElementFor(getEditedObject());
return new EditingSupport(funcCompColumn.getViewer()) {
@Override
protected void setValue(Object element, Object value) {
if(element instanceof Integer) {
if((drSpec.getRelatedTo().get((Integer)element)).getName().equals(value)) {
return;
}
if(value != null) {
top.runAsCommand(() -> {
Requirement newReq = MiraFactory.eINSTANCE.createRequirement();
newReq.setName((String)value);
drSpec.getRelatedTo().add(newReq);
viewer.refresh();
});
}
}
}
@Override
protected Object getValue(Object element) {
return element instanceof Requirement ? ((Requirement)element).getName() : "";
}
@Override
protected CellEditor getCellEditor(Object element) {
return new StyledTextCellEditor(getTextStyledTextActionHandler(),
(Composite)getViewer().getControl());
}
@Override
protected boolean canEdit(Object element) {
return false;
}
};
}
}
......@@ -419,9 +419,8 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
private Composite createNonFunctionalRelationshipSection(
FunctionalSpecification funcSpecification) {
Composite relatedToSection =
createNewSection(
"Non-Functional Requirement Relationships",
"This Section lists all the relationships between this functional requirement and other non-functional requirements:");
createNewSection("Relationships Section",
"Related to the following non-functional requirement(s):");
relatedToSection.setLayout(new GridLayout(1, false));
......@@ -452,9 +451,7 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
// Open dialog of components
ITreeContentProvider tcp = new FormalSpecificationTreeContentProvider();
ElementTreeSelectionDialog dlg =
new ElementTreeSelectionDialog(shell, new ModelElementLabelProvider(), tcp);
dlg.setAllowMultiple(false);
......@@ -491,9 +488,7 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
/** {@inheritDoc} */
@Override
public void widgetSelected(SelectionEvent e) {
// Open dialog of components
ITreeContentProvider tcp = new FormalSpecificationTreeContentProvider();
ElementTreeSelectionDialog dlg =
new ElementTreeSelectionDialog(shell, new ModelElementLabelProvider(), tcp);
dlg.setAllowMultiple(false);
......@@ -546,7 +541,8 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
if(element instanceof FakeChild) {
return "";
}
return funcSpecification.getRelatedTo().get((Integer)element).getName();
return funcSpecification.getRelatedTo().get((Integer)element).getReqId() + "-" +
funcSpecification.getRelatedTo().get((Integer)element).getName();
}
});
......
......@@ -20,19 +20,38 @@ import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.conqat.ide.commons.ui.jface.TreeContentProviderBase;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.TreeViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.fortiss.af3.mira.model.IFunctionalRequirement;
import org.fortiss.af3.mira.model.MiraFactory;
import org.fortiss.af3.mira.model.Requirement;
import org.fortiss.af3.mira.model.interfacebehaviour.InterfaceBehaviourSpecification;
import org.fortiss.tooling.base.model.element.IModelElementSpecification;
import org.fortiss.tooling.base.ui.editor.StyledTextCellEditor;
import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
import org.fortiss.tooling.kernel.service.IElementCompositorService;
import org.fortiss.tooling.kernel.service.IPersistencyService;
import org.fortiss.tooling.kernel.ui.presentation.ModelElementLabelProvider;
/**
* Editor for the "interface behaviour" aspect of a {@link Requirement}.
......@@ -41,6 +60,21 @@ import org.fortiss.tooling.kernel.service.IPersistencyService;
*/
public class InterfaceBehaviourAspectEditor<T extends Requirement> extends AspectEditorBase<T> {
/** The edited interface behavior specification. */
private InterfaceBehaviourSpecification ibsSpec;
/**
* The tree viewer for displaying the table that contains the relationships between the
* functional and the non-functional requirement
*/