net.sf.jasperreports.components.map.imageprovider.ChromeMapElementImageProvider Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jasperreports Show documentation
Show all versions of jasperreports Show documentation
Free Java Reporting Library
/*
* 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.components.map.imageprovider;
import net.sf.jasperreports.chrome.BrowserService;
import net.sf.jasperreports.chrome.Chrome;
import net.sf.jasperreports.chrome.ResourceManager;
import net.sf.jasperreports.components.map.MapComponent;
import net.sf.jasperreports.components.map.MapUtils;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRGenericPrintElement;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JasperReportsContext;
import net.sf.jasperreports.engine.type.ModeEnum;
import net.sf.jasperreports.engine.type.OnErrorTypeEnum;
import net.sf.jasperreports.engine.util.JRColorUtil;
import net.sf.jasperreports.renderers.Renderable;
import net.sf.jasperreports.renderers.SimpleDataRenderer;
import net.sf.jasperreports.renderers.util.RendererUtil;
import net.sf.jasperreports.web.util.VelocityUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
/**
* @author Narcis Marcu ([email protected])
*/
public class ChromeMapElementImageProvider extends AbstractMapElementImageProvider {
private static final Log log = LogFactory.getLog(ChromeMapElementImageProvider.class);
private static final String PAGE_TEMPLATE_RESOURCE = "net/sf/jasperreports/components/map/resources/templates/ChromeMapPage.vm";
private Boolean isEnabled = null;
public boolean isEnabled(JasperReportsContext jasperReportsContext) {
if (isEnabled == null) {
Chrome chrome = Chrome.instance(jasperReportsContext);
isEnabled = chrome.isEnabled();
}
return isEnabled;
}
@Override
protected Renderable createRenderable(JasperReportsContext jasperReportsContext, JRGenericPrintElement element) throws JRException {
Renderable cachedRenderable = (Renderable) element.getParameterValue(MapComponent.PARAMETER_CACHE_RENDERER);
if (cachedRenderable == null) {
try {
byte[] imageData = getImageData(jasperReportsContext, element);
cachedRenderable = new SimpleDataRenderer(imageData, null);
} catch (Exception e) {
if (log.isErrorEnabled()) {
log.error("Generating Chrome image for Map element failed!", e);
}
OnErrorTypeEnum onErrorType =
element.getParameterValue(MapComponent.PARAMETER_ON_ERROR_TYPE) == null
? MapComponent.DEFAULT_ON_ERROR_TYPE
: OnErrorTypeEnum.getByName((String)element.getParameterValue(MapComponent.PARAMETER_ON_ERROR_TYPE));
cachedRenderable = RendererUtil.getInstance(jasperReportsContext).handleImageError(e, onErrorType);
}
element.setParameterValue(MapComponent.PARAMETER_CACHE_RENDERER, cachedRenderable);
}
return cachedRenderable;
}
public byte[] getImageData(JasperReportsContext jasperReportsContext, JRGenericPrintElement element) throws JRException {
ResourceManager resourceManager = ResourceManager.instance();
File tempFolder = resourceManager.getTempFolder(jasperReportsContext);
File mapPageTempFile = null;
try {
mapPageTempFile = File.createTempFile("map_", ".html", tempFolder);
String mapPage = getMapHtmlPage(jasperReportsContext, element);
try (Writer writer = new OutputStreamWriter(new FileOutputStream(mapPageTempFile), StandardCharsets.UTF_8)) {
writer.write(mapPage);
}
Chrome chrome = Chrome.instance(jasperReportsContext);
BrowserService service = chrome.getService();
byte[] data = service.evaluateInPage(mapPageTempFile.toURI().toString(), null , page -> {
Object resultValue = page.evaluatePromise("renderResult()");
if (log.isTraceEnabled()) {
log.trace("Got result from evaluating map page promise: " + resultValue);
}
byte[] imageData = null;
if (resultValue != null) {
@SuppressWarnings("unchecked")
Map resultMap = (Map) resultValue;
int width = (int) resultMap.get("width");
int height = (int) resultMap.get("height");
float zoomFactor = 1.0f;
imageData = page.captureScreenshot(width, height, zoomFactor);
}
return imageData;
});
return data;
} catch (IOException e) {
throw new JRRuntimeException("Failed to create map page in temp folder " + tempFolder, e);
} finally {
if (mapPageTempFile != null) {
boolean deleted = mapPageTempFile.delete();
if (!deleted) {
if (log.isWarnEnabled()) {
log.warn("Failed to delete map temp page " + mapPageTempFile);
}
}
}
}
}
public String getMapHtmlPage(JasperReportsContext jasperReportsContext, JRGenericPrintElement element) {
Map velocityContext = new HashMap<>();
velocityContext.put("elementWidth", element.getWidth());
velocityContext.put("elementHeight", element.getHeight());
if (element.getModeValue() == ModeEnum.OPAQUE) {
velocityContext.put("backgroundColor", JRColorUtil.getColorHexa(element.getBackcolor()));
}
velocityContext.put("jasperreportsMapApiScript", VelocityUtil.processTemplate(MapUtils.MAP_API_SCRIPT, (VelocityContext) null));
MapUtils.prepareContextForVelocityTemplate(velocityContext, jasperReportsContext, element);
return VelocityUtil.processTemplate(PAGE_TEMPLATE_RESOURCE, velocityContext);
}
}