use of org.infinispan.protostream.AnnotationParserException in project protostream by infinispan.
the class AnnotatedDescriptorImpl method validateAttributes.
private void validateAttributes(AnnotationElement.Annotation annotation, AnnotationConfiguration annotationConfig) {
for (Map.Entry<String, AnnotationElement.Attribute> entry : annotation.getAttributes().entrySet()) {
AnnotationElement.Attribute attribute = entry.getValue();
final AnnotationAttributeConfiguration attributeConfig = annotationConfig.attributes().get(attribute.getName());
if (attributeConfig == null) {
throw new AnnotationParserException("Unexpected attribute '" + attribute.getName() + "' in annotation '" + annotation.getName() + "' on " + getFullName());
}
AnnotationElement.Value value = attribute.getValue();
if (!attributeConfig.multiple() && value instanceof AnnotationElement.Array) {
throw new AnnotationParserException("Annotation attribute '" + attribute.getName() + "' in annotation '" + annotation.getName() + "' on " + getFullName() + " does not accept array values");
}
if (value instanceof AnnotationElement.Array) {
for (AnnotationElement.Value v : ((AnnotationElement.Array) value).getValues()) {
validateAttribute(annotation, attribute, attributeConfig, v);
}
} else {
validateAttribute(annotation, attribute, attributeConfig, value);
}
}
}
use of org.infinispan.protostream.AnnotationParserException in project protostream by infinispan.
the class AnnotatedDescriptorImpl method processAnnotations.
/**
* Extract annotations by parsing the documentation comment and run the configured {@link
* AnnotationMetadataCreator}s.
*
* @throws AnnotationParserException if annotation parsing fails
*/
private void processAnnotations() throws AnnotationParserException {
// we are lazily processing the annotations, if there is a documentation text attached to this element
if (annotations == null) {
if (documentation != null) {
AnnotationParser parser = new AnnotationParser(documentation, true);
List<AnnotationElement.Annotation> parsedAnnotations = parser.parse();
Map<String, AnnotationElement.Annotation> _annotations = new LinkedHashMap<>();
Map<String, AnnotationElement.Annotation> _containers = new LinkedHashMap<>();
for (AnnotationElement.Annotation annotation : parsedAnnotations) {
AnnotationConfiguration annotationConfig = getAnnotationConfig(annotation);
if (annotationConfig == null) {
// unknown annotations are ignored, but we might want to log a warning
if (getAnnotationsConfig().logUndefinedAnnotations()) {
log.warnf("Encountered and ignored and unknown annotation \"%s\" on %s", annotation.getName(), fullName);
}
} else {
validateAttributes(annotation, annotationConfig);
// convert single values to arrays if needed and set the default values for missing attributes
normalizeValues(annotation, annotationConfig);
if (_annotations.containsKey(annotation.getName()) || _containers.containsKey(annotation.getName())) {
// did we just find a repeatable annotation?
if (annotationConfig.repeatable() != null) {
AnnotationElement.Annotation container = _containers.get(annotation.getName());
if (container == null) {
List<AnnotationElement.Value> values = new LinkedList<>();
values.add(_annotations.remove(annotation.getName()));
values.add(annotation);
AnnotationElement.Attribute value = new AnnotationElement.Attribute(annotation.position, AnnotationElement.Annotation.VALUE_DEFAULT_ATTRIBUTE, new AnnotationElement.Array(annotation.position, values));
container = new AnnotationElement.Annotation(annotation.position, annotationConfig.repeatable(), Collections.singletonMap(value.getName(), value));
_containers.put(annotation.getName(), container);
_annotations.put(container.getName(), container);
} else {
AnnotationElement.Array value = (AnnotationElement.Array) container.getAttributeValue(AnnotationElement.Annotation.VALUE_DEFAULT_ATTRIBUTE);
value.getValues().add(annotation);
}
} else {
// it's just a duplicate, not a proper 'repeated' annotation
throw new AnnotationParserException(String.format("Error: %s: duplicate annotation definition \"%s\" on %s", AnnotationElement.positionToString(annotation.position), annotation.getName(), fullName));
}
} else {
_annotations.put(annotation.getName(), annotation);
}
}
}
// annotations are now completely parsed and validated
annotations = _annotations.isEmpty() ? Collections.emptyMap() : Collections.unmodifiableMap(_annotations);
// create metadata based on the annotations
processedAnnotations = new LinkedHashMap<>();
for (AnnotationElement.Annotation annotation : annotations.values()) {
AnnotationConfiguration annotationConfig = getAnnotationConfig(annotation);
AnnotationMetadataCreator<Object, AnnotatedDescriptor> creator = (AnnotationMetadataCreator<Object, AnnotatedDescriptor>) annotationConfig.metadataCreator();
if (creator != null) {
Object metadataForAnnotation;
try {
metadataForAnnotation = creator.create(this, annotation);
} catch (Exception ex) {
log.errorf(ex, "Exception encountered while processing annotation \"%s\" on %s", annotation.getName(), fullName);
throw ex;
}
processedAnnotations.put(annotation.getName(), metadataForAnnotation);
}
}
} else {
annotations = Collections.emptyMap();
processedAnnotations = Collections.emptyMap();
}
}
}
use of org.infinispan.protostream.AnnotationParserException in project protostream by infinispan.
the class AnnotationLexer method nextToken.
public void nextToken() {
lastPos = AnnotationElement.makePosition(line, col);
sb.setLength(0);
while (true) {
pos = AnnotationElement.makePosition(line, col);
switch(ch) {
case ',':
scanNextChar();
token = AnnotationTokens.COMMA;
return;
case '(':
scanNextChar();
token = AnnotationTokens.LPAREN;
return;
case ')':
scanNextChar();
token = AnnotationTokens.RPAREN;
return;
case '{':
scanNextChar();
token = AnnotationTokens.LBRACE;
return;
case '}':
scanNextChar();
token = AnnotationTokens.RBRACE;
return;
case '@':
scanNextChar();
token = AnnotationTokens.AT;
return;
case '=':
scanNextChar();
token = AnnotationTokens.EQ;
return;
case '.':
scanNextChar();
if ('0' <= ch && ch <= '9') {
sb.append('.');
scanDecimal();
} else {
token = AnnotationTokens.DOT;
}
return;
case '_':
case '$':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
scanIdentifier();
return;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
scanNumber();
return;
case '\'':
scanNextChar();
if (ch == '\'') {
throw new AnnotationParserException(String.format("Error: %s: empty character literal", AnnotationElement.positionToString(pos)));
} else {
if (ch == '\r' || ch == '\n') {
throw new AnnotationParserException(String.format("Error: %s: illegal line end in character literal", AnnotationElement.positionToString(pos)));
}
scanLiteralChar();
if (ch == '\'') {
scanNextChar();
token = AnnotationTokens.CHARACTER_LITERAL;
} else {
throw new AnnotationParserException(String.format("Error: %s: unclosed character literal", AnnotationElement.positionToString(pos)));
}
}
return;
case '"':
scanNextChar();
while (ch != '"' && ch != '\r' && ch != '\n' && inputPos < input.length) {
scanLiteralChar();
}
if (ch == '"') {
token = AnnotationTokens.STRING_LITERAL;
scanNextChar();
} else {
throw new AnnotationParserException(String.format("Error: %s: unclosed string literal", AnnotationElement.positionToString(pos)));
}
return;
case ' ':
case '\t':
scanNextChar();
continue;
case '\f':
col = 0;
leadingWhitespace = true;
scanNextChar();
continue;
case '\r':
line++;
col = 0;
leadingWhitespace = true;
scanNextChar();
if (ch == '\n') {
col = 0;
leadingWhitespace = true;
scanNextChar();
}
continue;
case '\n':
line++;
col = 0;
leadingWhitespace = true;
scanNextChar();
continue;
default:
if (ch == '\0' && inputPos == input.length) {
token = AnnotationTokens.EOF;
} else if (Character.isJavaIdentifierStart(ch)) {
scanIdentifier();
} else {
throw new AnnotationParserException(String.format("Error: %s: illegal character: %c", AnnotationElement.positionToString(pos), ch));
}
return;
}
}
}
use of org.infinispan.protostream.AnnotationParserException in project protostream by infinispan.
the class AnnotationParser method parseValue.
private AnnotationElement.Value parseValue(int start) {
long pos = lexer.pos;
switch(lexer.token) {
case AT:
return parseAnnotation();
case LBRACE:
return parseArray();
case IDENTIFIER:
return parseIdentifier();
case INT_LITERAL:
case LONG_LITERAL:
case FLOAT_LITERAL:
case DOUBLE_LITERAL:
case CHARACTER_LITERAL:
case STRING_LITERAL:
case TRUE:
case FALSE:
AnnotationTokens tok = lexer.token;
String text = lexer.getText(start, lexer.getBufferPos());
Object value = null;
try {
switch(tok) {
case INT_LITERAL:
value = Integer.parseInt(text.trim());
break;
case LONG_LITERAL:
value = Long.parseLong(text.trim());
break;
case FLOAT_LITERAL:
value = Float.parseFloat(text.trim());
break;
case DOUBLE_LITERAL:
value = Double.parseDouble(text.trim());
break;
case CHARACTER_LITERAL:
value = text.charAt(1);
break;
case STRING_LITERAL:
{
value = text.substring(text.indexOf("\"") + 1, text.length() - 1);
break;
}
case TRUE:
value = Boolean.TRUE;
break;
case FALSE:
value = Boolean.FALSE;
break;
}
} catch (NumberFormatException e) {
throw new AnnotationParserException(String.format("Error: %s: invalid numeric value: %s", AnnotationElement.positionToString(lexer.pos), e.getMessage()));
}
AnnotationElement.Literal literal = new AnnotationElement.Literal(pos, value);
lexer.nextToken();
return literal;
}
throw new AnnotationParserException(String.format("Error: %s: literal expected", AnnotationElement.positionToString(lexer.pos)));
}
use of org.infinispan.protostream.AnnotationParserException in project protostream by infinispan.
the class AnnotatedDescriptorImpl method normalizeValues.
private void normalizeValues(AnnotationElement.Annotation annotation, AnnotationConfiguration annotationConfig) {
for (AnnotationAttributeConfiguration attributeConfig : annotationConfig.attributes().values()) {
AnnotationElement.Attribute attribute = annotation.getAttributes().get(attributeConfig.name());
if (attribute != null) {
AnnotationElement.Value value = attribute.getValue();
if (attributeConfig.multiple() && !(value instanceof AnnotationElement.Array)) {
// a single value will be automatically wrapped in an array node if the attribute was defined as 'multiple'
value = new AnnotationElement.Array(value.position, Collections.singletonList(value));
attribute = new AnnotationElement.Attribute(attribute.position, attributeConfig.name(), value);
annotation.getAttributes().put(attributeConfig.name(), attribute);
}
} else if (attributeConfig.defaultValue() != null) {
AnnotationElement.Value value = attributeConfig.type() == AnnotationElement.AttributeType.IDENTIFIER ? new AnnotationElement.Identifier(AnnotationElement.UNKNOWN_POSITION, (String) attributeConfig.defaultValue()) : new AnnotationElement.Literal(AnnotationElement.UNKNOWN_POSITION, attributeConfig.defaultValue());
if (attributeConfig.multiple()) {
value = new AnnotationElement.Array(value.position, Collections.singletonList(value));
}
attribute = new AnnotationElement.Attribute(AnnotationElement.UNKNOWN_POSITION, attributeConfig.name(), value);
annotation.getAttributes().put(attributeConfig.name(), attribute);
} else {
throw new AnnotationParserException("Attribute '" + attributeConfig.name() + "' of annotation '" + annotation.getName() + "' on " + getFullName() + " is required");
}
}
}
Aggregations