⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 whereclausetokenizer.java

📁 esri的ArcGIS Server超级学习模板程序(for java)
💻 JAVA
字号:
package com.esri.solutions.jitk.web.wfs.data.query.sql;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class WhereClauseTokenizer {
	protected int _currentIndex = 0;
	protected String _wc;
	protected List<String> _logicalOps = new ArrayList<String>();
	protected List<String> _comparisonOps = new ArrayList<String>();
	
	public WhereClauseTokenizer(String clause) {
		_wc = clause;
		buildLogicalOpsTable();
		buildComparisonOpsTable();
		_currentIndex = 0;
	}
	
	protected void buildLogicalOpsTable() {
		_logicalOps.add("AND");
		_logicalOps.add("OR");
		_logicalOps.add("NOT");
	}
	
	protected void buildComparisonOpsTable() {
		_comparisonOps.add("<>");
		_comparisonOps.add("<=");
		_comparisonOps.add(">=");
		_comparisonOps.add(">");
		_comparisonOps.add("<");
		_comparisonOps.add("=");
		_comparisonOps.add("LIKE");
		_comparisonOps.add("BETWEEN");
	}	
	
	/**
	 * Parses out the next token in the SQL WHERE clause. When no more tokens are available,
	 * null is returned.
	 * 
	 * NOTE: No support for mathmatical operations as left-hand values or aggregate functions.
	 * 
	 * @return Next token returned from this stateful tokenizer.
	 * @throws InvalidTokenException - Exception thrown if invalid token encountered
	 */
	public WhereClauseToken getNextToken() throws InvalidTokenException {
		String token = "";
		WhereClauseTokenType tokenType = WhereClauseTokenType.Whitespace;
		
		if (_currentIndex >= _wc.length()) {
			token = null;
		} else {
			tokenType = getStartTokenType(_wc.substring(_currentIndex));
			
			while ((tokenType == WhereClauseTokenType.Whitespace) && 
					((_currentIndex + 1) < _wc.length())) {
				_currentIndex++;
				tokenType = getStartTokenType(_wc.substring(_currentIndex));
			}	
			
			token = parseOutToken(tokenType);
		}
		
		if (token == null) {
			//End of parse string encountered
			return null;
		} else {
			_currentIndex += token.length();
			return new WhereClauseToken(token, tokenType);
		}
	}
	
	protected String parseOutToken(WhereClauseTokenType tokenType) 
	throws InvalidTokenException {
		String token = "";
		
		switch (tokenType) {
		case Whitespace:
			//End of string encountered
			token = null;
			break;
			
		case FieldName:
			token = parseOutFieldName();
			break;
		
		case Literal:
			token = parseOutLiteral();
			break;
		
		case LogicalOperator:
			token = parseOutLogicalOperator();
			break;
		
		case Parenthesis:
			token  = _wc.substring(_currentIndex, _currentIndex + 1);	
			break;
		
		case RelationalOperator:
			token = parseOutRelationOperator();
			break;
		
		default:
			String unparsedClause = _wc.substring(_currentIndex);
			throw new InvalidTokenException("Invalid parse state encounted for unparsed clause section " + unparsedClause);
		}	
		
		return token;
	}
	
	protected String parseOutFieldName() throws InvalidTokenException {
		int index = 0;
		String unparsedClause = _wc.substring(_currentIndex);
		char nextChar = unparsedClause.charAt(index);
		

		for (; index < unparsedClause.length(); index++) {
			nextChar = unparsedClause.charAt(index);
			
			if (!(Character.isLetterOrDigit(nextChar) || (nextChar == '.') || (nextChar == '_'))) {
				break;
			}
		}
		
		return unparsedClause.substring(0, index);
	}
	
	protected String parseOutLiteral() throws InvalidTokenException {
		String unparsedClause = _wc.substring(_currentIndex);
		int index = 0;
		char nextChar = unparsedClause.charAt(index);
		
		//If string literal
		if (nextChar == '\'') {
			index++;
			
			for (; index < unparsedClause.length(); index++) {
				 nextChar = unparsedClause.charAt(index);
				 
				if (nextChar == '\'') {
					return unparsedClause.substring(0, index + 1);
				}
			}
			
			throw new InvalidTokenException("Closing \' expected in string literal within " + unparsedClause);
		}
		//else literal is a number
		else {
			for (; index < unparsedClause.length(); index++) {
				nextChar = unparsedClause.charAt(index);
				
				if (!(Character.isDigit(nextChar) || nextChar == '.')) {
					break;
				}
			}
			
			return unparsedClause.substring(0, index);
		}
	}
	
	protected String parseOutLogicalOperator() throws InvalidTokenException {
		String unparsedClause = _wc.substring(_currentIndex);
		Collection<String> ops = _logicalOps;
		
		for (String op : ops) {
			int endIndex = op.length();
			
			if (unparsedClause.toUpperCase().substring(0, endIndex).equals(op)) {
				return op;
			}			
		}
		
		throw new InvalidTokenException(unparsedClause + " " +
				"did not contain a valid logical operator in the beginning of the sting");
	}	
	
	protected String parseOutRelationOperator() throws InvalidTokenException {
		String unparsedClause = _wc.substring(_currentIndex);
		Collection<String> ops = _comparisonOps;
		
		for (String op : ops) {
			int endIndex = op.length();
			
			//Ensure string comparison does not go out of range
			if (unparsedClause.length() >= op.length()) {
				if (unparsedClause.toUpperCase().substring(0, endIndex).equals(op)) {
					return op;
				}
			}
		}
		
		throw new InvalidTokenException(unparsedClause + " " +
				"did not contain a valid relational operator in the beginning of the sting");
	}
	
	protected boolean isRelationalOperatorStart(String unparsedClause) {
		char c = unparsedClause.charAt(0);
		boolean isLogicalOp = (c == '=') || (c == '<') || (c == '>');
		
		if (!isLogicalOp &&(unparsedClause.length() >= 5)) {
			isLogicalOp = unparsedClause.toUpperCase().substring(0, 5).equals("LIKE ");
		}		
		
		if (!isLogicalOp &&(unparsedClause.length() >= 8)) {
			isLogicalOp = unparsedClause.toUpperCase().substring(0, 8).equals("BETWEEN ");
		}
		
		return isLogicalOp;
	}
	
	protected boolean isLogicalOperator(String unparsedClause) {
		Collection<String> ops = _logicalOps;
		boolean isLogicOp = false;
		
		// Logical operators are delimited at the end by a space or (
		
		for (String op : ops) {
			String logicalOp = op + " ";
			int endIndex = logicalOp.length();
			
			//Don't attempt unsafe comparison due to length of string
			if (unparsedClause.length() >= logicalOp.length()) {
				if (unparsedClause.toUpperCase().substring(0, endIndex).equals(logicalOp)) {
					isLogicOp = true;
					break;
				}
			}
			
			logicalOp = op + "(";
			
			//Don't attempt unsafe comparison due to length of string
			if (unparsedClause.length() >= logicalOp.length()) {
				if (unparsedClause.toUpperCase().substring(0, endIndex).equals(logicalOp)) {
					isLogicOp = true;
					break;
				}	
			}
		}
		
		return isLogicOp;
	}
	
	protected WhereClauseTokenType getStartTokenType(String unparsedClause) 
	throws InvalidTokenException {
		char c = unparsedClause.charAt(0);
		WhereClauseTokenType type = WhereClauseTokenType.Whitespace;
		
		if (c == '(' || c == ')') {
			type = WhereClauseTokenType.Parenthesis;
		} 
		else if (Character.isDigit(c) || c == '\'') {
			type = WhereClauseTokenType.Literal;
		} 
		else if (isRelationalOperatorStart(unparsedClause)) {
			type =  WhereClauseTokenType.RelationalOperator;
		} 
		else if (isLogicalOperator(unparsedClause)) {
			type =  WhereClauseTokenType.LogicalOperator;
		} 
		else if (Character.isLetter(c)) {
			type = WhereClauseTokenType.FieldName;
		} 
		else if (Character.isWhitespace(c)) {
			type = WhereClauseTokenType.Whitespace;
		}
		else {
			throw new InvalidTokenException(String.valueOf(c) + " was deteremined to be invalid at it's location");
		}
		
		return type;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -