Expand my Community achievements bar.

Dive into Adobe Summit 2024! Explore curated list of AEM sessions & labs, register, connect with experts, ask questions, engage, and share insights. Don't miss the excitement.
SOLVED

Passing Flat PDF Name to DDX invoke method

Avatar

Level 4

Hi folks

I have a ask to generate PDF file which has blank pdf assembled with main pdf.

I had generated main PDF from XDP using OutputService.generatePDFOutput() and received a aemfd document PDF.

Now i have DDX file which is like below and I am not what I should be putting in 1st child <PDF source="<Name or Path...." tag.

<DDX xmlns="http://ns.adobe.com/DDX/1.0/">
  <PDF result="PDFWithblankPage">
    <!--Add this page to ddx_pageList-->
    <PDF source="<Name or Path for main PDF>"/>
    <PDF source="<Network Drive>/blank.pdf"/>
  </PDF>
</DDX>

 

I have checked the DDX file operation and it is working fine if I generate a static PDF, copy it at physical location with some name to PDF and provide the same Name to this DDX file. And it generates the desired PDF with blank page.

 

However I dont want intermediate PDF to be saved to a location and then pass to DDX as it will result in many temp PDFs getting created at that location and clean up will be an issue

 

Is there a way through which I can achieve the solution.

 

P.S. I am creating DDX file dynamically using java code everytime so that dynamic values can be filled.

1 Accepted Solution

Avatar

Correct answer by
Level 4

Hi Folks

I was able to achieve the solution by storing the PDF intermediately generated in temp location and then reading it from there to further DDX operation.

Thanks all for your suggestions and input, it helped build the solution.

 

View solution in original post

17 Replies

Avatar

Employee

You can use the AssemblerService API with

AssemblerResult invoke(Document ddx,
                       Map<String,Object> inputs,
                       AssemblerOptionSpec environment)
                throws OperationException

The DDX would contain <PDF source="<Name>"/>. you build a map for inputs where your document is an entry with String key "Name" and an com.adobe.aemfd.docmanager.Document object containing the document from the OutputService.generatePDFOutput() call.

Avatar

Level 4

Thanks Kosta,I am exactly doing this operation only, just to addI am assigning name to PDF generated from OutputService.generatePDFOutput using setAttribute("Name","FormName")

Now using this FormName i am creating input Map.

 

Now the issue, when I passing PDF originally generated in map is showing error

java.lang.IllegalStateException: Document is in a disposed state!
        at com.adobe.aemfd.docmanager.Document.checkDisposed(Document.java:236)
        at com.adobe.aemfd.docmanager.Document.passivate(Document.java:317)
        at com.adobe.aemfd.docmanager.Document.getInputStream(Document.java:357)

 

not sure from where this is getting injected

 

Avatar

Level 4

Just to add more details, first i am getting PDF document Information by invoking below DDX and passing PDF Document along to get info.xml

<DDX xmlns="http://ns.adobe.com/DDX/1.0/">
<DocumentInformation result="info.xml" source="formname.pdf"/>
</DDX>

 then parsing this info.xml by converting aemfd document retrieved to w3c Dom Document and getting Number of Pages.

At this point main pdf is throwing exception Document is in disposed state.

 

My requirement is to then invoke another Assembler DDX operation to combine main pdf with blank page pdf, but failing to get main pdf document.

Avatar

Employee

You would not need to get the formname unless you use it to dispay something. The "Name" part in DDX and inputs map is free to use. The Map only needs to have the same string key as the name in the DDX. You could actually use "name" literally for both. No need to modify the document. And are you sure the disposed state refers to your rendered document? Having this other info DDX may actually cause the originally rendered document to be disposed of (basically a form of garbage collection). What do you do with the number of pages information? Do you need it to assemble the 2 documents?

Avatar

Employee
BTW, there is a Blankpage DDX tag which adds a blank page without a file. If your empty page is really empty that might be an option. DDX reference: https://helpx.adobe.com/content/dam/help/en/experience-manager/6-5/forms/pdf/ddxRef.pdf

Avatar

Employee Advisor

@manu-gupta if you have to work with multiple document generated by more than one service use workbench and handle it in-memory. Safer option and reliable.

Avatar

Level 4

Nope it is same PDF for which I am getting the page count using one DDX and post doing some calculation based on page count I need to update the same PDF with new blank pages. I cannot use Workbench as solution is supposed to be on AEM 6.5.7/8 with Forms OSGI.

 

@Mayank_Gandhi @Kosta_Prokopiu1 any other way I can store the PDF before it is in disposition state?

Avatar

Employee
as you have OSGi Workbench will not help you. But there are AEM Forms workflows you could use instead of Java programming. There is also an Assembler step available. See here: https://experienceleague.adobe.com/docs/experience-manager-65/forms/workflows/aem-forms-workflow-ste...

Avatar

Employee Advisor
@manu-gupta why to even use assembler just add a blank page in xdp template itself.

Avatar

Level 4

@Mayank_Gandhi - Please keep it unanswered as my problem is different from what you suggest.

 

I have same XDP template serving different needs, for flat, fillable or print. ONLY in the case of print I am adding blank PDF page so I cannot put that in XDP. Hence I am looking for DDX operation to first generate the flat PDF then combine it with blank pdf at different places of main PDF(in between and as well as last pages) to generate Print version.

 

