view src/main/java/org/mpi/openmind/repository/services/PersistenceService.java @ 41:2079c35739c8

more comments and cleanup.
author casties
date Mon, 17 Oct 2016 12:28:39 +0200
parents 1cd9d9a67cad
children 5380bdeb7457
line wrap: on
line source

package org.mpi.openmind.repository.services;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.mpi.openmind.repository.bo.Attribute;
import org.mpi.openmind.repository.bo.Entity;
import org.mpi.openmind.repository.bo.Node;
import org.mpi.openmind.repository.bo.Relation;
import org.mpi.openmind.repository.bo.ViewerAttribute;
import org.mpi.openmind.repository.bo.ViewerPage;
import org.mpi.openmind.repository.bo.utils.RelationSortBySourceOW;
import org.mpi.openmind.repository.bo.utils.RelationSortByTargetOW;
import org.mpi.openmind.repository.services.utils.AttributeFilter;
import org.mpi.openmind.repository.services.utils.RelationFilter;
import org.mpi.openmind.repository.services.utils.RelationResultEntry;
import org.mpi.openmind.repository.utils.HibernateUtil;
import org.mpi.openmind.repository.utils.JDBCUtils;

/**
 * 
 * @author jurzua
 */
public class PersistenceService extends AbstractPersistenceService {

	private static Logger logger = Logger.getLogger(PersistenceService.class);
	public static String GROUP_BY_SOURCE = "group_by_source";
	public static String GROUP_BY_TARGET = "group_by_target";
	public static String GROUP_BY_RELATION = "group_by_relation";

	public Long getSourceRelationsCount(Entity entity, String relationName,
			String tarObjClass) {
		Long count = null;
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "select count(*) from Relation rel " + "where  "
					+ "rel.sourceId = :id AND "
					+ "rel.sourceModif = :modif AND "
					+ "rel.ownValue = :relationName AND "
					+ "rel.systemStatus = :systemStatus ";

			if (StringUtils.isNotEmpty(tarObjClass)) {
				hql += " AND rel.targetObjectClass = :tarObjClass ";
			}

			Query query = session.createQuery(hql);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setLong("id", entity.getId());
			query.setLong("modif", entity.getModificationTime());
			query.setString("relationName", relationName);
			if (StringUtils.isNotEmpty(tarObjClass)) {
				query.setString("tarObjClass", tarObjClass);
			}

			count = (Long) query.uniqueResult();

			session.getTransaction().commit();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return count;
	}

	public List<Relation> getRelationBySrcOCFromDB(String srcOC, int maxResult)
			throws Exception {
		List<Relation> relations = new ArrayList<Relation>();
		long start = System.currentTimeMillis();

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();

		String hql = "from Relation rel " + "where  "
				+ "rel.systemStatus = :systemStatus AND "
				+ "rel.sourceObjectClass = :srcOC ";

		Query query = session.createQuery(hql);
		query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
		query.setString("srcOC", srcOC);

		if (maxResult > 0) {
			query.setMaxResults(maxResult);
		}

		List<Relation> list = query.list();

		// TODO loading attributes
		/*
		 * for(Relation rel : relations){ List<Node> attrs =
		 * this.getNodes(session, null, rel.getSystemStatus(), rel.getId(),
		 * rel.getModificationTime(), null, null); for(Node attNode : attrs){
		 * if(attNode instanceof Attribute){
		 * rel.addAttribute((Attribute)attNode); } } }
		 */

		session.getTransaction().commit();

		logger.info("getRelationBySrcOC [" + srcOC + "] - execution time[ms]: "
				+ (System.currentTimeMillis() - start));
		return relations;
	}

	public List<Relation> getRelationByTarOCFromDB(String tarOC, int maxResult) {
		List<Relation> relations = new ArrayList<Relation>();
		long start = System.currentTimeMillis();

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();

		String hql = "from Relation rel " + "where  "
				+ "rel.systemStatus = :systemStatus AND "
				+ "rel.targetObjectClass = :tarOC ";

		Query query = session.createQuery(hql);
		query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
		query.setString("tarOC", tarOC);

		if (maxResult > 0) {
			query.setMaxResults(maxResult);
		}

		List<Relation> list = query.list();

		// TODO loading attributes
		/*
		 * for(Relation rel : relations){ List<Node> attrs =
		 * this.getNodes(session, null, rel.getSystemStatus(), rel.getId(),
		 * rel.getModificationTime(), null, null); for(Node attNode : attrs){
		 * if(attNode instanceof Attribute){
		 * rel.addAttribute((Attribute)attNode); } } }
		 */

		session.getTransaction().commit();

		logger.info("getRelationByTarOC [" + tarOC + "] - execution time[ms]: "
				+ (System.currentTimeMillis() - start));
		return relations;
	}

	/**
	 * Returns relation by name, where the parameter name is not substring.
	 * 
	 * @param name
	 * @param maxResult
	 * @return
	 */
	public List<Relation> getRelationByNameDB(String name, int maxResult)
			throws Exception {
		List<Relation> relations = new ArrayList<Relation>();
		long start = System.currentTimeMillis();

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.getTransaction().begin();

		String hql = "from Relation rel " + "where  "
				+ "rel.systemStatus = :systemStatus "
				+ " AND rel.ownValue = :name ";

		Query query = session.createQuery(hql);
		query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
		query.setString("name", name);

		if (maxResult > 0) {
			query.setMaxResults(maxResult);
		}

		relations = query.list();

		// loading attributes
		/*
		 * for(Relation rel : relations){ List<Node> attrs =
		 * this.getNodes(session, null, rel.getSystemStatus(), rel.getId(),
		 * rel.getModificationTime(), null, null); for(Node attNode : attrs){
		 * if(attNode instanceof Attribute){
		 * rel.addAttribute((Attribute)attNode); } } }
		 */

		session.getTransaction().commit();

		logger.debug("getRelationByName - execution time[ms]: "
				+ (System.currentTimeMillis() - start));
		return relations;
	}

	public List<Relation> getSourceRelationsJDBCFromDB(Entity entity,
			String relationName, String tarObjClass, int maxResult,
			boolean includeEntities) {

		List<Relation> relations = null;
		long start = System.currentTimeMillis();
		try {

			Connection conn = JDBCUtils.getConn();

			String sql = "select * from node " + "where " + "source_id = '"
					+ entity.getId() + "' AND " + "source_modif = '"
					+ entity.getModificationTime() + "' AND "
					+ "system_status = '" + Node.SYS_STATUS_CURRENT_VERSION
					+ "' ";

			if (StringUtils.isNotEmpty(relationName)) {
				sql += " AND own_value = '" + relationName + "' ";
			}
			if (StringUtils.isNotEmpty(tarObjClass)) {
				sql += " AND target_obj_class = '" + tarObjClass + "' ";
			}

			// logger.info(sql);
			Statement st = conn.createStatement();
			ResultSet rs = st.executeQuery(sql);
			relations = JDBCUtils.rs2Rels(rs);

			conn.close();

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}

		logger.debug("getSourceRelations JDBC - execution time[ms]: "
				+ (System.currentTimeMillis() - start));
		return relations;
	}

