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

net.sf.jasperreports.engine.util.JRLoader 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.engine.util;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

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

import net.sf.jasperreports.engine.DefaultJasperReportsContext;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRPropertiesUtil;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRVirtualizationHelper;
import net.sf.jasperreports.engine.JRVirtualizer;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReportsContext;


/**
 * Utility class that helps load serialized objects found in various locations 
 * such as files, URLs, and input streams.
 * 

* Many JasperReports processes, like report compilation, report filling and exporting, * often work with serialized objects. Sometimes it is useful to manually load those * serialized objects before submitting them to the desired JasperReport process. *

* The most interesting method exposed by this class is * {@link #getLocationInputStream(String) getLocationInputStream(String location)}. * When calling this method to load an InputStream object from * the supplied location, the program first tries to interpret the location as a valid resource name. If * this fails, then the program assumes that the supplied location is the name of a file on * disk and tries to read from it. If no file is found at that location, it will assume that the location * represents a valid URL. Only after this third * try fails an exception is thrown. *

* @author Teodor Danciu ([email protected]) */ public final class JRLoader { private static final Log log = LogFactory.getLog(JRLoader.class); public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_FROM_INPUT_STREAM_ERROR = "util.loader.byte.data.from.input.stream.error"; public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR = "util.loader.byte.data.loading.error"; public static final String EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_FILE = "util.loader.class.not.found.from.file"; public static final String EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_INPUT_STREAM = "util.loader.class.not.found.from.input.stream"; public static final String EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_URL = "util.loader.class.not.found.from.url"; public static final String EXCEPTION_MESSAGE_KEY_FILE_OPEN_ERROR = "util.loader.file.open.error"; public static final String EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_FILE_OPEN_ERROR = "util.loader.input.stream.from.file.open.error"; public static final String EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_URL_OPEN_ERROR = "util.loader.input.stream.from.url.open.error"; public static final String EXCEPTION_MESSAGE_KEY_OBJECT_FROM_FILE_LOADING_ERROR = "util.loader.object.from.file.loading.error"; public static final String EXCEPTION_MESSAGE_KEY_OBJECT_FROM_INPUT_STREAM_LOADING_ERROR = "util.loader.object.from.input.stream.loading.error"; public static final String EXCEPTION_MESSAGE_KEY_OBJECT_FROM_URL_LOADING_ERROR = "util.loader.object.from.url.loading.error"; public static final String EXCEPTION_MESSAGE_KEY_RESOURCE_NOT_FOUND = "util.loader.resource.not.found"; public static final String EXCEPTION_MESSAGE_KEY_URL_OPEN_ERROR = "util.loader.url.open.error"; /** * */ //private static boolean wasWarning; /** * */ public static Object loadObjectFromFile(String fileName) throws JRException { return loadObject(new File(fileName)); } /** * */ public static Object loadObject(File file) throws JRException { return loadObject(DefaultJasperReportsContext.getInstance(), file); } /** * */ public static Object loadObject(JasperReportsContext jasperReportsContext, File file) throws JRException { if (!file.exists() || !file.isFile()) { throw new JRException( new FileNotFoundException(String.valueOf(file)) ); } Object obj = null; try ( InputStream is = new BufferedInputStream(new FileInputStream(file)); ObjectInputStream ois = new ContextClassLoaderObjectInputStream(jasperReportsContext, is) ) { obj = ois.readObject(); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_OBJECT_FROM_FILE_LOADING_ERROR, new Object[]{file}, e); } catch (ClassNotFoundException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_FILE, new Object[]{file}, e); } return obj; } /** * */ public static Object loadObject(URL url) throws JRException { return loadObject(DefaultJasperReportsContext.getInstance(), url); } /** * */ public static Object loadObject(JasperReportsContext jasperReportsContext, URL url) throws JRException { Object obj = null; try ( InputStream is = url.openStream(); ObjectInputStream ois = new ContextClassLoaderObjectInputStream(jasperReportsContext, is) ) { obj = ois.readObject(); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_OBJECT_FROM_URL_LOADING_ERROR, new Object[]{url}, e); } catch (ClassNotFoundException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_URL, new Object[]{url}, e); } return obj; } /** * */ public static Object loadObject(InputStream is) throws JRException { return loadObject(DefaultJasperReportsContext.getInstance(), is); } /** * */ public static Object loadObject(JasperReportsContext jasperReportsContext, InputStream is) throws JRException { Object obj = null; ObjectInputStream ois = null; try { ois = new ContextClassLoaderObjectInputStream(jasperReportsContext, is); obj = ois.readObject(); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_OBJECT_FROM_INPUT_STREAM_LOADING_ERROR, null, e); } catch (ClassNotFoundException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_INPUT_STREAM, null, e); } return obj; } /** * */ public static InputStream getInputStream(File file) throws JRException { if (!file.exists() || !file.isFile()) { throw new JRException( new FileNotFoundException(String.valueOf(file)) );//FIXMEREPO this probably useless } FileInputStream fis = null; try { fis = new FileInputStream(file); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_FILE_OPEN_ERROR, new Object[]{file}, e); } return fis; } /** * */ public static InputStream getInputStream(URL url) throws JRException { InputStream is = null; try { is = url.openStream(); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_URL_OPEN_ERROR, new Object[]{url}, e); } return is; } /** * */ public static byte[] loadBytes(File file) throws JRException { try { return Files.readAllBytes(file.toPath()); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR, new Object[]{file}, e); } } /** * */ public static byte[] loadBytes(URL url) throws JRException { try (InputStream is = url.openStream()) { return readBytes(is); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR, new Object[]{url}, e); } } /** * */ public static byte[] loadBytes(InputStream is) throws JRException { try { return readBytes(is); } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_BYTE_DATA_FROM_INPUT_STREAM_ERROR, null, e); } } /** * */ public static byte[] readBytes(InputStream is) throws IOException { try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { byte[] bytes = new byte[10000]; int ln = 0; while ((ln = is.read(bytes)) > 0) { baos.write(bytes, 0, ln); } baos.flush(); return baos.toByteArray(); } } /** * */ public static byte[] loadBytesFromResource(String resourceName) throws JRException { return loadBytesFromResource(resourceName, null); } /** * */ public static byte[] loadBytesFromResource(String resourceName, ClassLoader classLoader) throws JRException { URL url = JRResourcesUtil.findClassLoaderResource(resourceName, classLoader); if (url != null) { return loadBytes(url); } throw new JRException( EXCEPTION_MESSAGE_KEY_RESOURCE_NOT_FOUND, new Object[]{resourceName}); } /** * Tries to open an input stream for a location. *

* The method tries to interpret the location as a file name, a resource name or * an URL. If any of these succeed, an input stream is created and returned. * * @param location the location * @return an input stream if the location is an existing file name, a resource name on * the classpath or an URL or null otherwise. * * @throws JRException */ public static InputStream getLocationInputStream(String location) throws JRException//FIXME deprecate this? { InputStream is = null; is = getResourceInputStream(location); if (is == null) { is = getFileInputStream(location); } if (is == null) { is = getURLInputStream(location); } return is; } /** * Tries to open a file for reading. * * @param filename the file name * @return an input stream for the file or null if the file was not found * @throws JRException */ public static InputStream getFileInputStream(String filename) throws JRException { InputStream is = null; File file = new File(filename); if (file.exists() && file.isFile()) { try { is = new FileInputStream(file); } catch (FileNotFoundException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_FILE_OPEN_ERROR, new Object[]{filename}, e); } } return is; } /** * Tries to open an input stream for a resource. * * @param resource the resource name * @return an input stream for the resource or null if the resource was not found */ public static InputStream getResourceInputStream(String resource) { InputStream is = null; ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader != null) { is = classLoader.getResourceAsStream(resource); } if (is == null) { classLoader = JRLoader.class.getClassLoader(); if (classLoader != null) { is = classLoader.getResourceAsStream(resource); } if (is == null) { is = JRPropertiesUtil.class.getResourceAsStream("/" + resource); } } return is; } /** * Scans the context classloader and the classloader of this class for all * resources that have a specified name, and returns a list of * {@link URL}s for the found resources. * * @param resource the resource names * @return a list of {@link URL}s of resources with the specified name; * the list is empty if no resources have been found for the name * @see ClassLoader#getResources(String) */ public static List getResources(String resource) { //skip duplicated resources Set resources = new LinkedHashSet<>(); collectResources(resource, JRLoader.class.getClassLoader(), resources); collectResources(resource, Thread.currentThread().getContextClassLoader(), resources); return new ArrayList<>(resources); } protected static void collectResources(String resourceName, ClassLoader classLoader, Set resources) { if (classLoader != null) { try { Enumeration urls = classLoader.getResources(resourceName); if (urls != null) { while (urls.hasMoreElements()) // class loaders should never return null on getResources, according to specs, but we've seen cases, so we protect our code here { URL url = urls.nextElement(); resources.add(url); } } } catch (IOException e) { throw new JRRuntimeException(e); } } } /** * Scans the context classloader and the classloader of this class for all * resources that have a specified name, and returns a list of * {@link ClassLoaderResource} objects for the found resources. * *

* The returned list contains the URLs of the resources, and for each resource * the highest classloader in the classloader hierarchy on which the resource * was found. *

* * @param resource the resource names * @return a list of resources with the specified name; * the list is empty if no resources have been found for the name * @see ClassLoader#getResources(String) */ public static List getClassLoaderResources( String resource) { Map resources = new LinkedHashMap<>(); collectResources(resource, JRLoader.class.getClassLoader(), resources); //TODO check if the classloader is the same collectResources(resource, Thread.currentThread() .getContextClassLoader(), resources); return new ArrayList<>(resources.values()); } protected static void collectResources(String resourceName, ClassLoader classLoader, Map resources) { if (classLoader == null) { return; } try { // creating a list of parent classloaders, with the highest in the // hierarchy first LinkedList classloaders = new LinkedList<>(); ClassLoader ancestorLoader = classLoader; while (ancestorLoader != null) { classloaders.addFirst(ancestorLoader); try { ancestorLoader = ancestorLoader.getParent(); } catch (SecurityException e) { // if we're not allowed to get the parent, stop here. // resources will be listed with the first classloader that // we're allowed to access. // one case when this happens is applets. // FIXME revisit logging on SecurityException for applet ancestorLoader = null; } } for (ClassLoader ancestor : classloaders) { Enumeration urls = ancestor.getResources(resourceName); if (urls != null) // class loaders should never return null on getResources, according to specs, but we've seen cases, so we protect our code here { while (urls.hasMoreElements()) { URL url = urls.nextElement(); // if this is the first time we see this resource, add it // with the current classloader. // this way a resource will be added with the most first // ancestor classloader that has it. if (!resources.containsKey(url)) { if (log.isDebugEnabled()) { log.debug("Found resource " + resourceName + " at "+ url + " in classloader " + ancestor); } ClassLoaderResource resource = new ClassLoaderResource( url, ancestor); resources.put(url, resource); } } } } } catch (IOException e) { throw new JRRuntimeException(e); } } /** * Returns the resource URL for a specified resource name. * * @param resource the resource name * @return the URL of the resource having the specified name, or * null if none found * @see ClassLoader#getResource(String) */ public static URL getResource(String resource) { URL location = null; ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader != null) { location = classLoader.getResource(resource); } if (location == null) { classLoader = JRLoader.class.getClassLoader(); if (classLoader != null) { location = classLoader.getResource(resource); } if (location == null) { location = JRPropertiesUtil.class.getResource("/" + resource); } } return location; } /** * Tries to open an input stream for an URL. * * @param spec the string to parse as an URL * @return an input stream for the URL or null if spec is not a valid URL * @throws JRException */ public static InputStream getURLInputStream(String spec) throws JRException { InputStream is = null; try { URL url = new URL(spec); is = url.openStream(); } catch (MalformedURLException e) { } catch (IOException e) { throw new JRException( EXCEPTION_MESSAGE_KEY_URL_OPEN_ERROR, new Object[]{spec}, e); } return is; } /** * Loads a JasperPrint object from a file, optionally using a virtualizer for * the object. * * @param fileName the file name * @param virtualizer the virtualizer * @return a JasperPrint object * @throws JRException * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer) */ public static JasperPrint loadJasperPrintFromFile(String fileName, JRVirtualizer virtualizer) throws JRException { if (virtualizer != null) { JRVirtualizationHelper.setThreadVirtualizer(virtualizer); } try { return (JasperPrint) loadObjectFromFile(fileName); } finally { if (virtualizer != null) { JRVirtualizationHelper.clearThreadVirtualizer(); } } } /** * Loads a JasperPrint object from a file, optionally using a virtualizer for * the object. * * @param file the file * @param virtualizer the virtualizer * @return a JasperPrint object * @throws JRException * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer) */ public static JasperPrint loadJasperPrint(File file, JRVirtualizer virtualizer) throws JRException { if (virtualizer != null) { JRVirtualizationHelper.setThreadVirtualizer(virtualizer); } try { return (JasperPrint) loadObject(file); } finally { if (virtualizer != null) { JRVirtualizationHelper.clearThreadVirtualizer(); } } } /** * Loads a JasperPrint object from a URL, optionally using a virtualizer for * the object. * * @param url the URL * @param virtualizer the virtualizer * @return a JasperPrint object * @throws JRException * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer) */ public static JasperPrint loadJasperPrint(URL url, JRVirtualizer virtualizer) throws JRException { if (virtualizer != null) { JRVirtualizationHelper.setThreadVirtualizer(virtualizer); } try { return (JasperPrint) loadObject(url); } finally { if (virtualizer != null) { JRVirtualizationHelper.clearThreadVirtualizer(); } } } /** * Loads a JasperPrint object from a stream, optionally using a virtualizer for * the object. * * @param is the stream * @param virtualizer the virtualizer * @return a JasperPrint object * @throws JRException * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer) */ public static JasperPrint loadJasperPrint(InputStream is, JRVirtualizer virtualizer) throws JRException { if (virtualizer != null) { JRVirtualizationHelper.setThreadVirtualizer(virtualizer); } try { return (JasperPrint) loadObject(is); } finally { if (virtualizer != null) { JRVirtualizationHelper.clearThreadVirtualizer(); } } } private JRLoader() { } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy