All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.jasperreports.j2ee.ejbql.JRJpaQueryExecuter Maven / Gradle / Ivy

The newest version!
/*
 * JasperReports - Free Java Reporting Library.
 * Copyright (C) 2001 - 2023 Cloud Software Group, Inc. All rights reserved.
 * http://www.jaspersoft.com
 *
 * Unless you have purchased a commercial license agreement from Jaspersoft,
 * the following license terms apply:
 *
 * This program is part of JasperReports.
 *
 * JasperReports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * JasperReports is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with JasperReports. If not, see .
 */
package net.sf.jasperreports.j2ee.ejbql;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.jasperreports.annotations.properties.Property;
import net.sf.jasperreports.annotations.properties.PropertyScope;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRDataset;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JRPropertiesUtil.PropertySuffix;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRValueParameter;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.query.EjbqlConstants;
import net.sf.jasperreports.engine.query.JRAbstractQueryExecuter;
import net.sf.jasperreports.engine.util.JRStringUtil;
import net.sf.jasperreports.properties.PropertyConstants;

/**
 * EJBQL query executer that uses the Java Persistence API.
 * 

* To use EJBQL in queries, an javax.persistence.EntityManager is needed. * When running or filling reports the em need to be supplied with the named parameter {@link net.sf.jasperreports.engine.query.EjbqlConstants#PARAMETER_JPA_ENTITY_MANAGER}. *

* Example: * *

 * Map parameters = new HashMap();
 * EntityManager em = emf.createEntityManager();
 * parameters.put(EjbqlConstants.PARAMETER_JPA_ENTITY_MANAGER, em);
 * JasperRunManager.runReportToPdfFile(fileName, parameters);
 * 
* *

* When dealing with large result sets, pagination can be used by setting the {@link net.sf.jasperreports.j2ee.ejbql.JRJpaQueryExecuter#PROPERTY_JPA_QUERY_PAGE_SIZE} property in the report template. *

* Example: * *

 * <property name="net.sf.jasperreports.ejbql.query.page.size" value="100"/>
 * 
* *

* Implementation-specific query hints can be set either using report properties in the report template, * or by supplying the named parameter {@link net.sf.jasperreports.engine.query.EjbqlConstants#PARAMETER_JPA_QUERY_HINTS_MAP} * containing a java.util.Map with named/value query hints. *

* Example using report property: * *

 * <property name="net.sf.jasperreports.ejbql.query.hint.fetchSize" value="100"/>
 * 
* * The name of the query hint need to be prefixed with {@link net.sf.jasperreports.j2ee.ejbql.JRJpaQueryExecuter#PROPERTY_JPA_QUERY_HINT_PREFIX net.sf.jasperreports.ejbql.query.hint.}. * Above example will set a query hint with the name fetchSize and the String value 100. *

* Example using map: * *

 * Map hints = new HashMap();
 * hints.put("fetchSize", 100);
 * hints.put("anyName", anyObject());
 * Map parameters = new HashMap();
 * EntityManager em = emf.createEntityManager();
 * parameters.put(EjbqlConstants.PARAMETER_JPA_ENTITY_MANAGER, em);
 * parameters.put(EjbqlConstants.PARAMETER_JPA_QUERY_HINTS_MAP, hints);
 * JasperRunManager.runReportToPdfFile(fileName, parameters);
 * 
* * Note that when using report properties only String values can be set as query hint. * When using a query hints map, any Object can be set as value. * * @author Marcel Overdijk ([email protected]) * @see JRJpaQueryExecuterFactory */ public class JRJpaQueryExecuter extends JRAbstractQueryExecuter { private static final Log log = LogFactory.getLog(JRJpaQueryExecuter.class); public static final String CANONICAL_LANGUAGE = "EJBQL"; /** * Property specifying the number of result rows to be retrieved at once. *

* Result pagination is implemented by javax.persistence.Query.setFirstResult() and javax.persistence.Query.setMaxResults(). *

* By default, all the rows are retrieved (no result pagination is performed). */ @Property( category = PropertyConstants.CATEGORY_DATA_SOURCE, scopes = {PropertyScope.CONTEXT, PropertyScope.DATASET}, scopeQualifications = {EjbqlConstants.QUERY_EXECUTER_NAME_EJBQL}, sinceVersion = PropertyConstants.VERSION_1_2_3, valueType = Integer.class ) public static final String PROPERTY_JPA_QUERY_PAGE_SIZE = JRPropertiesUtil.PROPERTY_PREFIX + "ejbql.query.page.size"; /** * Property specifying the prefix for EJBQL query hints. */ @Property( name = "net.sf.jasperreports.ejbql.query.hint.{hint}", category = PropertyConstants.CATEGORY_DATA_SOURCE, scopes = {PropertyScope.DATASET}, scopeQualifications = {EjbqlConstants.QUERY_EXECUTER_NAME_EJBQL}, sinceVersion = PropertyConstants.VERSION_1_2_3 ) public static final String PROPERTY_JPA_QUERY_HINT_PREFIX = JRPropertiesUtil.PROPERTY_PREFIX + "ejbql.query.hint."; private final Integer reportMaxCount; private EntityManager em; private Query query; /** * */ public JRJpaQueryExecuter( JasperReportsContext jasperReportsContext, JRDataset dataset, Map parameters ) { super(jasperReportsContext, dataset, parameters); em = (EntityManager)getParameterValue(EjbqlConstants.PARAMETER_JPA_ENTITY_MANAGER); reportMaxCount = (Integer)getParameterValue(JRParameter.REPORT_MAX_COUNT); if (em == null) { log.warn("The supplied javax.persistence.EntityManager object is null."); } parseQuery(); } @Override protected String getCanonicalQueryLanguage() { return CANONICAL_LANGUAGE; } @Override public JRDataSource createDatasource() throws JRException { JRDataSource datasource = null; String queryString = getQueryString(); if (em != null && queryString != null && queryString.trim().length() > 0) { createQuery(queryString); datasource = createResultDatasource(); } return datasource; } /** * Creates the EJBQL query object. * * @param queryString the query string */ protected synchronized void createQuery(String queryString) { if (log.isDebugEnabled()) { log.debug("EJBQL query: " + queryString); } query = em.createQuery(queryString); // Set parameters. List parameterNames = getCollectedParameterNames(); if (!parameterNames.isEmpty()) { // Use set to prevent the parameter to be set multiple times. Set namesSet = new HashSet<>(); for (Iterator iter = parameterNames.iterator(); iter.hasNext();) { String parameterName = iter.next(); if (namesSet.add(parameterName)) { JRValueParameter parameter = getValueParameter(parameterName); String ejbParamName = getEjbqlParameterName(parameterName); Object paramValue = parameter.getValue(); if (log.isDebugEnabled()) { log.debug("Parameter " + ejbParamName + ": " + paramValue); } query.setParameter(ejbParamName, paramValue); } } } // Set query hints. // First, set query hints supplied by the JPA_QUERY_HINTS_MAP parameter. Map queryHintsMap = (Map)getParameterValue(EjbqlConstants.PARAMETER_JPA_QUERY_HINTS_MAP); if (queryHintsMap != null) { for (Iterator> i = queryHintsMap.entrySet().iterator(); i.hasNext(); ) { Map.Entry pairs = i.next(); if (log.isDebugEnabled()) { log.debug("EJBQL query hint [" + pairs.getKey() + "] set."); } query.setHint(pairs.getKey(), pairs.getValue()); } } // Second, set query hints supplied by report properties which start with JREjbPersistenceQueryExecuterFactory.PROPERTY_JPA_PERSISTENCE_QUERY_HINT_PREFIX // Example: net.sf.jasperreports.ejbql.query.hint.fetchSize // This property will result in a query hint set with the name: fetchSize List properties = JRPropertiesUtil.getProperties(dataset, PROPERTY_JPA_QUERY_HINT_PREFIX); for (Iterator it = properties.iterator(); it.hasNext();) { PropertySuffix property = it.next(); String queryHint = property.getSuffix(); if (queryHint.length() > 0) { String value = property.getValue(); if (log.isDebugEnabled()) { log.debug("EJBQL query hint [" + queryHint + "] set to: " + value); } query.setHint(queryHint, value); } } } /** * Creates a data source out of the query result. * * @return the data source */ protected JRDataSource createResultDatasource() { JRDataSource resDatasource; try { int pageSize = getPropertiesUtil().getIntegerProperty(dataset, PROPERTY_JPA_QUERY_PAGE_SIZE, 0); resDatasource = new JRJpaDataSource(this, pageSize); } catch (NumberFormatException e) { throw new JRRuntimeException( EXCEPTION_MESSAGE_KEY_NUMERIC_TYPE_REQUIRED, new Object[]{PROPERTY_JPA_QUERY_PAGE_SIZE}, e); } return resDatasource; } @Override public synchronized void close() { query = null; } @Override public synchronized boolean cancelQuery() throws JRException { return false; } @Override protected String getParameterReplacement(String parameterName) { return ':' + getEjbqlParameterName(parameterName); } protected String getEjbqlParameterName(String parameterName) { return JRStringUtil.getJavaIdentifier(parameterName); } /** * Runs the query by calling javax.persistence.Query.getResultList. *

* All the result rows are returned. * * @return the result of the query as a list */ public List getResultList() { if (reportMaxCount != null) { query.setMaxResults(reportMaxCount); } return query.getResultList(); } /** * Returns a page of the query results by calling javax.persistence.Query.getResultList. * * @param firstIndex the index of the first row to return * @param resultCount the number of rows to return * @return result row list */ public List getResultList(int firstIndex, int resultCount) { if (reportMaxCount != null && firstIndex + resultCount > reportMaxCount) { resultCount = reportMaxCount - firstIndex; } query.setFirstResult(firstIndex); query.setMaxResults(resultCount); return query.getResultList(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy