net.sf.jasperreports.engine.fill.ThreadPoolSubreportRunnerFactory 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.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Lucian Chirita ([email protected])
*/
public class ThreadPoolSubreportRunnerFactory implements JRSubreportRunnerFactory
{
private static final Log log = LogFactory.getLog(ThreadPoolSubreportRunnerFactory.class);
private static final String THREAD_POOL_KEY = "net.sf.jasperreports.engine.fill.JRThreadSubreportRunner.ThreadPool";
@Override
public JRSubreportRunner createSubreportRunner(JRFillSubreport fillSubreport, JRBaseFiller subreportFiller)
{
JRFillContext fillContext = subreportFiller.getFillContext();
ExecutorServiceDisposable executor = (ExecutorServiceDisposable) fillContext.getFillCache(THREAD_POOL_KEY);
if (executor == null)
{
ExecutorService threadExecutor = createThreadExecutor(fillContext);
executor = new ExecutorServiceDisposable(threadExecutor);
fillContext.setFillCache(THREAD_POOL_KEY, executor);
}
return new ThreadExecutorSubreportRunner(fillSubreport, subreportFiller,
executor.getExecutorService());
}
protected ExecutorService createThreadExecutor(JRFillContext fillContext)
{
SubreportsThreadFactory threadFactory = new SubreportsThreadFactory(fillContext);
ExecutorService threadExecutor = Executors.newCachedThreadPool(threadFactory);
if (log.isDebugEnabled())
{
log.debug("created subreports thread executor " + threadExecutor
+ " for " + fillContext.getMasterFiller().getJasperReport().getName());
}
return threadExecutor;
}
protected static class ExecutorServiceDisposable implements JRFillContext.FillCacheDisposable
{
private final ExecutorService executorService;
public ExecutorServiceDisposable(ExecutorService executorService)
{
this.executorService = executorService;
}
public ExecutorService getExecutorService()
{
return executorService;
}
@Override
public void dispose()
{
if (log.isDebugEnabled())
{
log.debug("shutting down " + executorService);
}
executorService.shutdownNow();
}
}
protected static class SubreportsThreadFactory implements ThreadFactory
{
private final JRFillContext fillContext;
private final AtomicInteger threadCount;
public SubreportsThreadFactory(JRFillContext fillContext)
{
this.fillContext = fillContext;
this.threadCount = new AtomicInteger();
}
@Override
public Thread newThread(Runnable r)
{
String threadName = fillContext.getMasterFiller().getJasperReport().getName()
+ " subreports #" + threadCount.incrementAndGet();
Thread thread = new Thread(r, threadName);
if (log.isDebugEnabled())
{
log.debug("created thread " + thread);
}
return thread;
}
}
}