Skip to content

Commit 53d5819

Browse files
ProxyNexusMaximPlusov
authored andcommittedApr 19, 2024
Added pdf tests migration tool
1 parent b446b0f commit 53d5819

File tree

11 files changed

+871
-5
lines changed

11 files changed

+871
-5
lines changed
 

‎.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ hs_err_pid*
2222

2323
# Maven artefacts
2424
**/pom.xml.versionsBackup
25+
26+
# VisualStudioCode #
27+
.vscode/*
28+
eclipse-formatter.xml

‎fix-metadata/pom.xml

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
<artifactId>fix-metadata</artifactId>
1313

1414
<dependencies>
15-
1615
<dependency>
17-
<groupId>org.apache.pdfbox</groupId>
16+
<groupId>org.verapdf.pdfbox</groupId>
1817
<artifactId>pdfbox</artifactId>
19-
<version>2.0.24</version>
18+
<version>[2.0.62,2.1.0)</version>
2019
</dependency>
2120

2221
<dependency>

‎fix-metadata/src/main/java/org/verapdf/tools/FixMetadataTool.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public static void main(String[] args) throws Exception {
2828
PDDocument pdDocument = PDDocument.load(new File(args[0]));
2929
PDFAFlavour flavour = PDFAFlavour.byFlavourId(args[2]);
3030
if (flavour == PDFAFlavour.NO_FLAVOUR) {
31-
PDMetadata newMetadata = new PDMetadata(pdDocument, new FileInputStream(args[2]));
31+
PDMetadata newMetadata = new PDMetadata(pdDocument, new FileInputStream(args[2]), false);
3232
pdDocument.getDocumentCatalog().setMetadata(newMetadata);
3333
} else {
3434
Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
@@ -113,7 +113,7 @@ private static void setMetadata(PDDocument pdDocument, File file, PDFAFlavour fl
113113
} else {
114114
meta = meta.replace("TITLE", file.getName().substring(0, file.getName().length() - 4));
115115
}
116-
PDMetadata newMetadata = new PDMetadata(pdDocument, new ByteArrayInputStream(meta.getBytes()));
116+
PDMetadata newMetadata = new PDMetadata(pdDocument, new ByteArrayInputStream(meta.getBytes()), false);
117117
pdDocument.getDocumentCatalog().setMetadata(newMetadata);
118118
} catch (Exception e) {
119119
e.printStackTrace();

‎pdf-test-migration/pom.xml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>verapdf-tools</artifactId>
7+
<groupId>org.verapdf</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
11+
<modelVersion>4.0.0</modelVersion>
12+
<artifactId>pdf-test-migration</artifactId>
13+
<version>1.0-SNAPSHOT</version>
14+
15+
<properties>
16+
<maven.compiler.source>8</maven.compiler.source>
17+
<maven.compiler.target>8</maven.compiler.target>
18+
</properties>
19+
20+
<build>
21+
<finalName>pdf-test-migration</finalName>
22+
<plugins>
23+
<plugin>
24+
<groupId>org.apache.maven.plugins</groupId>
25+
<artifactId>maven-assembly-plugin</artifactId>
26+
<configuration>
27+
<archive>
28+
<manifest>
29+
<mainClass>org.verapdf.tools.TestMigration</mainClass>
30+
</manifest>
31+
</archive>
32+
<descriptorRefs>
33+
<descriptorRef>jar-with-dependencies</descriptorRef>
34+
</descriptorRefs>
35+
<appendAssemblyId>false</appendAssemblyId>
36+
</configuration>
37+
<executions>
38+
<execution>
39+
<id>make-assembly</id> <!-- this is used for inheritance merges -->
40+
<phase>package</phase> <!-- bind to the packaging phase -->
41+
<goals>
42+
<goal>single</goal>
43+
</goals>
44+
</execution>
45+
</executions>
46+
</plugin>
47+
<plugin>
48+
<groupId>org.apache.maven.plugins</groupId>
49+
<artifactId>maven-compiler-plugin</artifactId>
50+
<version>3.8.1</version>
51+
</plugin>
52+
</plugins>
53+
</build>
54+
55+
56+
57+
<dependencies>
58+
<dependency>
59+
<groupId>org.verapdf</groupId>
60+
<artifactId>fix-metadata</artifactId>
61+
<version>1.0-SNAPSHOT</version>
62+
</dependency>
63+
<dependency>
64+
<groupId>org.verapdf</groupId>
65+
<artifactId>pdf-deprecated-finder</artifactId>
66+
<version>1.0-SNAPSHOT</version>
67+
</dependency>
68+
<dependency>
69+
<groupId>org.verapdf</groupId>
70+
<artifactId>validation-model</artifactId>
71+
<version>${verapdf.version}</version>
72+
</dependency>
73+
74+
<dependency>
75+
<groupId>commons-cli</groupId>
76+
<artifactId>commons-cli</artifactId>
77+
<version>1.4</version>
78+
</dependency>
79+
</dependencies>
80+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.verapdf.tools;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public enum FeatureTag {
7+
PRESET(0), PRE_PROCESS(1), PROCESS(2), POST_PROCESS(3);
8+
9+
private final Integer value;
10+
11+
private FeatureTag(Integer id) {
12+
this.value = 1 << id;
13+
}
14+
15+
public Boolean checkTag(Integer tags) {
16+
return (this.value & tags) != 0;
17+
}
18+
19+
public static Integer getInteger(FeatureTag... tags) {
20+
Integer result = 0;
21+
22+
for (FeatureTag tag : tags) {
23+
if (!tag.checkTag(result)) {
24+
result += tag.value;
25+
}
26+
}
27+
28+
return result;
29+
}
30+
31+
public static List<FeatureTag> fromInteger(Integer value) {
32+
List<FeatureTag> tags = new ArrayList<FeatureTag>();
33+
34+
for (FeatureTag tag : FeatureTag.values()) {
35+
if (tag.checkTag(value)) {
36+
tags.add(tag);
37+
}
38+
}
39+
40+
return tags;
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.verapdf.tools;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
import org.apache.commons.cli.CommandLine;
7+
import org.apache.commons.cli.Option;
8+
import org.apache.pdfbox.pdmodel.PDDocument;
9+
10+
public class Features {
11+
private Map<OptionFeature, String> features = new HashMap<OptionFeature, String>();
12+
protected Boolean isPreset = false;
13+
14+
public Features(CommandLine commandLine) {
15+
for (Option option : commandLine.getOptions()) {
16+
OptionFeature optionFeature = OptionFeature.fromOption(option.getOpt());
17+
18+
features.put(optionFeature, option.getValue());
19+
}
20+
}
21+
22+
protected void modifyFeature(OptionFeature optionFeature, String argument) {
23+
features.put(optionFeature, argument);
24+
}
25+
26+
protected void removeFeature(OptionFeature optionFeature) {
27+
features.remove(optionFeature);
28+
}
29+
30+
public Boolean isFeatureEnabled(OptionFeature feature) {
31+
return features.containsKey(feature);
32+
}
33+
34+
public void checkPresets(TestMigration testMigration) {
35+
for (OptionFeature feature : OptionFeature.getOptionsByTag(FeatureTag.PRESET)) {
36+
if (!isFeatureEnabled(feature)) {
37+
continue;
38+
}
39+
40+
feature.preset(testMigration, features.get(feature));
41+
42+
if (isPreset) {
43+
return;
44+
}
45+
}
46+
}
47+
48+
public void runPreFeatures(TestMigration testMigration) {
49+
for (OptionFeature feature : OptionFeature.getOptionsByTag(FeatureTag.PRE_PROCESS)) {
50+
if (!isFeatureEnabled(feature)) {
51+
continue;
52+
}
53+
54+
feature.preFeature(testMigration, features.get(feature));
55+
}
56+
}
57+
58+
public void runFeatures(PDDocument document) throws Exception {
59+
for (OptionFeature feature : OptionFeature.getOptionsByTag(FeatureTag.PROCESS)) {
60+
if (!isFeatureEnabled(feature)) {
61+
continue;
62+
}
63+
64+
feature.feature(document, features.get(feature));
65+
}
66+
}
67+
68+
public void runPostFeatures(TestMigration testMigration, String targetFilePath) throws Exception {
69+
for (OptionFeature feature : OptionFeature.getOptionsByTag(FeatureTag.POST_PROCESS)) {
70+
if (!isFeatureEnabled(feature)) {
71+
continue;
72+
}
73+
74+
feature.postFeature(testMigration, targetFilePath, features.get(feature));
75+
}
76+
}
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
package org.verapdf.tools;
2+
3+
import java.io.File;
4+
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.HashMap;
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
import org.apache.commons.cli.Option;
11+
import org.apache.commons.cli.Options;
12+
import org.apache.pdfbox.cos.COSArray;
13+
import org.apache.pdfbox.cos.COSBase;
14+
import org.apache.pdfbox.cos.COSDictionary;
15+
import org.apache.pdfbox.pdmodel.PDDocument;
16+
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement;
17+
import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureTreeRoot;
18+
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
19+
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
20+
import org.verapdf.pdfa.flavours.PDFAFlavour;
21+
22+
public enum OptionFeature {
23+
UA2_PRESET("ua2_preset", "ua2", "Default preset for pdf-ua2 migration", false, false, FeatureTag.PRESET) {
24+
@Override
25+
public void preset(TestMigration testMigration, String argument) {
26+
Features features = testMigration.getFeatures();
27+
features.isPreset = true;
28+
29+
features.modifyFeature(TARGET_FLAVOUR, "ua2");
30+
features.modifyFeature(FIX_DEPRECATED, "");
31+
features.modifyFeature(FIX_METADATA, "");
32+
features.modifyFeature(SET_VERSION, "2.0");
33+
features.modifyFeature(REMOVE_OPENACTION, "");
34+
features.modifyFeature(ADD_NAMESPACE, "http://iso.org/pdf2/ssn");
35+
}
36+
},
37+
INPUT_FOLDER("parent_input_folder", "pif", "<arg> - path to parent input folder", true, false,
38+
FeatureTag.PRE_PROCESS) {
39+
@Override
40+
public void preFeature(TestMigration testMigration, String argument) {
41+
if (argument.endsWith("/")) {
42+
testMigration.inputParentFolderPath = argument;
43+
} else {
44+
testMigration.inputParentFolderPath = argument + "/";
45+
}
46+
}
47+
},
48+
TARGET_FOLDER("parent_target_folder", "ptf", "<arg> - path to parent target folder", true, false,
49+
FeatureTag.PRE_PROCESS) {
50+
@Override
51+
public void preFeature(TestMigration testMigration, String argument) {
52+
if (argument.endsWith("/")) {
53+
testMigration.targetParentFolderPath = argument;
54+
} else {
55+
testMigration.targetParentFolderPath = argument + "/";
56+
}
57+
}
58+
},
59+
CSV_FILE("csv_file", "csv",
60+
"<arg> - .csv file with <INPUT_FOLDER>;<INPUT_VERSION>;<OUTPUT_FOLDER>;<OUTPUT_VERSION>;<OUTLINE_HEADER> format",
61+
true, false, FeatureTag.PRE_PROCESS) {
62+
@Override
63+
public void preFeature(TestMigration testMigration, String argument) {
64+
testMigration.setCSVFile(argument);
65+
}
66+
},
67+
TARGET_FLAVOUR("flavour", "f", "Sets target flavour to <arg>", true, false, FeatureTag.PRE_PROCESS) {
68+
@Override
69+
public void preFeature(TestMigration testMigration, String argument) {
70+
testMigration.targetFlavour = PDFAFlavour.byFlavourId(argument);
71+
}
72+
},
73+
SET_OUTLINEHEADER("outline_header", "oh", "Replaces first outline with <arg>", true, false, FeatureTag.PROCESS) {
74+
@Override
75+
public void feature(PDDocument document, String argument) throws Exception {
76+
if (argument == null || argument.length() == 0) {
77+
return;
78+
}
79+
80+
ArrayList<String> oldOutlines = new ArrayList<String>();
81+
Map<String, List<String>> childs = new HashMap<String, List<String>>();
82+
PDOutlineItem currentOutlineItem = document.getDocumentCatalog().getDocumentOutline().getFirstChild();
83+
84+
currentOutlineItem = currentOutlineItem.getNextSibling();
85+
while (currentOutlineItem != null) {
86+
oldOutlines.add(currentOutlineItem.getTitle());
87+
PDOutlineItem childOutline = currentOutlineItem.getFirstChild();
88+
89+
List<String> subChilds = new ArrayList<String>();
90+
91+
while (childOutline != null) {
92+
subChilds.add(childOutline.getTitle());
93+
childOutline = childOutline.getNextSibling();
94+
}
95+
96+
childs.put(currentOutlineItem.getTitle(), subChilds);
97+
currentOutlineItem = currentOutlineItem.getNextSibling();
98+
}
99+
100+
PDDocumentOutline outlines = new PDDocumentOutline();
101+
currentOutlineItem = new PDOutlineItem();
102+
currentOutlineItem.setTitle(argument);
103+
104+
outlines.addFirst(currentOutlineItem);
105+
106+
for (String line : oldOutlines) {
107+
PDOutlineItem newOutline = new PDOutlineItem();
108+
newOutline.setTitle(line);
109+
110+
if (childs.get(line).size() > 0) {
111+
for (String subChild : childs.get(line)) {
112+
PDOutlineItem subChildOutline = new PDOutlineItem();
113+
subChildOutline.setTitle(subChild);
114+
115+
newOutline.addFirst(subChildOutline);
116+
}
117+
}
118+
119+
currentOutlineItem.insertSiblingAfter(newOutline);
120+
currentOutlineItem = newOutline;
121+
}
122+
123+
document.getDocumentCatalog().setDocumentOutline(outlines);
124+
}
125+
},
126+
SET_LANGUAGE("language", "l", "Set pdf language to <arg>", true, false, FeatureTag.PROCESS) {
127+
@Override
128+
public void feature(PDDocument document, String argument) throws Exception {
129+
if (argument == null) {
130+
return;
131+
}
132+
133+
document.getDocumentCatalog().setLanguage(argument);
134+
}
135+
},
136+
SET_VERSION("version", "v", "Set pdf version to <arg>", true, false, FeatureTag.PROCESS) {
137+
@Override
138+
public void feature(PDDocument document, String argument) throws Exception {
139+
if (argument == null) {
140+
return;
141+
}
142+
143+
try {
144+
Float version = Float.parseFloat(argument);
145+
146+
document.getDocument().setVersion(version);
147+
} catch (NumberFormatException exception) {
148+
return;
149+
}
150+
}
151+
},
152+
REMOVE_OPENACTION("remove_openaction", "ro", "Removes open action from document catalog", false, false,
153+
FeatureTag.PROCESS) {
154+
@Override
155+
public void feature(PDDocument document, String argument) throws Exception {
156+
document.getDocumentCatalog().setOpenAction(null);
157+
}
158+
},
159+
ADD_NAMESPACE("namespace", "ns", "Set <arg> namespace for document", true, false, FeatureTag.PROCESS) {
160+
@Override
161+
public void feature(PDDocument document, String argument) throws Exception {
162+
if (argument == null || argument.length() == 0) {
163+
return;
164+
}
165+
166+
PDStructureTreeRoot root = document.getDocumentCatalog().getStructureTreeRoot();
167+
168+
if (root != null) {
169+
COSArray namespaces = new COSArray();
170+
COSDictionary NS = new COSDictionary();
171+
172+
NS.setName("Type", "Namespace");
173+
NS.setString("NS", "http://iso.org/pdf2/ssn");
174+
175+
namespaces.add(NS);
176+
root.getCOSObject().setItem("Namespaces", namespaces);
177+
178+
COSBase base = root.getK();
179+
if (base instanceof COSDictionary) {
180+
COSDictionary dictionary = (COSDictionary) base;
181+
182+
dictionary.setItem("NS", NS);
183+
184+
return;
185+
}
186+
187+
root.getKids().forEach((child) -> {
188+
if (child instanceof PDStructureElement) {
189+
COSDictionary dictionary = ((PDStructureElement) child).getCOSObject();
190+
191+
dictionary.setItem("NS", NS);
192+
}
193+
});
194+
}
195+
}
196+
},
197+
FIX_DEPRECATED("fix_deprecated", "fd", "Fixes deprecated files", false, false, FeatureTag.PRE_PROCESS, FeatureTag.POST_PROCESS) {
198+
@Override
199+
public void preFeature(TestMigration testMigration, String argument) {
200+
testMigration.getTempDir().toFile().mkdirs();
201+
}
202+
203+
@Override
204+
public void postFeature(TestMigration testMigration, String targetFilePath, String argument) throws Exception {
205+
String[] args = { targetFilePath };
206+
207+
DeprecatedFinderCli.main(args);
208+
209+
File originalFile = new File(targetFilePath);
210+
File fixedFile = testMigration.getTempDir().resolve("fix_" + originalFile.getName()).toFile();
211+
212+
if (!fixedFile.exists()) {
213+
return;
214+
}
215+
216+
originalFile.delete();
217+
fixedFile.renameTo(new File(targetFilePath));
218+
}
219+
},
220+
FIX_METADATA("fix_metadata", "fm", "Fixes metadata", false, false, FeatureTag.PRE_PROCESS, FeatureTag.POST_PROCESS) {
221+
@Override
222+
public void preFeature(TestMigration testMigration, String argument) {
223+
testMigration.getTempDir().toFile().mkdirs();
224+
}
225+
226+
@Override
227+
public void postFeature(TestMigration testMigration, String targetFilePath, String argument) throws Exception {
228+
File originalFile = new File(targetFilePath);
229+
File temp = testMigration.getTempDir().resolve(originalFile.getName()).toFile();
230+
originalFile.renameTo(temp);
231+
232+
String[] args = { temp.getAbsolutePath(), targetFilePath, testMigration.targetFlavour.toString() };
233+
FixMetadataTool.main(args);
234+
235+
temp.delete();
236+
}
237+
};
238+
239+
private final String option;
240+
private final String short_form;
241+
private final String description;
242+
private final Boolean hasArgs;
243+
private final Boolean required;
244+
private final Integer featureTags;
245+
246+
public void preset(TestMigration testMigration, String argument) {
247+
248+
}
249+
250+
public void preFeature(TestMigration testMigration, String argument) {
251+
252+
}
253+
254+
public void feature(PDDocument document, String argument) throws Exception {
255+
256+
}
257+
258+
public void postFeature(TestMigration testMigration, String targetFilePath, String argument) throws Exception {
259+
260+
}
261+
262+
private OptionFeature(String option, String short_form, String description, Boolean hasArgs, Boolean required, FeatureTag... tags) {
263+
this.option = option;
264+
this.short_form = short_form;
265+
this.description = description;
266+
this.hasArgs = hasArgs;
267+
this.required = required;
268+
269+
this.featureTags = FeatureTag.getInteger(tags);
270+
}
271+
272+
public Boolean isRequired() {
273+
return required;
274+
}
275+
276+
public String getShortOption() {
277+
return short_form;
278+
}
279+
280+
public Boolean hasTag(FeatureTag tag) {
281+
return tag.checkTag(featureTags);
282+
}
283+
284+
public static OptionFeature fromOption(String shortFormOption) {
285+
return features.getOrDefault(shortFormOption, null);
286+
}
287+
288+
public static List<OptionFeature> getOptionsByTag(FeatureTag tag) {
289+
return featuresByTag.getOrDefault(tag, Arrays.asList());
290+
}
291+
292+
private static Map<String, OptionFeature> features = new HashMap<String, OptionFeature>();
293+
private static Map<FeatureTag, List<OptionFeature>> featuresByTag = new HashMap<FeatureTag, List<OptionFeature>>();
294+
static {
295+
for (FeatureTag tag : FeatureTag.values()) {
296+
featuresByTag.put(tag, new ArrayList<OptionFeature>());
297+
}
298+
299+
for (OptionFeature optionFeature : OptionFeature.values()) {
300+
features.put(optionFeature.short_form, optionFeature);
301+
302+
for (FeatureTag tag : FeatureTag.fromInteger(optionFeature.featureTags)) {
303+
featuresByTag.get(tag).add(optionFeature);
304+
}
305+
}
306+
}
307+
308+
public static Options generateOptions() {
309+
Options options = new Options();
310+
311+
for (OptionFeature optionFeature : OptionFeature.values()) {
312+
Option option = new Option(optionFeature.short_form, optionFeature.option, optionFeature.hasArgs,
313+
optionFeature.description);
314+
option.setRequired(optionFeature.required);
315+
316+
options.addOption(option);
317+
}
318+
319+
return options;
320+
}
321+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.verapdf.tools;
2+
3+
public class Task {
4+
public final String inputPath;
5+
public final String inputVersion;
6+
public final String targetPath;
7+
public final String targetVersion;
8+
public final String outlineHeader;
9+
10+
public final Boolean isSingleFile;
11+
12+
public Task(String inputPath, String inputVersion, String targetPath, String targetVersion, String outlineHeader, Boolean isSingleFile) {
13+
this.inputPath = inputPath;
14+
this.inputVersion = inputVersion;
15+
this.targetPath = targetPath;
16+
this.targetVersion = targetVersion;
17+
this.outlineHeader = outlineHeader;
18+
this.isSingleFile = isSingleFile;
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
package org.verapdf.tools;
2+
3+
import java.io.File;
4+
import java.io.FileInputStream;
5+
import java.nio.file.Path;
6+
import java.nio.file.Paths;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Scanner;
10+
import java.util.logging.Logger;
11+
12+
import org.apache.commons.cli.CommandLine;
13+
import org.apache.commons.cli.DefaultParser;
14+
import org.apache.commons.cli.HelpFormatter;
15+
import org.apache.commons.cli.Options;
16+
import org.apache.commons.cli.ParseException;
17+
import org.apache.pdfbox.pdmodel.PDDocument;
18+
import org.verapdf.pdfa.flavours.PDFAFlavour;
19+
20+
public class TestMigration {
21+
private static final String HELP = "[options] <INPUT_FILE> <OUTPUT_FILE> OR [options] <INPUT_FOLDER> <INPUT_VERSION> <OUTPUT_FOLDER> <OUTPUT_VERSION> OR [options] -csv <CSV_FILE>\n Options:\n";
22+
private static final Integer FORMATTER_WIDTH = 140;
23+
private static final Logger logger = Logger.getLogger(TestMigration.class.getCanonicalName());
24+
25+
public static void main(String[] args) {
26+
try {
27+
TestMigration testMigration = new TestMigration();
28+
29+
testMigration.run(args);
30+
} catch (Exception ex) {
31+
ex.printStackTrace();
32+
}
33+
}
34+
35+
protected PDFAFlavour targetFlavour = PDFAFlavour.NO_FLAVOUR;
36+
protected String inputParentFolderPath = "";
37+
protected String targetParentFolderPath = "";
38+
39+
private CommandLine commandLine;
40+
private HelpFormatter formatter = new HelpFormatter();
41+
private Features features;
42+
private List<Task> tasks = new ArrayList<Task>();
43+
private Boolean isFromCSV = false;
44+
45+
public TestMigration() {
46+
47+
}
48+
49+
public Features getFeatures() {
50+
return features;
51+
}
52+
53+
public Path getTempDir() {
54+
return Paths.get(System.getProperty("user.dir") + "\\fixed_files");
55+
}
56+
57+
private void clearTemp() {
58+
File folder = getTempDir().toFile();
59+
60+
if (folder == null || !folder.exists()) {
61+
return;
62+
}
63+
64+
for (File file : folder.listFiles()) {
65+
file.delete();
66+
}
67+
68+
folder.delete();
69+
}
70+
71+
protected void setCSVFile(String filePath) {
72+
Scanner scanner = null;
73+
try {
74+
scanner = new Scanner(new FileInputStream(new File(filePath)));
75+
Integer pos = 0;
76+
77+
while (scanner.hasNext()) {
78+
String[] args = scanner.nextLine().split(";");
79+
80+
if (args.length < 2) {
81+
throw new ParseException("line:" + pos + " - have less then 2 arguments");
82+
}
83+
84+
addSingleTask(args);
85+
}
86+
87+
isFromCSV = true;
88+
} catch (Exception ex) {
89+
logger.warning("Error during parsing csv file: " + ex.getMessage() + "");
90+
ex.printStackTrace();
91+
System.exit(1);
92+
} finally {
93+
if (scanner != null) {
94+
scanner.close();
95+
}
96+
}
97+
}
98+
99+
private void run(String inputArgs[]) {
100+
Options options = OptionFeature.generateOptions();
101+
commandLine = null;
102+
103+
formatter.setWidth(FORMATTER_WIDTH);
104+
105+
try {
106+
commandLine = (new DefaultParser()).parse(options, inputArgs);
107+
} catch (ParseException e) {
108+
System.out.println(e.getMessage());
109+
formatter.printHelp(HELP, options);
110+
111+
return;
112+
}
113+
114+
if (!isInputValid()) {
115+
formatter.printHelp(HELP, options);
116+
117+
return;
118+
}
119+
120+
clearTemp();
121+
122+
features = new Features(commandLine);
123+
features.checkPresets(this);
124+
features.runPreFeatures(this);
125+
126+
if (!isFromCSV) {
127+
addSingleTask(commandLine.getArgs());
128+
}
129+
130+
for (Task task : tasks) {
131+
logger.info("task - " + task.inputVersion + ":");
132+
133+
if (!task.isSingleFile) {
134+
proccessTask(task);
135+
136+
continue;
137+
}
138+
139+
proccessSingleFileTask(task);
140+
}
141+
142+
clearTemp();
143+
}
144+
145+
private void proccessSingleFileTask(Task task) {
146+
File inputFile = Paths.get(inputParentFolderPath + task.inputPath).toFile();
147+
File targetFile = Paths.get(targetParentFolderPath + task.targetPath).toFile();
148+
149+
File parent = targetFile.getParentFile();
150+
if (parent != null) {
151+
parent.mkdirs();
152+
}
153+
154+
try {
155+
PDDocument document = PDDocument.load(inputFile);
156+
features.runFeatures(document);
157+
158+
if (task.outlineHeader != null && task.outlineHeader.length() > 0) {
159+
OptionFeature.SET_OUTLINEHEADER.feature(document, task.outlineHeader);
160+
}
161+
162+
if (targetFile.exists()) {
163+
targetFile.delete();
164+
}
165+
166+
document.save(targetFile);
167+
168+
features.runPostFeatures(this, targetFile.getAbsolutePath());
169+
} catch (Exception e) {
170+
logger.warning(">Error during processing: " + inputFile.getName() + ", test skiped.");
171+
e.printStackTrace();
172+
}
173+
}
174+
175+
private void proccessTask(Task task) {
176+
File inputFolder = Paths.get(inputParentFolderPath + task.inputPath).toFile();
177+
File targetFolder = Paths.get(targetParentFolderPath + task.targetPath).toFile();
178+
179+
if (!inputFolder.exists()) {
180+
logger.warning(">Input folder '" + inputFolder.getAbsolutePath() + "'' not found, tests skipped");
181+
return;
182+
}
183+
184+
targetFolder.mkdirs();
185+
186+
File[] inputFiles = inputFolder.listFiles((dir, name) -> {
187+
return (name.startsWith(task.inputVersion) && name.endsWith(".pdf"));
188+
});
189+
190+
for (File inputFile : inputFiles) {
191+
String inputFileName = inputFile.getName();
192+
// file format '[version]-[fail/pass]-[testCase].pdf'
193+
String suffix = inputFileName.substring(task.inputVersion.length());
194+
195+
String targetFileName = task.targetVersion + suffix;
196+
String targetFilePath = targetParentFolderPath + task.targetPath + '/' + targetFileName;
197+
198+
try {
199+
PDDocument document = PDDocument.load(inputFile);
200+
features.runFeatures(document);
201+
202+
if (task.outlineHeader != null && task.outlineHeader.length() > 0) {
203+
OptionFeature.SET_OUTLINEHEADER.feature(document, task.outlineHeader);
204+
}
205+
206+
File targetFile = new File(targetFilePath);
207+
208+
if (targetFile.exists()) {
209+
targetFile.delete();
210+
}
211+
212+
document.save(targetFile);
213+
214+
features.runPostFeatures(this, targetFilePath);
215+
} catch (Exception e) {
216+
logger.warning(">Error during processing: " + inputFileName + ", test skiped.");
217+
e.printStackTrace();
218+
219+
continue;
220+
}
221+
222+
File targetFile = new File(targetFilePath);
223+
224+
if (!targetFile.exists()) {
225+
logger.warning(">Error during processing: " + inputFileName + ", test skiped.");
226+
continue;
227+
}
228+
229+
logger.info(">Migrated (" + inputFileName + ") -> (" + targetFileName + ")");
230+
}
231+
}
232+
233+
private void addSingleTask(String[] args) {
234+
if (args.length < 4) {
235+
addSingleFileTask(args);
236+
237+
return;
238+
}
239+
240+
String inputPath = args[0];
241+
String inputVersion = args[1];
242+
String targetPath = args[2];
243+
String targetVersion = args[3];
244+
String outlineHeader = "";
245+
246+
if (inputVersion.equals("all")) {
247+
inputVersion = "";
248+
}
249+
250+
if (targetVersion.equals("all")) {
251+
targetVersion = "";
252+
}
253+
254+
if (args.length > 4) {
255+
outlineHeader = args[4];
256+
}
257+
258+
tasks.add(new Task(inputPath, inputVersion, targetPath, targetVersion, outlineHeader, false));
259+
}
260+
261+
private void addSingleFileTask(String[] args) {
262+
String inputPath = args[0];
263+
String targetPath = args[1];
264+
String outlineHeader = "";
265+
266+
if (args.length > 2) {
267+
outlineHeader = args[2];
268+
}
269+
270+
File file = new File(inputPath);
271+
272+
if (!file.exists()) {
273+
logger.warning("Input file '" + inputPath + "'' not found");
274+
System.exit(1);
275+
276+
return;
277+
}
278+
279+
File targetFile = new File(targetPath);
280+
281+
tasks.add(new Task(inputPath, file.getName(), targetPath, targetFile.getName(), outlineHeader, true));
282+
}
283+
284+
private Boolean isInputValid() {
285+
for (OptionFeature optionFeature : OptionFeature.values()) {
286+
if (optionFeature.isRequired() && !commandLine.hasOption(optionFeature.getShortOption())) {
287+
return false;
288+
}
289+
}
290+
291+
return (commandLine.getArgs().length == 2 || commandLine.getArgs().length == 4
292+
|| commandLine.hasOption(OptionFeature.CSV_FILE.getShortOption()));
293+
}
294+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
7.1 General;7.1-t11;8.2 Logical structure/8.2.1 General;8.2.1-t01;8.2.1 General - StructureTreeRoot
2+
7.1 General;7.1-t03;8.2 Logical structure/8.2.2 Real content;8.2.2-t01;8.2.2 Real content - Artifact or real content
3+
7.1 General;7.1-t05;8.2 Logical structure/8.2.4 Structure types;8.2.4-t01;8.2.4 Structure types - Standard roles
4+
7.1 General;7.1-t06;8.2 Logical structure/8.2.4 Structure types;8.2.4-t02;8.2.4 Structure types - Circular mapping
5+
7.2 Text;7.2-t15;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.26 Table (Table, TR, TH, TD, THead, TBody, TFoot);8.2.5.26-t01;8.2.5.26 Table - Regular Table
6+
7.2 Text;7.2-t41;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.26 Table (Table, TR, TH, TD, THead, TBody, TFoot);8.2.5.26-t02;8.2.5.26 Table - Regular Table
7+
7.2 Text;7.2-t42;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.26 Table (Table, TR, TH, TD, THead, TBody, TFoot);8.2.5.26-t03;8.2.5.26 Table - Regular Table
8+
7.2 Text;7.2-t43;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.26 Table (Table, TR, TH, TD, THead, TBody, TFoot);8.2.5.26-t04;8.2.5.26 Table - Regular Table
9+
7.5 Tables;7.5-t01;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.26 Table (Table, TR, TH, TD, THead, TBody, TFoot);8.2.5.26-t05;8.2.5.26 Table - Headers; IDs and Scope
10+
7.5 Tables;7.5-t02;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.26 Table (Table, TR, TH, TD, THead, TBody, TFoot);8.2.5.26-t06;8.2.5.26 Table - Headers; IDs and Scope
11+
7.3 Graphics;7.5-t01;8.2 Logical structure/8.2.5 Additional requirements for specific structure types/8.2.5.28 Figure/8.2.5.28.2 Figure properties;8.2.5.28.2-t01;8.2.5.28 Figure - Figure alternative and replacement text
12+
7.2 Text;7.2-t29;8.4 Text representation for content/8.4.4 Declaring natural language;8.4.4-t02;8.4 Text representation for content - Natural language specification
13+
7.21 Fonts/7.21.3 Composite fonts/7.21.3.1 General;7.21.3.1-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.3 Composite fonts/8.4.5.3.1 General;8.4.5.3.1-t01;8.4.5 Fonts - 8.4.5.3 Composite fonts - CIDSystemInfo
14+
7.21 Fonts/7.21.3 Composite fonts/7.21.3.2 CIDFonts;7.21.3.2-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.3 Composite fonts/8.4.5.3.2 CIDFonts;8.4.5.3.2-t01;8.4.5 Fonts - 8.4.5.3 Composite fonts - CIDToGIDMap
15+
7.21 Fonts/7.21.3 Composite fonts/7.21.3.3 CMaps;7.21.3.3-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.4 CMaps;8.4.5.4-t01;8.4.5 Fonts - 8.4.5.4 Composite fonts - CMaps
16+
7.21 Fonts/7.21.3 Composite fonts/7.21.3.3 CMaps;7.21.3.3-t02;8.4 Text representation for content/8.4.5 Fonts/8.4.5.4 CMaps;8.4.5.4-t02;8.4.5 Fonts - 8.4.5.4 Composite fonts - WMode
17+
7.21 Fonts/7.21.3 Composite fonts/7.21.3.3 CMaps;7.21.3.3-t03;8.4 Text representation for content/8.4.5 Fonts/8.4.5.4 CMaps;8.4.5.4-t03;8.4.5 Fonts - 8.4.5.4 Composite fonts - CMaps
18+
7.21 Fonts/7.21.4 Embedding/7.21.4.1 General;7.21.4.1-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.5 Embedding/8.4.5.5.1 General;8.4.5.5.1-t01;8.4.5 Fonts - 8.4.5.5 Embedding - General
19+
7.21 Fonts/7.21.4 Embedding/7.21.4.1 General;7.21.4.1-t02;8.4 Text representation for content/8.4.5 Fonts/8.4.5.5 Embedding/8.4.5.5.1 General;8.4.5.5.1-t02;8.4.5 Fonts - 8.4.5.5 Embedding - Glyphs
20+
7.21 Fonts/7.21.5 Font metrics;7.21.5-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.6 Font metrics;8.4.5.6-t01;8.4.5 Fonts - 8.4.5.6 Font metrics - Glyph width
21+
7.21 Fonts/7.21.6 Character encodings;7.21.6-t02;8.4 Text representation for content/8.4.5 Fonts/8.4.5.7 Character encodings;8.4.5.7-t02;8.4.5 Fonts - 8.4.5.7 Character encodings - Non-symbolic TrueType fonts
22+
7.21 Fonts/7.21.6 Character encodings;7.21.6-t03;8.4 Text representation for content/8.4.5 Fonts/8.4.5.7 Character encodings;8.4.5.7-t03;8.4.5 Fonts - 8.4.5.7 Character encodings - Symbolic TrueType fonts
23+
7.21 Fonts/7.21.7 Unicode character maps;7.21.7-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.8 Unicode character maps;8.4.5.8-t01;8.4.5 Fonts - 8.4.5.8 Unicode character maps - Unicode mapping
24+
7.21 Fonts/7.21.7 Unicode character maps;7.21.7-t02;8.4 Text representation for content/8.4.5 Fonts/8.4.5.8 Unicode character maps;8.4.5.8-t02;8.4.5 Fonts - 8.4.5.8 Unicode character maps - Valid Unicode values
25+
7.21 Fonts/7.21.8 Use of .notdef glyph;7.21.8-t01;8.4 Text representation for content/8.4.5 Fonts/8.4.5.9 Use of .notdef glyph;8.4.5.9-t01;8.4.5 Fonts - 8.4.5.9 Use of .notdef glyph - Use of .notdef glyph
26+
7.10 Optional content;7.10-t02;8.7 Optional content;8.7-t02;8.7 Optional content - AS key
27+
7.1 General;7.1-t09;8.11 Metadata/8.11.1 General;8.11.1-t01;8.11 Metadata - 8.11.1 General - Dc title
28+
7.1 General;7.1-t10;8.11 Metadata/8.11.2 Interactive aspects;8.11.2-t01;8.11 Metadata - 8.11.2 Interactive aspects - DisplayDocTitle

‎pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<module>pdf-deprecated-finder</module>
2626
<module>pdf-stream-change</module>
2727
<module>pdf-stream-dump</module>
28+
<module>pdf-test-migration</module>
2829
<module>policy-generator</module>
2930
<module>preforma-classification</module>
3031
<module>profile-merger</module>

0 commit comments

Comments
 (0)
Please sign in to comment.