	/**
	 * Return the source Relations of the given entity.
	 * 
	 * @param entity
	 * @param relationName
	 * @param tarObjClass
	 * @param maxResult
	 * @param includeEntities
	 * @return
	 * @throws Exception
	 */
    public List<Relation> getSourceRelationsFromDB(Entity entity, String relationName, String tarObjClass,
            int maxResult, boolean includeEntities) throws Exception {

        List<Relation> relations = new ArrayList<Relation>();
        long start = System.currentTimeMillis();

        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        try {
            session.getTransaction().begin();
    
            /*
             * build query string
             */
            String hql = "from Relation rel where" 
                    + " rel.sourceId = :id"
                    + " AND rel.sourceModif = :modif"
                    + " AND rel.systemStatus = :systemStatus ";
            // TODO: previous versions are same without considering the modif
    
            if (StringUtils.equals(entity.getSystemStatus(), Node.SYS_STATUS_PREVIOUS_VERSION)) {
                hql += " AND rel.sourceModif = :modif";
            }
            if (StringUtils.isNotEmpty(relationName)) {
                hql += " AND rel.ownValue = :relationName";
            }
            if (StringUtils.isNotEmpty(tarObjClass)) {
                hql += " AND rel.targetObjectClass = :tarObjClass";
            }
    
            /*
             * create query object
             */
            Query query = session.createQuery(hql);
            
            /*
             * add query parameters
             */
            query.setLong("id", entity.getId());
            query.setLong("modif", entity.getModificationTime());
            query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
    
            if (StringUtils.isNotEmpty(relationName)) {
                query.setString("relationName", relationName);
            }
            if (StringUtils.isNotEmpty(tarObjClass)) {
                query.setString("tarObjClass", tarObjClass);
            }
            if (maxResult > 0) {
                query.setMaxResults(maxResult);
            }
    
            /*
             * run query
             */
            List<Relation> list = query.list();
            
            if (includeEntities) {
                /*
                 * load target Entities for the Relations
                 */
                for (Relation rel : list) {
                    List<Entity> tarList = getLightweightEntities(session, Node.SYS_STATUS_CURRENT_VERSION,
                            rel.getTargetId(), null, null, null, false, 1);
                    if (tarList.size() > 0) {
                        rel.setSource(entity);
                        rel.setTarget(tarList.get(0));
                        relations.add(rel);
                    }
                }
    
                Collections.sort(relations, new RelationSortByTargetOW());
            } else {
                relations = list;
            }
    
            /*
             * loading relation Attributes
             */
            for (Relation rel : relations) {
                // DANGER: getNodes returns all attributes in the db if id=null!
                if (rel.getId() == null) {
                    logger.error("Relation with id=null! Abort loading attributes.");
                    continue;
                }
                List<Node> attrs = this.getNodes(session, null, rel.getSystemStatus(), rel.getId(),
                        rel.getModificationTime(), null, null);
                for (Node attNode : attrs) {
                    if (attNode instanceof Attribute) {
                        rel.addAttribute((Attribute) attNode);
                    }
                }
            }
        } catch (Exception e) {
            logger.error(e);
        } finally {
            session.getTransaction().commit();
        }

        logger.debug("getSourceRelations - execution time[ms]: " + (System.currentTimeMillis() - start));
        return relations;
    }


    public Long getTargetRelationsCount(Entity entity, String relationName,
			String srcObjClass) {
		Long count = null;
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "select count(*) from Relation rel " + "where  "
					+ "rel.targetId = :id AND "
					+ "rel.targetModif = :modif AND "
					+ "rel.ownValue = :relationName AND "
					+ "rel.systemStatus = :systemStatus ";

			if (StringUtils.isNotEmpty(srcObjClass)) {
				hql += " AND rel.sourceObjectClass = :srcObjClass ";
			}

			Query query = session.createQuery(hql);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setLong("id", entity.getId());
			query.setLong("modif", entity.getModificationTime());
			if (StringUtils.isNotEmpty(relationName)) {
				query.setString("relationName", relationName);
			}
			if (StringUtils.isNotEmpty(srcObjClass)) {
				query.setString("srcObjClass", srcObjClass);
			}

			count = (Long) query.uniqueResult();

			session.getTransaction().commit();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return count;
	}


    /**
     * @param entity
     * @param relationName
     * @param srcObjClass
     * @param maxResult
     * @param includeEntities
     * @return
     */
    public List<Relation> getTargetRelationsFromDB(Entity entity,
			String relationName, String srcObjClass, int maxResult,
			boolean includeEntities) {
		List<Relation> relations = new ArrayList<Relation>();
		long start = System.currentTimeMillis();
		try {

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "from Relation rel " + "where  "
					+ "rel.targetId = :id AND "
					+ "rel.targetModif = :modif AND "
					+ "rel.systemStatus = :systemStatus ";

			if(StringUtils.equals(entity.getSystemStatus(), Node.SYS_STATUS_PREVIOUS_VERSION)){
				hql += " AND rel.targetModif = :modif ";
			}
			if (StringUtils.isNotEmpty(relationName)) {
				hql += " AND rel.ownValue = :relationName ";
			}
			if (StringUtils.isNotEmpty(srcObjClass)) {
				hql += " AND rel.sourceObjectClass = :srcObjClass ";
			}

			Query query = session.createQuery(hql);
			query.setLong("id", entity.getId());
			query.setLong("modif", entity.getModificationTime());
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			
			//if(StringUtils.equals(entity.getSystemStatus(), Node.SYS_STATUS_PREVIOUS_VERSION)){
			//	query.setLong("modif", entity.getModificationTime());	
			//}
			if (StringUtils.isNotEmpty(relationName)) {
				query.setString("relationName", relationName);
			}
			if (StringUtils.isNotEmpty(srcObjClass)) {
				query.setString("srcObjClass", srcObjClass);
			}
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}

			List<Relation> list = query.list();
			if (includeEntities) {
				for (Relation rel : list) {
					List<Entity> srcList = getLightweightEntities(session,
							Node.SYS_STATUS_CURRENT_VERSION, rel.getSourceId(),
							null, null, null, false, 1);
					if (srcList.size() > 0) {
						rel.setSource(srcList.get(0));
						rel.setTarget(entity);
						relations.add(rel);
					}
				}

				Collections.sort(relations, new RelationSortBySourceOW());
			} else {
				relations = list;
			}
			// loading attributes
			for (Relation rel : relations) {
	            // FIXME: getNodes finds all attributes if id=null!
	            if (rel.getId() == null) {
	                logger.error("Relation with id=null! Abort loading attributes.");
	                continue;
	            }
				List<Node> attrs = this.getNodes(session, null,
						rel.getSystemStatus(), rel.getId(),
						rel.getModificationTime(), null, null);
				for (Node attNode : attrs) {
					if (attNode instanceof Attribute) {
						rel.addAttribute((Attribute) attNode);
					}
				}
			}

			session.getTransaction().commit();

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		if (end - start > 500) {
			logger.debug("GetTargetRelations - execution time[ms]: "
					+ (end - start));
		}
		return relations;
	}

