1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package cz.hobrasoft.pdfmu.operation.args;
18
19 import com.itextpdf.text.DocumentException;
20 import com.itextpdf.text.pdf.PdfReader;
21 import com.itextpdf.text.pdf.PdfStamper;
22 import cz.hobrasoft.pdfmu.PdfmuUtils;
23 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_CLOSE;
24 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_EXISTS_FORCE_NOT_SET;
25 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_NOT_SPECIFIED;
26 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_OPEN;
27 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_STAMPER_CLOSE;
28 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_STAMPER_OPEN;
29 import static cz.hobrasoft.pdfmu.error.ErrorType.OUTPUT_WRITE;
30 import cz.hobrasoft.pdfmu.operation.OperationException;
31 import java.io.ByteArrayOutputStream;
32 import java.io.File;
33 import java.io.FileNotFoundException;
34 import java.io.FileOutputStream;
35 import java.io.IOException;
36 import java.io.OutputStream;
37 import java.util.AbstractMap.SimpleEntry;
38 import java.util.logging.Logger;
39 import net.sourceforge.argparse4j.impl.Arguments;
40 import net.sourceforge.argparse4j.inf.ArgumentParser;
41 import net.sourceforge.argparse4j.inf.Namespace;
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class OutPdfArgs implements ArgsConfiguration, AutoCloseable {
56
57 private static final Logger logger = Logger.getLogger(OutPdfArgs.class.getName());
58
59 private final String metavarIn;
60 private final String metavarOut = "OUT.pdf";
61 private final boolean allowAppend;
62
63 public OutPdfArgs(String metavarIn, boolean allowAppend) {
64 this.metavarIn = metavarIn;
65 this.allowAppend = allowAppend;
66 }
67
68 @Override
69 public void addArguments(ArgumentParser parser) {
70 parser.addArgument("-o", "--out")
71 .help(String.format("output PDF document (default: <%s>)", metavarIn))
72 .metavar(metavarOut)
73 .type(Arguments.fileType());
74
75 if (allowAppend) {
76 parser.addArgument("--append")
77 .help("append to the document, creating a new revision. If this option is disabled, the operation invalidates all the existing signatures.")
78 .type(boolean.class)
79 .setDefault(true);
80 }
81
82 parser.addArgument("-f", "--force")
83 .help(String.format("overwrite %s if it exists", metavarOut))
84 .type(boolean.class)
85 .action(Arguments.storeTrue());
86 }
87
88 private File file = null;
89 private boolean overwrite = false;
90 private boolean append = false;
91
92 @Override
93 public void setFromNamespace(Namespace namespace) {
94 file = namespace.get("out");
95 overwrite = namespace.getBoolean("force");
96
97 if (allowAppend) {
98 append = namespace.getBoolean("append");
99 } else {
100 append = false;
101 }
102 }
103
104
105
106
107
108
109
110
111 public void setDefaultFile(File file) {
112 if (this.file == null) {
113 logger.info("Output file has not been specified. Assuming in-place operation.");
114 this.file = file;
115 }
116 }
117
118 private ByteArrayOutputStream os;
119 private PdfStamper stp;
120
121 private void openOs() throws OperationException {
122 assert os == null;
123
124
125
126 os = new ByteArrayOutputStream((int) file.length());
127 }
128
129 private void openStpSignature(PdfReader pdfReader, char pdfVersion) throws OperationException {
130 assert os != null;
131 assert stp == null;
132
133 try {
134
135
136 stp = PdfStamper.createSignature(pdfReader, os, pdfVersion, null, append);
137 } catch (DocumentException | IOException ex) {
138 throw new OperationException(OUTPUT_STAMPER_OPEN, ex,
139 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
140 }
141 }
142
143 private void openStpNew(PdfReader pdfReader, char pdfVersion) throws OperationException {
144 assert os != null;
145 assert stp == null;
146
147
148 try {
149 stp = new PdfStamper(pdfReader, os, pdfVersion, append);
150 } catch (DocumentException | IOException ex) {
151 throw new OperationException(OUTPUT_STAMPER_OPEN, ex,
152 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
153 }
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170 public PdfStamper open(PdfReader pdfReader, boolean signature, char pdfVersion) throws OperationException {
171 if (file == null) {
172 throw new OperationException(OUTPUT_NOT_SPECIFIED);
173 }
174 assert file != null;
175
176 logger.info(String.format("Output file: %s", file));
177 if (file.exists()) {
178 logger.info("Output file already exists.");
179 if (overwrite) {
180 logger.info("Will overwrite the output file (--force flag is set).");
181 } else {
182 throw new OperationException(OUTPUT_EXISTS_FORCE_NOT_SET,
183 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
184 }
185 }
186
187 openOs();
188
189 if (signature) {
190 openStpSignature(pdfReader, pdfVersion);
191 } else {
192 openStpNew(pdfReader, pdfVersion);
193 }
194
195 return stp;
196 }
197
198
199
200
201
202
203
204 @Override
205 public void close() throws OperationException {
206 close(false);
207 }
208
209 public void close(boolean success) throws OperationException {
210 if (stp != null) {
211
212 if (success) {
213 try {
214 stp.close();
215 } catch (DocumentException | IOException ex) {
216 throw new OperationException(OUTPUT_STAMPER_CLOSE, ex,
217 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
218 }
219 }
220 stp = null;
221 }
222
223 if (os != null) {
224 if (success) {
225 assert file != null;
226 logger.info(String.format("Writing the output of the operation to the output file: %s", file));
227
228
229 {
230 OutputStream fileOs = null;
231 try {
232 fileOs = new FileOutputStream(file);
233 } catch (FileNotFoundException ex) {
234 throw new OperationException(OUTPUT_OPEN, ex,
235 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
236
237 }
238 assert fileOs != null;
239 try {
240 assert os != null;
241 os.writeTo(fileOs);
242 } catch (IOException ex) {
243 throw new OperationException(OUTPUT_WRITE, ex,
244 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
245 }
246 try {
247 fileOs.close();
248 } catch (IOException ex) {
249 throw new OperationException(OUTPUT_CLOSE, ex,
250 PdfmuUtils.sortedMap(new SimpleEntry<String, Object>("outputFile", file)));
251 }
252 }
253 }
254 os = null;
255 }
256 }
257
258 public PdfStamper getPdfStamper() {
259 return stp;
260 }
261
262 public File getFile() {
263 return file;
264 }
265
266 }