package org.raidenjpa.query.parser; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.raidenjpa.util.BadSmell; import org.raidenjpa.util.StringUtil; public class QueryWords { private int position; private String[] words; private String originalJpql; private static final String[] POSSIBLE_WORDS_AFTER_FROM = {"INNER", "WHERE", "JOIN", "LEFT", ","}; private static final String[] POSSIBLE_WORDS_AFTER_LOGIC_EXPRESSION = {"INNER", "LEFT", "RIGHT", "JOIN", "WHERE", "ORDER", "GROUP"}; private static final String[] LOGIC_OPERATORS = {"AND", "OR"}; @BadSmell("There is no test for the jpql ajust") public QueryWords(String jpql) { this.originalJpql = jpql; jpql = ajust(jpql); this.words = jpql.split(" "); } private String ajust(String jpql) { jpql = jpql.replaceAll(" ", " "); jpql = jpql.replaceAll(" ,", ","); jpql = jpql.replaceAll(",", " ,"); jpql = jpql.replaceAll("in\\(", "in ("); return jpql; } @BadSmell("This should not receive the index") public String get(int index) { return words[index]; } public String current() { return words[position]; } public String next() { return words[position++]; } public String getJpql() { return originalJpql; } public int length() { return words.length; } public boolean hasMoreWord() { return length() > position; } boolean existAlias() { if (!hasMoreWord()) { return false; } return !StringUtil.equalsIgnoreCase(current(), POSSIBLE_WORDS_AFTER_FROM); } public boolean isThereMoreWhereElements() { if (!hasMoreWord()) { return false; } return !StringUtil.equalsIgnoreCase(current(), POSSIBLE_WORDS_AFTER_LOGIC_EXPRESSION); } public boolean isLogicOperator() { return StringUtil.equalsIgnoreCase(current(), LOGIC_OPERATORS); } public boolean hasMoreFromItem() { if (!hasMoreWord()) { return false; } return ",".equals(current()); } public boolean hasMoreSelectItem() { return ",".equals(current()); } boolean hasMoreJoin() { if (!hasMoreWord()) { return false; } return StringUtil.equalsIgnoreCase(current(), "INNER", "JOIN", "LEFT", "RIGHT"); } public List<String> getAsPath() { return new ArrayList<String>(Arrays.asList(next().split("\\."))); } public boolean hasWithClause() { if (!hasMoreWord()) { return false; } return current().equalsIgnoreCase("WITH"); } public int getPosition() { return position; } @BadSmell("current or next?") public void require(String value) { if (!value.equalsIgnoreCase(current())) { throw new RuntimeException("Was expected '" + value + "' in position " + position + ", but found '" + current() + "' in jpql '" + originalJpql + "'"); } } public boolean hasMoreGroupByElements() { if (!hasMoreWord()) { return false; } return ",".equalsIgnoreCase(current()); } public boolean hasMoreOrderByElements() { if (!hasMoreWord()) { return false; } return ",".equalsIgnoreCase(current()); } }