use of org.osate.aadl2.AnnexSubclause in project osate2 by osate.
the class DefaultAnnexParser method parseAnnexSubclause.
/*
* (non-Javadoc)
*
* @see org.osate.annexsupport.AnnexParser#parseAnnexSubclause(java.lang.String,
* java.lang.String, java.lang.String, int, int, ParseErrorReporter)
*/
@Override
public AnnexSubclause parseAnnexSubclause(String annexName, String source, String filename, int line, int column, ParseErrorReporter errReporter) throws RecognitionException {
DefaultAnnexSubclause as = Aadl2Factory.eINSTANCE.createDefaultAnnexSubclause();
as.setName(annexName);
as.setSourceText(source);
return as;
}
use of org.osate.aadl2.AnnexSubclause in project osate2 by osate.
the class AnnexParserAgent method processAnnexSection.
/**
* Common functionality for processing either a {@link DefaultAnnexLibrary} or a {@link DefaultAnnexSubclause}.
* Processing involves parsing the text, attaching the resulting {@link AnnexLibrary} or {@link AnnexSubclause} to
* the {@link DefaultAnnexLibrary} or {@link DefaultAnnexSubclause}, setting the modes for the resulting
* {@link AnnexSubclause}, and either running the resolver or the linking service, depending upon which one if
* available. If the resolver produces errors, then the {@link AnnexLibrary} or {@link AnnexSubclause} will be
* detached from the {@link DefaultAnnexLibrary} or {@link DefaultAnnexSubclause}. All error, warning, and info
* messages that are produced from the parser, resolver, or linker will be passed along to
* {@code diagnosticsConsumer}.
*
* @param <A> Type of the resulting annex section. Expected to be {@link AnnexLibrary} or {@link AnnexSubclause}.
* @param <D> Type of the default annex section. Expected to be {@link DefaultAnnexLibrary} or
* {@link DefaultAnnexSubclause}.
* @param defaultAnnexSection Either the {@link DefaultAnnexLibrary} or {@link DefaultAnnexSubclause}.
* @param annexText Either the value of {@link DefaultAnnexLibrary#getSourceText()} or
* {@link DefaultAnnexSubclause#getSourceText()}.
* @param filename Name of the AADL file containing the annex section.
* @param diagnosticsConsumer Used for handling error, warning, and info messages.
* @param parserFunction Either
* {@link AnnexParser#parseAnnexLibrary(String, String, String, int, int, ParseErrorReporter)}
* or
* {@link AnnexParser#parseAnnexSubclause(String, String, String, int, int, ParseErrorReporter)}.
* @param setParsedAnnexSection Either {@link DefaultAnnexLibrary#setSourceText(String)} or
* {@link DefaultAnnexSubclause#setSourceText(String)}.
* @param copyModes Function for copying modes from the {@link DefaultAnnexSubclause} into the newly created
* {@link AnnexSubclause}. When processing an annex library, {@code copyModes} is expected to be a
* no-op {@link Consumer}.
*/
private <A extends NamedElement, D extends A> void processAnnexSection(D defaultAnnexSection, String annexText, String filename, IDiagnosticConsumer diagnosticsConsumer, ParserFunction<A> parserFunction, Consumer<A> setParsedAnnexSection, Consumer<A> copyModes) {
INode node = NodeModelUtils.findActualNodeFor(defaultAnnexSection);
int line = node.getStartLine() + computeLineOffset(node);
int offset = AnnexUtil.getAnnexOffset(defaultAnnexSection);
// look for plug-in parser
String annexName = defaultAnnexSection.getName();
if (annexText != null && annexText.length() > 6 && annexName != null) {
// strip {** **} from annex text
if (annexText.startsWith("{**")) {
annexText = annexText.substring(3, annexText.length() - 3);
}
annexName = AnnexModel.filterDisabledAnnexes(defaultAnnexSection, annexName);
AnnexParser ap = PARSER_REGISTRY.getAnnexParser(annexName);
try {
QueuingParseErrorReporter parseErrReporter = new QueuingParseErrorReporter();
parseErrReporter.setContextResource(defaultAnnexSection.eResource());
if (defaultAnnexSection instanceof AnnexSubclause) {
AnnexUtil.setCurrentAnnexSubclause((AnnexSubclause) defaultAnnexSection);
}
A annexSection = parserFunction.parse(ap, annexName, annexText, filename, line, offset, parseErrReporter);
if (defaultAnnexSection instanceof AnnexSubclause) {
AnnexUtil.setCurrentAnnexSubclause(null);
}
if (ParseResultHolder.Factory.INSTANCE.adapt(defaultAnnexSection).getParseResult() == null) {
// Only consume messages for non-Xtext annexes
consumeMessages(parseErrReporter, diagnosticsConsumer, annexText, line, offset);
}
if (annexSection != null) {
annexSection.setName(annexName);
setParsedAnnexSection.accept(annexSection);
// copy in modes list
copyModes.accept(annexSection);
// now resolve reference so we get messages if we have references to undefined items
AnnexResolver resolver = RESOLVER_REGISTRY.getAnnexResolver(annexName);
AnnexLinkingService linkingService = LINKING_SERVICE_REGISTRY.getAnnexLinkingService(annexName);
if (resolver != null && parseErrReporter.getNumErrors() == 0) {
// Don't resolve any annex with parsing errors.
QueuingParseErrorReporter resolveErrReporter = new QueuingParseErrorReporter();
AnalysisErrorReporterManager resolveErrManager = new AnalysisErrorReporterManager(new AnalysisToParseErrorReporterAdapter.Factory(aadlRsrc -> resolveErrReporter));
resolver.resolveAnnex(annexName, Collections.singletonList(annexSection), resolveErrManager);
consumeMessages(resolveErrReporter, diagnosticsConsumer, annexText, line, offset);
if (resolveErrReporter.getNumErrors() != 0) {
AnnexValidator.setNoValidation(defaultAnnexSection, annexName);
}
} else if (linkingService != null) {
try {
XtextResource res = (XtextResource) defaultAnnexSection.eResource();
ILinker linker = res.getLinker();
linker.linkModel(annexSection, diagnosticsConsumer);
} catch (Exception e) {
String message = "Linking Service error in " + filename + " at line " + line;
IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, e);
Activator.getDefault().getLog().log(status);
}
}
}
if (parseErrReporter.getNumErrors() > 0) {
AnnexValidator.setNoValidation(defaultAnnexSection, annexName);
}
} catch (RecognitionException e) {
String message = "Major parsing error in " + filename + " at line " + line;
IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, message, e);
Activator.getDefault().getLog().log(status);
}
}
}
use of org.osate.aadl2.AnnexSubclause in project osate2 by osate.
the class ConfigureInModesSection method addLocalMode.
private void addLocalMode(final Composite container, final Map.Entry<ModeFeature, ButtonState> entry, final Set<ModeFeature> derivedModesAvailable, final Map<ModeFeature, ModeFeature> localToDerivedModeMap, final Set<URI> urisOfElementsWhichRequireModes) {
final ModeFeature mf = entry.getKey();
final Button modeBtn = getWidgetFactory().createButton(container, mf.getName(), SWT.CHECK);
// Create derived mode drop down
final ComboViewer derivedModeFld;
final Label mappedLabel;
if (derivedModesAvailable == null) {
derivedModeFld = null;
mappedLabel = null;
} else {
mappedLabel = getWidgetFactory().createLabel(container, "->", SWT.CENTER);
mappedLabel.setText("->");
// Create mapped derived mode combo
derivedModeFld = new ComboViewer(container, SWT.DROP_DOWN | SWT.READ_ONLY);
derivedModeFld.setContentProvider(ArrayContentProvider.getInstance());
derivedModeFld.setLabelProvider(new LabelProvider() {
@Override
public String getText(final Object element) {
if (element instanceof ModeFeature) {
final ModeFeature modalFeature = (ModeFeature) element;
return modalFeature.getName();
}
return element.toString();
}
});
derivedModeFld.add(" ");
derivedModeFld.add(derivedModesAvailable.toArray());
final ModeFeature mappedDerivedMode = localToDerivedModeMap.get(mf);
// If child mode is contained in intersection of derived modes
if (derivedModesAvailable.contains(mappedDerivedMode)) {
derivedModeFld.setSelection(new StructuredSelection(mappedDerivedMode));
}
}
// Set button state
final ButtonState modeFeatureState = entry.getValue();
if (modeFeatureState == ButtonState.SELECTED) {
modeBtn.setSelection(true);
} else if (modeFeatureState == ButtonState.PARTIAL) {
modeBtn.setSelection(true);
modeBtn.setGrayed(true);
} else if (modeFeatureState == ButtonState.DISABLED_AND_PARTIAL || modeFeatureState == ButtonState.DISABLED) {
modeBtn.setEnabled(false);
boolean partialDisabled = modeFeatureState == ButtonState.DISABLED_AND_PARTIAL;
modeBtn.setGrayed(partialDisabled);
modeBtn.setSelection(partialDisabled);
if (derivedModeFld != null) {
derivedModeFld.getCombo().setEnabled(false);
mappedLabel.setEnabled(false);
}
}
final SelectionListener selectionListener = new SelectionAdapter() {
@Override
public void widgetSelected(final SelectionEvent e) {
// No changes if combo selection changes without enabled button
if (e.widget instanceof Combo && !modeBtn.getSelection()) {
return;
}
// Modify selected modal elements
final boolean modeBtnIsSelected = modeBtn.getSelection();
selectedBos.modify("Set In Modes", boc -> boc.getBusinessObject(NamedElement.class).isPresent(), boc -> {
final NamedElement ne = boc.getBusinessObject(NamedElement.class).get();
if (ne instanceof AnnexSubclause && ne.eContainer() instanceof DefaultAnnexSubclause) {
return (NamedElement) ne.eContainer();
}
return ne;
}, (ne, boc) -> {
final ModeFeature modeFeature = (ModeFeature) EcoreUtil.resolve(mf, ne.eResource());
if (ne instanceof Subcomponent && modeFeature instanceof Mode) {
final Subcomponent sc = (Subcomponent) ne;
// Remove mode binding always
for (final ModeBinding mb : sc.getOwnedModeBindings()) {
if (modeFeature.getName().equalsIgnoreCase(mb.getParentMode().getName())) {
sc.getOwnedModeBindings().remove(mb);
break;
}
}
// Add mode binding on button selection
if (modeBtnIsSelected) {
final ModeBinding newModeBinding = sc.createOwnedModeBinding();
newModeBinding.setParentMode((Mode) modeFeature);
final boolean isDerived = urisOfElementsWhichRequireModes.contains(EcoreUtil.getURI(ne));
// If modal element is derived, set derived mode
if (isDerived) {
final Object selection = ((StructuredSelection) derivedModeFld.getSelection()).getFirstElement();
final ModeFeature childMode = selection instanceof ModeFeature ? (ModeFeature) selection : null;
newModeBinding.setDerivedMode((Mode) childMode);
}
}
} else if (ne instanceof ModalPath) {
final ModalPath mp = (ModalPath) ne;
if (modeBtnIsSelected) {
mp.getInModeOrTransitions().add(modeFeature);
} else {
for (final ModeFeature mf : mp.getInModeOrTransitions()) {
if (modeFeature.getName().equalsIgnoreCase(mf.getName())) {
mp.getInModeOrTransitions().remove(mf);
break;
}
}
}
} else if (ne instanceof ModalElement && modeFeature instanceof Mode) {
final ModalElement modalElement = (ModalElement) ne;
if (modeBtnIsSelected) {
modalElement.getAllInModes().add((Mode) modeFeature);
} else {
for (final ModeFeature mf : modalElement.getInModes()) {
if (modeFeature.getName().equalsIgnoreCase(mf.getName())) {
modalElement.getAllInModes().remove(modeFeature);
break;
}
}
}
}
});
}
};
// Register selection listeners
modeBtn.addSelectionListener(selectionListener);
if (derivedModeFld != null) {
derivedModeFld.getCombo().addSelectionListener(selectionListener);
}
}
use of org.osate.aadl2.AnnexSubclause in project osate2 by osate.
the class DeleteHandler method createBusinessObjectRemovalOrRemoveDiagramElement.
/**
* Creates a BusinessObjectRemoval object which can be used to remove the business object for the diagram element.
* If the diagram element's business object is an embedded business object, remove the element.
* @param de
* @return
*/
private static BusinessObjectRemoval createBusinessObjectRemovalOrRemoveDiagramElement(final DiagramElement de) {
// Remove the EObject from the model
final Object bo = de.getBusinessObject();
final Object boHandler = de.getBusinessObjectHandler();
if (bo instanceof EObject) {
EObject boEObj = (EObject) bo;
if (boHandler instanceof CustomDeleter) {
final CustomDeleter deleter = (CustomDeleter) boHandler;
final EObject ownerBo = boEObj.eContainer();
return new BusinessObjectRemoval(ownerBo, (boToModify) -> {
deleter.delete(new CustomDeleteContext(boToModify, bo));
});
}
// When deleting AnnexSubclauses, the deletion must executed on the container DefaultAnnexSubclause
if (boEObj instanceof AnnexSubclause && boEObj.eContainer() instanceof DefaultAnnexSubclause) {
boEObj = boEObj.eContainer();
}
return new BusinessObjectRemoval(boEObj, (boToModify) -> EcoreUtil.remove(boToModify));
} else if (bo instanceof EmfContainerProvider) {
if (!(boHandler instanceof CustomDeleter)) {
throw new RuntimeException("Business object handler '" + boHandler + "' for " + EmfContainerProvider.class.getName() + " based business object must implement " + CustomDeleter.class.getCanonicalName() + ".");
}
final CustomDeleter deleter = (CustomDeleter) boHandler;
final EObject ownerBo = ((EmfContainerProvider) bo).getEmfContainer();
return new BusinessObjectRemoval(ownerBo, (boToModify) -> {
deleter.delete(new CustomDeleteContext(boToModify, bo));
});
} else if (bo instanceof EmbeddedBusinessObject) {
// For embedded business objects, there isn't a model from which to remove the business object.
// Instead, we remove the diagram element and return null.
final AgeDiagram diagram = DiagramElementUtil.getDiagram(de);
diagram.modify("Delete Element", m -> m.removeElement(de));
return null;
} else {
// canDelete() should have returned false in this case
throw new RuntimeException("Unhandled case: " + bo);
}
}
use of org.osate.aadl2.AnnexSubclause in project osate2 by osate.
the class AnnexHandler method getAnnexSubclauseIndex.
/**
* Returns a 0 based index for referencing an annex subclause in a list that contains only annex subclauses with the same type and owner
* @return
*/
public static int getAnnexSubclauseIndex(AnnexSubclause annexSubclause, final boolean useExtended) {
// Get the default annex library if a parsed annex subclause was specified. This is needed for the comparison later in the function.
if (!(annexSubclause instanceof DefaultAnnexSubclause)) {
if (annexSubclause.eContainer() instanceof DefaultAnnexSubclause) {
annexSubclause = (AnnexSubclause) annexSubclause.eContainer();
} else {
return -1;
}
}
final String annexName = annexSubclause.getName();
if (annexName == null) {
return -1;
}
final Classifier cl = annexSubclause.getContainingClassifier();
final List<Classifier> classifiers;
if (useExtended) {
classifiers = cl.getSelfPlusAllExtended();
// Get all related classifiers
if (cl instanceof ComponentImplementation) {
final ComponentType ct = ((ComponentImplementation) cl).getType();
if (ct != null) {
classifiers.addAll(ct.getSelfPlusAllExtended());
}
}
} else {
classifiers = Arrays.asList(cl);
}
int index = 0;
// Use reversed view of list so that base classifiers will be first. This is needed to ensure subclauses have unique indices
for (final Classifier tmpClassifier : Lists.reverse(classifiers)) {
for (final AnnexSubclause tmpSubclause : tmpClassifier.getOwnedAnnexSubclauses()) {
if (tmpSubclause == annexSubclause) {
return index;
} else if (annexName.equalsIgnoreCase(tmpSubclause.getName())) {
index++;
}
}
}
return -1;
}
Aggregations