1 /*
2  * JasperReports - Free Java Reporting Library.
3  * Copyright (C) 2001 - 2019 TIBCO Software Inc. All rights reserved.
4  * http://www.jaspersoft.com
5  *
6  * Unless you have purchased a commercial license agreement from Jaspersoft,
7  * the following license terms apply:
8  *
9  * This program is part of JasperReports.
10  *
11  * JasperReports is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * JasperReports is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Lesser General Public License for more details.
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * along with JasperReports. If not, see <http://www.gnu.org/licenses/>.
23  */

24 package net.sf.jasperreports.engine.util;
25
26 import java.io.BufferedInputStream;
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.File;
30 import java.io.FileInputStream;
31 import java.io.FileNotFoundException;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.ObjectInputStream;
35 import java.net.MalformedURLException;
36 import java.net.URL;
37 import java.util.ArrayList;
38 import java.util.Enumeration;
39 import java.util.LinkedHashMap;
40 import java.util.LinkedHashSet;
41 import java.util.LinkedList;
42 import java.util.List;
43 import java.util.Map;
44 import java.util.Set;
45
46 import net.sf.jasperreports.engine.DefaultJasperReportsContext;
47 import net.sf.jasperreports.engine.JRException;
48 import net.sf.jasperreports.engine.JRPropertiesUtil;
49 import net.sf.jasperreports.engine.JRRuntimeException;
50 import net.sf.jasperreports.engine.JRVirtualizationHelper;
51 import net.sf.jasperreports.engine.JRVirtualizer;
52 import net.sf.jasperreports.engine.JasperPrint;
53 import net.sf.jasperreports.engine.JasperReportsContext;
54
55 import org.apache.commons.logging.Log;
56 import org.apache.commons.logging.LogFactory;
57
58
59 /**
60  * Utility class that helps load serialized objects found in various locations 
61  * such as files, URLs, and input streams.
62  * <p>
63  * Many JasperReports processes, like report compilation, report filling and exporting,
64  * often work with serialized objects. Sometimes it is useful to manually load those
65  * serialized objects before submitting them to the desired JasperReport process.
66  * </p><p>
67  * The most interesting method exposed by this class is
68  * {@link #getLocationInputStream(String) getLocationInputStream(String location)}. 
69  * When calling this method to load an InputStream object from
70  * the supplied location, the program first tries to interpret the location as a valid resource name. If
71  * this fails, then the program assumes that the supplied location is the name of a file on
72  * disk and tries to read from it. If no file is found at that location, it will assume that the location 
73  * represents a valid URL. Only after this third
74  * try fails an exception is thrown.
75  * </p>
76  * @author Teodor Danciu (teodord@users.sourceforge.net)
77  */

