public AndExp(Exp term, Exp exp) {
this.term = term;
this.exp = exp;
}
/**
* in term and exp
* set + retain for intersect
*
* @return list of post obj
*/
@Override
public List<PostObj> evaluate() {
// AND
Set<PostObj> s1 = new HashSet<>(term.evaluate());
s1.retainAll(exp.evaluate());
return new ArrayList<>(s1);
}
public OrExp(Exp term, Exp exp) {
this.term = term;
this.exp = exp;
}
/**
* in term or exp
* set + addall for union
*
* @return list of post obj
*/
@Override
public List<PostObj> evaluate() {
// OR
Set<PostObj> s1 = new HashSet<>(term.evaluate());
s1.addAll(exp.evaluate());
return new ArrayList<>(s1);
}
public NotExp(Exp factor, StoreEngine se) {
this.factor = factor;
this.list = se.queryPost();
}
/**
* not in exp
* world - set for not
*
* @return list of post obj
*/
@Override
public List<PostObj> evaluate() {
// NOT
Set<PostObj> s1 = new HashSet<>(this.list);
s1.removeAll(factor.evaluate());
return new ArrayList<>(s1);
}
public class Tokenizer {
private String buffer; // String to be transformed into tokens each time next() is called.
private Token currentToken; // The current token. The next token is extracted when next() is called.
/**
* Tokenizer class constructor
* The constructor extracts the first token and save it to currentToken
* **** please do not modify this part ****
*/
public Tokenizer(String text) {
buffer = text; // save input text (string)
next(); // extracts the first token.
}
/**
* This function will find and extract a next token from {@code _buffer} and
* save the token to {@code currentToken}.
*/
public void next() {
buffer = buffer.trim(); // remove whitespace
if (buffer.isEmpty()) {
currentToken = null; // if there's no string left, set currentToken null and return
return;
}
/*
To help you, we have already written the first few steps in the tokenization process.
The rest will follow a similar format.
*/
char firstChar = buffer.charAt(0);
if (firstChar == '&')
currentToken = new Token("&", Token.Type.AND);
if (firstChar == '|')
currentToken = new Token("|", Token.Type.OR);
if (firstChar == '!')
currentToken = new Token("!", Token.Type.NOT);
if (firstChar == '(')
currentToken = new Token("(", Token.Type.LBRA);
if (firstChar == ')')
currentToken = new Token(")", Token.Type.RBRA);
if (firstChar == '#') {
int i = 1;
while (i < buffer.length()
&& (Character.isAlphabetic(buffer.charAt(i)) || Character.isDigit(buffer.charAt(i)))) {
i++;
}
currentToken = new Token(buffer.substring(0, i), Token.Type.TAG);
}
if (firstChar == '@') {
int i = 1;
while (i < buffer.length()
&& (Character.isAlphabetic(buffer.charAt(i)) || Character.isDigit(buffer.charAt(i)))) {
i++;
}
currentToken = new Token(buffer.substring(0, i), Token.Type.USER);
}
if (firstChar != '&'
&& firstChar != '|'
&& firstChar != '!'
&& firstChar != '('
&& firstChar != ')'
&& firstChar != '@'
&& firstChar != '#')
throw new Token.IllegalTokenException("IllegalToken");
// Remove the extracted token from buffer
int tokenLen = currentToken.getToken().length();
buffer = buffer.substring(tokenLen);
}
/**
* Returns the current token extracted by {@code next()}
* **** please do not modify this part ****
*
* @return type: Token
*/
public Token current() {
return currentToken;
}
/**
* Check whether there still exists another tokens in the buffer or not
* **** please do not modify this part ****
*
* @return type: boolean
*/
public boolean hasNext() {
return currentToken != null;
}
}
public class QueryEngine {
StoreEngine storeEngine;
Parser parser;
public QueryEngine(List<PostObj> postObjList) {
this.storeEngine = new StoreEngine(postObjList);
}
public QueryEngine(String jsonStr) {
this.storeEngine = new StoreEngine(jsonStr);
}
/**
* given query, return matched post obj
*
* @param query the query
* @return list of post obj
*/
public List<PostObj> queryObject(String query) {
this.parser = new Parser(new Tokenizer(query), storeEngine);
return this.parser.evaluate();
}
/**
* given query, return matched text
*
* @param query the query
* @return list of text
*/
public List<String> queryText(String query) {
this.parser = new Parser(new Tokenizer(query), storeEngine);
List<PostObj> list = this.parser.evaluate();
List<String> returnedList = new ArrayList<>();
for (PostObj postObj : list) {
returnedList.add(postObj.text);
}
return returnedList;
}
}