6
votes

I'm attempting to set the copyright metadata of a PDF using ColdFusion & iText. Adobe ColdFusion 9-11 allow getting & setting the Title, Subject, Keywords, Creator & Author fields, but doesn't appear to allow access to the "Additional Metadata" properties. (This is my first SO question.)

I found a potential iTextSharp/C# solution and have tried to convert it to CFML, but I haven't been able to determine how to successfully access System.IO.MemoryStream() w/ColdFusion. I get a "Could not find the ColdFusion component or interface MemoryStream. Ensure that the name is correct and that the component or interface exists." error and searching the internet doesn't offer any results.

https://stackoverflow.com/a/6942531/693068

NOTE: I'm using iText because the PDF files are created using ABBYY FineReader. I've encountered numerous issues in the past where ColdFusion refuses to identify non-Acrobat-generated PDFs as valid PDFs when using isPDFFile().

Any ideas? Does the functionality currently exist and just not documented anywhere? Thanks.

2

2 Answers

5
votes

(Too long for comments ...)

As Ryan mentioned, it might be possible using DDX. The cfpdf documentation lists Metadata as a supported element. So you may want to look into that option first.

I found a potential iTextSharp/C# solution

That said, there is no need to use an external C# library. CF is already bundled with an older version of iText (written in java). So use the java classes instead. iTextSharp is a port of the original java library, so the class and method names will usually be the same.

source = "c:/path/to/input.pdf";
target = "c:/path/to/output.pdf";
reader = createObject("java", "com.lowagie.text.pdf.PdfReader").init( source );
output = createObject("java", "java.io.FileOutputStream").init( target );
stamper = createObject("java", "com.lowagie.text.pdf.PdfStamper").init( reader, output );

copyrightName = "YOUR NAME HERE";
copyrightUrl = "http://www.example.com/";

baos = createObject("java", "java.io.ByteArrayOutputStream").init();
xmp = createObject("java", "com.lowagie.text.xml.xmp.XmpWriter").init(baos);
xmp.addRdfDescription("xmlns:dc=""http://purl.org/dc/elements/1.1/""", "<dc:rights><rdf:Alt><rdf:li xml:lang=""x-default"">"& copyrightName &"</rdf:li></rdf:Alt></dc:rights>");
xmp.addRdfDescription("xmlns:xmpRights=""http://ns.adobe.com/xap/1.0/rights/"""
                        , "<xmpRights:Marked>True</xmpRights:Marked><xmpRights:WebStatement>"& copyrightUrl &"</xmpRights:WebStatement>");
xmp.close();
stamper.setXmpMetadata(baos.toByteArray());
stamper.close();    
1
votes

You may be able to do this with the DDX capabilities. See these links:

System.IO.MemoryStream is a C# class. You won't be able to access it from CFML directly. You could try to use the .net integration features to access it, or the iTextSharp solution, directly.