Since I am on OSGI architecture so cannot use Workbench. So do you have any other alternate solution which I can use in JAVA API based maven project. This is using servlet call to trigger Assembler Service invoke Method.

 

I am on AEM 6.5.8 with forms package 6.0.334 and using corresponding jars.

 

Thanks

Avatar

Employee Advisor

@manu-guptaI am not marking it answered and we can't anyways. The solution was suggested as there was no architecture specified in the initial thread. The problem now you have highlighted has little to do with assembler and output but more on the implementation side. What's the diff between a print and a flat pdf? I don't think this is possible via API  without saving it to the disk/FTP or in temp. You can check with adobe consulting or support though.

Avatar

Employee

Find some more ideas regarding your assembly:

<DDX xmlns="http://ns.adobe.com/DDX/1.0/">
  <PDF result="outDoc">
    <XDP>
      <XDP source="xdp1"/>
      <XFAData source="xmldata"/>
    </XDP>
    <NoXFA flatten="true"/>
    <BlankPage/>
  </PDF>
</DDX>

This will take your XDP (all can be placed in the inputs map as Document objects in your java), render it as flat, no-XFA PDF with XML data coming from another Document object in the inputs map. Finally I add a BlankPage at the end (it can be positioned anywhere with DDX). DDX is very versatile but outside simple example such as this, it is not always easily visible how you could do things.

If you leave the NoXFA out you get an interactive XFA based PDF form.

 

And, you can put together the DDX as a string based on logic in your Java to match what you require.

Avatar

Level 4

this ddx xml i started with, my requirement is slightly more complex:

Flow start like this:

1. Upstream application sends JSON data

2. JAVA code converts the JSON to XML Data

3. Passes XDP path with XML Data to Output Services to generate flat pdf.

4. This PDF is sent to customer, if customer had requested Print Version then this PDF is converted to Print version as below

5. Once PDF is generated in step 4, its pages are to be calculated

6. If pdf has pages in multiples of 4, then we need to add 1 Number dynamically to PDF, which can done only using DDX operation, I cannot hardcode in XDP and then return the PDF 

7. If pages are NOT multiples of 4, then I have to 2 types of blank PDFs

8. Type 1 blank PDF will hold only text in center "Inserted Blank intentionally" and has to be placed as filler except on last Page, for e.g. if original PDF was 17 pages. then type 1 blank pdf will be placed on 18.19 pages.

9. Type 2 blank PDF will hold text in center "Inserted Blank Intentionally" along with Number on last page, like in example mentioned in previous step, this pdf blank will be placed on page 20.

10 then Final print version is generated to customer.

 

All the above steps require multiple DDX operation on main flat PDF, but after 1 DDX operation PDF is in Deposition state, which i am looking for answer.

 

Thanks again for help and guidance.

 

Manu

Avatar

Employee

Hi @manu-gupta
Let's go through your points and get some clarifications:
re 4.: does this mean that the PDF that you generate with DocumentService is not immediately used for assembly but goes directly to the customer as is? What is the difference between a flat PDF from DocService and the "Print version"? I am not sure I understand the sequence of events fully yet.
re 6.: What do you mean with "we need to add a 1 Number dynamically to PDF"? Page numbers? Or is this some kind of transaction ID that you need to put somewhere on the pages?
re 8.: Is type 1 filling the document to the next multiple of 4? so when we have 6 pages I would add 1 type 1 blank for page 7 and the special type 2 for page 8?

Avatar

Level 4

@Kosta_Prokopiu1  @Mayank_Gandhi 

at Step 4, there is condition we have put, if request is for flat, then PDF without any additional blank pages are generated and shared with customer. If the request has Print = true then we pass this flat pdf to DDX operation to add blank pages as described in step 6 onwards.

@Kosta_Prokopiu1 to answer your question "we need to add a 1 Number dynamically to PDF"? - it is just business defined number which needs to be added to footer of the page

your second q - Answer is YES, we had to add blanks that way.

 

One clear observation I had today - When my source flat non interactive static PDF is generated from output services and sent directly to DDX operations then I get error exception "500 Document is in a disposed state".

However if I decouple the process by:

1. generating the PDF from output services

2. storing in physical location

3. fetching the saved PDF and then doing DDX operation, then the solution works fine.

 

What is the issue when I directly consume PDF as Document Object and then send to DDX operation, why it is not working?

 

 

Avatar

Employee

Hi @manu-gupta ,

I am not sure why your Document variable is disposed before you use it in your DDX. But I have created a sample of a dynamic form which would produce the kind of blank pages depending on the number of content pages.See here https://documentcloud.adobe.com/link/track?uri=urn:aaid:scds:US:e101914c-4172-4668-937a-223e97aba5b4

It works based on 2 fields in the XML data

<root>
<printflag>1</printflag>
<bid>XYZ1765</bid>
</root>

If the printflag is 1 then the additional pages are shown, otherwise they stay hidden. bid is the business id which can be placed on the last page (I used the Masterpage but you are free to put it anywhere.

You can test the dynamic part by changing the number of records

Kosta_Prokopiu1_0-1622586098587.png

You would not need DDX in this case, just render the PDF with the printflag in the data. Preview with data in Designer.

Avatar

Correct answer by
Level 4

Hi Folks

I was able to achieve the solution by storing the PDF intermediately generated in temp location and then reading it from there to further DDX operation.

Thanks all for your suggestions and input, it helped build the solution.