1 21 package com.jaspersoft.jasperserver.api.engine.jasperreports.service.impl; 22 23 import java.io.BufferedOutputStream ; 24 import java.io.ByteArrayInputStream ; 25 import java.io.ByteArrayOutputStream ; 26 import java.io.File ; 27 import java.io.FileOutputStream ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.io.OutputStream ; 31 import java.util.ArrayList ; 32 import java.util.HashMap ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.jar.JarFile ; 37 38 import net.sf.jasperreports.engine.JRDataSource; 39 import net.sf.jasperreports.engine.JRException; 40 import net.sf.jasperreports.engine.JRExporterParameter; 41 import net.sf.jasperreports.engine.JRParameter; 42 import net.sf.jasperreports.engine.JasperCompileManager; 43 import net.sf.jasperreports.engine.JasperFillManager; 44 import net.sf.jasperreports.engine.JasperPrint; 45 import net.sf.jasperreports.engine.JasperReport; 46 import net.sf.jasperreports.engine.design.JasperDesign; 47 import net.sf.jasperreports.engine.export.JRPdfExporter; 48 import net.sf.jasperreports.engine.query.JRQueryExecuter; 49 import net.sf.jasperreports.engine.util.JRLoader; 50 import net.sf.jasperreports.engine.util.JRSaver; 51 import net.sf.jasperreports.engine.xml.JRXmlLoader; 52 53 import org.apache.commons.collections.OrderedMap; 54 import org.apache.commons.collections.ReferenceMap; 55 import org.apache.commons.logging.Log; 56 import org.apache.commons.logging.LogFactory; 57 58 import com.jaspersoft.jasperserver.api.JSExceptionWrapper; 59 import com.jaspersoft.jasperserver.api.common.domain.ExecutionContext; 60 import com.jaspersoft.jasperserver.api.common.domain.ValidationResult; 61 import com.jaspersoft.jasperserver.api.common.domain.impl.ValidationDetailImpl; 62 import com.jaspersoft.jasperserver.api.common.domain.impl.ValidationResultImpl; 63 import com.jaspersoft.jasperserver.api.common.service.BeanForInterfaceImplementationFactory; 64 import com.jaspersoft.jasperserver.api.engine.common.domain.Request; 65 import com.jaspersoft.jasperserver.api.engine.common.domain.Result; 66 import com.jaspersoft.jasperserver.api.engine.common.service.EngineService; 67 import com.jaspersoft.jasperserver.api.engine.common.service.SecurityContextProvider; 68 import com.jaspersoft.jasperserver.api.engine.jasperreports.common.ReportExecuter; 69 import com.jaspersoft.jasperserver.api.engine.jasperreports.domain.impl.ReportUnitRequestBase; 70 import com.jaspersoft.jasperserver.api.engine.jasperreports.domain.impl.ReportUnitResult; 71 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.JRQueryExecuterAdapter; 72 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.JarsClassLoader; 73 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryCacheMap; 74 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryContext; 75 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryResourceClassLoader; 76 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryResourceKey; 77 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryUtil; 78 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.ResourceCollector; 79 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryCacheMap.CacheObject; 80 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.RepositoryCacheMap.ObjectCache; 81 import com.jaspersoft.jasperserver.api.engine.jasperreports.util.repo.RepositoryURLHandlerFactory; 82 import com.jaspersoft.jasperserver.api.metadata.common.domain.FileResource; 83 import com.jaspersoft.jasperserver.api.metadata.common.domain.FileResourceData; 84 import com.jaspersoft.jasperserver.api.metadata.common.domain.Query; 85 import com.jaspersoft.jasperserver.api.metadata.common.domain.Resource; 86 import com.jaspersoft.jasperserver.api.metadata.common.domain.ResourceReference; 87 import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryCache; 88 import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryCacheableItem; 89 import com.jaspersoft.jasperserver.api.metadata.common.service.RepositoryService; 90 import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportDataSource; 91 import com.jaspersoft.jasperserver.api.metadata.jasperreports.domain.ReportUnit; 92 import com.jaspersoft.jasperserver.api.metadata.jasperreports.service.ReportDataSourceService; 93 import com.jaspersoft.jasperserver.api.metadata.jasperreports.service.ReportDataSourceServiceFactory; 94 import com.jaspersoft.jasperserver.api.metadata.user.domain.User; 95 96 97 101 public class EngineServiceImpl implements EngineService, ReportExecuter, CompiledReportProvider 102 { 103 protected static final Log log = LogFactory.getLog(EngineServiceImpl.class); 104 105 private BeanForInterfaceImplementationFactory dataSourceServiceFactories; 106 protected RepositoryService repository; 107 private SecurityContextProvider securityContextProvider; 108 private String loggedInUserReportParameterName; 109 110 private RepositoryCacheMap tempJarFiles; 111 private RepositoryCache compiledReportsCache; 112 private final ReferenceMap jarsClassLoaderCache; 113 private final ReferenceMap resourcesClassLoaderCache; 114 private final RepositoryCacheableItem cacheableCompiledReports; 115 116 public EngineServiceImpl() 117 { 118 jarsClassLoaderCache = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.SOFT); 119 resourcesClassLoaderCache = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.SOFT); 120 cacheableCompiledReports = new CacheableCompiledReports(); 121 } 122 123 126 public RepositoryService getRepositoryService() 127 { 128 return repository; 129 } 130 131 protected class CacheableCompiledReports implements RepositoryCacheableItem { 132 private static final String CACHE_NAME = "JasperReport"; 133 134 public String getCacheName() { 135 return CACHE_NAME; 136 } 137 138 public byte[] getData(ExecutionContext context, FileResource resource) { 139 InputStream jrxmlData = getFileResourceDataStream(context, resource); 140 JasperReport report = compileReport(jrxmlData); 141 byte[] reportBytes = reportBytes(report); 142 return reportBytes; 143 } 144 } 145 146 public void setRepositoryService(RepositoryService repository) { 147 this.repository = repository; 148 149 createJarFilesCache(); 150 } 151 152 public RepositoryCache getCompiledReportsCache() { 153 return compiledReportsCache; 154 } 155 156 public void setCompiledReportsCache(RepositoryCache compiledReportsCache) { 157 this.compiledReportsCache = compiledReportsCache; 158 } 159 160 protected final class TempJarFileCacheObject implements ObjectCache { 161 public boolean isValid(Object o) { 162 return true; 163 } 164 165 public Object create(ExecutionContext context, FileResource res) { 166 try { 167 File tempFile = File.createTempFile("report_jar", ".jar"); 168 tempFile.deleteOnExit(); 169 170 if (log.isInfoEnabled()) { 171 log.info("Created temp jar file \"" + tempFile.getPath() + "\" for resource \"" + res.getURIString() + "\""); 172 } 173 174 byte[] data = getFileResourceData(context, res); 175 OutputStream fileOut = new BufferedOutputStream (new FileOutputStream (tempFile)); 176 try { 177 fileOut.write(data); 178 fileOut.flush(); 179 } finally { 180 fileOut.close(); 181 } 182 183 JarFile jarFile = new JarFile (tempFile); 184 185 return jarFile; 186 } catch (IOException e) { 187 log.error(e, e); 188 throw new JSExceptionWrapper(e); 189 } 190 } 191 192 public void release(Object o) { 193 dispose((JarFile ) o); 194 } 195 } 196 197 protected void createJarFilesCache() { 198 this.tempJarFiles = new RepositoryCacheMap(this.repository, new TempJarFileCacheObject()); 199 } 200 201 protected InputStream getFileResourceDataStream(ExecutionContext context, FileResource fileResource) { 202 InputStream data; 203 if (fileResource.hasData()) { 204 data = fileResource.getDataStream(); 205 } else { 206 FileResourceData resourceData = repository.getResourceData(context, fileResource.getURIString()); 207 data = resourceData.getDataStream(); 208 } 209 return data; 210 } 211 212 protected CacheObject getCacheJarFile(ExecutionContext context, FileResource jar, boolean cache) { 213 return tempJarFiles.cache(context, jar, cache); 214 } 215 216 protected byte[] getFileResourceData(ExecutionContext context, FileResource fileResource) { 217 byte[] data; 218 if (fileResource.hasData()) { 219 data = fileResource.getData(); 220 } else { 221 FileResourceData resourceData = repository.getResourceData(context, fileResource.getURIString()); 222 data = resourceData.getData(); 223 } 224 return data; 225 } 226 227 public BeanForInterfaceImplementationFactory getDataSourceServiceFactories() { 228 return dataSourceServiceFactories; 229 } 230 231 public void setDataSourceServiceFactories(BeanForInterfaceImplementationFactory dataSourceServiceFactories) { 232 this.dataSourceServiceFactories = dataSourceServiceFactories; 233 } 234 235 238 public Result execute(ExecutionContext context, Request request) 239 { 240 ReportUnitRequestBase reportUnitRequest = (ReportUnitRequestBase) request; 241 return reportUnitRequest.execute(context, this); 242 } 243 244 245 248 public void exportToPdf(ExecutionContext context, String reportUnitURI, Map exportParameters) 249 { 250 setThreadRepositoryContext(context, null, reportUnitURI, false); 251 exportParameters.put(JRExporterParameter.URL_HANDLER_FACTORY, RepositoryURLHandlerFactory.getInstance()); 252 JRPdfExporter exporter = new JRPdfExporter(); 253 exporter.setParameters(exportParameters); 254 try { 255 exporter.exportReport(); 256 } catch(JRException e) { 257 log.error("Error while exporting report to PDF", e); 258 throw new JSExceptionWrapper(e); 259 } finally { 260 RepositoryUtil.clearThreadRepositoryContext(); 261 } 262 } 263 264 265 protected void setThreadRepositoryContext(ExecutionContext context, ReportUnit reportUnit, String reportUnitURI, boolean inMemoryUnit) 266 { 267 RepositoryContext repositoryContext = new RepositoryContext(); 268 repositoryContext.setRepository(repository); 269 repositoryContext.setContextResourceURI(reportUnitURI); 270 if (inMemoryUnit) { 271 repositoryContext.setReportUnit(reportUnit); 272 } 273 repositoryContext.setExecutionContext(context); 274 repositoryContext.setCompiledReportProvider(this); 275 RepositoryUtil.setThreadRepositoryContext(repositoryContext); 276 277 } 278 279 280 protected ReportUnitResult fillReport(ExecutionContext context, ReportUnit reportUnit, Map parameters, boolean inMemoryUnit) { 281 282 setThreadRepositoryContext(context, reportUnit, reportUnit.getURIString(), inMemoryUnit); 283 try { 284 OrigContextClassLoader origContext = setContextClassLoader(context, reportUnit, inMemoryUnit); 285 try { 286 JasperReport report = getJasperReport(context, reportUnit, inMemoryUnit); 287 Map reportParameters = getReportParameters(context, parameters); 288 289 ReportDataSource datasource = null; 290 ResourceReference queryRef = reportUnit.getQuery(); 291 Query query = queryRef == null ? null : (Query) getFinalResource(context, queryRef); 292 if (query != null && query.getDataSource() != null) { 293 datasource = (ReportDataSource) getFinalResource(context, query.getDataSource()); 294 } 295 296 ResourceReference dsRef = reportUnit.getDataSource(); 297 if (datasource == null && dsRef != null) { 298 datasource = (ReportDataSource) getFinalResource(context, dsRef); 299 } 300 301 return fillReport(context, report, reportParameters, datasource, query); 302 } finally { 303 revert(origContext); 304 } 305 } finally { 306 RepositoryUtil.clearThreadRepositoryContext(); 307 } 308 } 309 310 protected Map getReportParameters(ExecutionContext context, Map requestParameters) { 311 Map reportParameters = new HashMap (); 312 313 reportParameters.put(JRParameter.REPORT_URL_HANDLER_FACTORY, RepositoryURLHandlerFactory.getInstance()); 314 315 if (context != null && context.getLocale() != null) { 316 reportParameters.put(JRParameter.REPORT_LOCALE, context.getLocale()); 317 } 318 319 if (getSecurityContextProvider() != null) { 320 User user = getSecurityContextProvider().getContextUser(); 321 if (user != null) { 322 user.setPassword(null); 323 reportParameters.put(getLoggedInUserReportParameterName(), user); 324 } 325 } 326 327 if (requestParameters != null) { 328 reportParameters.putAll(requestParameters); 329 } 330 331 return reportParameters; 332 } 333 334 protected void revert(OrigContextClassLoader origContext) { 335 if (origContext.set) { 336 Thread.currentThread().setContextClassLoader(origContext.origClassLoader); 337 338 for (Iterator it = origContext.jars.iterator(); it.hasNext();) { 339 CacheObject cacheJarFile = (CacheObject) it.next(); 340 if (!cacheJarFile.isCached()) { 341 JarFile jarFile = (JarFile ) cacheJarFile.getObject(); 342 dispose(jarFile); 343 } 344 } 345 } 346 } 347 348 protected static class OrigContextClassLoader { 349 public final boolean set; 350 public final ClassLoader origClassLoader; 351 public final List jars; 352 353 public static final OrigContextClassLoader NOT_SET = new OrigContextClassLoader(false); 354 355 private OrigContextClassLoader(boolean set) { 356 this.set = set; 357 this.origClassLoader = null; 358 this.jars = null; 359 } 360 361 public OrigContextClassLoader(ClassLoader origClassLoader, List jars) { 362 this.set = true; 363 this.origClassLoader = origClassLoader; 364 this.jars = jars; 365 } 366 } 367 368 protected OrigContextClassLoader setContextClassLoader(ExecutionContext context, ReportUnit reportUnit, boolean inMemoryUnit) { 369 Thread thread = Thread.currentThread(); 370 ClassLoader origClassLoader = thread.getContextClassLoader(); 371 ClassLoader jarsClassLoader; 372 ClassLoader newClassLoader = null; 373 374 List jarFiles = getJarFiles(context, reportUnit, !inMemoryUnit); 375 if (jarFiles.isEmpty()) { 376 jarsClassLoader = origClassLoader; 377 } else { 378 newClassLoader = jarsClassLoader = getJarsClassLoader(origClassLoader, jarFiles); 379 } 380 381 Map resourceBundleKeys = getResourceBundleKeys(context, reportUnit); 382 if (!resourceBundleKeys.isEmpty()) { 383 newClassLoader = getResourcesClassLoader(jarsClassLoader, resourceBundleKeys, inMemoryUnit); 384 } 385 386 OrigContextClassLoader origContext; 387 if (newClassLoader == null) { 388 origContext = OrigContextClassLoader.NOT_SET; 389 } else { 390 origContext = new OrigContextClassLoader(origClassLoader, jarFiles); 391 thread.setContextClassLoader(newClassLoader); 392 } 393 394 return origContext; 395 } 396 397 protected ClassLoader getJarsClassLoader(ClassLoader origClassLoader, List jarFiles) { 398 boolean caching = true; 399 for (Iterator it = jarFiles.iterator(); caching && it.hasNext();) { 400 CacheObject cacheJarFile = (CacheObject) it.next(); 401 caching &= cacheJarFile.isCached(); 402 } 403 404 ClassLoader classLoader; 405 if (caching) { 406 Map childrenClassLoaders; 407 synchronized (jarsClassLoaderCache) { 408 childrenClassLoaders = (Map ) jarsClassLoaderCache.get(origClassLoader); 409 if (childrenClassLoaders == null) { 410 childrenClassLoaders = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT); 411 jarsClassLoaderCache.put(origClassLoader, childrenClassLoaders); 412 } 413 } 414 Object classLoaderKey = getJarFileNames(jarFiles); 415 synchronized (childrenClassLoaders) { 416 classLoader = (ClassLoader ) childrenClassLoaders.get(classLoaderKey); 417 if (classLoader == null) { 418 if (log.isDebugEnabled()) { 419 log.debug("Creating class loader for parent " + origClassLoader + " and jars " + classLoaderKey); 420 } 421 classLoader = createJarsClassLoader(origClassLoader, jarFiles); 422 childrenClassLoaders.put(classLoaderKey, classLoader); 423 } 424 } 425 } else { 426 classLoader = createJarsClassLoader(origClassLoader, jarFiles); 427 } 428 return classLoader; 429 } 430 431 protected ClassLoader createJarsClassLoader(ClassLoader origClassLoader, List jarFiles) { 432 JarFile [] jars = new JarFile [jarFiles.size()]; 433 int i = 0; 434 for (Iterator it = jarFiles.iterator(); it.hasNext(); ++i) { 435 jars[i] = (JarFile ) ((CacheObject) it.next()).getObject(); 436 } 437 438 return new JarsClassLoader(jars, origClassLoader); 439 } 440 441 private Object getJarFileNames(List jarFiles) { 442 List jarFileNames = new ArrayList (jarFiles.size()); 443 for (Iterator it = jarFiles.iterator(); it.hasNext();) { 444 JarFile jar = (JarFile ) ((CacheObject) it.next()).getObject(); 445 jarFileNames.add(jar.getName()); 446 } 447 return jarFileNames; 448 } 449 450 protected ClassLoader getResourcesClassLoader(ClassLoader parent, Map resourceBundleKeys, boolean inMemoryUnit) { 451 ClassLoader repositoryResourceClassLoader; 452 if (inMemoryUnit) { 453 repositoryResourceClassLoader = new RepositoryResourceClassLoader(parent, resourceBundleKeys, true); 454 } else { 455 Map childrenClassLoaders; 456 synchronized (resourcesClassLoaderCache) { 457 childrenClassLoaders = (Map ) resourcesClassLoaderCache.get(parent); 458 if (childrenClassLoaders == null) { 459 childrenClassLoaders = new ReferenceMap(ReferenceMap.HARD, ReferenceMap.SOFT); 460 resourcesClassLoaderCache.put(parent, childrenClassLoaders); 461 } 462 } 463 synchronized (childrenClassLoaders) { 464 repositoryResourceClassLoader = (ClassLoader ) childrenClassLoaders.get(resourceBundleKeys); 465 if (repositoryResourceClassLoader == null) { 466 if (log.isDebugEnabled()) { 467 log.debug("Creating class loader for parent " + parent + " and resources " + resourceBundleKeys); 468 } 469 repositoryResourceClassLoader = new RepositoryResourceClassLoader(parent, resourceBundleKeys, false); 470 childrenClassLoaders.put(resourceBundleKeys, repositoryResourceClassLoader); 471 } 472 } 473 } 474 return repositoryResourceClassLoader; 475 } 476 477 protected List getJarFiles(ExecutionContext context, ReportUnit reportUnit, boolean cache) { 478 List jarFiles = new ArrayList (); 479 List resources = reportUnit.getResources(); 480 if (resources != null && !resources.isEmpty()) { 481 for (Iterator it = resources.iterator(); it.hasNext();) { 482 ResourceReference resRef = (ResourceReference) it.next(); 483 FileResource resource = getFinalFileResource(context, resRef); 484 if (resource.getFileType().equals(FileResource.TYPE_JAR)) { 485 CacheObject cacheJarFile = getCacheJarFile(context, resource, cache); 486 jarFiles.add(cacheJarFile); 487 } 488 } 489 } 490 return jarFiles; 491 } 492 493 protected Map getResourceBundleKeys(ExecutionContext context, ReportUnit reportUnit) { 494 Map resourceBundleKeys = new HashMap (); 495 List resources = reportUnit.getResources(); 496 if (resources != null && !resources.isEmpty()) { 497 for (Iterator it = resources.iterator(); it.hasNext();) { 498 ResourceReference resRef = (ResourceReference) it.next(); 499 FileResource finalResource = getFinalFileResource(context, resRef); 500 if (finalResource.getFileType().equals(FileResource.TYPE_RESOURCE_BUNDLE)) { 501 String resName; 502 if (resRef.isLocal()) { 503 resName = resRef.getLocalResource().getName(); 504 } else { 505 resName = finalResource.getName(); } 507 resourceBundleKeys.put(resName, new RepositoryResourceKey(finalResource)); 508 } 509 } 510 } 511 return resourceBundleKeys; 512 } 513 514 protected JasperReport getJasperReport(ExecutionContext context, ReportUnit reportUnit, boolean inMemoryUnit) { 515 FileResource reportRes = (FileResource) getFinalResource(context, 516 reportUnit.getMainReport()); 517 JasperReport report; 518 try { 519 if (inMemoryUnit) { 520 InputStream fileResourceData = getFileResourceDataStream(context, reportRes); 521 report = compileReport(fileResourceData); 522 } else { 523 InputStream compiledReport = getCompiledReport(context, reportRes); 524 report = (JasperReport) JRLoader.loadObject(compiledReport); 525 } 526 return report; 527 } catch (JRException e) { 528 log.error(e, e); 529 throw new JSExceptionWrapper(e); 530 } 531 } 532 533 protected ReportUnitResult fillReport(ExecutionContext context, JasperReport report, Map reportParameters, ReportDataSource datasource, Query query) { 534 ReportDataSourceService dataSourceService = null; 535 boolean dsClosing = false; 536 try { 537 if (datasource != null) { 538 dataSourceService = createDataSourceService(datasource); 539 dataSourceService.setReportParameterValues(reportParameters); 540 } 541 542 JasperPrint print; 543 if (query == null) { 544 print = JasperFillManager.fillReport(report, reportParameters); 545 } else { 546 print = fillQueryReport(context, report, reportParameters, query); 547 } 548 549 dsClosing = true; 550 if (dataSourceService != null) { 551 dataSourceService.closeConnection(); 552 dataSourceService = null; 553 } 554 555 ReportUnitResult result = new ReportUnitResult(); 556 result.setJasperPrint(print); 557 return result; 558 } catch (JRException e) { 559 log.error("Error while filling report", e); 560 throw new JSExceptionWrapper(e); 561 } finally { 562 if (!dsClosing && dataSourceService != null) { 563 try { 565 dataSourceService.closeConnection(); 566 } catch (Exception e) { 567 log.error("Error while closing data source connection", e); 568 } 569 } 570 } 571 } 572 573 protected JasperPrint fillQueryReport(ExecutionContext context, JasperReport report, Map reportParameters, Query query) throws JRException { 574 JRQueryExecuter queryExecuter = JRQueryExecuterAdapter.createQueryExecuter(report, reportParameters, query); 575 boolean closing = false; 576 try { 577 JRDataSource reportDatasource = queryExecuter.createDatasource(); 578 JasperPrint printReport = JasperFillManager.fillReport(report, reportParameters, reportDatasource); 579 closing = true; 580 queryExecuter.close(); 581 return printReport; 582 } finally { 583 if (!closing) { 584 queryExecuter.close(); 585 } 586 } 587 } 588 589 public ReportDataSourceService createDataSourceService(ReportDataSource dataSource) { 590 ReportDataSourceServiceFactory factory = (ReportDataSourceServiceFactory) getDataSourceServiceFactories().getBean(dataSource.getClass()); 591 return factory.createService(dataSource); 592 } 593 594 597 public Resource[] getResources(ResourceReference jrxmlReference) 598 { 599 FileResource jrxml = (FileResource) getFinalResource(null, jrxmlReference); 601 return ResourceCollector.getResources(getFileResourceDataStream(null, jrxml)); 602 } 603 604 protected Resource getRepositoryResource(ExecutionContext context, String uri) 605 { 606 return getRepositoryService().getResource(context, uri); 607 } 608 609 protected Resource getFinalResource(ExecutionContext context, ResourceReference res) { 610 Resource finalRes; 611 if (res.isLocal()) { 612 finalRes = res.getLocalResource(); 613 } else { 614 finalRes = getRepositoryResource(context, res.getReferenceURI()); 615 } 616 return finalRes; 617 } 618 619 protected FileResource getFinalFileResource(ExecutionContext context, ResourceReference resRef) { 620 FileResource res = (FileResource) getFinalResource(context, resRef); 621 while (res.isReference()) { 622 res = (FileResource) getRepositoryResource(context, res.getReferenceURI()); 623 } 624 return res; 625 } 626 627 public ValidationResult validate(ExecutionContext context, ReportUnit reportUnit) { 628 OrigContextClassLoader origContext = setContextClassLoader(context, reportUnit, true); 629 ValidationResultImpl result = new ValidationResultImpl(); 630 try { 631 ResourceReference mainReport = reportUnit.getMainReport(); 632 if (mainReport != null) { 633 validateJRXML(context, result, mainReport); 634 } 635 636 List resources = reportUnit.getResources(); 637 if (resources != null && !resources.isEmpty()) { 638 for (Iterator iter = resources.iterator(); iter.hasNext();) { 639 ResourceReference resource = (ResourceReference) iter.next(); 640 validateJRXML(context, result, resource); 641 } 642 } 643 } finally { 644 revert(origContext); 645 } 646 return result; 647 } 648 649 protected void validateJRXML(ExecutionContext context, ValidationResultImpl result, ResourceReference resourceRef) { 650 FileResource resource = getFinalFileResource(context, resourceRef); 651 if (resource.getFileType().equals(FileResource.TYPE_JRXML)) { 652 try { 653 JasperCompileManager.compileReport(getFileResourceDataStream(context, resource)); 654 } catch (JRException e) { 655 ValidationDetailImpl detail = new ValidationDetailImpl(); 656 detail.setValidationClass(FileResource.class); 657 detail.setName(resource.getName()); 658 detail.setLabel(resource.getLabel()); 659 detail.setResult(ValidationResult.STATE_ERROR); 660 detail.setException(e); 661 detail.setMessage(e.getMessage()); 662 result.addValidationDetail(detail); 663 } 664 } 665 } 666 667 public ReportUnitResult executeReport(ExecutionContext context, String reportUnitURI, Map parameters) { 668 ReportUnit reportUnit = (ReportUnit) getRepositoryResource(context, reportUnitURI); 669 return fillReport(context, reportUnit, parameters, false); 670 } 671 672 public ReportUnitResult executeReport(ExecutionContext context, ReportUnit reportUnit, Map parameters) { 673 return fillReport(context, reportUnit, parameters, true); 674 } 675 676 public InputStream getCompiledReport(ExecutionContext context, InputStream jrxmlData) { 677 JasperReport report = compileReport(jrxmlData); 678 byte[] reportBytes = reportBytes(report); 679 return new ByteArrayInputStream (reportBytes); 680 } 681 682 protected JasperReport compileReport(InputStream jrxmlData) { 683 try { 684 JasperDesign design = JRXmlLoader.load(jrxmlData); 685 JasperReport report = JasperCompileManager.compileReport(design); 686 return report; 687 } catch (JRException e) { 688 log.error(e, e); 689 throw new JSExceptionWrapper(e); 690 } 691 } 692 693 protected InputStream getCompiledReport(ExecutionContext context, FileResource jrxml) { 694 return compiledReportsCache.cache(context, jrxml, cacheableCompiledReports); 695 } 696 697 protected byte[] reportBytes(JasperReport report) { 698 try { 699 ByteArrayOutputStream bout = new ByteArrayOutputStream (); 700 JRSaver.saveObject(report, bout); 701 byte[] reportBytes = bout.toByteArray(); 702 return reportBytes; 703 } catch (JRException e) { 704 log.error(e, e); 705 throw new JSExceptionWrapper(e); 706 } 707 } 708 709 public InputStream getCompiledReport(ExecutionContext context, String jrxmlURI) { 710 return compiledReportsCache.cache(context, jrxmlURI, cacheableCompiledReports); 711 } 712 713 public JasperReport getMainJasperReport(ExecutionContext context, String reportUnitURI) { 714 ReportUnit reportUnit = (ReportUnit) getRepositoryResource(context, reportUnitURI); 715 OrigContextClassLoader origContext = setContextClassLoader(context, reportUnit, false); 716 try { 717 JasperReport jasperReport = getJasperReport(context, reportUnit, false); 718 return jasperReport; 719 } finally { 720 revert(origContext); 721 } 722 } 723 724 public void release() { 725 tempJarFiles.release(); 726 } 727 728 protected void dispose(JarFile jarFile) { 729 try { 730 jarFile.close(); 731 } catch (IOException e) { 732 log.warn("Unable to close jar file \"" + jarFile.getName() + "\"", e); 733 } 734 File file = new File (jarFile.getName()); 735 if (file.exists() && !file.delete()) { 736 log.warn("Unable to delete jar file \"" + jarFile.getName() + "\""); 737 } 738 } 739 740 public void clearCaches(Class resourceItf, String resourceURI) { 741 if (FileResource.class.isAssignableFrom(resourceItf)) { 742 compiledReportsCache.clearCache(resourceURI, cacheableCompiledReports); 744 } 745 } 746 747 public String getLoggedInUserReportParameterName() { 748 return loggedInUserReportParameterName; 749 } 750 751 public void setLoggedInUserReportParameterName( 752 String loggedInUserReportParameterName) { 753 this.loggedInUserReportParameterName = loggedInUserReportParameterName; 754 } 755 756 public SecurityContextProvider getSecurityContextProvider() { 757 return securityContextProvider; 758 } 759 760 public void setSecurityContextProvider( 761 SecurityContextProvider securityContextProvider) { 762 this.securityContextProvider = securityContextProvider; 763 } 764 765 766 public OrderedMap executeQuery(ExecutionContext context, 767 ResourceReference queryReference, String keyColumn, String [] resultColumns, 768 ResourceReference defaultDataSourceReference) { 769 Query query = (Query) getFinalResource(context, queryReference); 770 771 ResourceReference dataSourceReference = query.getDataSource(); 772 if (dataSourceReference == null) { 773 dataSourceReference = defaultDataSourceReference; 774 } 775 776 if (dataSourceReference == null) { 777 return null; 778 } 779 780 ReportDataSource dataSource = (ReportDataSource) getFinalResource(context, dataSourceReference); 781 782 ReportDataSourceService dataSourceService = createDataSourceService(dataSource); 783 boolean dsClosing = false; 784 try { 785 Map parameters = new HashMap (); 786 dataSourceService.setReportParameterValues(parameters); 787 788 OrderedMap result = JRQueryExecuterAdapter.executeQuery(query, keyColumn, resultColumns, parameters); 789 790 dsClosing = true; 791 if (dataSourceService != null) { 792 dataSourceService.closeConnection(); 793 dataSourceService = null; 794 } 795 796 return result; 797 } finally { 798 if (!dsClosing && dataSourceService != null) { 799 try { 801 dataSourceService.closeConnection(); 802 } catch (Exception e) { 803 log.error("Error while closing data source connection", e); 804 } 805 } 806 } 807 808 } 809 810 } 811 | Popular Tags |