13 Replies Latest reply on Apr 27, 2014 1:02 PM by senorita

    saving pdf before rendering it to ui

      Hi All,

      I am using seam-pdf.jar(i-text) for pdf generation.
      According to my business logic before rendering pdf to user i need to save it in some contenet management system(say alfresco) for future reference.

      I need byte[] of generated pdf.

      I am new to seam and what i have learned is that pdf generation in seam is on-the-fly and only last one conversation.

      Code i have written is


      ========================================================
      @Stateful
      @Name("ApostillePDFGeneratorContext")
      @Scope(ScopeType.CONVERSATION)
      public  class ApostillePDFGeneratorContextBean implements ApostillePDFGeneratorContext {
             

             
      // calling it from ui  
        public String generatePDF(){
                      tryIt();
                      return "appostillingTemplate";
              }
             
             
      //Tweak : hard coded id...how to get id at runtime..not known as of now but id per converation is always one(observation)
             
      @Begin
      private void tryIt(){
      EmptyFacesContext emptyFacesContext = new EmptyFacesContext();

      byte[] bytes = null;

      try {

      Renderer renderer = Renderer.instance();
      renderer.render("/view/ApositllePDFTemplate.xhtml");
                             
                                                         Context conversation = Contexts.getConversationContext();
                         
                                                  DocumentStore store=DocumentStore.instance();

      //I HAVE HARD CODED ID AS "1".(dont to how to get docID)                                               DocumentData data=store.getDocumentData("1");

      bytes=data.getData();
      } finally {
         emptyFacesContext.restore();
      }
        endConversation();
      }
             
      @End
      private void endConversation(){
      System.out.println("pdf conversation ended");  
      }
             
      }


      ==================================================

      public class EmptyFacesContext extends MockFacesContext {

         FacesContext originalFacesContext;

      public EmptyFacesContext(){
          super(new MockExternalContext());
      originalFacesContext =FacesContext.getCurrentInstance();
              createViewRoot();
                     
              FacesContext.setCurrentInstance(this);
          }

          public void restore(){
               setCurrentInstance(originalFacesContext);
          }

      }

      ========================================================

      My Propblem(s) :
      1) how to get docID at runtime
      2)Is there any other way to save pdf before rendering it.

      Any help would be really appreciated.
      Thanks in advance.

      Best Regards,
      Pulkit Mehra
        • 1. Re: saving pdf before rendering it to ui
          mdesignz

          There are a couple of solutions here:


          https://jira.jboss.org/jira/browse/JBSEAM-2613

          • 2. Re: saving pdf before rendering it to ui

            Hi Robert,

            Thanks for the reply.Your sugesstion really helped me but i am stuck in below piece of code.

            ===============================================================
            DocumentStore store=DocumentStore.instance();

            //I HAVE HARD CODED ID AS "1".(dont know how to get docID of generated PDF)

            DocumentData data=store.getDocumentData("1");

            Bytes[] bytes=data.getData();

            ===============================================================

            problems faced:

            1)I am not able to get docID of generated pdf by using API's.

            Any reply would be really appriciated.
            Thanks in advance.

            Regards,
            Pulkit
            • 3. Re: saving pdf before rendering it to ui
              mdesignz

              In your p:document tag, add this:


              exportKey="#{someSeamComponent.documentKey}"


              (Obviously, the component name and attribute are arbitrary).


              Then, when you get the data from the DocumentStore, reference the documentKey attribute.


              If you wanted to make your hardcoded example work, simply add this to your p:document tag and you should be all set:


              exportKey="1"


              Here's a complete example from something I'm working on:




              <p:document xmlns:ui="http://java.sun.com/jsf/facelets"
                   xmlns:f="http://java.sun.com/jsf/core"
                   xmlns:p="http://jboss.com/products/seam/pdf" type="PDF"
                   pageSize="LETTER" orientation="portrait" margins="72 72 72 72"
                   subject="Your Subject Here"
                   title="Your Title Here"
                   author="Your Name Here" creator="And Here Too"
                   keywords="Some keywords"
                   exportKey="#{pdfMap.documentKey}">
              
              




              Then, after rendering it:




              DocumentData docStoreData = (DocumentData)Contexts.getEventContext().get(pdfMap.getDocumentKey());





              Notice that you're looking at the Event context.


              Hope this helps.


              • 4. Re: saving pdf before rendering it to ui

                Hello,


                I spend a lot of time trying to put it together, thanks for the discussions around this :P
                but I don't really get it. So my question is :


                where should I call this ApostillePDFGeneratorContextBean.tryIt() ?
                Indeed every time I end up with the error : seam URI scheme is not file


                I obviously miss something but what?


                nb:I didn't modify UIDocument.java from jboss-seam-pdf-sources.jar.

                • 5. Re: saving pdf before rendering it to ui
                  Click HELP for text formatting instructions. Then edit this text and check the preview.

                  Hi Pigeret,

                  Here is my complete code :

                  1. Make a conversation bean and add this method into it :
                  //===========================================================
                  @Begin
                  public byte[] renderingPDFForBytes(){
                     
                     byte[] pdfBytes=null;
                     EmptyFacesContext emptyFacesContext = new EmptyFacesContext();
                                                                                                  byte[] bytes = null;
                  try {

                          Renderer renderer = Renderer.instance();
                          renderer.render("ApostillingTemplate.xhtml");
                    Context conversation = Contexts.getConversationContext();
                                     
                    for(String s : conversation.getNames()){
                         System.out.println("s  : "+s);
                     }
                                         
                     String h=Manager.instance().getCurrentConversationId();
                       store=DocumentStore.instance();

                    //My Proble is this hard coded ID...I need dynamic ID
                    DocumentData data=store.getDocumentData("1); 

                     pdfBytes=data.getData();

                  } finally {
                      emptyFacesContext.restore();
                     }

                     endConversation();
                     return pdfBytes;
                  }
                         
                          /**
                           * End conversation.
                           */
                          @End
                          public void endConversation(){
                                  System.out.println("pdf conversation ended");  
                          }
                         
                  //=======================================================

                  2)Here is My EmptyFacesContext :

                  //========================================================

                  import javax.faces.context.FacesContext;

                  import org.jboss.seam.mock.MockExternalContext;
                  import org.jboss.seam.mock.MockFacesContext;

                  public class EmptyFacesContext extends MockFacesContext {

                      FacesContext originalFacesContext;

                      public EmptyFacesContext(){
                          super(new MockExternalContext());
                          originalFacesContext = FacesContext.getCurrentInstance();
                          createViewRoot();
                                  System.out.println("inside empty faces context");
                          FacesContext.setCurrentInstance(this);
                      }

                      public void restore(){
                          System.out.println("inside restore");
                          setCurrentInstance(originalFacesContext);
                      }

                  }

                  //============================================================

                  3)Here is Templeate for Generating PDF .Save it as ApostillingTemplate.xhtml

                  <?xml version="1.0" encoding="UTF-8"?>
                  <p:document
                          xmlns:p="http://jboss.com/products/seam/pdf"
                          xmlns:ui="http://java.sun.com/jsf/facelets"
                          xmlns:s="http://jboss.com/products/seam/taglib"
                          xmlns:f="http://java.sun.com/jsf/core"
                          xmlns:c="http://java.sun.com/jstl/core"
                      paperSize="A4"
                      creator="PIA"
                      title="Apostilling Template"
                      type="pdf"
                      exportKey="1"
                      >

                  <p:paragraph alignment="center">
                  <p:font size="18" style="underline bold" family="Arial, Verdana, sans-serif">
                  <p:text value="APOSTILLE"/>
                  </p:font>
                  </p:paragraph>

                  <p:paragraph><p:text value="   "/></p:paragraph>

                  <p:paragraph alignment="center">
                  <p:font size="10" style="bold" family="Arial, Verdana, sans-serif">
                  <p:text value="dfdf"/>
                  </p:font>
                  </p:paragraph>

                  <p:font size="9" family="Arial, Verdana, sans-serif">
                  <p:table columns="2" widths="1 25">
                          <f:facet name="defaultCell">
                                  <p:cell horizontalAlignment="left" verticalAlignment="top" paddingTop="20" border="0">
                                  </p:cell>
                          </f:facet>

                  <p:cell><p:paragraph><p:text value="1."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph><p:text value="Country: "/> <p:text value="fsdfr"/></p:paragraph>
                  </p:cell>

                  <p:cell></p:cell>
                  <p:cell><p:paragraph><p:text value="This public document"/></p:paragraph></p:cell>

                  <p:cell><p:paragraph><p:text value="2."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph><p:text value="Has been signed by     "/> <p:text value="dsfdfd"/></p:paragraph>
                  </p:cell>

                  <p:cell><p:paragraph><p:text value="3."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph><p:text value="Acting in the capacity of     "/> <p:text value="gfgreertre"/></p:paragraph>
                  </p:cell>

                  <p:cell><p:paragraph><p:text value="4."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph><p:text value="Bears the seal/stamp     "/> <p:text value="gfgrftr"/></p:paragraph>
                  </p:cell>

                  <p:cell></p:cell>
                  <p:cell><p:paragraph><p:text value="Certified"/></p:paragraph></p:cell>

                  <p:cell><p:paragraph><p:text value="5."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph>
                  <p:text value="At "/> <p:text value="fdgrfr"/>
                  <p:text value="            "/>
                  <p:text value="6. On "/> <p:text value="fsfffgfsd"/>
                          </p:text>
                  </p:paragraph>
                  </p:cell>

                  <p:cell><p:paragraph><p:text value="7."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph>

                  </p:paragraph>
                  </p:cell>


                  <p:cell><p:paragraph><p:text value="8."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph>
                  <p:text value="Number:"/>
                  <p:text value=""/>
                  </p:paragraph>
                  </p:cell>

                  <p:cell><p:paragraph><p:text value="9."/></p:paragraph></p:cell>

                  <p:cell>
                  <p:paragraph><p:text value="Seal"/>
                  <p:text value="                           "/>
                  <p:text value="10. Signature:"/></p:paragraph>
                  </p:cell>
                  </p:table>

                  <p:table columns="5" widths="2 1 2 2 1">
                                  <f:facet name="defaultCell">
                                          <p:cell horizontalAlignment="left" verticalAlignment="top" paddingTop="20" border="0"></p:cell>
                                  </f:facet>
                                  <p:cell>
                                                  </p:cell>

                                  <p:cell></p:cell>

                                  <p:cell>
                                                                  </p:cell>


                                  <p:cell horizontalAlignment="left" verticalAlignment="bottom" paddingTop="40" border="0">
                                 
                                  <p:paragraph alignment="right></p:paragraph>

                                  </p:cell>

                                  <p:cell></p:cell>
                                  <p:cell></p:cell>

                  </p:table>
                  </p:font>

                  <p:table columns="1">
                          <f:facet name="defaultCell">
                                  <p:cell horizontalAlignment="justify" verticalAlignment="top" paddingTop="40" border="0">
                                  </p:cell>
                          </f:facet>

                          <p:cell>
                                  <p:paragraph>
                                  <p:font size="7" family="Arial, Verdana, sans-serif" style="bold">
                                 
                                  </p:font>
                                  <p:font size="7" family="Arial, Verdana, sans-serif">
                                 
                                  </p:font>
                                  </p:paragraph>
                          </p:cell>
                  </p:table>


                  </p:document>

                  //========================================================


                  4:My web.xml.

                  //========================================================

                  <?xml version="1.0" encoding="UTF-8"?>
                  <web-app id="WebApp_ID" version="2.5"
                  xmlns="http://java.sun.com/xml/ns/javaee"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
                  <display-name>ecanoc</display-name>
                  <context-param>
                    <param-name>org.richfaces.SKIN</param-name>
                    <param-value>#{themebean.skin}</param-value>
                  </context-param>
                         
                    <context-param>
                          <param-name>org.ajax4jsf.RESOURCE_URI_PREFIX</param-name>
                          <param-value>a4jResources</param-value>
                      </context-param>     

                  <!-- Filter for tomahawk -->
                  <filter>
                    <filter-name>MyFacesExtensionsFilter</filter-name>
                    <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
                    <init-param>
                     <param-name>maxFileSize</param-name>
                     <param-value>20m</param-value>
                    </init-param>
                  </filter>
                         
                  <context-param>
                    <param-name>facelets.DEVELOPMENT</param-name>
                    <param-value>true</param-value>
                  </context-param>
                  <context-param>
                    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
                    <param-value>.xhtml</param-value>
                  </context-param>
                  <context-param>
                    <param-name>org.ajax4jsf.SKIN</param-name>
                    <param-value>classic</param-value>
                  </context-param>
                  <context-param>
                    <param-name>facelets.LIBRARIES</param-name>
                    <param-value>/WEB-INF/sandbox.taglib.xml; /WEB-INF/tomahawk.taglib.xml</param-value>
                  </context-param>
                  <filter>
                    <filter-name>Seam Filter</filter-name>
                    <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
                  </filter>
                  <filter>
                    <display-name>Ajax4jsf Filter</display-name>
                    <filter-name>ajax4jsf</filter-name>
                    <filter-class>org.ajax4jsf.Filter</filter-class>
                  </filter>

                  <!-- extension mapping for adding <script/>, <link/>, and other resource tags to JSF-pages  -->

                  <!-- extension mapping for serving page-independent resources (javascript, stylesheets, images, etc.)  -->
                  <filter-mapping>
                          <filter-name>MyFacesExtensionsFilter</filter-name>
                          <!-- servlet-name must match the name of your javax.faces.webapp.FacesServlet entry -->
                          <servlet-name>Faces Servlet</servlet-name>
                      </filter-mapping>

                  <filter-mapping>
                    <filter-name>MyFacesExtensionsFilter</filter-name>
                    <url-pattern>*.xhtml</url-pattern>
                  </filter-mapping>
                  <filter-mapping>
                    <filter-name>MyFacesExtensionsFilter</filter-name>
                    <url-pattern>/faces/myFacesExtensionResource/*</url-pattern>
                  </filter-mapping>
                  <filter-mapping>
                    <filter-name>Seam Filter</filter-name>
                    <url-pattern>/*</url-pattern>
                  </filter-mapping>
                  <filter-mapping>
                    <filter-name>ajax4jsf</filter-name>
                    <servlet-name>Faces Servlet</servlet-name>
                    <dispatcher>REQUEST</dispatcher>
                    <dispatcher>FORWARD</dispatcher>
                    <dispatcher>INCLUDE</dispatcher>
                  </filter-mapping>

                  <filter>
                          <filter-name>Seam Servlet Filter</filter-name>
                          <filter-class>org.jboss.seam.servlet.SeamServletFilter</filter-class>
                  </filter>
                  <filter-mapping>
                          <filter-name>Seam Servlet Filter</filter-name>
                          <url-pattern>*.pdf</url-pattern>
                  </filter-mapping>

                  <listener>
                    <listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
                  </listener>
                  <servlet>
                    <servlet-name>Faces Servlet</servlet-name>
                    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
                    <load-on-startup>1</load-on-startup>
                  </servlet>
                  <servlet>
                    <servlet-name>Seam Resource Servlet</servlet-name>
                    <servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
                  </servlet>

                  <servlet-mapping>
                    <servlet-name>Faces Servlet</servlet-name>
                    <url-pattern>*.xhtml</url-pattern>
                  </servlet-mapping>
                  <servlet-mapping>
                    <servlet-name>Seam Resource Servlet</servlet-name>
                    <url-pattern>/seam/resource/*</url-pattern>
                  </servlet-mapping>

                  <welcome-file-list>
                    <welcome-file>index.xhtml</welcome-file>
                  </welcome-file-list>
                  <login-config>
                    <auth-method>BASIC</auth-method>
                  </login-config>
                  <!--<security-constraint>
                    <display-name>Restrict raw XHTML Documents</display-name>
                    <web-resource-collection>
                     <web-resource-name>XHTML</web-resource-name>
                     <url-pattern>*.xhtml</url-pattern>
                    </web-resource-collection>
                    <auth-constraint/>
                  </security-constraint>
                  <login-config>
                    <auth-method>BASIC</auth-method>
                  </login-config>-->
                  <session-config>
                          <session-timeout>30</session-timeout>
                  </session-config>
                  </web-app>



                  //==========================================================

                  5: Call Conversation bean method(renderingPDFForBytes).PDF is generated on the fly in one request cycle.In order to get PDF bytes we have to mention its unique ID..which is  always 1(my observation).
                  Still i am not able to get ID by using some Seam API.

                  I hope this will Help.

                  regards,
                  Pulkit
                  • 6. Re: saving pdf before rendering it to ui
                    Hi thanks for the complete reply,
                    nevertheless still doesn't work.

                    I have seam 2.1.1GA.

                    when it is on the line :
                    EmptyFacesContext emptyFacesContext = new EmptyFacesContext();

                    I still got this exception so I assume I don't understand this line and what it is involving
                    since I can't figure out why it is throwing an error.
                    So I still need you help on that one

                    20:52:37,076 ERROR [STDERR] java.lang.IllegalArgumentException: URI scheme is not "file"
                    20:52:37,097 ERROR [STDERR]      at java.io.File.<init>(File.java:366)
                    20:52:37,097 ERROR [STDERR]      at org.jboss.seam.mock.MockServletContext.<init>(MockServletContext.java:59)
                    20:52:37,097 ERROR [STDERR]      at org.jboss.seam.mock.MockExternalContext.<init>(MockExternalContext.java:50)
                    20:52:37,098 ERROR [STDERR]      at com.nerodia.pdf.EmptyFacesContext.<init>(EmptyFacesContext.java:14)
                    20:52:37,098 ERROR [STDERR]      at com.nerodia.pdf.PdfSaverByte.renderingPDFForBytes(PdfSaverByte.java:50)
                    20:52:37,099 ERROR [STDERR]      at com.nerodia.pdf.PdfSaverByte.generatePDF(PdfSaverByte.java:39)
                    20:52:37,099 ERROR [STDERR]      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                    20:52:37,099 ERROR [STDERR]      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                    20:52:37,099 ERROR [STDERR]      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                    20:52:37,100 ERROR [STDERR]      at java.lang.reflect.Method.invoke(Method.java:597)
                    20:52:37,100 ERROR [STDERR]      at org.jboss.aop.joinpoint.MethodInvocation.invokeTarget(MethodInvocation.java:122)
                    20:52:37,100 ERROR [STDERR]      at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:111)
                    20:52:37,100 ERROR [STDERR]      at org.jboss.ejb3.EJBContainerInvocationWrapper.invokeNext(EJBContainerInvocationWrapper.java:69)
                    20:52:37,100 ERROR [STDERR]      at org.jboss.ejb3.interceptors.aop.InvocationContextInterceptor$InvocationContext.proceed(InvocationContextInterceptor.java:138)
                    ................
                    • 7. Re: saving pdf before rendering it to ui
                      if it can enlight you this line throw the exception `first`
                      (MockServletContext.java:59) :

                      webappRoot = new File(getClass().getResource("/.").toURI());

                      I also use urlrewrite, in my project.
                      Can it be problematic?
                      • 8. Re: saving pdf before rendering it to ui

                        hi,
                        me again...
                        I tried lots of way to solve this problem,
                        but I am stuck :/
                        I don't want to use the solution which consist on modifying the pdflib because
                        sometime the web user will need to download the pdf, and sometime we will need to save
                        it first to make a preview (on the fly).
                        Honestly I spend the last few evening trying to understand what is the problem.


                        So my team and I have :
                        JSeam 2.1.1GA
                        JBoss-5.0.1.GA
                        EAR project


                        the vfs folder doesn't seam to exists and so the web.xml doesn't either.


                        Just ask if I can give more infos,


                        I am stuck,
                        this sound like an SOS and it is.
                        Is there another way to get a byte response?



                        Sincerely,
                        black bird

                        • 9. Re: saving pdf before rendering it to ui

                          Hi guys,


                          Are there any luck on this?


                          The problem seems to be originated from the vfs in jboss.


                          Constructor of MockServletContext:59 is throwing the exception


                          webappRoot = new File(getClass().getResource("/.").toURI());
                          because getClass().getResource("/.").toURI() returns vsfmemory:///blahblah instead of the expected "file:///c:/jbossdeployment"


                          vsfmemory:/// is not a URI file scheme.


                          Inputs are very much appreciated.


                          Thanks,


                          Ivan

                          • 10. Re: saving pdf before rendering it to ui
                            zeppelinux.dmitry.diligesoft.com

                            I found the solution that works for me.




                            class EmptyFacesContext extends MockFacesContext {
                            
                                FacesContext originalFacesContext;
                            
                                public EmptyFacesContext() {
                                    super(new MockExternalContext(new MyMockServletContext()));
                                    originalFacesContext = FacesContext.getCurrentInstance();
                                    createViewRoot();
                                    FacesContext.setCurrentInstance(this);
                                }
                            
                                public void restore() {
                                    setCurrentInstance(originalFacesContext);
                                }
                            
                            }



                            Note the MyMockServletContext in the constructor, it is the same code as MockServletContext coming with Seam except of the line for discovering the web.xml path:



                            File webxml = new File(((ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext()).getRealPath("/WEB-INF/web.xml"));




                            It returns correct path in my environment (Glassfish V2)


                            • 11. Re: saving pdf before rendering it to ui

                              Problem has been solved now. The same work in JBossAS 5.1


                              Thanks

                              • 12. Re: saving pdf before rendering it to ui
                                r0b3n

                                I know this thread is a bit old but I just struggled to save multiple generated documents into single files. As none of the mentioned solutions worked for me with seam 2.2.2, I finally came up with this strikingly simple solution:

                                private static ByteArrayDocumentData getMostRecentDocumentDataFromStore() throws IOException, IllegalArgumentException {
                                        DocumentStore doc = DocumentStore.instance();
                                        // try to find the last available id
                                        Integer lastId = 1;
                                        while (doc.idIsValid(lastId.toString())) {
                                            lastId++;
                                        }
                                        ByteArrayDocumentData docStoreData = (ByteArrayDocumentData) doc.getDocumentData(Long.toString(lastId - 1));
                                        return docStoreData;
                                    }

                                 

                                So I simply increment a counter until the document store says it is an invalid ID. Than I use the last value which worked. Saves me from using MockContexts or Reflection...

                                • 13. Re: saving pdf before rendering it to ui
                                  senorita

                                  Dear Robert,

                                   

                                  Would you please send me the source code that you tried. Thanks in advance.@