blob: 5c30ec6969127b91ea1241f4c7db2faf0466b1cc [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.persistence.criteria;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Compares a pair of String ignoring case-sensitivity of set of reserved words.
*
*/
public class StringComparison {
private static List<String> _reserved = Arrays.asList(new String[] {
"ALL", "AND", "ANY", "AS", "ASC", "AVG",
"BETWEEN", "BIT_LENGTH", "BY",
"CASE", "CHAR_LENGTH", "CHARACTER_LENGTH", "CLASS", "COALESCE",
"COUNT","CURRENT_DATE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
"DELETE", "DESC", "DISTINCT",
"EMPTY", "ENTRY", "EXISTS",
"FALSE", "FETCH", "FROM",
"GROUP",
"HAVING",
"IN", "INDEX", "INNER", "IS",
"JOIN",
"KEY",
"LEFT", "LIKE", "LOWER",
"MAX", "MEMBER", "MIN", "MOD",
"NEW", "NOT", "NULL", "NULLIF",
"OBJECT", "OF", "OR", "ORDER", "OUTER",
"POSITION",
"SELECT", "SOME", "SUM",
"THEN", "TRIM", "TRUE", "TYPE",
"UNKNOWN", "UPDATE", "UPPER",
"VALUE",
"WHEN", "WHERE",
});
private boolean isReservedWord(String s) {
return _reserved.contains(s.toUpperCase());
}
public List<String> tokenize(String s) throws IOException {
List<String> list = new ArrayList<>();
StreamTokenizer tok = new StreamTokenizer(new StringReader(s));
tok.resetSyntax();
tok.wordChars('a', 'z');
tok.wordChars('0', '9');
tok.wordChars('A', 'Z');
tok.wordChars('\'', '\'');
tok.wordChars('=', '=');
tok.wordChars('>', '>');
tok.wordChars('<', '<');
tok.wordChars('!', '!');
tok.wordChars('.', '.');
for (int ttype; (ttype = tok.nextToken()) != StreamTokenizer.TT_EOF;) {
if (ttype == StreamTokenizer.TT_WORD)
list.add(tok.sval);
}
return list;
}
public boolean compare(String s1, String s2) {
try {
List<String> list1 = tokenize(s1);
List<String> list2 = tokenize(s2);
if (list1.size() != list2.size()) {
System.err.println("Unequal tokens " + list1.size() + "!="
+ list2.size());
return false;
}
for (int i = 0; i < list1.size(); i++) {
String a = list1.get(i);
String b = list2.get(i);
boolean match =
isReservedWord(a) ? a.equalsIgnoreCase(b) : a.equals(b);
if (!match) {
System.err.println("[" + a + "] does not match [" + b
+ "]");
return false;
}
}
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static void main(String[] args) throws Exception {
StringComparison c = new StringComparison();
String s1 = "SELECT DISTINCT o FROM Order AS o JOIN o.lineItems AS l "
+ "WHERE l.shipped != FALSE and l.name like 'hello'";
String s2 = "select DISTINCT o FROM Order AS o JOIN o.lineItems AS l "
+ "WHERE l.shipped != FALSE and l.name like 'hello'";
boolean match = c.compare(s1, s2);
if (!match) {
System.err.println(s1);
System.err.println(c.tokenize(s1));
System.err.println(s2);
System.err.println(c.tokenize(s2));
}
}
}