package com.globant.katari.report.domain;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.ListUtils;
import org.apache.commons.lang.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.transform.AliasToBeanConstructorResultTransformer;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import com.globant.katari.hibernate.coreuser.domain.Role;
/**
* The Client repository. It provides access to the report definitions.
*
* @author sergio.sobek
*/
public class JasperReportRepository extends HibernateDaoSupport {
/** The class logger. */
private static Logger log =
LoggerFactory.getLogger(JasperReportRepository.class);
/** The entity class name. */
private static final String CLASS_NAME = ReportDefinition.class.getName();
/**
* Gets a list with all the report definitions.
*
* @return a list with all the report definitions
*/
@SuppressWarnings("unchecked")
public List<ReportDefinition> getReportList() {
log.trace("getReportTemplateList");
return getHibernateTemplate().find("from ReportDefinition");
}
/**
* Finds a ReportDefinition given its id.
*
* @param anId the id of the ReportDefinition to be found.
* @return the ReportDefinition that has the specified id or null if no such
* ReportDefinition exists. It must be greater than zero.
*/
public ReportDefinition findReportDefinitionById(final long anId) {
log.trace("findReportTemplateById");
Validate.isTrue(anId > 0, "The id must be greater than zero.");
return (ReportDefinition) getHibernateTemplate().get(CLASS_NAME, anId);
}
/**
* Given a name, it finds a Report Definition.
*
* @param aName the name of the ReportDefinition to be found.
* @return the ReportDefinition that has the specified name or null if no such
* ReportDefinition exists. It cannot be null.
*/
@SuppressWarnings("unchecked")
public ReportDefinition findReportDefinition(final String aName) {
log.trace("findReportTemplateByName");
Validate.notNull(aName, "The name cannot be null.");
ReportDefinition result = null;
String query = "from " + CLASS_NAME + " where name = ?";
List<ReportDefinition> list = getHibernateTemplate().find(query, aName);
if (!list.isEmpty()) {
result = list.get(0);
}
return result;
}
/**
* Finds a report with the given name and return its id.
*
* @param name the name of the ReportDefinition to be found. It cannot null.
*
* @return the long id of the report, 0 if no report found.
*/
public long findIdForName(final String name) {
Validate.notNull(name, "The name cannot be null.");
String hqlQuery = "select definition.id from ReportDefinition definition"
+ " where name = ?";
Query query = getSession().createQuery(hqlQuery);
long retunId = 0;
Long foundId = (Long) query.setParameter(0, name).uniqueResult();
if (foundId != null) {
retunId = foundId;
}
return retunId;
}
/**
* Given a list of roles, it finds Report Definitions.
*
* @param roles list of roles. Cannot be null and cannot contain null
* elements.
*
* @return the ReportDefinition that has one of the specified role or empty if
* no such ReportDefinition exists. It never returns null.
*/
@SuppressWarnings("unchecked")
public List<ReportDefinition> findReportsByRole(
final Collection<Role> roles) {
Validate.notNull(roles, "The roles cannot be null.");
Validate.noNullElements(roles, "The roles cannot has null element.");
String hqlQuery;
Query query;
// if no role given return only reports without roles, a new query if used
// because empty in() clause in sql is not allowed, another option is set a
// negative default id, but i dont like it
if (roles.isEmpty()) {
hqlQuery = "select definition from"
+ " ReportDefinition definition left join definition.roles as role"
+ " where role is null";
query = getSession().createQuery(hqlQuery);
} else {
hqlQuery = "select definition from"
+ " ReportDefinition definition left join definition.roles as role"
+ " where role in(:roles) or role is null";
query = getSession().createQuery(hqlQuery);
query.setParameterList("roles", roles);
}
return query.list();
}
/**
* Saves a new Report Definition or updates an existing Report Definition to
* the database.
* @param aReportDefinition the ReportDefinition to be saved. It cannot be
* null.
*/
public void save(final ReportDefinition aReportDefinition) {
log.trace("save");
Validate.notNull(aReportDefinition, "the report definition cannot be null");
getHibernateTemplate().saveOrUpdate(aReportDefinition);
}
/**
* Deletes a ReportDefinition from the database.
*
* @param aReportDefinition the ReportDefinition to be deleted. It cannot be
* null.
*/
public void remove(final ReportDefinition aReportDefinition) {
log.trace("remove");
Validate.notNull(aReportDefinition, "the reportTemplate cannot be null");
getHibernateTemplate().delete(aReportDefinition);
}
/** Builds a list of options used in a drop down tag from a sql query.
*
* The query must return two columns, aliased to value and label. The
* label is shown to the user and the value gets post when the user selects
* the corresponding option.
*
* @param parameter the parameter definition, it cannot be null.
* @param parameterValues the parameter values, it cannot be null.
*
* @return a list of options.
*/
@SuppressWarnings({ "unchecked", "deprecation" })
public List<DropdownOptions> getDropdownOptions(final ParameterDefinition
parameter, final Map<String, String> parameterValues) {
Validate.notNull(parameter, "the parameter cannnot be null.");
Validate.notNull(parameterValues, "the parameterValues cannnot be null.");
Constructor constructor;
try {
constructor = DropdownOptions.class.getConstructor(
new Class[] {String.class, String.class});
} catch (NoSuchMethodException e) {
log.error("Error obtaining constructor DropdownOptions(String, String)",
e);
throw new RuntimeException("Error obtaining constructor", e);
}
Query query = getSession().createSQLQuery(parameter.getDropdownQuery())
.addScalar("value", Hibernate.STRING)
.addScalar("label", Hibernate.STRING)
.setResultTransformer(new AliasToBeanConstructorResultTransformer(
constructor));
for (String name : query.getNamedParameters()) {
String value = parameterValues.get(name);
if (value == null) {
return ListUtils.EMPTY_LIST;
}
query.setParameter(name, value);
}
return query.list();
}
}