001/* 002 * $Id: PdfFileSpecification.java 4784 2011-03-15 08:33:00Z blowagie $ 003 * 004 * This file is part of the iText (R) project. 005 * Copyright (c) 1998-2011 1T3XT BVBA 006 * Authors: Bruno Lowagie, Paulo Soares, et al. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Affero General Public License version 3 010 * as published by the Free Software Foundation with the addition of the 011 * following permission added to Section 15 as permitted in Section 7(a): 012 * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY 1T3XT, 013 * 1T3XT DISCLAIMS THE WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 014 * 015 * This program is distributed in the hope that it will be useful, but 016 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 017 * or FITNESS FOR A PARTICULAR PURPOSE. 018 * See the GNU Affero General Public License for more details. 019 * You should have received a copy of the GNU Affero General Public License 020 * along with this program; if not, see http://www.gnu.org/licenses or write to 021 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 022 * Boston, MA, 02110-1301 USA, or download the license from the following URL: 023 * http://itextpdf.com/terms-of-use/ 024 * 025 * The interactive user interfaces in modified source and object code versions 026 * of this program must display Appropriate Legal Notices, as required under 027 * Section 5 of the GNU Affero General Public License. 028 * 029 * In accordance with Section 7(b) of the GNU Affero General Public License, 030 * a covered work must retain the producer line in every PDF that is created 031 * or manipulated using iText. 032 * 033 * You can be released from the requirements of the license by purchasing 034 * a commercial license. Buying such a license is mandatory as soon as you 035 * develop commercial activities involving the iText software without 036 * disclosing the source code of your own applications. 037 * These activities include: offering paid services to customers as an ASP, 038 * serving PDFs on the fly in a web application, shipping iText with a closed 039 * source product. 040 * 041 * For more information, please contact iText Software Corp. at this 042 * address: sales@itextpdf.com 043 */ 044package com.itextpdf.text.pdf; 045 046import java.io.File; 047import java.io.FileInputStream; 048import java.io.IOException; 049import java.io.InputStream; 050import java.net.URL; 051import com.itextpdf.text.error_messages.MessageLocalization; 052 053import com.itextpdf.text.pdf.collection.PdfCollectionItem; 054/** Specifies a file or an URL. The file can be extern or embedded. 055 * 056 * @author Paulo Soares 057 */ 058public class PdfFileSpecification extends PdfDictionary { 059 protected PdfWriter writer; 060 protected PdfIndirectReference ref; 061 062 /** Creates a new instance of PdfFileSpecification. The static methods are preferred. */ 063 public PdfFileSpecification() { 064 super(PdfName.FILESPEC); 065 } 066 067 /** 068 * Creates a file specification of type URL. 069 * @param writer the <CODE>PdfWriter</CODE> 070 * @param url the URL 071 * @return the file specification 072 */ 073 public static PdfFileSpecification url(PdfWriter writer, String url) { 074 PdfFileSpecification fs = new PdfFileSpecification(); 075 fs.writer = writer; 076 fs.put(PdfName.FS, PdfName.URL); 077 fs.put(PdfName.F, new PdfString(url)); 078 return fs; 079 } 080 081 /** 082 * Creates a file specification with the file embedded. The file may 083 * come from the file system or from a byte array. The data is flate compressed. 084 * @param writer the <CODE>PdfWriter</CODE> 085 * @param filePath the file path 086 * @param fileDisplay the file information that is presented to the user 087 * @param fileStore the byte array with the file. If it is not <CODE>null</CODE> 088 * it takes precedence over <CODE>filePath</CODE> 089 * @throws IOException on error 090 * @return the file specification 091 */ 092 public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[]) throws IOException { 093 return fileEmbedded(writer, filePath, fileDisplay, fileStore, PdfStream.BEST_COMPRESSION); 094 } 095 096 /** 097 * Creates a file specification with the file embedded. The file may 098 * come from the file system or from a byte array. The data is flate compressed. 099 * @param writer the <CODE>PdfWriter</CODE> 100 * @param filePath the file path 101 * @param fileDisplay the file information that is presented to the user 102 * @param fileStore the byte array with the file. If it is not <CODE>null</CODE> 103 * it takes precedence over <CODE>filePath</CODE> 104 * @param compressionLevel the compression level to be used for compressing the file 105 * it takes precedence over <CODE>filePath</CODE> 106 * @throws IOException on error 107 * @return the file specification 108 * @since 2.1.3 109 */ 110 public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], int compressionLevel) throws IOException { 111 return fileEmbedded(writer, filePath, fileDisplay, fileStore, null, null, compressionLevel); 112 } 113 114 115 /** 116 * Creates a file specification with the file embedded. The file may 117 * come from the file system or from a byte array. 118 * @param writer the <CODE>PdfWriter</CODE> 119 * @param filePath the file path 120 * @param fileDisplay the file information that is presented to the user 121 * @param fileStore the byte array with the file. If it is not <CODE>null</CODE> 122 * it takes precedence over <CODE>filePath</CODE> 123 * @param compress sets the compression on the data. Multimedia content will benefit little 124 * from compression 125 * @throws IOException on error 126 * @return the file specification 127 */ 128 public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], boolean compress) throws IOException { 129 return fileEmbedded(writer, filePath, fileDisplay, fileStore, null, null, compress ? PdfStream.BEST_COMPRESSION : PdfStream.NO_COMPRESSION); 130 } 131 132 /** 133 * Creates a file specification with the file embedded. The file may 134 * come from the file system or from a byte array. 135 * @param writer the <CODE>PdfWriter</CODE> 136 * @param filePath the file path 137 * @param fileDisplay the file information that is presented to the user 138 * @param fileStore the byte array with the file. If it is not <CODE>null</CODE> 139 * it takes precedence over <CODE>filePath</CODE> 140 * @param compress sets the compression on the data. Multimedia content will benefit little 141 * from compression 142 * @param mimeType the optional mimeType 143 * @param fileParameter the optional extra file parameters such as the creation or modification date 144 * @throws IOException on error 145 * @return the file specification 146 */ 147 public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], boolean compress, String mimeType, PdfDictionary fileParameter) throws IOException { 148 return fileEmbedded(writer, filePath, fileDisplay, fileStore, mimeType, fileParameter, compress ? PdfStream.BEST_COMPRESSION : PdfStream.NO_COMPRESSION); 149 } 150 151 /** 152 * Creates a file specification with the file embedded. The file may 153 * come from the file system or from a byte array. 154 * @param writer the <CODE>PdfWriter</CODE> 155 * @param filePath the file path 156 * @param fileDisplay the file information that is presented to the user 157 * @param fileStore the byte array with the file. If it is not <CODE>null</CODE> 158 * it takes precedence over <CODE>filePath</CODE> 159 * @param mimeType the optional mimeType 160 * @param fileParameter the optional extra file parameters such as the creation or modification date 161 * @param compressionLevel the level of compression 162 * @throws IOException on error 163 * @return the file specification 164 * @since 2.1.3 165 */ 166 public static PdfFileSpecification fileEmbedded(PdfWriter writer, String filePath, String fileDisplay, byte fileStore[], String mimeType, PdfDictionary fileParameter, int compressionLevel) throws IOException { 167 PdfFileSpecification fs = new PdfFileSpecification(); 168 fs.writer = writer; 169 fs.put(PdfName.F, new PdfString(fileDisplay)); 170 fs.setUnicodeFileName(fileDisplay, false); 171 PdfEFStream stream; 172 InputStream in = null; 173 PdfIndirectReference ref; 174 PdfIndirectReference refFileLength = null; 175 try { 176 if (fileStore == null) { 177 refFileLength = writer.getPdfIndirectReference(); 178 File file = new File(filePath); 179 if (file.canRead()) { 180 in = new FileInputStream(filePath); 181 } 182 else { 183 if (filePath.startsWith("file:/") || filePath.startsWith("http://") || filePath.startsWith("https://") || filePath.startsWith("jar:")) { 184 in = new URL(filePath).openStream(); 185 } 186 else { 187 in = BaseFont.getResourceStream(filePath); 188 if (in == null) 189 throw new IOException(MessageLocalization.getComposedMessage("1.not.found.as.file.or.resource", filePath)); 190 } 191 } 192 stream = new PdfEFStream(in, writer); 193 } 194 else { 195 stream = new PdfEFStream(fileStore); 196 } 197 stream.put(PdfName.TYPE, PdfName.EMBEDDEDFILE); 198 stream.flateCompress(compressionLevel); 199 PdfDictionary param = new PdfDictionary(); 200 if (fileParameter != null) { 201 param.merge(fileParameter); 202 } 203 204 if (fileStore != null) { 205 param.put(PdfName.SIZE, new PdfNumber(stream.getRawLength())); 206 stream.put(PdfName.PARAMS, param); 207 } 208 else 209 stream.put(PdfName.PARAMS, refFileLength); 210 211 if (mimeType != null) 212 stream.put(PdfName.SUBTYPE, new PdfName(mimeType)); 213 214 ref = writer.addToBody(stream).getIndirectReference(); 215 if (fileStore == null) { 216 stream.writeLength(); 217 param.put(PdfName.SIZE, new PdfNumber(stream.getRawLength())); 218 writer.addToBody(param, refFileLength); 219 } 220 } 221 finally { 222 if (in != null) 223 try{in.close();}catch(Exception e){} 224 } 225 PdfDictionary f = new PdfDictionary(); 226 f.put(PdfName.F, ref); 227 f.put(PdfName.UF, ref); 228 fs.put(PdfName.EF, f); 229 return fs; 230 } 231 232 /** 233 * Creates a file specification for an external file. 234 * @param writer the <CODE>PdfWriter</CODE> 235 * @param filePath the file path 236 * @return the file specification 237 */ 238 public static PdfFileSpecification fileExtern(PdfWriter writer, String filePath) { 239 PdfFileSpecification fs = new PdfFileSpecification(); 240 fs.writer = writer; 241 fs.put(PdfName.F, new PdfString(filePath)); 242 fs.setUnicodeFileName(filePath, false); 243 return fs; 244 } 245 246 /** 247 * Gets the indirect reference to this file specification. 248 * Multiple invocations will retrieve the same value. 249 * @throws IOException on error 250 * @return the indirect reference 251 */ 252 public PdfIndirectReference getReference() throws IOException { 253 if (ref != null) 254 return ref; 255 ref = writer.addToBody(this).getIndirectReference(); 256 return ref; 257 } 258 259 /** 260 * Sets the file name (the key /F) string as an hex representation 261 * to support multi byte file names. The name must have the slash and 262 * backslash escaped according to the file specification rules 263 * @param fileName the file name as a byte array 264 */ 265 public void setMultiByteFileName(byte fileName[]) { 266 put(PdfName.F, new PdfString(fileName).setHexWriting(true)); 267 } 268 269 /** 270 * Adds the unicode file name (the key /UF). This entry was introduced 271 * in PDF 1.7. The filename must have the slash and backslash escaped 272 * according to the file specification rules. 273 * @param filename the filename 274 * @param unicode if true, the filename is UTF-16BE encoded; otherwise PDFDocEncoding is used; 275 */ 276 public void setUnicodeFileName(String filename, boolean unicode) { 277 put(PdfName.UF, new PdfString(filename, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING)); 278 } 279 280 /** 281 * Sets a flag that indicates whether an external file referenced by the file 282 * specification is volatile. If the value is true, applications should never 283 * cache a copy of the file. 284 * @param volatile_file if true, the external file should not be cached 285 */ 286 public void setVolatile(boolean volatile_file) { 287 put(PdfName.V, new PdfBoolean(volatile_file)); 288 } 289 290 /** 291 * Adds a description for the file that is specified here. 292 * @param description some text 293 * @param unicode if true, the text is added as a unicode string 294 */ 295 public void addDescription(String description, boolean unicode) { 296 put(PdfName.DESC, new PdfString(description, unicode ? PdfObject.TEXT_UNICODE : PdfObject.TEXT_PDFDOCENCODING)); 297 } 298 299 /** 300 * Adds the Collection item dictionary. 301 */ 302 public void addCollectionItem(PdfCollectionItem ci) { 303 put(PdfName.CI, ci); 304 } 305}