package com.save4j;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.save4j.model.MappingInfo;
import com.save4j.model.database.Database;
import com.save4j.model.database.Table;
public class Save4j {
protected final static Log logger = LogFactory.getLog(Save4j.class);
public static long save(Object object) {
try {
Database database = generateDatabaseInformation();
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Map<String, MappingInfo> map = getObjectFields(object);
// Once we have the database mapping, compare it to the actual
// database and create/modify as needed
// In development mode, do this every time (for changes on the
// fly, but in production mode do this the first time -- or on
// startup -- then store in a global constants file)
return -1;
}
private static Map<String, MappingInfo> getObjectFields(Object object) {
Map<String, MappingInfo> map = new HashMap<String, MappingInfo>();
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
map.put(field.getName(), processObjectField(field));
}
catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return map;
}
private static MappingInfo processObjectField(Field field) throws InstantiationException, IllegalAccessException {
MappingInfo mapping = new MappingInfo();
mapping.setName(convertCaseChangeToUnderscore(field.getName()));
if (isFieldPrimitive(field.getType())) {
mapping.setType(getFieldType(field));
}
else if (isFieldOneToMany(field.getType())) {
mapping.setOneToMany(true);
}
// One to one object
else {
mapping.setOneToOne(true);
}
return mapping;
}
private static String getFieldType(Field field) {
return "" + field.getType();
}
private static boolean isFieldPrimitive(Class<?> clazz) throws InstantiationException, IllegalAccessException {
if (clazz.isPrimitive()) {
return true;
}
Object obj = clazz.newInstance();
if (obj instanceof String || obj instanceof Number ||
obj instanceof Boolean || obj instanceof Character) {
return true;
}
return false;
}
private static boolean isFieldOneToMany(Class<?> clazz) throws InstantiationException, IllegalAccessException {
Object obj = clazz.newInstance();
if (obj instanceof Collection || obj instanceof Map) {
return true;
}
return false;
}
/**
*
* @param input
* @param delimiterChars
* @return
*/
public static String convertCaseChangeToUnderscore(String input, char... delimiterChars ) {
if (input == null) {
return null;
}
input = input.trim();
if (input.length() == 0) {
return "";
}
input = input.replaceAll("([A-Z]+)([A-Z][a-z])", "$1_$2");
input = input.replaceAll("([a-z\\d])([A-Z])", "$1_$2");
input = input.replace('-', '_');
if (delimiterChars != null) {
for (char delimiterChar : delimiterChars) {
input = input.replace(delimiterChar, '_');
}
}
return input.toLowerCase();
}
private static Database generateDatabaseInformation() throws ClassNotFoundException, SQLException {
Database database = new Database();
// Load the database driver - in this case, we
// use the Jdbc/Odbc bridge driver.//com.mysql.jdbc.Driver
Class.forName(Constants.DATABASE_DRIVER_POSTGRES);
// Open a connection to the database
Connection conn = DriverManager.getConnection(
Constants.DATABASE_URL,
Constants.DATABASE_USERNAME,
Constants.DATABASE_PASSWORD
);
//createDatabase();
// Get DatabaseMetaData
DatabaseMetaData dbmd = conn.getMetaData();
// Get all column types for the table "sysforeignkeys", in schema
// "dbo" and catalog "test".
ResultSet rs = dbmd.getColumns(null, null, "users", "%");
int columns = 0;
// Printout table data
while (rs != null && rs.next()) {
// Get dbObject metadata
String dbObjectCatalog = rs.getString(1);
String dbObjectSchema = rs.getString(2);
String dbObjectName = rs.getString(3);
String dbColumnName = rs.getString(4);
String dbColumnTypeName = rs.getString(6);
int dbColumnSize = rs.getInt(7);
int dbDecimalDigits = rs.getInt(9);
String dbColumnDefault = rs.getString(13);
int dbOrdinalPosition = rs.getInt(17);
String dbColumnIsNullable = rs.getString(18);
// Printout
System.out.println("Col(" + dbOrdinalPosition + "): " + dbColumnName
+ " (" + dbColumnTypeName +")");
System.out.println(" Nullable: " + dbColumnIsNullable +
", Size: " + dbColumnSize);
System.out.println(" Position in table: " + dbOrdinalPosition
+ ", Decimal digits: " + dbDecimalDigits);
}
if (columns == 0) {
// create table
}
// Free database resources
rs.close();
conn.close();
return database;
}
private static void createDatabase() throws SQLException {
Statement stmt = null;
//STEP 3: Open a connection
System.out.println("Connecting to database...");
Connection conn = DriverManager.getConnection(
Constants.DATABASE_URL,
Constants.DATABASE_USERNAME,
Constants.DATABASE_PASSWORD
);
//STEP 4: Execute a query
System.out.println("Creating database...");
stmt = conn.createStatement();
String sql = "CREATE DATABASE STUDENTS";
stmt.executeUpdate(sql);
System.out.println("Database created successfully...");
if(stmt!=null) {
stmt.close();
}
if(conn!=null) {
conn.close();
}
}
}