	/**
	 * <p>
	 * Returns the relations directly for the given entity from the DB, which
	 * conforms the given input.
	 * </p>
	 * <p>
	 * Only the variable srcObjClass can be null.
	 * </p>
	 * <p>
	 * If every existing element from the DB is expected, the variable maxResult
	 * should be -1, otherwise this value limits the returned result-set.
	 * </p>
	 * 
	 * @param entity
	 * @param relationName
	 * @param tarObjClass
	 * @param maxResult
	 * @return
	 */
	public List<Relation> getTargetRelationsError(Entity entity,
			String relationName, String srcObjClass, int maxResult) {
		List<Relation> relations = new ArrayList<Relation>();
		try {
			logger.debug("### get Target Relations ###");

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "from Relation rel, Entity src " + "where  "
					+ "rel.targetId = :id AND " + "rel.targetModif = :mod AND "
					+ "rel.ownValue = :relationName AND "
					+ "rel.systemStatus = :systemStatus AND "
					+ "src.systemStatus = :systemStatus AND "
					+ "src.id = rel.sourceId ";

			if (StringUtils.isNotEmpty(srcObjClass)) {
				hql += " AND rel.sourceObjectClass = :srcObjClass ";
			}

			hql += " order by src.ownValue ";

			Query query = session.createQuery(hql);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setLong("id", entity.getId());
			query.setLong("mod", entity.getModificationTime());
			query.setString("relationName", relationName);
			if (StringUtils.isNotEmpty(srcObjClass)) {
				query.setString("srcObjClass", srcObjClass);
			}
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}

			List<Object> list = query.list();

			for (Object o : list) {
				Object[] array = (Object[]) o;
				if (array.length > 0) {
					Relation rel = (Relation) array[0];
					Entity src = (Entity) array[1];
					src.setLightweight(true);
					rel.setSource(src);
					rel.setTarget(entity);
					relations.add(rel);
				}
			}

			session.getTransaction().commit();

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return relations;
	}

