package pl.zgora.uz.wmie.fe.util;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.NotNullExpression;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.SimpleExpression;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.impl.CriteriaImpl.Subcriteria;
import org.hibernate.sql.JoinFragment;
/**
* Klasa zawirajace pewne przydatne metody do hibernate.
*
* @author Miro007
*/
public class HibernateUtil {
public static final SessionFactory sessionFactory = new Configuration()
.configure("pl/zgora/uz/wmie/fe/config/hibernate.cfg.xml")
.buildSessionFactory();
public static final int TYPE_OF_JOIN_TABLE = JoinFragment.LEFT_OUTER_JOIN;
public static HibernateUtil object;
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
// hide constructor
private HibernateUtil() {
}
// create object - singleton
public static void create() {
if (object == null) {
object = new HibernateUtil();
}
}
/**
* Tworzy aliasy z projekcji.
*
* @param criteria -
* obiekt Criteria
* @param projectionList -
* projekcje
* @return - nowe projekcje
* @throws IllegalAccessException
* @throws Exception
*/
public static ProjectionList projectionSupport(Criteria criteria,
ProjectionList projectionList) throws Exception {
ProjectionList newProjectionList = Projections.projectionList();
Map<String, String> aliasesToCreate = new HashMap<String, String>();
for (int i = 0; i < projectionList.getLength(); i++) {
Projection projection = projectionList.getProjection(i);
String projectionString = projection.toString();
if (projectionString.indexOf(".") != -1) {
String[] splitedString = projectionString.split("\\.");
createAlias(criteria, splitedString);
newProjectionList.add(Projections.property(splitedString[splitedString.length-2]+"."+splitedString[splitedString.length-1]));
} else {
newProjectionList.add(projection);
}
}
return newProjectionList;
}
/**
* Tworzy aliasy z kryterionow.
*
* @param criteria -
* obiekt Criteria
* @param projectionList -
* projekcje
* @return - nowe projekcje
* @throws NoSuchFieldException
* @throws SecurityException
*/
public static List<Criterion> criterionSupport(Criteria criteria,
List<Criterion> criterionList) throws Exception {
// TODO z refleksji wez pola
for (Criterion criterion : criterionList) {
Field field = criterion.getClass().getDeclaredFields()[0];
field.setAccessible(true);
String criterionString = field.get(criterion).toString();
if (criterionString.indexOf(".") != -1) {
String[] splitedString = criterionString.split("\\.");
createAlias(criteria, splitedString);
if(criterionString.length() > 2){
field.set(criterion, splitedString[splitedString.length - 2]+"."+splitedString[splitedString.length - 1]);
}
}
}
// czyszczenie podwujnych aliasow
System.out.println(criterionList);
return criterionList;
}
public static List<Order> orderSupport(Criteria criteria,
List<Order> orderList) throws Exception {
Map<String, String> aliasesToCreate = new HashMap<String, String>();
for (Order order : orderList) {
Field field = order.getClass().getDeclaredFields()[2];
field.setAccessible(true);
String orderString = field.get(order).toString();
if (orderString.indexOf(".") != -1) {
String[] splitedString = orderString.split("\\.");
createAlias(criteria, splitedString);
if(orderString.length() > 2){
field.set(order, splitedString[splitedString.length - 2] + "."
+ splitedString[splitedString.length - 1]);
}
}
}
Iterator<String> iterator = aliasesToCreate.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
Field field = criteria.getClass().getDeclaredFields()[7];
field.setAccessible(true);
List<Subcriteria> aliasesCriteria = (List<Subcriteria>) field
.get(criteria);
if (!containsAliasAlready(aliasesCriteria, aliasesToCreate.get(key))) {
criteria.createAlias(key, aliasesToCreate.get(key),
TYPE_OF_JOIN_TABLE);
}
}
return orderList;
}
private static void createAlias(Criteria criteria, String[] columns) throws Exception{
Map<String, String> aliasesFromCriteria = new HashMap<String, String>();
Map<String, String> aliasesToCreate = new HashMap<String, String>();
Field field = criteria.getClass().getDeclaredFields()[7];
field.setAccessible(true);
List<Subcriteria> aliasesCriteria = (List<Subcriteria>) field.get(criteria);
for(Subcriteria subcriteria : aliasesCriteria){
aliasesFromCriteria.put(subcriteria.getAlias(), "true");
}
for (int i = columns.length - 2; i >= 0; i--) {
if (aliasesFromCriteria.get(columns[i]) == null) {
if (columns.length == 2) {
aliasesToCreate.put(columns[i], columns[i]);
} else {
if(i==0){
aliasesToCreate.put(columns[i], columns[i]);
} else {
aliasesToCreate.put(columns[i-1] + "." + columns[i],
columns[i]);
}
}
}
}
for(String key :aliasesToCreate.keySet()){
criteria.createAlias(key, aliasesToCreate.get(key).toString(), TYPE_OF_JOIN_TABLE);
}
}
public static boolean containsAliasAlready(
List<Subcriteria> aliasesCriteria, String alias) {
for (Subcriteria subcriteria : aliasesCriteria) {
if (alias.equals(subcriteria.getAlias())) {
return true;
}
}
return false;
}
}