Commit 721ef630 authored by Saad bin Abid's avatar Saad bin Abid
Browse files

changed the mira meta-model and added the table in the Functional Requirement...

changed the mira meta-model and added the table in the Functional Requirement Editor to add the relationship between functional and non-functional requirements.
parent 3c500841
......@@ -17,8 +17,10 @@ package org.fortiss.af3.mira.ui.editor;
import static org.eclipse.core.runtime.IStatus.ERROR;
import static org.eclipse.jface.dialogs.ErrorDialog.openError;
import static org.fortiss.af3.mira.model.functional.FunctionalPackage.Literals.FUNCTIONAL_SPECIFICATION__CODE_SPECIFICATION;
import static org.fortiss.af3.mira.ui.utils.HighlightUtils.createSimpleSourceViewer;
import static org.fortiss.af3.mira.ui.utils.MiraLayoutUtils.multiLineInputFactory;
import static org.fortiss.tooling.kernel.ui.util.DataBindingUtils.bind;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickFirstInstanceOf;
import static org.fortiss.tooling.kernel.utils.EcoreUtils.pickInstanceOf;
......@@ -37,19 +39,25 @@ import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ComboBoxViewerCellEditor;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
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.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
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.Display;
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.expression.model.definitions.FunctionDefinition;
import org.fortiss.af3.mira.model.INonFunctionalRequirement;
import org.fortiss.af3.mira.model.MiraFactory;
import org.fortiss.af3.mira.model.Requirement;
import org.fortiss.af3.mira.model.functional.FunctionalComponent;
import org.fortiss.af3.mira.model.functional.FunctionalFactory;
......@@ -59,18 +67,22 @@ import org.fortiss.tooling.base.ui.ToolingBaseUIActivator;
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;
import org.fortiss.tooling.kernel.ui.service.IActionService;
import org.fortiss.tooling.kernel.ui.util.SelectionUtils;
/**
* Editor for the functional specification aspect of a {@link Requirement}.
*
* @author mou
* @author abid
*/
public class FunctionalRequirementEditor<T extends Requirement> extends AspectEditorBase<T> {
/** The edited functional specification. */
private FunctionalSpecification funcSpec;
/** The default shell - for component dialog. */
private Shell shell;
/** Label width. */
public static final int PROPERTIES_LABEL_WIDTH = 150;
......@@ -90,6 +102,13 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
* not cost anything.
*/
private TreeViewer viewer;
/**
* The tree viewer for displaying the table that contains the relationships between the
* functional and the non-functional requirement
*/
private TreeViewer reqViewer;
/** Top level element for the edited object. */
private ITopLevelElement top;
......@@ -100,7 +119,8 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
EList<IModelElementSpecification> specs = editedObject.getSpecifications();
funcSpec = pickFirstInstanceOf(FunctionalSpecification.class, specs);
addFunctionalSpecificationSection(funcSpec);
createCodeSpecificationSection();
createCodeSpecificationSection(funcSpec);
createNonFunctionalRelationshipSection(funcSpec);
}
/** Section for functional component. */
......@@ -373,7 +393,7 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
}
/** Section for code Specification. */
private Composite createCodeSpecificationSection() {
private Composite createCodeSpecificationSection(FunctionalSpecification funcSpecification) {
Composite parent =
createNewSection(
"Code Specification",
......@@ -386,15 +406,193 @@ public class FunctionalRequirementEditor<T extends Requirement> extends AspectEd
multiLineInputFactory.applyTo(desc.getTextWidget());
localRegisteredSourceViewers.add(desc);
desc.addSelectionChangedListener(new ISelectionChangedListener() {
bind(dbc, desc.getTextWidget(), funcSpecification,
FUNCTIONAL_SPECIFICATION__CODE_SPECIFICATION);
return parent;
}
/**
* @return section for relationships between this functional requirement and non-functional
* requirements
*/
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:");
relatedToSection.setLayout(new GridLayout(1, false));
createNonFunctionalRequirementTable(relatedToSection, funcSpecification);
reqViewer.setContentProvider(new TreeContentProviderBase() {
@Override
public void selectionChanged(SelectionChangedEvent event) {
// Do nothing
public Object[] getChildren(Object parentElement) {
if(parentElement instanceof List<?>) {
List<Object> range = new ArrayList<Object>();
range.add(new FakeChild());
range.addAll(IntStream
.rangeClosed(0, funcSpecification.getRelatedTo().size() - 1).boxed()
.collect(Collectors.toList()));
return range.toArray();
}
return new Object[0];
}
});
viewer.getControl().addKeyListener(new ViewerKeyAdapter());
return parent;
reqViewer.getControl().addKeyListener(new ViewerKeyAdapter());
reqViewer.setInput(funcSpecification.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 Non-Functional Requirement(s)");
List<Requirement> reqsList =
pickInstanceOf(Requirement.class, editedObject.getContainer()
.getContainedElements());
List<Requirement> nonFuncReqList = new ArrayList<Requirement>();
for(Requirement req : reqsList) {
if(pickInstanceOf(INonFunctionalRequirement.class, req.getSpecifications())
.size() > 0) {
nonFuncReqList.add(req);
}
}
dlg.setInput(nonFuncReqList);
if(dlg.open() == 1 || dlg.getResult().length == 0) {
return;
}
modelContext.runAsCommand(new Runnable() {
@Override
public void run() {
funcSpecification.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 Non-Functional Requirement(s)");
List<Requirement> nonFuncReqList = new ArrayList<Requirement>();
nonFuncReqList.addAll(pickFirstInstanceOf(FunctionalSpecification.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() {
funcSpecification.getRelatedTo().remove(dlg.getFirstResult());
reqViewer.refresh();
}
});
}
});
return relatedToSection;
}
/**
* @param relatedToSection
* section for relating the functional requirement to non-functional requirements
* @param funcSpecification
* functional specification of the functional requirement
*/
public void createNonFunctionalRequirementTable(Composite relatedToSection,
FunctionalSpecification funcSpecification) {
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("Non-Functional Requirement Name");
nameColumn.setLabelProvider(new ColumnLabelProvider() {
/** {@inheritDoc} */
@Override
public String getText(Object element) {
if(element instanceof FakeChild) {
return "";
}
return funcSpecification.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((funcSpec.getRelatedTo().get((Integer)element)).getName().equals(value)) {
return;
}
if(!emptyOrAlreadyExists((String)value)) {
top.runAsCommand(() -> {
Requirement newReq = MiraFactory.eINSTANCE.createRequirement();
newReq.setName((String)value);
funcSpec.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;
}
};
}
}
......@@ -540,12 +540,11 @@
<eStructuralFeatures xsi:type="ecore:EReference" name="functionalComponent"
upperBound="-1" eType="#//functional/FunctionalComponent" containment="true"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="relatedTo" upperBound="-1"
eType="#//functional/RelatedTo" containment="true"/>
eType="#//Requirement"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="codeSpecification" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="statementSequence" eType="ecore:EClass platform:/resource/org.fortiss.af3.expression/model/expression.ecore#//terms/imperative/StatementSequence"
containment="true"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="RelatedTo" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement"/>
<eClassifiers xsi:type="ecore:EClass" name="FunctionalComponent" eSuperTypes="platform:/resource/org.fortiss.tooling.kernel/model/kernel.ecore#//INamedCommentedElement">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="output" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
</eClassifiers>
......
......@@ -295,7 +295,6 @@
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute mira.ecore#//functional/FunctionalSpecification/codeSpecification"/>
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference mira.ecore#//functional/FunctionalSpecification/statementSequence"/>
</genClasses>
<genClasses ecoreClass="mira.ecore#//functional/RelatedTo"/>
<genClasses ecoreClass="mira.ecore#//functional/FunctionalComponent">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute mira.ecore#//functional/FunctionalComponent/output"/>
</genClasses>
......
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