net.sf.jasperreports.components.map.imageprovider.ChromeMapElementImageProvider 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.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);
}
}