3 Replies Latest reply on Apr 14, 2008 10:32 PM by Steve Hunter

    Open PDF template in new window

    Steve Hunter Newbie

      This is probably something simple but the solution is eluding me so here it is. 


      I've been trying to open a Seam PDF template in a new window using a ServletOutputStream but have been getting an EJBTransactionRolledbackException / NullPointerException:


      javax.faces.el.EvaluationException: javax.ejb.EJBTransactionRolledbackException
              at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:9
      1)
              at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:91)
              at javax.faces.component.UICommand.broadcast(UICommand.java:383)
              at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:184)
              at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:162)
              at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:350)
              at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:97)
              at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:251)
              at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
              at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
      ...
      Caused by: java.lang.NullPointerException
              at ca.saanich.bsc.reports.RptThemeProgressAction.viewReport(RptThemeProgressAction.java:101)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:585)
              at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
              at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
              at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:44)
              at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
              at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31)
      



      Line 101 of the RptThemeProgressAction.java (see below code) file is


      String path = externalContext.getResource("/reports/pdfRptThemeProgress.seam").getPath();'


      Within my project WAR file there is a reports directory with a pdfRptThemeProgress.xhtml PDF template which references an entity bean.  The entity bean is created via the setResultList() function call inside the viewReport() method (see below).  My app page has some query filters and calls the viewReport() method via a commandButton.


      <h:commandButton value="View Report"
      action="#{rptThemeProgress.viewReport}"/>


      The code for the view report method is the following:


              public void viewReport()
              {               
                      // set report values
                      setRptYear              (rptYear);
                      setRptOrgUnit           (rptOrgUnit);   
                      setRptActive            (rptActive);
                      setRptUseCode           (rptUseCode);
      
                      if (rptYear == null || rptActive == null)
                      {
                              // mandatory filters were left blank
                              facesMessages.add("WARNING: Cannot display results - Please complete selection criteria");      
                      }
                      else
                      {
                              // set results for report entity
                              setResultList();
      
                              try
                              {
                                      FacesContext facesContext = FacesContext.getCurrentInstance();
                                      ExternalContext externalContext = facesContext.getExternalContext(); 
                                      String path = externalContext.getResource("/reports/pdfRptThemeProgress.seam").getPath(); 
                                      File file = new File(path);
                                      HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
              
                                      if(file != null && file.exists()) 
                                      {
                                              FileInputStream fis = new FileInputStream(file);
                                              ServletOutputStream os = response.getOutputStream();    
                                              response.setContentType("application/pdf");
                                              response.setHeader("Content-Disposition", "attachement; filename=pdfRptThemeProgress.xhtml");
           
                                              long length = file.length();        
                                              byte[] bytes  = new byte[(int)length];
      
                                              // Read in the bytes
                                              int offset = 0;
                                              int numRead = 0;
                                              while (offset < bytes.length && (numRead=fis.read(bytes, offset, bytes.length-offset)) >= 0) 
                                              {
                                                      offset += numRead;
                                              }
                                              
                                              // Ensure all the bytes have been read in
                                              if (offset < bytes.length) {
                                                      throw new IOException("Could not completely read file "+file.getName());
                                              }
              
                                              os.write(bytes);
                                              os.flush();
                                              fis.close();
                                              os.close();
              
                                              facesContext.responseComplete();
                                      }
                                      else
                                      {
                                              System.out.println("File doesn't exist");
                                      }
                              }
                              catch (IOException ex)
                              {
                                      facesMessages.add(FacesMessage.SEVERITY_INFO, "Invalid input - IOException");
                              }
                      }
              }
      



      Any thoughts on a solution or alternative method would be appreciated.  Previously I had been opening the PDF via a javascript popup however I was having difficulties getting the report to find a graphic contained with the project.


      See previous post http://www.seamframework.org/Community/PDFGenerationImageProblemsConfigurationIssue#comment4502




        • 1. Re: Open PDF template in new window
          Pete Muir Master

          You have an NPE in your code.


          But try using ResourceLoader.instance().getResource() - it checks all classpaths in your project.

          • 2. Re: Open PDF template in new window
            Steve Hunter Newbie

            So the NPE was related to the file extension .SEAM versus .XHTML.  When I use the .XHTML extension it locates the file but unfortunately it only the xhtml tags/code and not the filled in .SEAM PDF report as seen in the browser.


            Here's the new code using the ResourceLoader method:


            FacesContext facesContext = FacesContext.getCurrentInstance();
            ExternalContext externalContext = facesContext.getExternalContext(); 
            HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();               
            URL fileURL = ResourceLoader.instance().getResource(DOWNLOAD_PATH);
            
            if(fileURL != null) 
            {
                 InputStream inputStream = fileURL.openStream();
                 BufferedInputStream buf = new BufferedInputStream(inputStream);
                 ServletOutputStream os = response.getOutputStream();     
                 response.setContentType("application/pdf");
                 response.setHeader("Content-Disposition", "attachement; filename=pdfRptThemeProgress.xhtml");
            
                 int readBytes = 0;
                 
                 //read from the file; write to the ServletOutputStream
                 while ((readBytes = buf.read()) != -1)
                 {
                      os.write(readBytes);
                 }     
            
                 os.close();
                 buf.close();     
                 facesContext.responseComplete();
            
            }               
            



            Any suggestions on how to output the XHMTL document as a PDF using this method?

            • 3. Re: Open PDF template in new window
              Steve Hunter Newbie

              CORRECTION: excuse the error, meant to say
              'unfortunately it only SHOWS the xhtml tags/code', that is it opens up in a text editor not a PDF viewer.