Skip to content

Commit f6d83fd

Browse files
committed
Support special IDREF validation via ExtensionsErrorReporter.isPresent
- The quicklinks.exsd defines two attributes that are specified as IDREFs to command IDs but they actually permit a command spec and even wildcards. - This leads to warnings when those aspects are used and those warnings are impossible for the user to fix. - If we disable the basedOn type for those, the extension attributes no longer support Browse... to find a command, which makes authoring very inconvenient. - Ideally PDE is made aware of these special attribute so support specialized validation.
1 parent 77439fd commit f6d83fd

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/ExtensionsErrorReporter.java

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import java.util.Iterator;
2121
import java.util.Map;
2222
import java.util.StringTokenizer;
23+
import java.util.regex.Pattern;
24+
import java.util.regex.PatternSyntaxException;
2325

2426
import org.eclipse.core.resources.IFile;
2527
import org.eclipse.core.resources.IMarker;
@@ -657,15 +659,54 @@ private void validateIdentifierAttribute(Element element, Attr attr, ISchemaAttr
657659
String basedOn = attInfo.getBasedOn();
658660
// only validate if we have a valid value and basedOn value
659661
if (value != null && basedOn != null && value.length() > 0 && basedOn.length() > 0) {
660-
Map<String, IConfigurationElement> attributes = PDESchemaHelper.getValidAttributes(attInfo);
661-
if (!attributes.containsKey(value)) { // report error if we are missing something
662+
// report error if we are missing something
663+
if (!isPresent(attInfo, value)) {
662664
VirtualMarker marker = report(NLS.bind(PDECoreMessages.ExtensionsErrorReporter_unknownIdentifier, (new String[] {attr.getValue(), attr.getName()})), getLine(element, attr.getName()), severity, PDEMarkerFactory.CAT_OTHER);
663665
addMarkerAttribute(marker, PDEMarkerFactory.compilerKey, CompilerFlags.P_UNKNOWN_IDENTIFIER);
664666
}
665667
}
666668
}
667669
}
668670

671+
private boolean isPresent(ISchemaAttribute attInfo, String value) {
672+
// This is the normal case.
673+
Map<String, IConfigurationElement> attributes = PDESchemaHelper.getValidAttributes(attInfo);
674+
if (attributes.containsKey(value)) {
675+
return true;
676+
}
677+
// Determine if this is a special case.
678+
// https://github.com/eclipse-platform/eclipse.platform/blob/master/ua/org.eclipse.ui.intro.quicklinks/schema/quicklinks.exsd
679+
String qualifiedName = attInfo.getSchema().getPointId() + '.' + attInfo.getParent().getName() + '.'
680+
+ attInfo.getName();
681+
// The command may include simple '*' wildcards to match any substring.
682+
boolean allowsWildcard = "org.eclipse.ui.intro.quicklinks.override.command".equals(qualifiedName); //$NON-NLS-1$
683+
// These both allow not just an ID but also a command spec as consumed
684+
// by org.eclipse.ui.commands.ICommandService.deserialize(String)
685+
boolean allowsCommandSpec = allowsWildcard
686+
|| "org.eclipse.ui.intro.quicklinks.command.id".equals(qualifiedName); //$NON-NLS-1$
687+
if (allowsCommandSpec || allowsWildcard) {
688+
String baseValue = value;
689+
// Validate just the command ID part of the command spec if present.
690+
int index = value.indexOf("("); //$NON-NLS-1$
691+
if (index != -1) {
692+
baseValue = value.substring(0, index);
693+
}
694+
// If a simple wildcard is permitted and is present...
695+
if (allowsWildcard && baseValue.contains("*")) { //$NON-NLS-1$
696+
try {
697+
// Convert it to a pattern and match against all keys.
698+
Pattern pattern = Pattern.compile(baseValue.replace(".", "\\.").replace("*", ".*")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
699+
return attributes.keySet().stream().anyMatch(pattern.asMatchPredicate());
700+
} catch (PatternSyntaxException ex) {
701+
//$FALL-THROUGH$
702+
}
703+
}
704+
// If we extracted a base value, test it like we did the value.
705+
return value != baseValue && attributes.containsKey(baseValue);
706+
}
707+
return false;
708+
}
709+
669710
protected void reportUnusedAttribute(Element element, String attName, int severity) {
670711
String message = NLS.bind(PDECoreMessages.Builders_Manifest_unused_attribute, attName);
671712
VirtualMarker marker = report(message, getLine(element, attName), severity, PDEMarkerFactory.CAT_OTHER);

0 commit comments

Comments
 (0)