package com.phonoforce.tramory;
import com.phonoforce.tramory.annotations.EntitySet;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import javax.persistence.Id;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
public class Server implements Closeable {
private static Server instance;
private SessionFactory sessionFactory;
private Server() {
this.sessionFactory = new Configuration().configure().buildSessionFactory();
}
public static Server getInstance() {
if (instance == null) {
instance = new Server();
}
return instance;
}
public <T> T getEntityById(Class<T> clazz, int id) {
Session session = this.sessionFactory.openSession();
T entity = null;
try {
session.beginTransaction();
entity = session.get(clazz, id);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
session.close();
}
return entity;
}
public void insertIntoDB(Object entity) {
Session session = this.sessionFactory.openSession();
try {
session.beginTransaction();
session.saveOrUpdate(entity);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
session.close();
}
}
private int getEntityId(Object entity) {
for (Method method : entity.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(Id.class)) {
try {
return (int) method.invoke(entity);
} catch (Exception e) {
return -1;
}
}
}
return -1;
}
public void insertEntity(Object entity) {
for (Method method : entity.getClass().getDeclaredMethods()) {
if (method.isAnnotationPresent(EntitySet.class)) {
try {
Set<Object> set = (Set<Object>) method.invoke(entity);
List<Object> itemList = new LinkedList<>();
List<Object> itemList2 = new LinkedList<>();
for (Object entity1 : set) {
Object entity2 = this.getEntityById(entity1.getClass(), this.getEntityId(entity1));
if (entity2 != null) {
itemList2.add(entity1);
itemList.add(entity2);
}
}
set.removeAll(itemList2);
set.addAll(itemList);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
}
this.insertIntoDB(entity);
}
public <T> T dropEntityById(Class<T> clazz, int id) {
Session session = this.sessionFactory.openSession();
T entity = this.getEntityById(clazz, id);
try {
session.beginTransaction();
session.delete(entity);
session.getTransaction().commit();
} catch (HibernateException e) {
e.printStackTrace();
session.getTransaction().rollback();
} finally {
session.close();
}
return entity;
}
public void close() throws IOException {
this.sessionFactory.close();
}
}