PropertiesLinkingDiagnosticMessageProvider.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.xtext.aadl2.properties.linking;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.xtext.diagnostics.Diagnostic;
import org.eclipse.xtext.diagnostics.DiagnosticMessage;
import org.eclipse.xtext.diagnostics.Severity;
import org.eclipse.xtext.linking.impl.LinkingDiagnosticMessageProvider;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.osate.aadl2.Aadl2Package;
import org.osate.aadl2.ContainedNamedElement;
import org.osate.aadl2.ContainmentPathElement;
import org.osate.aadl2.PropertyAssociation;
import org.osate.aadl2.Subcomponent;
import org.osate.aadl2.modelsupport.util.AadlUtil;
import org.osate.aadl2.util.Aadl2Util;
import org.osate.core.OsateCorePlugin;
public class PropertiesLinkingDiagnosticMessageProvider extends LinkingDiagnosticMessageProvider {
@Override
public DiagnosticMessage getUnresolvedProxyMessage(ILinkingDiagnosticContext context) {
EClass referenceType = context.getReference().getEReferenceType();
String targetName = null;
if (Aadl2Package.eINSTANCE.getAbstractNamedValue() == referenceType) {
targetName = "Property Constant, Property Definition, Enumeration or Unit literal";
String msg = "Couldn't resolve reference to " + targetName + " '" + context.getLinkText() + "'."
+ " For classifier references use classifier( <ref> ).";
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
boolean suppressError = false;
if (Aadl2Package.eINSTANCE.getProperty() == referenceType) {
boolean showWarningInstead = false;
if (context.getLinkText().indexOf("::") > 0) {
// get preferences ~ same as org.osate.ui.utils.PropertySetModel
String[] ignoredPerPreference = getIgnoredPropertySetPreference();
showWarningInstead = getIgnoredPropertySetAlertPreference();
// FIXME - should process property set name only
for (String propSetName : context.getLinkText().split("::")) {
if (!suppressError) {
// check against preference
for (String pref : ignoredPerPreference) {
if (pref.equalsIgnoreCase(propSetName)) {
suppressError = true;
break;
}
}
}
}
}
String msg = "Couldn't resolve reference to property definition '" + context.getLinkText() + "'."
+ (context.getLinkText().indexOf("::") < 0 ? " Property set name may be missing." : "");
if (suppressError) {
if (showWarningInstead) {
return new DiagnosticMessage(msg, Severity.WARNING, Diagnostic.LINKING_DIAGNOSTIC);
} else {
return null;
}
} else {
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
}
if (Aadl2Package.eINSTANCE.getPropertyType() == referenceType) {
String msg = "Couldn't resolve reference to property type '" + context.getLinkText() + "'."
+ (context.getLinkText().indexOf("::") < 0 ? " Property set name may be missing." : "");
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
if (Aadl2Package.eINSTANCE.getPropertyConstant() == referenceType) {
String msg = "Couldn't resolve reference to property constant '" + context.getLinkText() + "'."
+ (context.getLinkText().indexOf("::") < 0 ? " Property set name may be missing." : "");
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
if (Aadl2Package.eINSTANCE.getNamedElement() == referenceType) {
EObject obj = context.getContext();
if (obj instanceof ContainmentPathElement) {
Subcomponent sub = AadlUtil.getContainingSubcomponent(obj);
INode node = NodeModelUtils.findActualNodeFor(obj);
String name = NodeModelUtils.getTokenText(node);
if (sub != null && !(obj.eContainer() instanceof ContainmentPathElement)) {
String msg = "Could not find path element " + name + " in subcomponent " + sub.getName();
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
}
String msg = "Couldn't resolve reference to '" + context.getLinkText() + "'.";
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
if (Aadl2Package.eINSTANCE.getMode() == referenceType) {
EObject cxt = context.getContext();
PropertyAssociation pa = AadlUtil.getContainingPropertyAssociation(cxt);
boolean iscontainedPA = (pa != null && !pa.getAppliesTos().isEmpty());
String msg = "Couldn't resolve reference to mode '" + context.getLinkText() + "'";
if (iscontainedPA) {
EList<ContainedNamedElement> appl = pa.getAppliesTos();
ContainedNamedElement path = appl.get(appl.size() - 1);
msg = msg + " in applies to '" + Aadl2Util.getPrintablePathName(path) + "'.";
} else {
msg = msg + ".";
}
return new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC);
}
DiagnosticMessage msg = super.getUnresolvedProxyMessage(context);
if (referenceType.getName().equals("ModelUnit")) { // check with clause against ignored property set preference
// check against preference
for (String inIgnoredPrefList : getIgnoredPropertySetPreference()) {
if (inIgnoredPrefList.equalsIgnoreCase(context.getLinkText())) {
return new DiagnosticMessage(context.getLinkText()
+ " property set is missing. Install additional plug-ins that have this property set",
Severity.WARNING, Diagnostic.LINKING_DIAGNOSTIC);
}
}
}
return msg;
}
private String[] getIgnoredPropertySetPreference() {
// get preferences ~ same as org.osate.ui.utils.PropertySetModel
String[] ignoredPerPreference = new String[] {};
if (Platform.isRunning()) {
String separator = "&~!";
String PREFS_IGNORED_PROPERTY_SET_NAMES = "org.osate.ui.internal.propertysetnames";
final IPreferenceStore store = OsateCorePlugin.getDefault().getPreferenceStore();
String allNames = store.getString(PREFS_IGNORED_PROPERTY_SET_NAMES);
if (allNames != null && !allNames.isEmpty()) {
ignoredPerPreference = allNames.split(separator);
}
}
return ignoredPerPreference;
}
private Boolean getIgnoredPropertySetAlertPreference() {
Boolean showWarningInstead = false;
if (Platform.isRunning()) {
String PREFS_SHOW_WARNING = "org.osate.ui.internal.propertysetnames.showWarning";
final IPreferenceStore store = OsateCorePlugin.getDefault().getPreferenceStore();
showWarningInstead = store.getBoolean(PREFS_SHOW_WARNING);
}
return showWarningInstead;
}
}