001/*
002 * $Id: PdfCopyFields.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.IOException;
047import java.io.OutputStream;
048import java.security.cert.Certificate;
049import java.util.HashMap;
050import java.util.List;
051
052import com.itextpdf.text.DocWriter;
053import com.itextpdf.text.DocumentException;
054import com.itextpdf.text.pdf.interfaces.PdfEncryptionSettings;
055import com.itextpdf.text.pdf.interfaces.PdfViewerPreferences;
056
057/**
058 * Concatenates PDF documents including form fields. The rules for the form field
059 * concatenation are the same as in Acrobat. All the documents are kept in memory unlike
060 * PdfCopy.
061 * @author  Paulo Soares
062 */
063public class PdfCopyFields
064        implements PdfViewerPreferences, PdfEncryptionSettings {
065
066    private PdfCopyFieldsImp fc;
067
068    /**
069     * Creates a new instance.
070     * @param os the output stream
071     * @throws DocumentException on error
072     */
073    public PdfCopyFields(OutputStream os) throws DocumentException {
074        fc = new PdfCopyFieldsImp(os);
075    }
076
077    /**
078     * Creates a new instance.
079     * @param os the output stream
080     * @param pdfVersion the pdf version the output will have
081     * @throws DocumentException on error
082     */
083    public PdfCopyFields(OutputStream os, char pdfVersion) throws DocumentException {
084        fc = new PdfCopyFieldsImp(os, pdfVersion);
085    }
086
087    /**
088     * Concatenates a PDF document.
089     * @param reader the PDF document
090     * @throws DocumentException on error
091     */
092    public void addDocument(PdfReader reader) throws DocumentException, IOException {
093        fc.addDocument(reader);
094    }
095
096    /**
097     * Concatenates a PDF document selecting the pages to keep. The pages are described as a
098     * <CODE>List</CODE> of <CODE>Integer</CODE>. The page ordering can be changed but
099     * no page repetitions are allowed.
100     * @param reader the PDF document
101     * @param pagesToKeep the pages to keep
102     * @throws DocumentException on error
103     */
104    public void addDocument(PdfReader reader, List<Integer> pagesToKeep) throws DocumentException, IOException {
105        fc.addDocument(reader, pagesToKeep);
106    }
107
108    /**
109     * Concatenates a PDF document selecting the pages to keep. The pages are described as
110     * ranges. The page ordering can be changed but
111     * no page repetitions are allowed.
112     * @param reader the PDF document
113     * @param ranges the comma separated ranges as described in {@link SequenceList}
114     * @throws DocumentException on error
115     */
116    public void addDocument(PdfReader reader, String ranges) throws DocumentException, IOException {
117        fc.addDocument(reader, SequenceList.expand(ranges, reader.getNumberOfPages()));
118    }
119
120    /** Sets the encryption options for this document. The userPassword and the
121     *  ownerPassword can be null or have zero length. In this case the ownerPassword
122     *  is replaced by a random string. The open permissions for the document can be
123     *  AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
124     *  AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
125     *  The permissions can be combined by ORing them.
126     * @param userPassword the user password. Can be null or empty
127     * @param ownerPassword the owner password. Can be null or empty
128     * @param permissions the user permissions
129     * @param strength128Bits <code>true</code> for 128 bit key length, <code>false</code> for 40 bit key length
130     * @throws DocumentException if the document is already open
131     */
132    public void setEncryption(byte userPassword[], byte ownerPassword[], int permissions, boolean strength128Bits) throws DocumentException {
133        fc.setEncryption(userPassword, ownerPassword, permissions, strength128Bits ? PdfWriter.STANDARD_ENCRYPTION_128 : PdfWriter.STANDARD_ENCRYPTION_40);
134    }
135
136    /**
137     * Sets the encryption options for this document. The userPassword and the
138     *  ownerPassword can be null or have zero length. In this case the ownerPassword
139     *  is replaced by a random string. The open permissions for the document can be
140     *  AllowPrinting, AllowModifyContents, AllowCopy, AllowModifyAnnotations,
141     *  AllowFillIn, AllowScreenReaders, AllowAssembly and AllowDegradedPrinting.
142     *  The permissions can be combined by ORing them.
143     * @param strength true for 128 bit key length. false for 40 bit key length
144     * @param userPassword the user password. Can be null or empty
145     * @param ownerPassword the owner password. Can be null or empty
146     * @param permissions the user permissions
147     * @throws DocumentException if the document is already open
148     */
149    public void setEncryption(boolean strength, String userPassword, String ownerPassword, int permissions) throws DocumentException {
150        setEncryption(DocWriter.getISOBytes(userPassword), DocWriter.getISOBytes(ownerPassword), permissions, strength);
151    }
152
153    /**
154     * Closes the output document.
155     */
156    public void close() {
157        fc.close();
158    }
159
160    /**
161     * Opens the document. This is usually not needed as addDocument() will do it
162     * automatically.
163     */
164    public void open() {
165        fc.openDoc();
166    }
167
168    /**
169     * Adds JavaScript to the global document
170     * @param js the JavaScript
171     */
172    public void addJavaScript(String js) {
173        fc.addJavaScript(js, !PdfEncodings.isPdfDocEncoding(js));
174    }
175
176    /**
177     * Sets the bookmarks. The list structure is defined in
178     * <CODE>SimpleBookmark#</CODE>.
179     * @param outlines the bookmarks or <CODE>null</CODE> to remove any
180     */
181    public void setOutlines(List<HashMap<String, Object>> outlines) {
182        fc.setOutlines(outlines);
183    }
184
185    /** Gets the underlying PdfWriter.
186     * @return the underlying PdfWriter
187     */
188    public PdfWriter getWriter() {
189        return fc;
190    }
191
192    /**
193     * Gets the 1.5 compression status.
194     * @return <code>true</code> if the 1.5 compression is on
195     */
196    public boolean isFullCompression() {
197        return fc.isFullCompression();
198    }
199
200    /**
201     * Sets the document's compression to the new 1.5 mode with object streams and xref
202     * streams. It can be set at any time but once set it can't be unset.
203     * <p>
204     * If set before opening the document it will also set the pdf version to 1.5.
205     */
206    public void setFullCompression() {
207        fc.setFullCompression();
208    }
209
210        /**
211         * @see com.itextpdf.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(byte[], byte[], int, int)
212         */
213        public void setEncryption(byte[] userPassword, byte[] ownerPassword, int permissions, int encryptionType) throws DocumentException {
214                fc.setEncryption(userPassword, ownerPassword, permissions, encryptionType);
215        }
216
217        /**
218         * @see com.itextpdf.text.pdf.interfaces.PdfViewerPreferences#addViewerPreference(com.itextpdf.text.pdf.PdfName, com.itextpdf.text.pdf.PdfObject)
219         */
220        public void addViewerPreference(PdfName key, PdfObject value) {
221                fc.addViewerPreference(key, value);
222        }
223
224        /**
225         * @see com.itextpdf.text.pdf.interfaces.PdfViewerPreferences#setViewerPreferences(int)
226         */
227        public void setViewerPreferences(int preferences) {
228                fc.setViewerPreferences(preferences);
229        }
230
231        /**
232         * @see com.itextpdf.text.pdf.interfaces.PdfEncryptionSettings#setEncryption(java.security.cert.Certificate[], int[], int)
233         */
234        public void setEncryption(Certificate[] certs, int[] permissions, int encryptionType) throws DocumentException {
235                fc.setEncryption(certs, permissions, encryptionType);
236        }
237}