public String toString(Token t) { if (t.getKind().hasPayload()) { return t.stringValue(); } else { return t.kind.toString().toLowerCase(); } }
/** * Eat an identifier, possibly qualified (meaning that it is dotted). TODO AndyC Could create * complete identifiers (a.b.c) here rather than a sequence of them? (a, b, c) */ private SpelNodeImpl eatPossiblyQualifiedId() { LinkedList<SpelNodeImpl> qualifiedIdPieces = new LinkedList<SpelNodeImpl>(); Token node = peekToken(); while (isValidQualifiedId(node)) { nextToken(); if (node.kind != TokenKind.DOT) { qualifiedIdPieces.add(new Identifier(node.stringValue(), toPos(node))); } node = peekToken(); } if (qualifiedIdPieces.isEmpty()) { if (node == null) { raiseInternalException(expressionString.length(), SpelMessage.OOD); } raiseInternalException( node.startpos, SpelMessage.NOT_EXPECTED_TOKEN, "qualified ID", node.getKind().toString().toLowerCase()); } int pos = toPos( qualifiedIdPieces.getFirst().getStartPosition(), qualifiedIdPieces.getLast().getEndPosition()); return new QualifiedIdentifier( pos, qualifiedIdPieces.toArray(new SpelNodeImpl[qualifiedIdPieces.size()])); }
private boolean peekIdentifierToken(String identifierString) { if (!moreTokens()) { return false; } Token t = peekToken(); return t.kind == TokenKind.IDENTIFIER && t.stringValue().equalsIgnoreCase(identifierString); }
private boolean isValidQualifiedId(Token node) { if (node == null || node.kind == TokenKind.LITERAL_STRING) { return false; } if (node.kind == TokenKind.DOT || node.kind == TokenKind.IDENTIFIER) { return true; } String value = node.stringValue(); return StringUtils.hasLength(value) && VALID_QUALIFIED_ID_PATTERN.matcher(value).matches(); }
private boolean maybeEatNullReference() { if (peekToken(TokenKind.IDENTIFIER)) { Token nullToken = peekToken(); if (!nullToken.stringValue().equalsIgnoreCase("null")) { return false; } nextToken(); constructedNodes.push(new NullLiteral(toPos(nullToken))); return true; } return false; }
// relationalOperator // : EQUAL | NOT_EQUAL | LESS_THAN | LESS_THAN_OR_EQUAL | GREATER_THAN // | GREATER_THAN_OR_EQUAL | INSTANCEOF | BETWEEN | MATCHES private Token maybeEatRelationalOperator() { Token t = peekToken(); if (t == null) { return null; } if (t.isNumericRelationalOperator()) { return t; } if (t.isIdentifier()) { String idString = t.stringValue(); if (idString.equalsIgnoreCase("instanceof")) { return t.asInstanceOfToken(); } else if (idString.equalsIgnoreCase("matches")) { return t.asMatchesToken(); } else if (idString.equalsIgnoreCase("between")) { return t.asBetweenToken(); } } return null; }
private boolean maybeEatTypeReference() { if (peekToken(TokenKind.IDENTIFIER)) { Token typeName = peekToken(); if (!typeName.stringValue().equals("T")) { return false; } nextToken(); eatToken(TokenKind.LPAREN); SpelNodeImpl node = eatPossiblyQualifiedId(); // dotted qualified id // Are there array dimensions? int dims = 0; while (peekToken(TokenKind.LSQUARE, true)) { eatToken(TokenKind.RSQUARE); dims++; } eatToken(TokenKind.RPAREN); constructedNodes.push(new TypeReference(toPos(typeName), node, dims)); return true; } return false; }
// parse: @beanname @'bean.name' // quoted if dotted private boolean maybeEatBeanReference() { if (peekToken(TokenKind.BEAN_REF)) { Token beanRefToken = nextToken(); Token beanNameToken = null; String beanname = null; if (peekToken(TokenKind.IDENTIFIER)) { beanNameToken = eatToken(TokenKind.IDENTIFIER); beanname = beanNameToken.data; } else if (peekToken(TokenKind.LITERAL_STRING)) { beanNameToken = eatToken(TokenKind.LITERAL_STRING); beanname = beanNameToken.stringValue(); beanname = beanname.substring(1, beanname.length() - 1); } else { raiseInternalException(beanRefToken.startpos, SpelMessage.INVALID_BEAN_REFERENCE); } BeanReference beanReference = new BeanReference(toPos(beanNameToken), beanname); constructedNodes.push(beanReference); return true; } return false; }