78 public final class JRLoader
79 {
80
81     private static final Log log = LogFactory.getLog(JRLoader.class);
82     public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_FROM_INPUT_STREAM_ERROR = "util.loader.byte.data.from.input.stream.error";
83     public static final String EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR = "util.loader.byte.data.loading.error";
84     public static final String EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_FILE = "util.loader.class.not.found.from.file";
85     public static final String EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_INPUT_STREAM = "util.loader.class.not.found.from.input.stream";
86     public static final String EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_URL = "util.loader.class.not.found.from.url";
87     public static final String EXCEPTION_MESSAGE_KEY_FILE_OPEN_ERROR = "util.loader.file.open.error";
88     public static final String EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_FILE_OPEN_ERROR = "util.loader.input.stream.from.file.open.error";
89     public static final String EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_URL_OPEN_ERROR = "util.loader.input.stream.from.url.open.error";
90     public static final String EXCEPTION_MESSAGE_KEY_OBJECT_FROM_FILE_LOADING_ERROR = "util.loader.object.from.file.loading.error";
91     public static final String EXCEPTION_MESSAGE_KEY_OBJECT_FROM_INPUT_STREAM_LOADING_ERROR = "util.loader.object.from.input.stream.loading.error";
92     public static final String EXCEPTION_MESSAGE_KEY_OBJECT_FROM_URL_LOADING_ERROR = "util.loader.object.from.url.loading.error";
93     public static final String EXCEPTION_MESSAGE_KEY_RESOURCE_NOT_FOUND = "util.loader.resource.not.found";
94     public static final String EXCEPTION_MESSAGE_KEY_URL_OPEN_ERROR = "util.loader.url.open.error";
95
96     /**
97      *
98      */

99     //private static boolean wasWarning;
100
101
102     /**
103      *
104      */

105     public static Object loadObjectFromFile(String fileName) throws JRException
106     {
107         return loadObject(new File(fileName));
108     }
109
110
111     /**
112      *
113      */

114     public static Object loadObject(File file) throws JRException
115     {
116         return loadObject(DefaultJasperReportsContext.getInstance(), file);
117     }
118
119
120     /**
121      *
122      */

123     public static Object loadObject(JasperReportsContext jasperReportsContext, File file) throws JRException
124     {
125         if (!file.exists() || !file.isFile())
126         {
127             throw new JRException( new FileNotFoundException(String.valueOf(file)) );
128         }
129
130         Object obj = null;
131
132         FileInputStream fis = null;
133         ObjectInputStream ois = null;
134
135         try
136         {
137             fis = new FileInputStream(file);
138             BufferedInputStream bufferedIn = new BufferedInputStream(fis);
139             ois = new ContextClassLoaderObjectInputStream(jasperReportsContext, bufferedIn);
140             obj = ois.readObject();
141         }
142         catch (IOException e)
143         {
144             throw 
145                 new JRException(
146                     EXCEPTION_MESSAGE_KEY_OBJECT_FROM_FILE_LOADING_ERROR,
147                     new Object[]{file},
148                     e);
149         }
150         catch (ClassNotFoundException e)
151         {
152             throw 
153                 new JRException(
154                     EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_FILE,
155                     new Object[]{file},
156                     e);
157         }
158         finally
159         {
160             if (ois != null)
161             {
162                 try
163                 {
164                     ois.close();
165                 }
166                 catch(IOException e)
167                 {
168                 }
169             }
170
171             if (fis != null)
172             {
173                 try
174                 {
175                     fis.close();
176                 }
177                 catch(IOException e)
178                 {
179                 }
180             }
181         }
182
183         return obj;
184     }
185
186
187     /**
188      *
189      */

190     public static Object loadObject(URL url) throws JRException
191     {
192         return loadObject(DefaultJasperReportsContext.getInstance(), url);
193     }
194
195
196     /**
197      *
198      */

199     public static Object loadObject(JasperReportsContext jasperReportsContext, URL url) throws JRException
200     {
201         Object obj = null;
202
203         InputStream is = null;
204         ObjectInputStream ois = null;
205
206         try
207         {
208             is = url.openStream();
209             ois = new ContextClassLoaderObjectInputStream(jasperReportsContext, is);
210             obj = ois.readObject();
211         }
212         catch (IOException e)
213         {
214             throw 
215                 new JRException(
216                     EXCEPTION_MESSAGE_KEY_OBJECT_FROM_URL_LOADING_ERROR,
217                     new Object[]{url},
218                     e);
219         }
220         catch (ClassNotFoundException e)
221         {
222             throw 
223                 new JRException(
224                     EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_URL,
225                     new Object[]{url},
226                     e);
227         }
228         finally
229         {
230             if (ois != null)
231             {
232                 try
233                 {
234                     ois.close();
235                 }
236                 catch(IOException e)
237                 {
238                 }
239             }
240
241             if (is != null)
242             {
243                 try
244                 {
245                     is.close();
246                 }
247                 catch(IOException e)
248                 {
249                 }
250             }
251         }
252
253         return obj;
254     }
255
256
257     /**
258      *
259      */

260     public static Object loadObject(InputStream is) throws JRException
261     {
262         return loadObject(DefaultJasperReportsContext.getInstance(), is);
263     }
264
265
266     /**
267      *
268      */

269     public static Object loadObject(JasperReportsContext jasperReportsContext, InputStream is) throws JRException
270     {
271         Object obj = null;
272
273         ObjectInputStream ois = null;
274
275         try
276         {
277             ois = new ContextClassLoaderObjectInputStream(jasperReportsContext, is);
278             obj = ois.readObject();
279         }
280         catch (IOException e)
281         {
282             throw 
283                 new JRException(
284                     EXCEPTION_MESSAGE_KEY_OBJECT_FROM_INPUT_STREAM_LOADING_ERROR,
285                     null,
286                     e);
287         }
288         catch (ClassNotFoundException e)
289         {
290             throw 
291                 new JRException(
292                     EXCEPTION_MESSAGE_KEY_CLASS_NOT_FOUND_FROM_INPUT_STREAM,
293                     null,
294                     e);
295         }
296
297         return obj;
298     }
299
300
301     /**
302      *
303      */

304     public static InputStream getInputStream(File file) throws JRException
305     {
306         if (!file.exists() || !file.isFile())
307         {
308             throw new JRException( new FileNotFoundException(String.valueOf(file)) );//FIXMEREPO this probably useless
309         }
310
311         FileInputStream fis = null;
312
313         try
314         {
315             fis = new FileInputStream(file);
316         }
317         catch (IOException e)
318         {
319             throw 
320                 new JRException(
321                     EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_FILE_OPEN_ERROR,
322                     new Object[]{file},
323                     e);
324         }
325
326         return fis;
327     }
328
329
330     /**
331      *
332      */

333     public static InputStream getInputStream(URL url) throws JRException
334     {
335         InputStream is = null;
336
337         try
338         {
339             is = url.openStream();
340         }
341         catch (IOException e)
342         {
343             throw 
344                 new JRException(
345                     EXCEPTION_MESSAGE_KEY_INPUT_STREAM_FROM_URL_OPEN_ERROR,
346                     new Object[]{url},
347                     e);
348         }
349
350         return is;
351     }
352
353
354     /**
355      *
356      */

357     public static byte[] loadBytes(File file) throws JRException
358     {
359         ByteArrayOutputStream baos = null;
360         FileInputStream fis = null;
361
362         try
363         {
364             fis = new FileInputStream(file);
365             baos = new ByteArrayOutputStream();
366
367             byte[] bytes = new byte[10000];
368             int ln = 0;
369             while ((ln = fis.read(bytes)) > 0)
370             {
371                 baos.write(bytes, 0, ln);
372             }
373
374             baos.flush();
375         }
376         catch (IOException e)
377         {
378             throw 
379                 new JRException(
380                     EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR,
381                     new Object[]{file},
382                     e);
383         }
384         finally
385         {
386             if (baos != null)
387             {
388                 try
389                 {
390                     baos.close();
391                 }
392                 catch(IOException e)
393                 {
394                 }
395             }
396
397             if (fis != null)
398             {
399                 try
400                 {
401                     fis.close();
402                 }
403                 catch(IOException e)
404                 {
405                 }
406             }
407         }
408
409         return baos.toByteArray();
410     }
411
412
413     /**
414      *
415      */

416     public static byte[] loadBytes(URL url) throws JRException
417     {
418         ByteArrayOutputStream baos = null;
419         InputStream is = null;
420
421         try
422         {
423             is = url.openStream();
424             baos = new ByteArrayOutputStream();
425
426             byte[] bytes = new byte[10000];
427             int ln = 0;
428             while ((ln = is.read(bytes)) > 0)
429             {
430                 baos.write(bytes, 0, ln);
431             }
432
433             baos.flush();
434         }
435         catch (IOException e)
436         {
437             throw 
438                 new JRException(
439                     EXCEPTION_MESSAGE_KEY_BYTE_DATA_LOADING_ERROR,
440                     new Object[]{url},
441                     e);
442         }
443         finally
444         {
445             if (baos != null)
446             {
447                 try
448                 {
449                     baos.close();
450                 }
451                 catch(IOException e)
452                 {
453                 }
454             }
455
456             if (is != null)
457             {
458                 try
459                 {
460                     is.close();
461                 }
462                 catch(IOException e)
463                 {
464                 }
465             }
466         }
467
468         return baos.toByteArray();
469     }
470
471
472     /**
473      *
474      */

475     public static byte[] loadBytes(InputStream is) throws JRException
476     {
477         ByteArrayOutputStream baos = null;
478
479         try
480         {
481             baos = new ByteArrayOutputStream();
482
483             byte[] bytes = new byte[10000];
484             int ln = 0;
485             while ((ln = is.read(bytes)) > 0)
486             {
487                 baos.write(bytes, 0, ln);
488             }
489
490             baos.flush();
491         }
492         catch (IOException e)
493         {
494             throw 
495                 new JRException(
496                     EXCEPTION_MESSAGE_KEY_BYTE_DATA_FROM_INPUT_STREAM_ERROR,
497                     null,
498                     e);
499         }
500         finally
501         {
502             if (baos != null)
503             {
504                 try
505                 {
506                     baos.close();
507                 }
508                 catch(IOException e)
509                 {
510                 }
511             }
512         }
513
514         return baos.toByteArray();
515     }
516
517     public static InputStream loadToMemoryInputStream(InputStream is) throws JRException
518     {
519         if (is instanceof ByteArrayInputStream)
520         {
521             return is;
522         }
523         
524         try
525         {
526             byte[] bytes = loadBytes(is);
527             return new ByteArrayInputStream(bytes);
528         }
529         finally
530         {
531             try
532             {
533                 is.close();
534             }
535             catch (IOException e)
536             {
537                 if (log.isWarnEnabled())
538                 {
539                     log.warn("Failed to close input stream " + is, e);
540                 }
541             }
542         }
543     }
544
545     /**
546      *
547      */

548     public static byte[] loadBytesFromResource(String resourceName) throws JRException
549     {
550         return loadBytesFromResource(resourceName, null);
551     }
552
553
554     /**
555      *
556      */

557     public static byte[] loadBytesFromResource(String resourceName, ClassLoader classLoader) throws JRException
558     {
559         URL url = JRResourcesUtil.findClassLoaderResource(resourceName, classLoader);
560         if (url != null)
561         {
562             return loadBytes(url);
563         }
564         throw 
565             new JRException(
566                 EXCEPTION_MESSAGE_KEY_RESOURCE_NOT_FOUND,
567                 new Object[]{resourceName});
568     }
569         
570     
571     /**
572      * Tries to open an input stream for a location.
573      * <p>
574      * The method tries to interpret the location as a file name, a resource name or
575      * an URL.  If any of these succeed, an input stream is created and returned.
576      * 
577      * @param location the location
578      * @return an input stream if the location is an existing file name, a resource name on
579      * the classpath or an URL or <code>null</code> otherwise.
580      * 
581      * @throws JRException
582      */

583     public static InputStream getLocationInputStream(String location) throws JRException//FIXME deprecate this?
584     {
585         InputStream is = null;
586         
587         is = getResourceInputStream(location);
588         
589         if (is == null)
590         {
591             is = getFileInputStream(location);
592         }
593         
594         if (is == null)
595         {
596             is = getURLInputStream(location);
597         }
598         
599         return is;
600     }
601
602
603     /**
604      * Tries to open a file for reading.
605      * 
606      * @param filename the file name
607      * @return an input stream for the file or <code>null</code> if the file was not found
608      * @throws JRException
609      */

610     public static InputStream getFileInputStream(String filename) throws JRException
611     {
612         InputStream is = null;
613         
614         File file = new File(filename);
615         if (file.exists() && file.isFile())
616         {
617             try
618             {
619                 is = new FileInputStream(file);
620             }
621             catch (FileNotFoundException e)
622             {
623                 throw 
624                     new JRException(
625                         EXCEPTION_MESSAGE_KEY_FILE_OPEN_ERROR,
626                         new Object[]{filename},
627                         e);
628             }
629         }
630         
631         return is;
632     }
633
634
635     /**
636      * Tries to open an input stream for a resource.
637      *  
638      * @param resource the resource name
639      * @return an input stream for the resource or <code>null</code> if the resource was not found
640      */

641     public static InputStream getResourceInputStream(String resource)
642     {
643         InputStream is = null;
644         
645         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();        
646         if (classLoader != null)
647         {
648             is = classLoader.getResourceAsStream(resource);
649         }
650         
651         if (is == null)
652         {
653             classLoader = JRLoader.class.getClassLoader();
654             if (classLoader != null)
655             {
656                 is = classLoader.getResourceAsStream(resource);
657             }
658             
659             if (is == null)
660             {
661                 is = JRPropertiesUtil.class.getResourceAsStream("/" + resource);
662             }
663         }
664
665         return is;
666     }
667
668     /**
669      * Scans the context classloader and the classloader of this class for all 
670      * resources that have a specified name, and returns a list of
671      * {@link URL}s for the found resources.
672      * 
673      * @param resource the resource names
674      * @return a list of {@link URL}s of resources with the specified name;
675      * the list is empty if no resources have been found for the name
676      * @see ClassLoader#getResources(String)
677      */

678     public static List<URL> getResources(String resource)
679     {
680         //skip duplicated resources
681         Set<URL> resources = new LinkedHashSet<URL>();
682         collectResources(resource, JRLoader.class.getClassLoader(), 
683                 resources);
684         collectResources(resource, Thread.currentThread().getContextClassLoader(), 
685                 resources);
686         return new ArrayList<URL>(resources);
687     }
688
689
690     protected static void collectResources(String resourceName,
691             ClassLoader classLoader, Set<URL> resources)
692     {
693         if (classLoader != null)
694         {
695             try
696             {
697                 Enumeration<URL> urls = classLoader.getResources(resourceName);
698                 if (urls != null)
699                 {
700                     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
701                     {
702                         URL url = urls.nextElement();
703                         resources.add(url);
704                     }
705                 }
706             }
707             catch (IOException e)
708             {
709                 throw new JRRuntimeException(e);
710             }
711         }
712     }
713
714     /**
715      * Scans the context classloader and the classloader of this class for all 
716      * resources that have a specified name, and returns a list of
717      * {@link ClassLoaderResource} objects for the found resources.
718      * 
719      * <p>
720      * The returned list contains the URLs of the resources, and for each resource
721      * the highest classloader in the classloader hierarchy on which the resource
722      * was found.
723      * </p>
724      * 
725      * @param resource the resource names
726      * @return a list of resources with the specified name;
727      * the list is empty if no resources have been found for the name
728      * @see ClassLoader#getResources(String)
729      */

730     public static List<ClassLoaderResource> getClassLoaderResources(
731             String resource)
732     {
733         Map<URL, ClassLoaderResource> resources = 
734             new LinkedHashMap<URL, ClassLoaderResource>();
735         collectResources(resource, JRLoader.class.getClassLoader(), resources);
736         //TODO check if the classloader is the same
737         collectResources(resource, Thread.currentThread()
738                 .getContextClassLoader(), resources);
739         return new ArrayList<ClassLoaderResource>(resources.values());
740     }
741
742     protected static void collectResources(String resourceName,
743             ClassLoader classLoader, Map<URL, ClassLoaderResource> resources)
744     {
745         if (classLoader == null)
746         {
747             return;
748         }
749         
750         try
751         {
752             // creating a list of parent classloaders, with the highest in the
753             // hierarchy first
754             LinkedList<ClassLoader> classloaders = new LinkedList<ClassLoader>();
755             ClassLoader ancestorLoader = classLoader;
756             while (ancestorLoader != null)
757             {
758                 classloaders.addFirst(ancestorLoader);
759                 
760                 try
761                 {
762                     ancestorLoader = ancestorLoader.getParent();
763                 }
764                 catch (SecurityException e)
765                 {
766                     // if we're not allowed to get the parent, stop here.
767                     // resources will be listed with the first classloader that
768                     // we're allowed to access.
769                     // one case when this happens is applets.
770                     // FIXME revisit logging on SecurityException for applet
771                     ancestorLoader = null;
772                 }
773             }
774
775             for (ClassLoader ancestor : classloaders)
776             {
777                 Enumeration<URL> urls = ancestor.getResources(resourceName);
778                 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
779                 {
780                     while (urls.hasMoreElements())
781                     {
782                         URL url = urls.nextElement();
783                         // if this is the first time we see this resource, add it
784                         // with the current classloader.
785                         // this way a resource will be added with the most first
786                         // ancestor classloader that has it.
787                         if (!resources.containsKey(url))
788                         {
789                             if (log.isDebugEnabled())
790                             {
791                                 log.debug("Found resource " + resourceName 
792                                         + " at "+ url + " in classloader " + ancestor);
793                             }
794                             
795                             ClassLoaderResource resource = new ClassLoaderResource(
796                                     url, ancestor);
797                             resources.put(url, resource);
798                         }
799                     }
800                 }
801             }
802         } catch (IOException e)
803         {
804             throw new JRRuntimeException(e);
805         }
806     }
807
808     /**
809      * Returns the resource URL for a specified resource name.
810      * 
811      * @param resource the resource name
812      * @return the URL of the resource having the specified name, or
813      * <code>null</code> if none found
814      * @see ClassLoader#getResource(String)
815      */

816     public static URL getResource(String resource)
817     {
818         URL location = null;
819         
820         ClassLoader classLoader = Thread.currentThread().getContextClassLoader();        
821         if (classLoader != null)
822         {
823             location = classLoader.getResource(resource);
824         }
825         
826         if (location == null)
827         {
828             classLoader = JRLoader.class.getClassLoader();
829             if (classLoader != null)
830             {
831                 location = classLoader.getResource(resource);
832             }
833             
834             if (location == null)
835             {
836                 location = JRPropertiesUtil.class.getResource("/" + resource);
837             }
838         }
839
840         return location;
841     }
842
843     /**
844      * Tries to open an input stream for an URL.
845      * 
846      * @param spec the string to parse as an URL
847      * @return an input stream for the URL or null if <code>spec</code> is not a valid URL
848      * @throws JRException
849      */

850     public static InputStream getURLInputStream(String spec) throws JRException
851     {
852         InputStream is = null;
853         
854         try
855         {
856             URL url = new URL(spec);
857             is = url.openStream();
858         }
859         catch (MalformedURLException e)
860         {
861         }
862         catch (IOException e)
863         {
864             throw 
865                 new JRException(
866                     EXCEPTION_MESSAGE_KEY_URL_OPEN_ERROR,
867                     new Object[]{spec},
868                     e);
869         }
870         
871         return is;
872     }
873     
874     /**
875      * Loads a JasperPrint object from a file, optionally using a virtualizer for
876      * the object.
877      * 
878      * @param fileName the file name
879      * @param virtualizer the virtualizer
880      * @return a JasperPrint object
881      * @throws JRException
882      * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer)
883      */

884     public static JasperPrint loadJasperPrintFromFile(String fileName, JRVirtualizer virtualizer) throws JRException
885     {
886         if (virtualizer != null)
887         {
888             JRVirtualizationHelper.setThreadVirtualizer(virtualizer);
889         }
890         try
891         {
892             return (JasperPrint) loadObjectFromFile(fileName);
893         }
894         finally
895         {
896             if (virtualizer != null)
897             {
898                 JRVirtualizationHelper.clearThreadVirtualizer();
899             }
900         }
901     }
902     
903     /**
904      * Loads a JasperPrint object from a file, optionally using a virtualizer for
905      * the object.
906      * 
907      * @param file the file
908      * @param virtualizer the virtualizer
909      * @return a JasperPrint object
910      * @throws JRException
911      * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer)
912      */

913     public static JasperPrint loadJasperPrint(File file, JRVirtualizer virtualizer) throws JRException
914     {
915         if (virtualizer != null)
916         {
917             JRVirtualizationHelper.setThreadVirtualizer(virtualizer);
918         }
919         try
920         {
921             return (JasperPrint) loadObject(file);
922         }
923         finally
924         {
925             if (virtualizer != null)
926             {
927                 JRVirtualizationHelper.clearThreadVirtualizer();
928             }
929         }
930     }
931
932     /**
933      * Loads a JasperPrint object from a URL, optionally using a virtualizer for
934      * the object.
935      * 
936      * @param url the URL
937      * @param virtualizer the virtualizer
938      * @return a JasperPrint object
939      * @throws JRException
940      * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer)
941      */

942     public static JasperPrint loadJasperPrint(URL url, JRVirtualizer virtualizer) throws JRException
943     {
944         if (virtualizer != null)
945         {
946             JRVirtualizationHelper.setThreadVirtualizer(virtualizer);
947         }
948         try
949         {
950             return (JasperPrint) loadObject(url);
951         }
952         finally
953         {
954             if (virtualizer != null)
955             {
956                 JRVirtualizationHelper.clearThreadVirtualizer();
957             }
958         }
959     }
960     
961     /**
962      * Loads a JasperPrint object from a stream, optionally using a virtualizer for
963      * the object.
964      * 
965      * @param is the stream
966      * @param virtualizer the virtualizer
967      * @return a JasperPrint object
968      * @throws JRException
969      * @see JRVirtualizationHelper#setThreadVirtualizer(JRVirtualizer)
970      */

971     public static JasperPrint loadJasperPrint(InputStream is, JRVirtualizer virtualizer) throws JRException
972     {
973         if (virtualizer != null)
974         {
975             JRVirtualizationHelper.setThreadVirtualizer(virtualizer);
976         }
977         try
978         {
979             return (JasperPrint) loadObject(is);
980         }
981         finally
982         {
983             if (virtualizer != null)
984             {
985                 JRVirtualizationHelper.clearThreadVirtualizer();
986             }
987         }
988     }
989     
990     private JRLoader()
991     {
992     }
993 }
994