private void validateJavaFeatureAccess(Class<?> clazz, String[] nameTokens, Expression context, IIssueCallback validator) { if (nameTokens.length != 1) { validator.error("For Java objects parameters no feature access is supported.", context, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); } }
/** * Checks whether an {@link EClassifier} defines a feature with the selected name; if not, reports an error for the * selected reference. */ private void checkClassifierFeature(EClassifier classifier, String featureName, Expression ref, IIssueCallback validator, boolean userSpecified) { if (classifier instanceof EClass) { EClass classDef = (EClass) classifier; if (classDef.getEStructuralFeature(featureName) == null) { if (userSpecified) { validator.error( String.format("Invalid feature type %s in EClass %s", featureName, classifier.getName()), ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, UNKNOWN_ATTRIBUTE_CODE); } else { validator.warning(String.format( "EClass %s does not define a name attribute, so the string representation might be inconvinient to use. Perhaps a feature qualifier is missing?", classifier.getName()), ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, UNKNOWN_ATTRIBUTE_CODE); } } } else if (classifier == null) { return; } }
validator.error("Surrogate pattern must have exactly 2 parameters.", pattern, PatternLanguagePackage.Literals.PATTERN__PARAMETERS, PATTERN_ISSUE_CODE); return; validator.error("The 'source' parameter must be EClass.", source, PatternLanguagePackage.Literals.VARIABLE__TYPE, PATTERN_ISSUE_CODE); return; validator.error("The 'feature' parameter must not be empty.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, ANNOTATION_ISSUE_CODE); return; validator.error(String.format("Cannot find feature %s of EClass %s.", featureName, sourceClass.getName()), contextForFeature, contextESFForFeature, ANNOTATION_ISSUE_CODE); return; boolean featureError = false; if(!feature.isDerived()) { validator.error(String.format("Feature %s is not derived.",featureName), contextForFeature, contextESFForFeature, METAMODEL_ISSUE_CODE); featureError = true; validator.error(String.format("Feature %s is not transient.",featureName), contextForFeature, contextESFForFeature, METAMODEL_ISSUE_CODE); featureError = true; validator.error(String.format("Feature %s is not volatile.",featureName), contextForFeature, contextESFForFeature, METAMODEL_ISSUE_CODE); featureError = true;
validator.error("Query-based feature pattern must have at least two parameters.", pattern, PatternLanguagePackage.Literals.PATTERN__PARAMETERS, PATTERN_ISSUE_CODE); return; source = PatternLanguageHelper.getParameterByName(pattern, ((VariableReference) ref).getVar()).orElse(null); if (pattern.getParameters().get(0).equals(source)) { validator.warning("The 'source' parameter is not needed if it is the first pattern parameter.", ref, PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VAR, ANNOTATION_ISSUE_CODE); validator.error("The 'source' parameter must be EClass.", source, PatternLanguagePackage.Literals.VARIABLE__TYPE, PATTERN_ISSUE_CODE); return; validator.error("The 'feature' parameter must not be empty.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, ANNOTATION_ISSUE_CODE); return; validator.error(String.format("Cannot find feature %s of EClass %s.", featureName, sourceClass.getName()), contextForFeature, contextESFForFeature, ANNOTATION_ISSUE_CODE); return; boolean featureError = false; if(!feature.isDerived()) { validator.error(String.format("Feature %s is not derived.",featureName), contextForFeature, contextESFForFeature, METAMODEL_ISSUE_CODE); featureError = true; validator.error(String.format("Feature %s is not transient.",featureName), contextForFeature, contextESFForFeature, METAMODEL_ISSUE_CODE);
/** * Validates a path expression referring to a simple pattern parameter * * @param expression * the string representation of the path expression. Not inside '$' symbols. * @param pattern * the containing pattern * @param ref * a reference for the annotation parameter for error localization * @param validator * the validator to report the found issues * @since 2.0 */ public void validateParameterString(String expression, Pattern pattern, ValueReference ref, IIssueCallback validator) { if (expression.contains(".")) { validator.error("Expression must refer to a single parameter.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); } Optional<Variable> parameter = PatternLanguageHelper.getParameterByName(pattern, expression); if (!parameter.isPresent()) { validator.error(String.format("Unknown parameter name %s", expression), ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, UNKNOWN_VARIABLE_CODE); return; } }
StringTokenizer tokenizer = new StringTokenizer(expression, "$", true); if (expression.isEmpty() || tokenizer.countTokens() == 0) { validator.error("Expression must not be empty.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); return; if (token.equals("$")) { if (inExpression && !foundToken) { validator.error("Empty reference ($$) in message is not allowed.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); validator.error("Inconsistent model references - a $ character is missing.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE);
private void validateClassifierFeatureAccess(EClassifier classifier, String[] nameTokens, Expression context, IIssueCallback validator) { if (nameTokens.length == 1) { checkClassifierFeature(classifier, "name", context, validator, false); } else if (nameTokens.length == 2) { String featureName = nameTokens[1]; checkClassifierFeature(classifier, featureName, context, validator, true); } else { validator.error("Only direct feature references are supported.", context, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); } }
private boolean checkFeatureUniquenessOnQBFAnnotations(Annotation annotation, IIssueCallback validator, Pattern pattern) { Collection<Annotation> qbfAnnotations = PatternLanguageHelper.getAnnotationsByName(pattern, "QueryBasedFeature"); if(qbfAnnotations.size() > 1) { ValueReference feature = PatternLanguageHelper.getFirstAnnotationParameter(annotation, FEATURE_PARAMETER_NAME); if(feature == null) { validator.error("Feature must be specified when multiple QueryBasedFeature annotations are used on a single pattern.", annotation, PatternLanguagePackage.Literals.ANNOTATION__NAME, ANNOTATION_ISSUE_CODE); return true; } else { String featureName = ((StringValue) feature).getValue(); for (Annotation antn : qbfAnnotations) { ValueReference otherFeature = PatternLanguageHelper.getFirstAnnotationParameter(antn, FEATURE_PARAMETER_NAME); if(otherFeature != null) { String otherFeatureName = ((StringValue) otherFeature).getValue(); if(featureName.equals(otherFeatureName)) { validator.error("Feature must be unique among multiple QueryBasedFeature annotations used on a single pattern.", annotation, PatternLanguagePackage.Literals.ANNOTATION__NAME, ANNOTATION_ISSUE_CODE); return true; } } } } } return false; }
private boolean checkFeatureUniquenessOnSurrogateAnnotations(Annotation annotation, IIssueCallback validator, Pattern pattern) { Collection<Annotation> qbfAnnotations = PatternLanguageHelper.getAnnotationsByName(pattern, "Surrogate"); if(qbfAnnotations.size() > 1) { ValueReference feature = PatternLanguageHelper.getFirstAnnotationParameter(annotation, FEATURE_PARAMETER_NAME); if(feature == null) { validator.error("Feature must be specified when multiple Surrogate annotations are used on a single pattern.", annotation, PatternLanguagePackage.Literals.ANNOTATION__NAME, ANNOTATION_ISSUE_CODE); return true; } else { String featureName = ((StringValue) feature).getValue(); for (Annotation antn : qbfAnnotations) { ValueReference otherFeature = PatternLanguageHelper.getFirstAnnotationParameter(antn, FEATURE_PARAMETER_NAME); if(otherFeature != null) { String otherFeatureName = ((StringValue) otherFeature).getValue(); if(featureName.equals(otherFeatureName)) { validator.error("Feature must be unique among multiple Surrogate annotations used on a single pattern.", annotation, PatternLanguagePackage.Literals.ANNOTATION__NAME, ANNOTATION_ISSUE_CODE); return true; } } } } } return false; }
String[] tokens = expression.split("\\."); if (expression.isEmpty() || tokens.length == 0) { validator.error("Expression must not be empty.", ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, GENERAL_ISSUE_CODE); return; validator.error(String.format("Unknown parameter name %s", tokens[0]), ref, PatternLanguagePackage.Literals.STRING_VALUE__VALUE, UNKNOWN_VARIABLE_CODE); return; validateClassifierFeatureAccess(classifier, tokens, ref, validator); } else { validator.error(String.format("Label expressions only supported on EMF types, not on %s", type.getPrettyPrintableName()), parameter.get(), PatternLanguagePackage.Literals.VARIABLE__NAME, GENERAL_ISSUE_CODE);