Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.sf.jasperreports.engine.fill.PartReportFiller Maven / Gradle / Ivy
/*
* JasperReports - Free Java Reporting Library.
* Copyright (C) 2001 - 2019 TIBCO Software 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.engine.fill;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import net.sf.jasperreports.engine.BookmarkHelper;
import net.sf.jasperreports.engine.BookmarkIterator;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRGroup;
import net.sf.jasperreports.engine.JROrigin;
import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRScriptletException;
import net.sf.jasperreports.engine.JRStyle;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.PrintPart;
import net.sf.jasperreports.engine.part.DelayedPrintPart;
import net.sf.jasperreports.engine.part.FillPart;
import net.sf.jasperreports.engine.part.FillPartPrintOutput;
import net.sf.jasperreports.engine.part.FillParts;
import net.sf.jasperreports.engine.part.FillPrintPart;
import net.sf.jasperreports.engine.part.FillPrintPartQueue;
import net.sf.jasperreports.engine.part.FillingPrintPart;
import net.sf.jasperreports.engine.part.FinalFillingPrintPart;
import net.sf.jasperreports.engine.part.GroupFillParts;
import net.sf.jasperreports.engine.part.PartEvaluationTime;
import net.sf.jasperreports.engine.part.PartPrintOutput;
import net.sf.jasperreports.engine.type.IncrementTypeEnum;
import net.sf.jasperreports.engine.type.ResetTypeEnum;
import net.sf.jasperreports.engine.type.SectionTypeEnum;
import net.sf.jasperreports.engine.util.JRDataUtils;
import net.sf.jasperreports.parts.PartFillerParent;
/**
* @author Lucian Chirita ([email protected] )
*/
public class PartReportFiller extends BaseReportFiller
{
private static final Log log = LogFactory.getLog(PartReportFiller.class);
public static final String EXCEPTION_MESSAGE_KEY_EVALUATION_GROUP_NOT_FOUND = "fill.part.filler.evaluation.group.not.found";
public static final String EXCEPTION_MESSAGE_KEY_UNKNOWN_EVALUATION_TIME_TYPE = "fill.part.filler.unknown.evaluation.time.type";
public static final String EXCEPTION_MESSAGE_KEY_UNSUPPORTED_SECTION_TYPE = "fill.part.filler.unsupported.section.type";
private FillParts detailParts;
private List groupParts;
private Map groupPartsByName;
private FillPrintPartQueue partQueue;
private List reportEvaluatedParts;
public PartReportFiller(JasperReportsContext jasperReportsContext, JasperReport jasperReport) throws JRException
{
this(jasperReportsContext, SimpleJasperReportSource.from(jasperReport), null);
}
public PartReportFiller(JasperReportsContext jasperReportsContext, JasperReport jasperReport,
PartFillerParent parent) throws JRException
{
this(jasperReportsContext, SimpleJasperReportSource.from(jasperReport), parent);
}
public PartReportFiller(JasperReportsContext jasperReportsContext, JasperReportSource reportSource,
PartFillerParent parent) throws JRException
{
super(jasperReportsContext, reportSource, parent);
detailParts = new FillParts(jasperReport.getDetailSection(), factory);
JRGroup[] reportGroups = jasperReport.getGroups();
if (reportGroups == null || reportGroups.length == 0)
{
groupParts = Collections.emptyList();
groupPartsByName = Collections.emptyMap();
}
else
{
groupParts = new ArrayList(reportGroups.length);
groupPartsByName = new HashMap();
for (JRGroup reportGroup : reportGroups)
{
GroupFillParts groupFillParts = new GroupFillParts(reportGroup, factory);
groupParts.add(groupFillParts);
groupPartsByName.put(reportGroup.getName(), groupFillParts);
}
}
initDatasets();
reportEvaluatedParts = new ArrayList();
if (parent == null)
{
JasperPrintPartOutput jasperPrintOutput = new JasperPrintPartOutput();
partQueue = new FillPrintPartQueue(jasperPrintOutput);
}
else
{
partQueue = parent.getFiller().partQueue;
}
}
@Override
protected void jasperReportSet()
{
if (jasperReport.getSectionType() != SectionTypeEnum.PART)
{
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_UNSUPPORTED_SECTION_TYPE,
new Object[]{jasperReport.getSectionType()});
}
}
@Override
protected JRFillObjectFactory initFillFactory()
{
return new JRFillObjectFactory(this);
}
@Override
public JasperPrint fill(Map parameterValues) throws JRException
{
//FIXMEBOOK copied from JRBaseFiller
if (parameterValues == null)
{
parameterValues = new HashMap();
}
if (log.isDebugEnabled())
{
log.debug("Fill " + fillerId + ": filling report");
}
setParametersToContext(parameterValues);
fillingThread = Thread.currentThread();
JRResourcesFillUtil.ResourcesFillContext resourcesContext =
JRResourcesFillUtil.setResourcesFillContext(parameterValues);
boolean success = false;
try
{
createBoundElemementMaps();
/* if (parent != null)
{
parent.registerSubfiller(this);
}
*/
setParameters(parameterValues);
setBookmarkHelper();
//loadStyles();
jasperPrint.setName(jasperReport.getName());
jasperPrint.setPageWidth(jasperReport.getPageWidth());
jasperPrint.setPageHeight(jasperReport.getPageHeight());
jasperPrint.setTopMargin(jasperReport.getTopMargin());
jasperPrint.setLeftMargin(jasperReport.getLeftMargin());
jasperPrint.setBottomMargin(jasperReport.getBottomMargin());
jasperPrint.setRightMargin(jasperReport.getRightMargin());
jasperPrint.setOrientation(jasperReport.getOrientationValue());
jasperPrint.setFormatFactoryClass(jasperReport.getFormatFactoryClass());
jasperPrint.setLocaleCode(JRDataUtils.getLocaleCode(getLocale()));
jasperPrint.setTimeZoneId(JRDataUtils.getTimeZoneId(getTimeZone()));
propertiesUtil.transferProperties(mainDataset, jasperPrint,
JasperPrint.PROPERTIES_PRINT_TRANSFER_PREFIX);
/* jasperPrint.setDefaultStyle(defaultStyle);
if (styles != null && styles.length > 0)
{
for (int i = 0; i < styles.length; i++)
{
addPrintStyle(styles[i]);
}
}
*/
/* */
mainDataset.start();
/* */
fillReport();
if (bookmarkHelper != null)
{
jasperPrint.setBookmarks(bookmarkHelper.getRootBookmarks());
}
if (log.isDebugEnabled())
{
log.debug("Fill " + fillerId + ": ended");
}
success = true;
return jasperPrint;
}
finally
{
mainDataset.closeDatasource();
mainDataset.disposeParameterContributors();
if (success && parent == null)
{
// commit the cached data
fillContext.cacheDone();
}
/* if (parent != null)
{
parent.unregisterSubfiller(this);
}
*/
delayedActions.dispose();
fillingThread = null;
//kill the subreport filler threads
//killSubfillerThreads();
if (parent == null)
{
fillContext.dispose();
}
JRResourcesFillUtil.revertResourcesFillContext(resourcesContext);
}
}
private void createBoundElemementMaps()
{
createBoundElementMaps(JREvaluationTime.EVALUATION_TIME_MASTER);
}
@Override
protected void ignorePaginationSet(Map parameterValues)
{
//NOP
}
protected void fillReport() throws JRException
{
if (mainDataset.next())
{
startReport();
fillFirstGroupHeaders();
calculateDetail();
fillDetail();
while (mainDataset.next())
{
checkInterrupted();
estimateGroups();
fillChangedGroupFooters();
fillChangedGroupEvaluatedParts();
calculateGroups();
fillChangedGroupHeaders();
calculateDetail();
fillDetail();
}
fillLastGroupFooters();
fillLastGroupEvaluatedParts();
}
else
{
//no records
//might not be required, but it's safer to do it because it used to happen before mainDataset.next()
startReport();
}
fillReportEvaluatedParts();
assert partQueue.isCollapsed();
if (isMasterReport())
{
resolveMasterBoundElements();
}
}
protected void startReport() throws JRScriptletException, JRException
{
scriptlet.callBeforeReportInit();
calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT);
scriptlet.callAfterReportInit();
}
protected void calculateDetail() throws JRScriptletException, JRException
{
scriptlet.callBeforeDetailEval();
calculator.calculateVariables(true);
scriptlet.callAfterDetailEval();
}
protected void estimateGroups() throws JRException
{
calculator.estimateGroupRuptures();
}
protected void calculateGroups() throws JRException
{
scriptlet.callBeforeGroupInit();
calculator.initializeVariables(ResetTypeEnum.GROUP, IncrementTypeEnum.GROUP);
scriptlet.callAfterGroupInit();
}
protected void fillDetail() throws JRException
{
fillParts(detailParts, JRExpression.EVALUATION_DEFAULT);
}
protected void fillFirstGroupHeaders() throws JRException
{
for (GroupFillParts group : groupParts)
{
fillParts(group.getHeaderParts(), JRExpression.EVALUATION_DEFAULT);
}
}
protected void fillChangedGroupHeaders() throws JRException
{
for (GroupFillParts group : groupParts)
{
if (group.hasChanged())
{
fillParts(group.getHeaderParts(), JRExpression.EVALUATION_DEFAULT);
}
}
}
private void fillChangedGroupFooters() throws JRException
{
for (ListIterator iterator = groupParts.listIterator(groupParts.size()); iterator.hasPrevious();)
{
GroupFillParts group = iterator.previous();
if (group.hasChanged())
{
fillParts(group.getFooterParts(), JRExpression.EVALUATION_OLD);
}
}
}
private void fillLastGroupFooters() throws JRException
{
for (ListIterator iterator = groupParts.listIterator(groupParts.size()); iterator.hasPrevious();)
{
GroupFillParts group = iterator.previous();
fillParts(group.getFooterParts(), JRExpression.EVALUATION_DEFAULT);
}
}
protected void fillParts(FillParts parts, byte evaluation) throws JRException
{
for (FillPart part : parts.getParts())
{
checkInterrupted();
fillPart(part, evaluation);
}
}
protected void fillPart(FillPart part, byte evaluation) throws JRException
{
PartEvaluationTime evaluationTime = part.getEvaluationTime();
switch (evaluationTime.getEvaluationTimeType())
{
case NOW:
{
PartPrintOutput appendOutput = partQueue.tail().getOutput();
if (appendOutput != null)
{
// can write directly to the previous output
part.fill(evaluation, appendOutput);
}
else
{
// previous part is delayed, creating a new part with local output
FillPartPrintOutput localOutput = new FillPartPrintOutput(this);
part.fill(evaluation, localOutput);
// adding to the queue
partQueue.appendOutput(localOutput);
}
break;
}
case REPORT:
{
DelayedPrintPart delayedPart = partQueue.appendDelayed(part);
reportEvaluatedParts.add(delayedPart);
break;
}
case GROUP:
{
GroupFillParts groupFillParts = groupPartsByName.get(evaluationTime.getEvaluationGroup());
if (groupFillParts == null)//verified at compile time, checking twice nonetheless
{
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_EVALUATION_GROUP_NOT_FOUND,
new Object[]{evaluationTime.getEvaluationGroup()});
}
DelayedPrintPart delayedPart = partQueue.appendDelayed(part);
groupFillParts.addGroupEvaluatedPart(delayedPart);
break;
}
default:
throw
new JRRuntimeException(
EXCEPTION_MESSAGE_KEY_UNKNOWN_EVALUATION_TIME_TYPE,
new Object[]{evaluationTime.getEvaluationTimeType()});
}
}
@Override
public boolean isPageFinal(int pageIndex)
{
if (isSubreport())
{
// shouldn't be called
return false;
}
return ((JasperPrintPartOutput) partQueue.head().getOutput()).isPageFinal(pageIndex);
}
protected void partPageUpdated(int pageIndex)
{
if (fillListener != null)
{
fillListener.pageUpdated(jasperPrint, pageIndex);
}
}
protected void fillReportEvaluatedParts() throws JRException
{
fillDelayedEvaluatedParts(reportEvaluatedParts, JRExpression.EVALUATION_DEFAULT);
}
protected void fillChangedGroupEvaluatedParts() throws JRException
{
for (GroupFillParts group : groupParts)
{
if (group.hasChanged())
{
fillDelayedEvaluatedParts(group.getGroupEvaluatedParts(), JRExpression.EVALUATION_OLD);
}
}
}
protected void fillLastGroupEvaluatedParts() throws JRException
{
for (GroupFillParts group : groupParts)
{
fillDelayedEvaluatedParts(group.getGroupEvaluatedParts(), JRExpression.EVALUATION_DEFAULT);
}
}
protected void fillDelayedEvaluatedParts(List parts, byte evaluation) throws JRException
{
for (ListIterator it = parts.listIterator(); it.hasNext();)
{
DelayedPrintPart part = it.next();
it.remove();
fillDelayedPart(evaluation, part);
}
}
protected void fillDelayedPart(byte evaluation, DelayedPrintPart part) throws JRException
{
partQueue.fillDelayed(part, this, evaluation);
}
public BookmarkHelper getFirstBookmarkHelper()
{
for(FillPrintPart part = partQueue.head(); part != null; part = part.nextPart())
{
PartPrintOutput output = part.getOutput();
if (output != null)
{
BookmarkHelper bookmarks = output.getBookmarkHelper();
if (bookmarks.hasBookmarks())
{
return bookmarks;
}
}
}
return null;
}
protected class JasperPrintPartOutput implements PartPrintOutput
{
private final ReadWriteLock currentFillPartLock = new ReentrantReadWriteLock();
private transient int currentPartStartIndex;
private FillingPrintPart currentFillingPart;
@Override
public void startPart(PrintPart part, FillingPrintPart fillingPart)
{
int startIndex = jasperPrint.getPages().size();
jasperPrint.addPart(startIndex, part);
currentFillPartLock.writeLock().lock();
try
{
currentPartStartIndex = startIndex;
currentFillingPart = fillingPart;
}
finally
{
currentFillPartLock.writeLock().unlock();
}
if (log.isDebugEnabled())
{
log.debug("added part " + part.getName() + " at index " + startIndex);
}
}
public boolean isPageFinal(int pageIndex)
{
currentFillPartLock.readLock().lock();
try
{
JRPrintPage page = getPage(pageIndex);
boolean hasMasterActions = delayedActions.hasDelayedActions(page);
if (hasMasterActions)
{
return false;
}
boolean isFinal;
if (pageIndex < currentPartStartIndex)
{
isFinal = true;
}
else
{
isFinal = currentFillingPart.isPageFinal(page);
}
return isFinal;
}
finally
{
currentFillPartLock.readLock().unlock();
}
}
@Override
public void addPage(JRPrintPage page, DelayedFillActions delayedActionsSource)
{
int pageIndex = jasperPrint.getPages().size();
if (log.isDebugEnabled())
{
log.debug("adding part page at index " + pageIndex);
}
jasperPrint.addPage(page);
addLastPageBookmarks();
delayedActions.moveMasterEvaluations(delayedActionsSource, page, pageIndex);
if (fillListener != null)
{
fillListener.pageGenerated(jasperPrint, pageIndex);
}
}
@Override
public JRPrintPage getPage(int pageIndex)
{
return jasperPrint.getPages().get(pageIndex);
}
@Override
public void pageUpdated(int partPageIndex)
{
partPageUpdated(currentPartStartIndex + partPageIndex);
}
@Override
public void append(FillPartPrintOutput output)
{
addStyles(output.getStyles());
addOrigins(output.getOrigins());
int pageOffset = jasperPrint.getPages().size();
BookmarkHelper outputBookmarks = output.getBookmarkHelper();
BookmarkIterator bookmarkIterator = null;
if (bookmarkHelper != null && outputBookmarks != null)
{
bookmarkIterator = outputBookmarks.bookmarkIterator();
}
DelayedFillActions sourceActions = output.getDelayedActions();
// adding in an organic order: for each part the pages that belong to the part,
// and for each page the bookmarks that belong to the page
ListIterator pagesIterator = output.getPages().listIterator();
int prevPartStart = 0;
for (Map.Entry partEntry : output.getParts().entrySet())
{
int partStart = partEntry.getKey();
// add the pages that belong to the previous part
for (int i = prevPartStart; i < partStart; i++)
{
JRPrintPage page = pagesIterator.next();
addPage(page, pageOffset, sourceActions, bookmarkIterator);
}
prevPartStart = partStart;
PrintPart part = partEntry.getValue();
startPart(part, FinalFillingPrintPart.instance());
}
// add the pages that belong to the last part
while (pagesIterator.hasNext())
{
JRPrintPage page = pagesIterator.next();
addPage(page, pageOffset, sourceActions, bookmarkIterator);
}
}
protected void addPage(JRPrintPage page, int pageOffset,
DelayedFillActions sourceActions, BookmarkIterator sourceBookmarkIterator)
{
int pageIndex = jasperPrint.getPages().size();
if (log.isDebugEnabled())
{
log.debug("adding part page at index " + pageIndex);
}
jasperPrint.addPage(page);
if (sourceBookmarkIterator != null)
{
int sourcePageIndex = pageIndex - pageOffset;
while (sourceBookmarkIterator.hasBookmark()
&& sourceBookmarkIterator.bookmark().getPageIndex() == sourcePageIndex)
{
bookmarkHelper.addBookmark(sourceBookmarkIterator.bookmark(), pageOffset);
sourceBookmarkIterator.next();
}
}
delayedActions.moveMasterEvaluations(sourceActions, page, pageIndex);
if (fillListener != null)
{
fillListener.pageGenerated(jasperPrint, pageIndex);
}
}
@Override
public BookmarkHelper getBookmarkHelper()
{
return bookmarkHelper;
}
@Override
public void addStyles(Collection stylesList)
{
for (JRStyle style : stylesList)
{
try
{
jasperPrint.addStyle(style, true);
}
catch (JRException e)
{
// should not happen
throw new JRRuntimeException(e);
}
}
}
@Override
public void addOrigins(Collection origins)
{
for (JROrigin origin : origins)
{
jasperPrint.addOrigin(origin);
}
}
}
}