/**
* Implements operations for managing the collection table of the aidr_predict DB
*
* @author Koushik
*/
package qa.qcri.aidr.dbmanager.ejb.remote.facade.imp;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.EJBTransactionRolledbackException;
import javax.ejb.Stateless;
import javax.persistence.NoResultException;
import javax.persistence.Query;
import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import qa.qcri.aidr.common.exception.PropertyNotSetException;
import qa.qcri.aidr.common.wrapper.CollectionBriefInfo;
import qa.qcri.aidr.dbmanager.dto.CollectionDTO;
import qa.qcri.aidr.dbmanager.ejb.local.facade.impl.CoreDBServiceFacadeImp;
import qa.qcri.aidr.dbmanager.ejb.remote.facade.CollectionResourceFacade;
import qa.qcri.aidr.dbmanager.ejb.remote.facade.UsersResourceFacade;
import qa.qcri.aidr.dbmanager.entities.misc.Collection;
import qa.qcri.aidr.dbmanager.entities.model.ModelFamily;
@Stateless(name="CollectionResourceFacadeImp")
public class CollectionResourceFacadeImp extends CoreDBServiceFacadeImp<Collection, Long> implements CollectionResourceFacade {
private static final Logger logger = Logger.getLogger("db-manager-log");
private static final String SELECT_COLLECTION_FOR_ATTRIBUTE_CRISIS_TYPE = "SELECT c.name as name,"+
" a.user_name as owner,"+
" c.code as code,"+
" c.lang_filters as langFilter,"+
" count(1) as trainingCount"+
" FROM collection c "+
" JOIN document doc " +
" ON doc.crisisID = c.id "+
" JOIN document_nominal_label dnl"+
" ON doc.documentID = dnl.documentID"+
" JOIN nominal_label nl"+
" ON dnl.nominalLabelID = nl.nominalLabelID"+
" JOIN account a "+
" ON c.owner_id = a.id"+
" WHERE nl.nominalAttributeID = :nominalAttributeID"+
" AND c.crisis_type = :crisis_type ";
@EJB
private UsersResourceFacade userLocalEJB;
protected CollectionResourceFacadeImp(){
super(Collection.class);
}
@Override
public List<CollectionDTO> findByCriteria(String columnName, Object value) throws PropertyNotSetException {
List<Collection> list = getAllByCriteria(Restrictions.eq(columnName,value));
List<CollectionDTO> dtoList = new ArrayList<CollectionDTO>();
if (list != null && !list.isEmpty()) {
for (Collection c: list) {
dtoList.add(new CollectionDTO(c));
}
}
return dtoList;
}
@Override
public List findAllCrisisIds() {
Criteria criteria = getCurrentSession().createCriteria(Collection.class);
criteria.setProjection(Projections.distinct(Projections.property("id")));
try {
List result = criteria.list();
return result;
} catch (HibernateException e) {
logger.error("Error in findAllCrisisIds(). ",e);
return null;
}
}
@Override
public Integer deleteCrisis(CollectionDTO crisis) throws PropertyNotSetException {
try {
Collection managed = em.merge(crisis.toEntity());
em.remove(managed);
} catch (Exception e) {
return 0;
}
return 1;
}
@Override
public CollectionDTO addCrisis(CollectionDTO crisis) {
try {
Collection c = crisis.toEntity();
em.persist(c);
em.flush();
em.refresh(c);
return new CollectionDTO(c);
} catch (Exception e) {
logger.error("Error in addCrisis for crisis code : " + crisis.getCode(), e);
return null;
}
}
@Override
public CollectionDTO findCrisisByID(Long id) throws PropertyNotSetException {
Collection collection = getById(id);
if (collection != null) {
CollectionDTO dto = new CollectionDTO(collection);
return dto;
} else {
return null;
}
}
@Override
public CollectionDTO getCrisisWithAllFieldsByID(Long id) throws PropertyNotSetException {
Collection collection = getById(id);
if (collection != null) {
Hibernate.initialize(collection.getModelFamilies());
Hibernate.initialize(collection.getDocuments());
CollectionDTO dto = new CollectionDTO(collection);
return dto;
} else {
return null;
}
}
@Override
public CollectionDTO getCrisisByCode(String code) throws PropertyNotSetException {
Criterion criterion = Restrictions.eq("code", code);
Collection collection = (Collection) getByCriteria(criterion);
return collection != null ? new CollectionDTO(collection) : null;
}
@Override
public CollectionDTO editCrisis(CollectionDTO crisis) throws PropertyNotSetException {
try {
Collection c = crisis.toEntity();
Collection cr = getById(c.getCrisisId());
if (cr != null) {
cr = em.merge(c);
em.flush();
em.refresh(cr);
return cr != null ? new CollectionDTO(cr) : null;
} else {
logger.error("Not found");
throw new RuntimeException("Not found");
}
} catch (Exception e) {
logger.error("Exception in merging/updating crisis: " + crisis.getCrisisID(), e);
}
return null;
}
@Override
public List<CollectionDTO> getAllCrisis() throws PropertyNotSetException {
logger.info("Received request for fetching all crisis!!!");
List<CollectionDTO> dtoList = new ArrayList<CollectionDTO>();
List<Collection> collections = getAll();
if (collections != null && !collections.isEmpty()) {
for (Collection collection : collections) {
logger.info("Converting to DTO crisis: " + collection.getCode() + ", " + collection.getName() + ", " + collection.getCrisisId());
CollectionDTO dto = new CollectionDTO(collection);
dtoList.add(dto);
}
}
logger.info("Done creating DTO list, size = " + dtoList.size());
return dtoList;
}
@Override
public List<CollectionDTO> getAllCrisisWithModelFamilies() throws PropertyNotSetException {
List<CollectionDTO> dtoList = new ArrayList<CollectionDTO>();
List<Collection> crisisList = getAll();
if (crisisList != null && !crisisList.isEmpty()) {
for (Collection crisis : crisisList) {
try {
Hibernate.initialize(crisis.getModelFamilies()); // fetching lazily loaded data
CollectionDTO dto = new CollectionDTO(crisis);
dtoList.add(dto);
} catch (HibernateException e) {
logger.error("Hibernate initialization error for lazy objects in : " + crisis.getCrisisId());
}
}
}
return dtoList;
}
@Override
public List<CollectionDTO> getAllCrisisByUserID(Long userID) throws PropertyNotSetException{
List<CollectionDTO> dtoList = userLocalEJB.findAllCrisisByUserID(userID);
return dtoList;
}
@Override
public boolean isCrisisExists(String crisisCode) throws PropertyNotSetException {
CollectionDTO dto = getCrisisByCode(crisisCode);
return dto != null ? true : false;
}
@SuppressWarnings("rawtypes")
@Override
public HashMap<String, Integer> countClassifiersByCrisisCodes(List<String> codes) {
// TODO: convert native query to Hibernate/JPA
String sqlQuery = "select cr.code, " +
" (select count(*) from model_family mf where mf.crisisID = cr.id) as mf_amount " +
" from collection cr " +
" where cr.code in (:codes) and classifier_enabled = 1;";
try {
Query nativeQuery = em.createNativeQuery(sqlQuery);
nativeQuery.setParameter("codes", codes);
List resultList = nativeQuery.getResultList();
HashMap<String, Integer> rv = new HashMap<String, Integer>();
for(Object obj : resultList){
Object[] objs = ((Object[])obj);
rv.put((String)objs[0], ((BigInteger)objs[1]).intValue());
}
return rv;
} catch (Exception e) {
logger.error(e.getMessage());
}
return null;
}
@Override
public List<CollectionDTO> getAllCrisisWithModelFamilyNominalAttribute() throws PropertyNotSetException {
List<CollectionDTO> dtoList = new ArrayList<CollectionDTO>();
List<Collection> list = getAll();
if (list != null && !list.isEmpty()) {
for (Collection c: list) {
try {
Hibernate.initialize(c.getModelFamilies());
for (ModelFamily mf : c.getModelFamilies()) {
if(mf.hasNominalAttribute()){
Hibernate.initialize(mf.getNominalAttribute().getNominalLabels());
}
}
dtoList.add(new CollectionDTO(c));
} catch (HibernateException e) {
logger.error("Hibernate initialization error for lazy objects in : " + c.getCrisisId());
}
}
}
return dtoList;
}
@Override
public CollectionDTO getWithModelFamilyNominalAttributeByCrisisID(Long crisisID) throws PropertyNotSetException {
Collection crisis = getById(crisisID);
if (crisis != null) {
try {
Hibernate.initialize(crisis.getModelFamilies());
for (ModelFamily mf : crisis.getModelFamilies()) {
if(mf.hasNominalAttribute()){
Hibernate.initialize(mf.getNominalAttribute().getNominalLabels());
}
}
return new CollectionDTO(crisis);
} catch (HibernateException e) {
logger.error("Hibernate initialization error for lazy objects in : " + crisis.getCrisisId());
}
}
return null;
}
@Override
public List<CollectionDTO> findActiveCrisis() throws PropertyNotSetException {
List<CollectionDTO> dtoList = new ArrayList<CollectionDTO>();
List<Collection> list = getAllByCriteria(Restrictions.eq("isTrashed", false));
if (list != null && !list.isEmpty()) {
for (Collection c: list) {
try {
Hibernate.initialize(c.getModelFamilies());
for(ModelFamily mf : c.getModelFamilies()){
if(mf.isIsActive()){
dtoList.add(new CollectionDTO(c));
}
}
} catch (HibernateException e) {
logger.error("Hibernate initialization error for lazy objects in : " + c.getCrisisId());
}
}
}
return dtoList;
}
@Override
public int deleteCrisis(Long id) {
Collection collection = getById(id);
if (collection != null) {
delete(collection);
em.flush();
return 1;
}
return 0;
}
@Override
public List<CollectionBriefInfo> getCrisisForNominalAttributeById(Integer attributeID, Integer crisis_type, String lang_filters, Long collectionId) throws PropertyNotSetException {
List<CollectionBriefInfo> result = new ArrayList<CollectionBriefInfo>();
String finalSQLQuery = SELECT_COLLECTION_FOR_ATTRIBUTE_CRISIS_TYPE;
if(collectionId != null) {
finalSQLQuery += "AND c.id != :collectionId ";
}
String intermediateCriteria = "";
if(lang_filters != null && !lang_filters.isEmpty()) {
String[] languageList = lang_filters.split(",");
for(int index = 0; index < languageList.length; index++) {
if(!languageList[index].isEmpty()) {
intermediateCriteria += " FIND_IN_SET('" + languageList[index] + "' , c.lang_filters )";
if(index != languageList.length - 1) {
intermediateCriteria += " OR";
}
}
}
if(!intermediateCriteria.isEmpty()) {
intermediateCriteria = " AND (" + intermediateCriteria + " OR c.lang_filters = '')";
}
}
finalSQLQuery = finalSQLQuery + intermediateCriteria + " GROUP BY doc.crisisID";;
logger.error("Final Query ::: " + finalSQLQuery);
Query query = em.createNativeQuery(finalSQLQuery);
query.setParameter("nominalAttributeID", attributeID);
query.setParameter("crisis_type", crisis_type);
if (collectionId != null) {
query.setParameter("collectionId", collectionId);
}
List<Object[]> rows = null;
try {
rows = query.getResultList();
for (Object[] row : rows) {
CollectionBriefInfo collectionBriefInfo = new CollectionBriefInfo();
collectionBriefInfo.setName((String) row[0]);
collectionBriefInfo.setOwner((String) row[1]);
collectionBriefInfo.setCode((String) row[2]);
collectionBriefInfo.setLanguage((String) row[3]);
collectionBriefInfo.setTrainingCount(((BigInteger) row[4]).intValue());
result.add(collectionBriefInfo);
}
} catch (Exception e) {
logger.error("Error in fetching collections for attribute : " + attributeID, e);
}
return result;
}
}