	/**
	 * <p>
	 * Returns the entities of class "tarObjClass" directly from the DB, which
	 * are connected to the given entity by a relation of name "relationName".
	 * </p>
	 * <p>
	 * Only the variable tarObjClass can be null.
	 * </p>
	 * <p>
	 * If its expected all existing element from the DB, the variable maxResult
	 * should be -1, otherwise this value limits the returned result-set.
	 * </p>
	 * 
	 * @param entity
	 * @param relationName
	 * @param tarObjClass
	 * @param maxResult
	 * @return
	 */
	public List<Entity> getTargetsForSourceRelation(Entity entity,
			String relationName, String tarObjClass, int maxResult) {
		List<Entity> entities = new ArrayList<Entity>();
		try {
			logger.debug("### get Targets For Source Relation ###");

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Relation rel, Entity tar " + "where  "
					+ "rel.sourceId = :id AND " + "rel.sourceModif = :mod AND "
					+ "rel.ownValue = :relationName AND "
					+ "rel.systemStatus = :systemStatus AND "
					+ "tar.systemStatus = :systemStatus AND "
					+ "tar.id = rel.targetId ";

			if (StringUtils.isNotEmpty(tarObjClass)) {
				hql += " AND rel.targetObjectClass = :tarObjClass ";
			}

			hql += " order by tar.ownValue ";

			Query query = session.createQuery(hql);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setLong("id", entity.getId());
			query.setLong("mod", entity.getModificationTime());
			query.setString("relationName", relationName);
			if (StringUtils.isNotEmpty(tarObjClass)) {
				query.setString("tarObjClass", tarObjClass);
			}
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}

			List<Object> list = query.list();

			for (Object o : list) {
				Object[] array = (Object[]) o;
				if (array.length > 0) {
					Entity ent = (Entity) array[1];
					ent.setLightweight(true);
					entities.add(ent);
				}
			}

			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.debug("Target For SourceRelation - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return entities;
	}

	/**
	 * <p>
	 * Returns the entities of class "srcObjClass" directly from the DB, which
	 * are connected to the given entity by a relation of name "relationName".
	 * </p>
	 * <p>
	 * Only the variable srcObjClass can be null.
	 * </p>
	 * <p>
	 * If its expected all existing element from the DB, the variable maxResult
	 * should be -1, otherwise this value limits the returned result-set.
	 * </p>
	 * 
	 * @param entity
	 * @param relationName
	 * @param tarObjClass
	 * @param maxResult
	 * @return
	 */
	public List<Entity> getSourcesForTargetRelation(Entity entity,
			String relationName, String srcObjClass, int maxResult) {
		List<Entity> entities = new ArrayList<Entity>();
		try {
			logger.debug("### get Sources For TargetRelation ###");

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Relation rel, Entity src " + "where  "
					+ "rel.targetId = :id AND " + "rel.targetModif = :mod AND "
					+ "rel.ownValue = :relationName AND "
					+ "rel.systemStatus = :systemStatus AND "
					+ "src.systemStatus = :systemStatus AND "
					+ "src.id = rel.sourceId ";

			if (StringUtils.isNotEmpty(srcObjClass)) {
				hql += " AND rel.sourceObjectClass = :srcObjClass ";
			}

			hql += " order by src.ownValue ";

			Query query = session.createQuery(hql);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setLong("id", entity.getId());
			query.setLong("mod", entity.getModificationTime());
			query.setString("relationName", relationName);
			if (StringUtils.isNotEmpty(srcObjClass)) {
				query.setString("srcObjClass", srcObjClass);
			}
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}

			List<Object> list = query.list();

			for (Object o : list) {
				Object[] array = (Object[]) o;
				if (array.length > 0) {
					Entity ent = (Entity) array[1];
					ent.setLightweight(true);
					entities.add(ent);
				}
			}

			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.debug("Sources For TargetRelation - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return entities;
	}
	
	public ViewerAttribute saveViewerAttribute(ViewerAttribute att){
		try {
			logger.debug("### saveViewerAttribute ###");
			
			Session session =  HibernateUtil.getSessionFactory()
						.getCurrentSession();
			session.getTransaction().begin();
			session.saveOrUpdate(att);
			session.getTransaction().commit();
			
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return att;
	}
	
	public ViewerPage saveViewerPage(ViewerPage page){
		try {
			logger.debug("### saveViewerPage ###");
			
			Session session =  HibernateUtil.getSessionFactory()
						.getCurrentSession();
			session.getTransaction().begin();
			session.saveOrUpdate(page);
			session.getTransaction().commit();
			
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return page;
	}
	
	public int removeViewerAttribute(Long id){
		int rows = 0;
		try {
			logger.debug("$$$ removeViewerAttribute [ID=" + id + "]");
			
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.beginTransaction();
			String sql = "DELETE FROM ViewerAttribute WHERE id = :id";
			Query query = session.createQuery(sql);
			query.setLong("id", id);
			
			rows = query.executeUpdate();
			session.getTransaction().commit();
			
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return rows;
	}
	
	public int removeViewerPage(Long id){
		int rows = 0;
		try {
			logger.debug("$$$ removeViewerPage [ID=" + id + "]");
			
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.beginTransaction();
			String sql = "DELETE FROM ViewerPage WHERE id = :id";
			Query query = session.createQuery(sql);
			query.setLong("id", id);
			
			rows = query.executeUpdate();
			session.getTransaction().commit();
			
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return rows;
	}
	
	public List<ViewerAttribute> getViewerAttributes(){
		List<ViewerAttribute> list = new ArrayList<ViewerAttribute>();
		try {
			logger.debug("$$$ getViewerAttributes");

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();
			
			String hql = "from ViewerAttribute";
			Query query = session.createQuery(hql);
			list = query.list();
			
			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.debug("getViewerAttributes - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		
		return list;
	}
	
	public List<ViewerPage> getViewerPages(){
		List<ViewerPage> list = new ArrayList<ViewerPage>();
		try {
			logger.info("$$$$ getViewerPages");

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();
			
			String hql = "from ViewerPage";
			Query query = session.createQuery(hql);
			list = query.list();
			
			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("getViewerPages - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		
		return list;
	}

	/**
	 * This method returns a list of entities with same attributes and same own
	 * value than the given entity
	 * 
	 * @param entity
	 * @param substring
	 * @param maxResults
	 * @return
	 */
	public List<Entity> searchEntity(Entity entity, boolean substring,
			int maxResult) {
		List<Entity> entities = new ArrayList<Entity>();
		try {
			logger.debug("### Starting Search Entity ###");
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String div = (substring) ? " like " : " = ";

			String hql = "from Entity ent ";

			for (int i = 0; i < entity.getAttributes().size(); i++) {
				hql += ", Attribute att" + i + " ";
			}

			hql += " where  " + "ent.systemStatus = :systemStatus AND "
					+ "ent.objectClass = :objectClass AND " + "ent.ownValue "
					+ div + " :ownValue ";

			if (entity.getAttributes().size() > 0)
				hql += "AND ";

			for (int i = 0; i < entity.getAttributes().size(); i++) {
				hql += "att" + i + ".systemStatus = :systemStatus AND ";
				hql += "att" + i + ".sourceId = ent.id AND ";
				hql += "att" + i + ".objectClass = :objectClass" + i + " AND ";
				hql += "att" + i + ".ownValue " + div + " :ownValue" + i + " ";
				if (i < (entity.getAttributes().size() - 1))
					hql += "AND ";
			}
			hql += " GROUP by ent.id";

			Query query = session.createQuery(hql);
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setString("objectClass", entity.getObjectClass());
			query.setString(
					"ownValue",
					(substring) ? "%" + entity.getOwnValue() + "%" : entity
							.getOwnValue());

			int i = 0;
			for (Attribute att : entity.getAttributes()) {
				query.setString("objectClass" + i, att.getObjectClass());
				query.setString(
						"ownValue" + i,
						(substring) ? "%" + att.getOwnValue() + "%" : att
								.getOwnValue());
				i++;
			}

			List<Object> list = query.list();

			for (Object o : list) {
				Object[] array = (Object[]) o;
				if (array.length > 0) {
					Entity ent = (Entity) array[0];
					ent.setLightweight(true);
					entities.add(ent);
				}
			}

			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("Search Entity - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return entities;
	}

	public List<Entity> searchEntity(String objectClass, String ownValue,
			int maxResult) {
		try {
			logger.info("### Starting Search Entity ###");
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Entity " + "where  "
					+ "systemStatus = :systemStatus AND "
					+ "objectClass like :objectClass ";

			if (StringUtils.isNotEmpty(ownValue)) {
				hql += "AND ownValue like :ownValue ";
			}

			Query query = session.createQuery(hql);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setString("objectClass", objectClass);
			if (StringUtils.isNotEmpty(ownValue)) {
				query.setString("ownValue", "%" + ownValue + "%");
			}

			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}

			List<Entity> list = query.list();

			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("Search Entity - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");
			return list;
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}

	public List<Attribute> getAttributeByDefByName(String def, String name,
			int maxResults) {
		List<Attribute> list = null;
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "from Attribute " + "where  "
					+ "objectClass = :name AND "
					+ "systemStatus = :systemStatus AND "
					+ "sourceObjectClass = :sourceObjectClass ";

			Query query = session.createQuery(hql);
			query.setString("name", name);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setString("sourceObjectClass", def);
			if (maxResults > 0) {
				query.setMaxResults(maxResults);
			}

			list = query.list();

			session.getTransaction().commit();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return list;
	}

	/**
	 * Returns an attribute directly from the DB no implemented yet!
	 * 
	 * @param entity
	 * @param name
	 * @return
	 */
	public Attribute getAttributeByName(Entity entity, String name) {
		Attribute att = null;
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "from Attribute " + "where  "
					+ "objectClass = :name AND "
					+ "systemStatus = :systemStatus AND " + "sourceId = :id ";

			Query query = session.createQuery(hql);
			query.setMaxResults(1);
			query.setString("name", name);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setLong("id", entity.getId());

			List<Attribute> list = query.list();
			if (list.size() > 0) {
				att = (Attribute) list.get(0);
			}

			session.getTransaction().commit();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return att;
	}

	public List<Attribute> getAllAttributesJDBC(Long entId, int maxResult) {
		List<Attribute> atts = null;
		long start = System.currentTimeMillis();
		try {
			Connection conn = JDBCUtils.getConn();

			String sql = "select * from node " + "where  "
					+ "system_status = '" + Node.SYS_STATUS_CURRENT_VERSION
					+ "' AND " + "source_id = '" + entId + "' "
					+ "order by object_class";

			if (maxResult > 0) {
				// query.setMaxResults(maxResult);
			}

			Statement st = conn.createStatement();
			ResultSet rs = st.executeQuery(sql);
			atts = JDBCUtils.rs2Atts(rs);

			conn.close();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}

		logger.debug("getAllAttributes JDBC - execution time[ms]: "
				+ (System.currentTimeMillis() - start));
		return atts;
	}

	/**
	 * Returns a list of all attribute for an entity directly from the DB.
	 * 
	 * @param entity
	 * @param name
	 * @return
	 */
    public List<Attribute> getAllAttributes(Long entId, int maxResult) {
        List<Attribute> atts = null;
        long start = System.currentTimeMillis();
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        try {
            session.getTransaction().begin();

            String hql = "from Attribute where" 
                    + " systemStatus = :systemStatus" 
                    + " AND sourceId = :id "
                    + " order by objectClass";

            Query query = session.createQuery(hql);
            if (maxResult > 0) {
                query.setMaxResults(maxResult);
            }
            query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
            query.setLong("id", entId);

            atts = query.list();

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            session.getTransaction().commit();
        }
        logger.debug("getAllAttributes - execution time[ms]: " + (System.currentTimeMillis() - start));
        return atts;
    }

	/**
	 * Here the entities can more than one time in the result set.
	 * 
	 * @param filters
	 * @param maxResult
	 * @return
	 */
	public Map<Attribute, Entity> searchAttEntityByAttributeFilter(
			List<AttributeFilter> filters, int maxResult) {
		Map<Attribute, Entity> result = new HashMap<Attribute, Entity>();
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "from Entity as ent, Attribute as att " + "where  "
					+ "att.systemStatus = :systemStatus AND "
					+ "ent.systemStatus = :systemStatus AND "
					+ "ent.id = att.sourceId AND (";

			int count = 0;
			for (AttributeFilter filter : filters) {
				hql += " ( ";
				if (StringUtils.isNotEmpty(filter.getEntObjectClass())) {
					hql += "att.sourceObjectClass = :sourceObjectClass" + count
							+ " ";
					if (StringUtils.isNotEmpty(filter.getName())
							|| StringUtils.isNotEmpty(filter.getOwnValue()))
						hql += " AND ";
				}
				if (StringUtils.isNotEmpty(filter.getName())) {
					hql += "att.objectClass = :name" + count + " ";
					if (StringUtils.isNotEmpty(filter.getOwnValue()))
						hql += " AND ";
				}
				if (StringUtils.isNotEmpty(filter.getOwnValue())) {
					if (filter.isNormalize()) {
						hql += "att.normalizedOwnValue like :ownValue" + count
								+ " ";
					} else {
						hql += "att.ownValue like :ownValue" + count + " ";
					}
				}

				hql += " ) ";
				count++;
				if (filters.size() > count)
					hql += " OR ";
			}

			hql += " ) group by att.id ";
			// I removed this line because the buffer of MyISAM is to
			// small and it could be a reason to return lesser rows. I hope so!
			// order by ent.ownValue

			Query query = session.createQuery(hql);
			if (maxResult > 0)
				query.setMaxResults(maxResult);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);

			count = 0;
			for (AttributeFilter filter : filters) {
				if (StringUtils.isNotEmpty(filter.getName()))
					query.setString("name" + count, filter.getName());
				if (StringUtils.isNotEmpty(filter.getOwnValue()))
					query.setString("ownValue" + count,
							"%" + filter.getOwnValue() + "%");
				if (StringUtils.isNotEmpty(filter.getEntObjectClass()))
					query.setString("sourceObjectClass" + count,
							filter.getEntObjectClass());
				count++;
			}

			List<Object> listO = query.list();
			for (Object o : listO) {
				Object[] array = (Object[]) o;
				if (array.length > 1) {
					Entity ent = (Entity) array[0];
					ent.setLightweight(true);
					Attribute att = (Attribute) array[1];
					result.put(att, ent);
				}
			}

			session.getTransaction().commit();
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * here the entities not repeated
	 * 
	 * @param filters
	 * @param maxResult
	 * @return
	 */
	public Map<Entity, Attribute> searchEntityByAttributeFilter(
			List<AttributeFilter> filters, int maxResult) {
		Map<Entity, Attribute> result = new HashMap<Entity, Attribute>();
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();

			String hql = "FROM Entity AS ent, Attribute AS att " 
			        + "WHERE  "
					+ "att.systemStatus = :systemStatus AND "
					+ "ent.systemStatus = :systemStatus AND "
					+ "ent.id = att.sourceId AND (";

			int count = 0;
			for (AttributeFilter filter : filters) {
				hql += " ( ";
				if (StringUtils.isNotEmpty(filter.getEntObjectClass())) {
					hql += "att.sourceObjectClass = :sourceObjectClass" + count
							+ " ";
					if (StringUtils.isNotEmpty(filter.getName())
							|| StringUtils.isNotEmpty(filter.getOwnValue()))
						hql += " AND ";
				}
				if (StringUtils.isNotEmpty(filter.getName())) {
					hql += "att.objectClass = :name" + count + " ";
					if (StringUtils.isNotEmpty(filter.getOwnValue()))
						hql += " AND ";
				}
				if (StringUtils.isNotEmpty(filter.getOwnValue())) {
                    if (filter.isNormalize()) {
                        hql += "att.normalizedOwnValue LIKE :ownValue" + count + " ";
                    } else if (filter.isRegex()) {
                        hql += "REGEXP(att.ownValue, :ownValue" + count + ") = 1 ";
                    } else {
                        hql += "att.ownValue LIKE :ownValue" + count + " ";
                    }
				}

				hql += " ) ";
				count++;
				if (filters.size() > count)
					hql += " OR ";
			}

            /* ROC: led to hibernate errors when using search by attribute
               hql += " ) group by att.sourceId order by ent.ownValue";
            */
			hql += " ) order by ent.ownValue";

			// create hibernate Query from hql
			Query query = session.createQuery(hql);
						
			// set maxResults
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}
			
			// only query CURRENT_VERSIONs
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);

			count = 0;
			// map AttributeFilters to query parameters
            for (AttributeFilter filter : filters) {
                if (StringUtils.isNotEmpty(filter.getName())) {
                    // objectClass = :name
                    query.setString("name" + count, filter.getName());
                }
                if (StringUtils.isNotEmpty(filter.getOwnValue())) {
                    if (filter.isRegex()) {
                        // ownValue rlike :ownValue
                        query.setString("ownValue" + count, filter.getOwnValue());
                    } else {
                        // ownValue like %:ownValue%
                        query.setString("ownValue" + count, "%" + filter.getOwnValue() + "%");
                    }
                }
                if (StringUtils.isNotEmpty(filter.getEntObjectClass())) {
                    // sourceObjectClass = :sourceObjectClass
                    query.setString("sourceObjectClass" + count, filter.getEntObjectClass());
                }
                count++;
            }

            // execute query
			List<Object> listO = query.list();
			
			// pack query result in Map
			for (Object o : listO) {
				Object[] array = (Object[]) o;
				if (array.length > 1) {
					Entity ent = (Entity) array[0];
					ent.setLightweight(true);
					Attribute att = (Attribute) array[1];
					result.put(ent, att);
				}
			}

			session.getTransaction().commit();
			
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return result;
	}

	/**
	 * 
	 * @param filters
	 * @param maxResults
	 * @return
	 */
	public List<Attribute> searchAttribute(List<AttributeFilter> filters,
			int maxResult) {
		try {
			// logger.info("");
			// logger.info("### Starting Search Attribute [entObjClass="+entObjClass+", name="+name+", ownValue="+ownValue+", contentType="+contentType+"]###");
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Attribute " + "where  "
					+ "systemStatus = :systemStatus AND (";

			int count = 0;
			for (AttributeFilter filter : filters) {
				hql += " ( ";
				if (StringUtils.isNotEmpty(filter.getEntObjectClass())) {
					hql += "sourceObjectClass = :sourceObjectClass" + count
							+ " ";
					if (StringUtils.isNotEmpty(filter.getName())
							|| StringUtils.isNotEmpty(filter.getOwnValue()))
						hql += " AND ";
				}
				if (StringUtils.isNotEmpty(filter.getName())) {
					hql += "objectClass like :name" + count + " ";
					if (StringUtils.isNotEmpty(filter.getOwnValue()))
						hql += " AND ";
				}
				if (StringUtils.isNotEmpty(filter.getOwnValue())) {
					if (filter.isNormalize()) {
						hql += "normalizedOwnValue like :ownValue" + count
								+ " ";
					} else {
						hql += "ownValue like :ownValue" + count + " ";
					}
				}

				hql += " ) ";
				count++;
				if (filters.size() > count)
					hql += " OR ";
			}

			hql += " ) group by sourceId";

			Query query = session.createQuery(hql);
			if (maxResult > 0)
				query.setMaxResults(maxResult);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);

			count = 0;
			for (AttributeFilter filter : filters) {
				if (StringUtils.isNotEmpty(filter.getName()))
					query.setString("name" + count, filter.getName() + "%");
				if (StringUtils.isNotEmpty(filter.getOwnValue()))
					query.setString("ownValue" + count,
							"%" + filter.getOwnValue() + "%");
				if (StringUtils.isNotEmpty(filter.getEntObjectClass()))
					query.setString("sourceObjectClass" + count,
							filter.getEntObjectClass());
				count++;
			}

			List<Attribute> list = query.list();

			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("Found " + list.size() + " elements");
			logger.info("Search Attribute - Time execution: " + diff
					/ (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]\n");
			return list;
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * <p>
	 * Returns only an attribute searched by its name, its value and by an
	 * attribute which belong to the same entity
	 * </p>
	 * <p>
	 * For example to find all Country by which contains in its value "Germa"
	 * the input should be so:
	 * </p>
	 * <p>
	 * firstName = "name" firstValue = "Germ" secondName = "type" secondValue =
	 * "country" internally both attributes are binding by the unique entity of
	 * type "PLACE". Only the attribute of the first-name and -value will be
	 * returned.
	 * </p>
	 * 
	 * @param name
	 * @param ownValue
	 * @param entObjClass
	 * @param maxResults
	 * @return
	 */
	public List<Attribute> searchAttribute(String firstName, String firstValue,
			String secondName, String secondValue, String entObjClass,
			int maxResults) {
		List<Attribute> list = new ArrayList<Attribute>();
		Session session = null;
		try {
			logger.info("Starting Search Attribute " + "[entObjClass="
					+ entObjClass + ", firstName=" + firstName
					+ ", firstValue=" + firstValue + ", secondName="
					+ secondName + ", secondValue=" + secondValue + "]");

			session = HibernateUtil.getSessionFactory().getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Attribute as a1, Attribute as a2 " + "where  "

			+ "a1.sourceId = a2.sourceId AND "

			+ "a1.systemStatus = :systemStatus AND "
					+ "a2.systemStatus = :systemStatus AND "

					+ "a1.objectClass like :firstName AND "
					+ "a2.objectClass like :secondName AND "

					+ "a1.ownValue like :firstValue AND "
					+ "a2.ownValue like :secondValue AND "

					+ "a1.sourceObjectClass = :entObjClass AND "
					+ "a2.sourceObjectClass = :entObjClass ";

			hql += "group by a1.sourceId ";

			Query query = session.createQuery(hql);
			query.setString("firstName", "%" + firstName + "%");
			query.setString("firstValue", "%" + firstValue + "%");
			query.setString("secondName", "%" + secondName + "%");
			query.setString("secondValue", "%" + secondValue + "%");
			query.setString("entObjClass", entObjClass);
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			if (maxResults > 0) {
				query.setMaxResults(maxResults);
			}

			List<Object> listO = query.list();

			for (Object o : listO) {
				Object[] array = (Object[]) o;
				if (array.length > 0) {
					Attribute firstAtt = (Attribute) array[0];
					list.add(firstAtt);
				}
			}

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} finally {
			session.getTransaction().commit();
		}
		return list;
	}

	/**
	 * <p>
	 * only the ownValue of the attribute and of the entity can be null
	 * </p>
	 * <p>
	 * The ownValue, the attName and the attOwnValue are searched as substring.
	 * </p>
	 * 
	 * @param objectClass
	 * @param ownValue
	 * @param attName
	 * @param attOwnValue
	 * @param maxResult
	 * @return
	 */
	public List<Entity> searchEntityByAttribute(String objectClass,
			String ownValue, String attName, String attOwnValue, int maxResult) {
		List<Entity> entities = new ArrayList<Entity>();
		try {

			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Entity as ent, Attribute as att " + "where  "
					+ "ent.systemStatus = :systemStatus AND "
					+ "att.systemStatus = :systemStatus AND "
					+ "ent.objectClass = :objectClass AND ";

			if (StringUtils.isNotEmpty(ownValue)) {
				hql += "ent.ownValue like :ownValue AND ";
			}

			if (StringUtils.isNotEmpty(attOwnValue)) {
				hql += "att.ownValue like :attOwnValue AND ";
			}

			hql += "att.objectClass like :attName AND "
					+ "ent.id = att.sourceId " + "group by ent.id ";

			Query query = session.createQuery(hql);
			if (maxResult > 0) {
				query.setMaxResults(maxResult);
			}
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setString("objectClass", objectClass);
			if (StringUtils.isNotEmpty(ownValue))
				query.setString("ownValue", "%" + ownValue + "%");
			query.setString("attName", "%" + attName + "%");
			if (StringUtils.isNotEmpty(attOwnValue))
				query.setString("attOwnValue", "%" + attOwnValue + "%");

			List<Object> listO = query.list();

			for (Object o : listO) {
				Object[] array = (Object[]) o;
				if (array.length > 0) {
					Entity ent = (Entity) array[0];
					ent.setLightweight(true);
					entities.add(ent);
				}
			}

			session.getTransaction().commit();

			return entities;
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * <p>
	 * This method searches attributes, which match the input's parameters.
	 * </p>
	 * <p>
	 * Any parameter must be empty, excepted contentType.
	 * </p>
	 * 
	 * @param name
	 * @param ownValue
	 * @param entObjClass
	 * @param maxResults
	 * @return list of attributes filtered by input's parameters
	 */
	public List<Attribute> searchAttribute(String name, String ownValue,
			String entObjClass, String contentType, int maxResults) {
		List<Attribute> list = new ArrayList<Attribute>();
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		try {
			// logger.info("");
			// logger.info("### Starting Search Attribute [entObjClass="
			// + entObjClass + ", name=" + name + ", ownValue=" + ownValue
			// + ", contentType=" + contentType + "]###");

			session.getTransaction().begin();
			// Long start = System.currentTimeMillis();

			String hql = "from Attribute " + "where  "
					+ "systemStatus = :systemStatus AND "
					+ "objectClass like :name AND ";
			if (StringUtils.isNotEmpty(ownValue)) {
				hql += "ownValue like :ownValue AND ";
			}
			if (StringUtils.isNotEmpty(contentType)) {
				hql += "contentType like :contentType AND ";
			}
			hql += "sourceObjectClass = :sourceObjectClass ";
			hql += "group by id order by ownValue";

			Query query = session.createQuery(hql);
			if (maxResults > 0) {
				query.setMaxResults(maxResults);
			}
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			query.setString("name", name + "%");
			if (StringUtils.isNotEmpty(ownValue)) {
				query.setString("ownValue", "%" + ownValue + "%");
			}
			query.setString("sourceObjectClass", entObjClass);
			if (StringUtils.isNotEmpty(contentType)) {
				query.setString("contentType", contentType);
			}

			list = query.list();

			// Long end = System.currentTimeMillis();
			// Long diff = end - start;
			// logger.info("Found " + list.size() + " elements");
			// logger.info("Search Attribute - Time execution: " + diff
			// / (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
			// + "[min] " + diff / 1000 + "[sec]\n");

		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		} finally {
			session.getTransaction().commit();
		}
		return list;
	}

	/**
	 * 
	 * @param objClass
	 * @param relName
	 * @param objClassSrc
	 * @param attName
	 * @param attValue
	 * @param maxResults
	 * @return
	 */
	public List<Entity> searchEntityByAttributeOfTarRelation(String objClass,
			String relName, String objClassSrc, String attName,
			String attValue, int maxResults) {
		List<Entity> entityList = new ArrayList<Entity>();
		Session session = null;
		try {

			if (StringUtils.isEmpty(objClass) || StringUtils.isEmpty(relName)
					|| StringUtils.isEmpty(objClassSrc)
					|| StringUtils.isEmpty(attName)
					|| StringUtils.isEmpty(attValue)) {
				throw new Exception(
						"At least one of these parameters was empty: objClass, relName, objClassSrc, attName, attValue.");
			}

			session = HibernateUtil.getSessionFactory().getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Relation as rel, Attribute as att "
					+ "where "
					+ "att.sourceObjectClass = :objClassSrc AND "
					+
					// "att.sourceObjectClass = rel.sourceObjectClass AND " +
					"rel.targetObjectClass = :objClass AND "
					+ "rel.ownValue = :relName AND "
					+ "att.ownValue like :attValue AND "
					+ "att.objectClass = :attName AND "
					+ "att.systemStatus = :systemStatus AND "
					+ "rel.systemStatus = :systemStatus AND "
					+ "rel.sourceId = att.sourceId " + "group by att.sourceId";

			Query query = session.createQuery(hql);
			if (maxResults > 0) {
				query.setMaxResults(maxResults);
			}

			query.setString("objClass", objClass);
			query.setString("relName", relName);
			query.setString("objClassSrc", objClassSrc);
			query.setString("attName", attName);
			query.setString("attValue", "%" + attValue + "%");
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);

			List<Object> list = query.list();
			List<Long> idList = new ArrayList<Long>();
			for (Object o : list) {
				Object[] array = (Object[]) o;
				Relation rel = (Relation) array[0];
				idList.add(rel.getTargetId());
			}

			for (Long id : idList) {
				List<Entity> l = getLightweightEntities(session,
						Node.SYS_STATUS_CURRENT_VERSION, id, null, null, null,
						true, -1);
				if (l.size() > 0) {
					entityList.add(l.get(0));
				}
			}

			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("searchEntityByAttributeOfTarRelation - Time execution: "
							+ diff
							/ (60 * 60 * 1000)
							+ "[hours] "
							+ diff
							/ (60 * 1000) + "[min] " + diff / 1000 + "[sec]");
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			session.getTransaction().commit();
		}
		return entityList;
	}

	/**
	 * returns the attribute found and the corresponding entity
	 * 
	 * @param objClass
	 * @param relName
	 * @param objClassSrc
	 * @param attName
	 * @param attValue
	 * @param maxResults
	 * @return
	 */
	public Map<Entity, Attribute> searchEntityByAttributeOfTarRelation2(
			String objClass, String relName, String objClassSrc,
			String attName, String attValue, int maxResults) {
		Map<Entity, Attribute> entityMap = new HashMap<Entity, Attribute>();
		Session session = null;
		try {

			if (StringUtils.isEmpty(objClass) || StringUtils.isEmpty(relName)
					|| StringUtils.isEmpty(objClassSrc)
					|| StringUtils.isEmpty(attName)
					|| StringUtils.isEmpty(attValue)) {
				throw new Exception(
						"At least one of these parameters was empty: objClass, relName, objClassSrc, attName, attValue.");
			}

			session = HibernateUtil.getSessionFactory().getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from Relation as rel, Attribute as att "
					+ "where "
					+ "att.sourceObjectClass = :objClassSrc AND "
					+
					// "att.sourceObjectClass = rel.sourceObjectClass AND " +
					"rel.targetObjectClass = :objClass AND "
					+ "rel.ownValue = :relName AND "
					+ "att.ownValue like :attValue AND "
					+ "att.objectClass = :attName AND "
					+ "att.systemStatus = :systemStatus AND "
					+ "rel.systemStatus = :systemStatus AND "
					+ "rel.sourceId = att.sourceId " + "group by att.sourceId";

			Query query = session.createQuery(hql);
			if (maxResults > 0) {
				query.setMaxResults(maxResults);
			}

			query.setString("objClass", objClass);
			query.setString("relName", relName);
			query.setString("objClassSrc", objClassSrc);
			query.setString("attName", attName);
			query.setString("attValue", "%" + attValue + "%");
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);

			List<Object> list = query.list();
			Map<Long, Attribute> map = new HashMap<Long, Attribute>();
			for (Object o : list) {
				Object[] array = (Object[]) o;
				Relation rel = (Relation) array[0];
				Attribute att = (Attribute) array[1];
				map.put(rel.getTargetId(), att);
			}

			for (Long id : map.keySet()) {
				List<Entity> l = getLightweightEntities(session,
						Node.SYS_STATUS_CURRENT_VERSION, id, null, null, null,
						true, -1);
				if (l.size() > 0) {
					entityMap.put(l.get(0), map.get(id));
				}
			}

			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("searchEntityByAttributeOfTarRelation - Time execution: "
							+ diff
							/ (60 * 60 * 1000)
							+ "[hours] "
							+ diff
							/ (60 * 1000) + "[min] " + diff / 1000 + "[sec]");
		} catch (Exception e) {
			logger.error(e.getMessage());
		} finally {
			session.getTransaction().commit();
		}
		return entityMap;
	}

	/**
	 * TODO
	 * 
	 * @param objClass
	 * @param relName
	 * @param objClassTar
	 * @param attName
	 * @param attValue
	 * @param maxResults
	 * @return
	 */
	public List<Entity> searchEntityByAttributeOfSrcRelation(String objClass,
			String relName, String objClassTar, String attName,
			String attValue, int maxResults) {
		try {

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * This method search a
	 * 
	 * @param filter
	 *            RelationFilter
	 * @param maxResults
	 * @return
	 */
	public List<RelationResultEntry> searchByRelation(RelationFilter filter,
			String grouping, int maxResults) {
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hql = "from ";
			if (filter.srcInclude) {
				if (filter.srcAttInclude) {
					hql += "Attribute as srcAtt, ";
					hql += "NodeJoin as joinSrcAtt, ";
				}
				hql += "Entity as src, ";
			}
			hql += "Relation as rel ";
			if (filter.tarInclude) {
				hql += ", ";
				hql += "Entity as tar ";
				if (filter.tarAttInclude) {
					hql += ", ";
					hql += "NodeJoin as joinTarAtt, ";
					hql += "Attribute as tarAtt ";
				}
			}

			hql += "where  ";
			if (filter.srcInclude) {
				if (filter.srcAttInclude) {
					hql += "srcAtt.systemStatus = :systemStatus AND ";
					hql += "joinSrcAtt.sourceSystemStatus = :systemStatus AND joinSrcAtt.targetSystemStatus = :systemStatus AND ";
					hql += "joinSrcAtt.sourceId = src.id AND joinSrcAtt.targetId = srcAtt.id AND ";
					hql += "srcAtt.ownValue like :srcAttOwnValue AND ";
					hql += "srcAtt.objectClass like :srcAttName AND ";
				}
				hql += "src.systemStatus = :systemStatus AND ";
				hql += "rel.sourceId = src.id AND ";
				hql += "src.ownValue like :srcOwnValue AND ";
				hql += "src.objectClass like :srcObjectClass AND ";
			}
			if (filter.tarInclude) {
				if (filter.tarAttInclude) {
					hql += "tarAtt.systemStatus = :systemStatus AND ";
					hql += "joinTarAtt.sourceSystemStatus = :systemStatus AND joinTarAtt.targetSystemStatus = :systemStatus AND ";
					hql += "joinTarAtt.sourceId = tar.id AND joinTarAtt.targetId = tarAtt.id AND ";
					hql += "tarAtt.ownValue like :tarAttOwnValue AND ";
					hql += "tarAtt.objectClass like :tarAttName AND ";
				}
				hql += "tar.systemStatus = :systemStatus AND ";
				hql += "rel.targetId = tar.id AND ";
				hql += "tar.ownValue like :tarOwnValue AND ";
				hql += "tar.objectClass like :tarObjectClass AND ";
			}
			hql += "rel.systemStatus = :systemStatus AND ";
			hql += "rel.ownValue like :relOwnValue AND ";
			hql += "rel.objectClass like :relObjectClass ";

			hql += ") ";

			// setup of the field, which is used to group the result entries.
			if (GROUP_BY_SOURCE.equals(grouping) && filter.srcInclude) {
				hql += " group by src.id";
			} else {
				if (GROUP_BY_TARGET.equals(grouping) && filter.tarInclude) {
					hql += " group by tar.id";
				} else {
					hql += " group by rel.id";
				}
			}

			Query query = session.createQuery(hql);
			if (maxResults > 0) {
				query.setMaxResults(maxResults);
			}

			// setting the values of the filter in the query.
			query.setString("systemStatus", Node.SYS_STATUS_CURRENT_VERSION);
			if (filter.srcInclude) {
				if (filter.srcAttInclude) {
					if (StringUtils.isNotEmpty(filter.srcAttOwnValue)) {
						query.setString("srcAttOwnValue", "%"
								+ filter.srcAttOwnValue);
					}
					if (StringUtils.isNotEmpty(filter.srcAttName)) {
						query.setString("srcAttName", "%" + filter.srcAttName);
					}
				}
				if (StringUtils.isNotEmpty(filter.srcOwnValue)) {
					query.setString("srcOwnValue", "%" + filter.srcOwnValue);
				}
				if (StringUtils.isNotEmpty(filter.srcObjectClass)) {
					query.setString("srcObjectClass", "%"
							+ filter.srcObjectClass);
				}
			}
			if (filter.tarInclude) {
				if (filter.tarAttInclude) {
					if (StringUtils.isNotEmpty(filter.tarAttOwnValue)) {
						query.setString("tarAttOwnValue", filter.tarAttOwnValue);
					}
					if (StringUtils.isNotEmpty(filter.tarAttName)) {
						query.setString("tarAttName", filter.tarAttName);
					}
				}
				if (StringUtils.isNotEmpty(filter.tarObjectClass)) {
					query.setString("tarObjectClass", filter.tarObjectClass);
				}
				if (StringUtils.isNotEmpty(filter.tarOwnValue)) {
					query.setString("tarOwnValue", filter.tarOwnValue);
				}
			}
			if (StringUtils.isNotEmpty(filter.relOwnValue)) {
				query.setString("relOwnValue", filter.relOwnValue);
			}
			if (StringUtils.isNotEmpty(filter.relObjectClass)) {
				query.setString("relObjectClass", filter.relObjectClass);
			}

			List<Object> list = query.list();
			List<RelationResultEntry> resultSet = new ArrayList<RelationResultEntry>();
			RelationResultEntry entry;
			for (Object o : list) {
				entry = new RelationResultEntry();
				int index = 0;
				Object[] array = (Object[]) o;
				// Object item = (Object) array[0];
				if (filter.srcInclude) {
					if (filter.srcAttInclude) {
						entry.srcAttribute = (Attribute) array[index];
						index++;
						index++;
						// hql += "Attribute as srcAtt, ";
						// hql += "NodeJoin as joinSrcAtt, ";
					}
					entry.source = (Entity) array[index];
					index++;
					// hql += "Entity as src, ";
				}
				// hql += "Relation as rel ";
				entry.relation = (Relation) array[index];
				index++;
				if (filter.tarInclude) {
					// hql += "Entity as tar ";
					entry.target = (Entity) array[index];
					index++;
					if (filter.tarAttInclude) {
						index++;
						entry.tarAttribute = (Attribute) array[index];
						// hql += "NodeJoin as joinTarAtt, ";
						// hql += "Attribute as tarAtt ";
					}
				}
				resultSet.add(entry);
			}
			// //////////////////////////////////////////
			// //////////////////////////////////////////
			// //////////////////////////////////////////
			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.info("GetLightweightEntities BY RELATION - Time execution: "
							+ diff
							/ (60 * 60 * 1000)
							+ "[hours] "
							+ diff
							/ (60 * 1000) + "[min] " + diff / 1000 + "[sec]");
			return resultSet;
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * <p>
	 * Returns a list of entities filtered by the following rules:
	 * </p>
	 * if <b>ownValue</b> is no empty, the entities returned have into ownValue
	 * the given substring.
	 * 
	 * @param ownValue
	 * @param objectClass
	 * @param filters
	 * @return
	 */

	/**
	 * TODO: what will be returned if it is searching a null value eg:
	 * identifier=null?
	 * 
	 * @param ownValue
	 * @param objectClass
	 * @param attObjClass
	 * @param attOwnValue
	 * @param assertions
	 * @param maxResults
	 * @return
	 */
	public List<Entity> getLightweightEntitiesByAttribute(String ownValue,
			String objectClass, String attObjClass, String attOwnValue,
			Boolean assertions, int maxResults, boolean substring) {
		logger.debug("Get LW Entities By Attribute [maxResults: " + maxResults
				+ "]");

		List<Entity> entities = new ArrayList<Entity>();

		if (substring) {
			ownValue = (StringUtils.isEmpty(ownValue)) ? "" : "%" + ownValue
					+ "%";
			objectClass = (StringUtils.isEmpty(objectClass)) ? "" : "%"
					+ objectClass + "%";
			attOwnValue = (StringUtils.isEmpty(attOwnValue)) ? "" : "%"
					+ attOwnValue + "%";
			attObjClass = (StringUtils.isEmpty(attObjClass)) ? "" : "%"
					+ attObjClass + "%";
		}

		String type = (assertions) ? Node.TYPE_ABOX : Node.TYPE_TBOX;
		String equalityOperator = (substring) ? " like " : " = ";

		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.getTransaction().begin();
			Long start = System.currentTimeMillis();

			String hqlEntities = "from Entity as ent, Attribute as att "
					+ "where  ent.systemStatus = :systemStatus AND att.systemStatus = :systemStatus AND "
					+ "att.sourceId = ent.id AND ";

			if (StringUtils.isNotEmpty(ownValue)) {
				hqlEntities += "ent.ownValue " + equalityOperator
						+ " :ownValue AND ";
			}
			if (StringUtils.isNotEmpty(objectClass)) {
				hqlEntities += "ent.objectClass " + equalityOperator
						+ " :objectClass AND ";
			}
			if (StringUtils.isNotEmpty(attOwnValue)) {
				hqlEntities += "att.ownValue " + equalityOperator
						+ " :attOwnValue AND ";
			}
			if (StringUtils.isNotEmpty(attObjClass)) {
				hqlEntities += "att.objectClass " + equalityOperator
						+ " :attObjClass AND ";
			}
			hqlEntities += "ent.type = :type "
					+ "group by ent.id order by ent.ownValue";

			Query queryEntities = session.createQuery(hqlEntities);
			queryEntities.setString("systemStatus",
					Node.SYS_STATUS_CURRENT_VERSION);
			queryEntities.setString("type", type);
			if (StringUtils.isNotEmpty(ownValue)) {
				queryEntities.setString("ownValue", ownValue);
			}
			if (StringUtils.isNotEmpty(objectClass)) {
				queryEntities.setString("objectClass", objectClass);
			}
			if (StringUtils.isNotEmpty(attOwnValue)) {
				queryEntities.setString("attOwnValue", attOwnValue);
			}
			if (StringUtils.isNotEmpty(attObjClass)) {
				queryEntities.setString("attObjClass", attObjClass);
			}
			if (maxResults > 0) {
				queryEntities.setMaxResults(maxResults);
			}

			entities = new ArrayList<Entity>();
			List<Object> list = queryEntities.list();
			for (Object o : list) {
				Object[] array = (Object[]) o;
				Object item = (Object) array[0];
				if (item instanceof Entity) {
					// logger.info("Entity= " + item);
					Entity ent = (Entity) item;
					ent.setLightweight(true);
					entities.add(ent);
				}
			}

			session.getTransaction().commit();
			Long end = System.currentTimeMillis();
			Long diff = end - start;
			logger.debug("GetLightweightEntitiesByAttribute - Time execution: "
					+ diff / (60 * 60 * 1000) + "[hours] " + diff / (60 * 1000)
					+ "[min] " + diff / 1000 + "[sec]");
		} catch (Exception e) {
			logger.error(e.getMessage());
			e.printStackTrace();
		}
		return entities;
	}

}