byte[] enc = getDocument().getEncryption().encrypt(buf, this);
return PDFText.toHex(enc, true);
} else {
- return "(" + text + ")";
+ return PDFText.escapeText(text, false);
}
}
}
//Find filespec reference for the embedded file
- filename = PDFText.toPDFString(filename, '_');
PDFArray files = embeddedFiles.getNames();
- PDFReference embeddedFileRef = null;
+ PDFFileSpec fileSpec = null;
int i = 0;
while (i < files.length()) {
- String name = (String)files.get(i);
i++;
PDFReference ref = (PDFReference)files.get(i);
- if (name.equals(filename)) {
- embeddedFileRef = ref;
+ if (ref.getObject() instanceof PDFFileSpec
+ && ((PDFFileSpec)ref.getObject()).getUnicodeFilename().equals(filename)) {
+ fileSpec = (PDFFileSpec)ref.getObject();
break;
}
i++;
}
- if (embeddedFileRef == null) {
+ if (fileSpec == null) {
throw new IllegalStateException(
"No embedded file with name " + filename + " present.");
}
//This finally seems to work:
StringBuffer scriptBuffer = new StringBuffer();
scriptBuffer.append("this.exportDataObject({cName:\"");
- scriptBuffer.append(filename);
+ scriptBuffer.append(fileSpec.getFilename());
scriptBuffer.append("\", nLaunch:2});");
PDFJavaScriptLaunchAction action = new PDFJavaScriptLaunchAction(scriptBuffer.toString());
* @param filename the filename represented by this object
*/
public PDFFileSpec(String filename) {
+ this(filename, filename);
+ }
- /* generic creation of object */
- super();
+ /**
+ * create a /FileSpec object.
+ *
+ * @param filename the filename represented by this object
+ * @param unicodeFilename the unicode filename represented by this object
+ */
+ public PDFFileSpec(String filename, String unicodeFilename) {
put("Type", new PDFName("Filespec"));
put("F", filename);
- put("UF", filename); // for non-ascii filenames, since PDF 1.7, 3.10.2
+ put("UF", unicodeFilename); // for non-ascii filenames, since PDF 1.7, 3.10.2
}
- private String getFilename() {
+ /**
+ * Gets the filename.
+ * @return filename
+ */
+ public String getFilename() {
return (String)get("F");
}
+ /**
+ * Gets the unicode filename
+ * @return unicode filename
+ */
+ public String getUnicodeFilename() {
+ return (String)get("UF");
+ }
+
/**
* Associates an dictionary with pointers to embedded file streams with this file spec.
* @param embeddedFileDict the dictionary with pointers to embedded file streams
return dPartRoot;
}
- public void addAF(PDFFileSpec fileSpec, String filename) {
+ public void addAF(PDFFileSpec fileSpec) {
if (af == null) {
af = new PDFArray();
put("AF", af);
}
af.add(fileSpec);
- fileSpec.put("UF", filename);
fileSpec.put("AFRelationship", new PDFName("Data"));
}
}
import org.apache.fop.pdf.PDFPageLabels;
import org.apache.fop.pdf.PDFReference;
import org.apache.fop.pdf.PDFSetOCGStateAction;
-import org.apache.fop.pdf.PDFText;
import org.apache.fop.pdf.PDFTransitionAction;
import org.apache.fop.pdf.PDFXMode;
import org.apache.fop.pdf.Version;
}
PDFDictionary dict = new PDFDictionary();
dict.put("F", file);
- String filename = PDFText.toPDFString(embeddedFile.getFilename(), '_');
- PDFFileSpec fileSpec = new PDFFileSpec(filename);
- pdfDoc.getRoot().addAF(fileSpec, filename);
+ PDFFileSpec fileSpec = new PDFFileSpec(embeddedFile.getFilename(), embeddedFile.getUnicodeFilename());
+ String filename = fileSpec.getFilename();
+ pdfDoc.getRoot().addAF(fileSpec);
fileSpec.setEmbeddedFile(dict);
if (embeddedFile.getDesc() != null) {
fileSpec.setDescription(embeddedFile.getDesc());
nameArray = new PDFArray();
embeddedFiles.setNames(nameArray);
}
- String name = PDFText.toPDFString(filename);
- nameArray.add(name);
+ nameArray.add(filename);
nameArray.add(new PDFReference(fileSpec));
}
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
+import org.apache.fop.pdf.PDFText;
+
/**
* This is the pass-through value object for the PDF extension.
*/
/** filename attribute */
private String filename;
+ /** unicode filename attribute */
+ private String unicodeFilename;
+
/** description attribute (optional) */
private String desc;
*/
public PDFEmbeddedFileAttachment(String filename, String src, String desc) {
super();
- this.filename = filename;
+ this.setFilename(filename);
this.src = src;
this.desc = desc;
}
return filename;
}
+ /**
+ * Returns the unicode file name.
+ * @return the file name
+ */
+ public String getUnicodeFilename() {
+ return unicodeFilename;
+ }
+
/**
* Sets the file name.
* @param name The file name to set.
*/
public void setFilename(String name) {
- this.filename = name;
+ if (!PDFText.toPDFString(name).equals(name)) {
+ // replace with auto generated filename, because non-ascii chars are used.
+ this.filename = "att" + name.hashCode();
+ } else {
+ this.filename = name;
+ }
+ this.unicodeFilename = name;
}
/**
Assert.assertTrue(out.toString().contains(
"<<\n /Type /Filespec\n /F (filename)\n /UF (filename)\n /AFRelationship /Data"));
Assert.assertTrue(out.toString().contains("<<\n/S /JavaScript\n"
- + "/JS (this.exportDataObject({cName:\"filename\", nLaunch:2});)\n>>"));
+ + "/JS (this.exportDataObject\\({cName:\"filename\", nLaunch:2}\\);)\n>>"));
+ }
+
+ @Test
+ public void testAddEmbeddedFileGermanUmlaut() throws IFException {
+ PDFDocumentHandler docHandler = new PDFDocumentHandler(new IFContext(ua));
+ docHandler.setFontInfo(new FontInfo());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ docHandler.setResult(new StreamResult(out));
+ docHandler.startDocument();
+ docHandler.startPage(0, "", "", new Dimension());
+
+ String germanAe = "\u00E4";
+ String unicodeFilename = "t" + germanAe + "st";
+ PDFEmbeddedFileAttachment fileAtt = new PDFEmbeddedFileAttachment(unicodeFilename,
+ "src", "desc");
+ docHandler.handleExtensionObject(fileAtt);
+ docHandler.getDocumentNavigationHandler().renderLink(new Link(
+ new URIAction("embedded-file:" + unicodeFilename, false), new Rectangle()));
+ docHandler.endDocument();
+ Assert.assertTrue(out.toString().contains(
+ "<<\n /Type /Filespec\n /F (" + fileAtt.getFilename() + ")\n /UF "
+ + PDFText.escapeText(fileAtt.getUnicodeFilename()) + "\n /AFRelationship /Data"));
+ Assert.assertTrue(out.toString().contains("<<\n/S /JavaScript\n"
+ + "/JS (this.exportDataObject\\({cName:\"" + fileAtt.getFilename() + "\", nLaunch:2}\\);)\n>>"));
+ }
+
+ @Test
+ public void testAddEmbeddedFileParenthesis() throws IFException {
+ PDFDocumentHandler docHandler = new PDFDocumentHandler(new IFContext(ua));
+ docHandler.setFontInfo(new FontInfo());
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ docHandler.setResult(new StreamResult(out));
+ docHandler.startDocument();
+ docHandler.startPage(0, "", "", new Dimension());
+
+ String unicodeFilename = "t(st";
+ PDFEmbeddedFileAttachment fileAtt = new PDFEmbeddedFileAttachment(unicodeFilename,
+ "src", "desc");
+ docHandler.handleExtensionObject(fileAtt);
+ docHandler.getDocumentNavigationHandler().renderLink(new Link(
+ new URIAction("embedded-file:" + unicodeFilename, false), new Rectangle()));
+ docHandler.endDocument();
+ Assert.assertTrue(out.toString().contains(
+ "<<\n /Type /Filespec\n /F (t\\(st)\n /UF (t\\(st)\n /AFRelationship /Data"));
+ Assert.assertTrue(out.toString().contains("<<\n/S /JavaScript\n"
+ + "/JS (this.exportDataObject\\({cName:\"t\\(st\", nLaunch:2}\\);)\n>>"));
}
}
assertTrue(bos.toString().contains("/Subtype /Type1\n"));
assertTrue(bos.toString().contains("/Subtype /Type1C"));
}
+
+ @Test
+ public void testGetExternalAction() {
+
+ String germanAe = "\u00E4";
+ String filename = "test";
+ String unicodeFilename = "t" + germanAe + "st.pdf";
+ PDFFileSpec fileSpec = new PDFFileSpec(filename, unicodeFilename);
+
+ PDFDocument doc = new PDFDocument("");
+ doc.registerObject(fileSpec);
+ PDFNames names = doc.getRoot().getNames();
+ if (names == null) {
+ //Add Names if not already present
+ names = doc.getFactory().makeNames();
+ doc.getRoot().setNames(names);
+ }
+
+ PDFEmbeddedFiles embeddedFiles = names.getEmbeddedFiles();
+ if (embeddedFiles == null) {
+ embeddedFiles = new PDFEmbeddedFiles();
+ doc.assignObjectNumber(embeddedFiles);
+ doc.addTrailerObject(embeddedFiles);
+ names.setEmbeddedFiles(embeddedFiles);
+ }
+
+ PDFArray nameArray = embeddedFiles.getNames();
+ if (nameArray == null) {
+ nameArray = new PDFArray();
+ embeddedFiles.setNames(nameArray);
+ }
+ nameArray.add(fileSpec.getFilename());
+ nameArray.add(new PDFReference(fileSpec));
+
+ PDFFactory pdfFactory = new PDFFactory(doc);
+ String target = "embedded-file:" + unicodeFilename;
+ PDFJavaScriptLaunchAction pdfAction = (PDFJavaScriptLaunchAction)
+ pdfFactory.getExternalAction(target, false);
+
+ String expectedString = "<<\n/S /JavaScript\n/JS (this.exportDataObject\\({cName:\""
+ + fileSpec.getFilename() + "\", nLaunch:2}\\);)\n>>";
+
+ assertEquals(expectedString, pdfAction.toPDFString());
+ }
}
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id: PDFFactoryTestCase.java 1823552 2018-02-08 12:26:33Z ssteiner $ */\r
+\r
+package org.apache.fop.pdf;\r
+\r
+import org.junit.Test;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+public class PDFFileSpecTestCase {\r
+\r
+ @Test\r
+ public void testPDFFileSpec() {\r
+ String germanAe = "\u00E4";\r
+ String filename = "test";\r
+ String unicodeFilename = "t" + germanAe + "st";\r
+ PDFFileSpec fileSpec = new PDFFileSpec(filename, unicodeFilename);\r
+ assertEquals(fileSpec.getUnicodeFilename(), unicodeFilename);\r
+ assertEquals(fileSpec.getFilename(), filename);\r
+ }\r
+}\r
package org.apache.fop.pdf;
+import org.apache.fop.render.pdf.extensions.PDFEmbeddedFileAttachmentTest;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
PDFReferenceTestCase.class,
PDFResourcesTestCase.class,
VersionTestCase.class,
- VersionControllerTestCase.class
+ VersionControllerTestCase.class,
+ PDFRootTestCase.class,
+ PDFFileSpecTestCase.class,
+ PDFEmbeddedFileAttachmentTest.class
})
public class PDFLibraryTestSuite {
}
{"examples.html?foo#bar", quote("/URI (examples.html?foo#bar)")},
{"examples.html", quote("<< /URI (examples.html)")},
{"file:examples.html", quote("<< /Type /Filespec /F (examples.html)")},
+
+ // parenthesis
+ {"simple_report_(version2.pdf", quote("<< /URI (simple_report_\\(version2.pdf)")}
});
}
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id: PDFFactoryTestCase.java 1823552 2018-02-08 12:26:33Z ssteiner $ */\r
+\r
+package org.apache.fop.pdf;\r
+\r
+import org.junit.Test;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+\r
+public class PDFRootTestCase {\r
+\r
+ @Test\r
+ public void testAddAf() {\r
+ String germanAe = "\u00E4";\r
+ String unicodeFilename = "t" + germanAe + "st.pdf";\r
+ PDFFileSpec fileSpec = new PDFFileSpec(unicodeFilename);\r
+\r
+ String filename = fileSpec.getFilename();\r
+\r
+ PDFDocument doc = new PDFDocument("");\r
+ doc.getRoot().addAF(fileSpec);\r
+\r
+ assertEquals(filename, fileSpec.getFilename());\r
+ assertEquals(unicodeFilename, fileSpec.getUnicodeFilename());\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * Licensed to the Apache Software Foundation (ASF) under one or more\r
+ * contributor license agreements. See the NOTICE file distributed with\r
+ * this work for additional information regarding copyright ownership.\r
+ * The ASF licenses this file to You under the Apache License, Version 2.0\r
+ * (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+/* $Id: PDFRenderingUtil.java 1761019 2016-09-16 10:43:45Z ssteiner $ */\r
+\r
+package org.apache.fop.render.pdf.extensions;\r
+\r
+import org.junit.Test;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertFalse;\r
+\r
+public class PDFEmbeddedFileAttachmentTest {\r
+\r
+ @Test\r
+ public void testGetFilename() {\r
+ String germanAe = "\u00E4";\r
+ String unicodeFilename = "t" + germanAe + "st";\r
+ String src = "src";\r
+ String desc = "desc";\r
+ PDFEmbeddedFileAttachment fileAtt = new PDFEmbeddedFileAttachment(unicodeFilename, src, desc);\r
+ assertEquals(fileAtt.getUnicodeFilename(), unicodeFilename);\r
+ assertFalse(fileAtt.getFilename().contains(germanAe));\r
+ assertEquals(fileAtt.getSrc(), src);\r
+ assertEquals(fileAtt.getDesc(), desc);\r
+ }\r
+\r
+}\r