package org.butor.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.butor.json.CommonRequestArgs;
import org.butor.json.JsonHelper;
import org.butor.json.service.Context;
import org.butor.json.service.ResponseHandler;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.jdbc.JdbcTestUtils;
import com.google.common.base.Throwables;
import com.google.common.io.Closeables;
public class ButorTestUtil {
public Context context(final CommonRequestArgs commonRequestArgs, final ResponseHandler<Object> rh) {
return new Context() {
@Override
public ResponseHandler<Object> getResponseHandler() {
return rh;
}
@Override
public CommonRequestArgs getRequest() {
return commonRequestArgs;
}
};
}
public static CommonRequestArgs getCommonRequestArgs(String commonRequestJSON) {
CommonRequestArgs commonRequestArgs = new JsonHelper().deserialize(commonRequestJSON, CommonRequestArgs.class);
return commonRequestArgs;
}
public void assertObjectEqual(Object expected, Object actual) {
assertObjectEqual("",expected,actual);
}
public void assertObjectEqual(String message,Object expected, Object actual) {
Map<String, Object> mapExpected = getFieldMap(expected);
Map<String, Object> mapActualMap = getFieldMap(actual);
for (Entry<String,Object> entry : mapExpected.entrySet()) {
Object actualValue = mapActualMap.get(entry.getKey());
Object expectedValue = entry.getValue();
assertEquals(String.format("Field differs : %s, %s\n",entry.getKey(),message),expectedValue, actualValue);
}
assertEquals(expected, actual);
}
private Map<String, Object> getFieldMap(Object o1) {
Map<String, Object> mapObject1 = new TreeMap<String, Object>();
for (Field f : o1.getClass().getDeclaredFields()) {
f.setAccessible(true);
try {
mapObject1.put(f.getName(), f.get(o1));
} catch (Exception e) {
Throwables.propagate(e);
}
}
return mapObject1;
}
public void executeSQL(JdbcTemplate jt, URL sqlURL, String dbName) throws IOException {
executeSQL(jt, sqlURL, dbName, "derby");
}
public void executeSQL(JdbcTemplate jt, URL sqlURL, String dbName, String jdbcDriverType) throws IOException {
String sql = getStringFromURL(sqlURL);
executeSQL(jt, sql, dbName, jdbcDriverType);
}
public String getStringFromURL(URL url) throws IOException {
StringWriter sw = new StringWriter();
InputStream is =null;
try {
is = url.openStream();
while(true) {
int c = is.read();
if (c == -1)
break;
sw.append((char)c);
}
} finally {
Closeables.closeQuietly(is);
}
return sw.toString();
}
public void executeSQL(JdbcTemplate jt, String sqlData, String dbName, String jdbcDriverType) throws IOException {
assertNotNull(jt);
List<String> scriptlines = new ArrayList<String>();
// TODO extract this code from JdbcTestUtils so that we don't
// include spring-test in compile scope if we move the method to butor-dao?
JdbcTestUtils.splitSqlScript(sqlData, ';', scriptlines);
for (String sqlOri : scriptlines) {
try {
String trimmedSql = sqlOri.trim();
if (trimmedSql.trim().length()==0 || trimmedSql.startsWith("#") || trimmedSql.startsWith("/*")
|| trimmedSql.startsWith("-")) {
continue;
}
if (jdbcDriverType.equals("derby")) {
if (!trimmedSql.startsWith("DROP DATABASE") && !trimmedSql.startsWith("ALTER TABLE")) {
String sql = sqlOri.replace("`", "");
sql = sql.replace("CREATE DATABASE IF NOT EXISTS " + dbName, "CREATE SCHEMA " + dbName);
sql = sql.replace("DROP TABLE IF EXISTS ", "DROP TABLE ");
sql = sql.replace("NOT NULL", "NOT_NU__");
sql = sql.replace("NULL", "");
sql = sql.replace("DATETIME", "TIMESTAMP");
sql = sql.replace("NOW()", "CURRENT_TIMESTAMP");
sql = sql.replace("NOT_NU__", "NOT NULL");
sql = sql.replace("ENGINE = InnoDB", "");
sql = sql.replace("AUTO_INCREMENT", "GENERATED BY DEFAULT AS IDENTITY");
System.out.println(sql);
jt.execute(sql);
}
}
else {
System.out.println(sqlOri);
jt.execute(sqlOri);
}
} catch (Throwable e) {
System.out.println("====> " + e.getMessage());
if (e instanceof BadSqlGrammarException) {
String msg = ((BadSqlGrammarException) e).getSQLException().getMessage();
if (msg.indexOf("because it does not exist") > -1) {
continue;
} else if (msg.indexOf("already exists") > -1) {
continue;
}
fail(e.getMessage());
}
}
}
}
public static JsonHelper getJsonHelperWithLocalTimeFormatter() {
return new JsonHelper("yyyy-MM-dd HH:mm:ss.SSS");
}
}