diff --git a/README.md b/README.md
index ee47fa4d..11756e3e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# ODF Validator
-Latest version is 0.14.0.
+Latest version is 0.16.0.
## About
diff --git a/docs/developer/index.md b/docs/developer/index.md
index f5ebf668..4e9920c2 100644
--- a/docs/developer/index.md
+++ b/docs/developer/index.md
@@ -44,7 +44,7 @@ To include the core validation library in your project, add the following depend
org.openpreservation.odf
odf-core
- 0.14.0
+ 0.16.0
```
diff --git a/odf-apps/pom.xml b/odf-apps/pom.xml
index 8e248d3c..3ba7861f 100644
--- a/odf-apps/pom.xml
+++ b/odf-apps/pom.xml
@@ -5,7 +5,7 @@
org.openpreservation.odf
odf-validator
- 0.14.0
+ 0.16.0
../pom.xml
diff --git a/odf-apps/src/main/java/org/openpreservation/odf/apps/CliValidator.java b/odf-apps/src/main/java/org/openpreservation/odf/apps/CliValidator.java
index d2911dde..5e29971e 100644
--- a/odf-apps/src/main/java/org/openpreservation/odf/apps/CliValidator.java
+++ b/odf-apps/src/main/java/org/openpreservation/odf/apps/CliValidator.java
@@ -125,10 +125,14 @@ private static Integer results(final Path path, final ValidationReport report) {
ConsoleFormatter.info(FACTORY.getInfo("APP-3").getMessage());
}
results(report.documentMessages.getMessages());
- outputSummary(report.documentMessages);
+ outputSummary(isEncrypted(report), report.documentMessages);
return status;
}
+ private static boolean isEncrypted(final ValidationReport report) {
+ return report.document.isPackage() && report.document.getPackage().isEncrypted();
+ }
+
private static Integer results(final Map> messageMap) {
Integer status = 0;
for (Map.Entry> entry : messageMap.entrySet()) {
@@ -140,9 +144,6 @@ private static Integer results(final Map> messageMap) {
private static Integer results(final Path path, final ProfileResult report) {
Integer status = 0;
ConsoleFormatter.colourise(FACTORY.getInfo("APP-5", report.getName(), path.toString(), "bold"));
- if (report.getValidationReport() != null) {
- status = results(report.getValidationReport().documentMessages.getMessages());
- }
for (Map.Entry> entry : report.getMessageLog().getMessages().entrySet()) {
status = Math.max(status, results(entry.getKey(), entry.getValue()));
}
@@ -153,7 +154,7 @@ private static Integer results(final Path path, final ProfileResult report) {
? report.getValidationReport().documentMessages
: Messages.messageLogInstance();
profileMessages.add(report.getMessageLog().getMessages());
- outputSummary(profileMessages);
+ outputSummary(isEncrypted(report.getValidationReport()), profileMessages);
return status;
}
@@ -168,8 +169,12 @@ private static Integer results(final String path, final List messages)
return status;
}
- private static void outputSummary(final MessageLog messageLog) {
- if (messageLog.hasErrors()) {
+ private static void outputSummary(final boolean isEncrypted, final MessageLog messageLog) {
+ if (isEncrypted) {
+ ConsoleFormatter.error(String.format(
+ "INCOMPLETE encrypted entries are not supported, %d errors, %d warnings and %d info messages.",
+ messageLog.getErrorCount(), messageLog.getWarningCount(), messageLog.getInfoCount()));
+ } else if (messageLog.hasErrors()) {
ConsoleFormatter.error(String.format("NOT VALID, %d errors, %d warnings and %d info messages.",
messageLog.getErrorCount(), messageLog.getWarningCount(), messageLog.getInfoCount()));
} else if (messageLog.hasWarnings()) {
diff --git a/odf-core/pom.xml b/odf-core/pom.xml
index ce375317..1a3e6079 100644
--- a/odf-core/pom.xml
+++ b/odf-core/pom.xml
@@ -5,7 +5,7 @@
org.openpreservation.odf
odf-validator
- 0.14.0
+ 0.16.0
../pom.xml
diff --git a/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackage.java b/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackage.java
index 892b8c1f..9d418c4e 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackage.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackage.java
@@ -230,4 +230,11 @@ public interface OdfPackage {
* @return true if the file uses any namespaces outside of the ODF
*/
public boolean isExtended();
+
+ /**
+ * Discover if the package had any encrypted entries.
+ *
+ * @return true if the package has encrypted entries
+ */
+ public boolean isEncrypted();
}
diff --git a/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackageImpl.java b/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackageImpl.java
index 2b4c33dd..f7d2b428 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackageImpl.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/pkg/OdfPackageImpl.java
@@ -218,8 +218,10 @@ public List getXmlEntryPaths() {
@Override
public Set getXmlEntries() {
Set entries = new HashSet<>();
- for (FileEntry entry : this.manifest.getEntriesByMediaType("text/xml")) {
- entries.add(entry);
+ if (this.manifest != null) {
+ for (FileEntry entry : this.manifest.getEntriesByMediaType("text/xml")) {
+ entries.add(entry);
+ }
}
return entries;
}
@@ -338,4 +340,17 @@ public boolean isExtended() {
}
return false;
}
+
+ @Override
+ public boolean isEncrypted() {
+ if (this.manifest == null) {
+ return false;
+ }
+ for (FileEntry entry : this.manifest.getEntries()) {
+ if (entry.isEncrypted()) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/odf-core/src/main/java/org/openpreservation/odf/pkg/PackageParserImpl.java b/odf-core/src/main/java/org/openpreservation/odf/pkg/PackageParserImpl.java
index 0641e5a0..111151ca 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/pkg/PackageParserImpl.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/pkg/PackageParserImpl.java
@@ -32,9 +32,11 @@
import org.xml.sax.SAXException;
final class PackageParserImpl implements PackageParser {
- private static String toParseConst = "toParse";
- private static String badFeature = "Unsupported Zip feature: %s";
- private static String ioException = "IO Exception reading stream: %s";
+ private static final String TO_PARSE = "toParse";
+ private static final String MESS_BAD_FEATURE = "Unsupported Zip feature: %s";
+ private static final String MESS_IO_EXCEPTION = "IO Exception reading stream: %s";
+ private static final String[] VERSION_FILE_PATHS = { Constants.PATH_MANIFEST, Constants.NAME_SETTINGS,
+ Constants.NAME_CONTENT };
static final PackageParser getInstance() {
return new PackageParserImpl();
@@ -75,19 +77,19 @@ private PackageParserImpl() {
@Override
public OdfPackage parsePackage(final Path toParse) throws ParseException, FileNotFoundException {
- Objects.requireNonNull(toParse, String.format(Checks.NOT_NULL, toParseConst, "Path"));
+ Objects.requireNonNull(toParse, String.format(Checks.NOT_NULL, TO_PARSE, "Path"));
return this.parsePackage(toParse, toParse.getFileName().toString());
}
@Override
public OdfPackage parsePackage(final File toParse) throws ParseException, FileNotFoundException {
- Objects.requireNonNull(toParse, String.format(Checks.NOT_NULL, toParseConst, "File"));
+ Objects.requireNonNull(toParse, String.format(Checks.NOT_NULL, TO_PARSE, "File"));
return this.parsePackage(toParse.toPath(), toParse.getName());
}
@Override
public OdfPackage parsePackage(final InputStream toParse, final String name) throws ParseException {
- Objects.requireNonNull(toParse, String.format(Checks.NOT_NULL, toParseConst, "InputStream"));
+ Objects.requireNonNull(toParse, String.format(Checks.NOT_NULL, TO_PARSE, "InputStream"));
Objects.requireNonNull(name, String.format(Checks.NOT_NULL, name, "String"));
try (BufferedInputStream bis = new BufferedInputStream(toParse)) {
final Path temp = Files.createTempFile("odf", ".pkg");
@@ -98,22 +100,22 @@ public OdfPackage parsePackage(final InputStream toParse, final String name) thr
}
}
- private final OdfPackage parsePackage(final Path toParse, final String name) throws ParseException, FileNotFoundException {
+ private final OdfPackage parsePackage(final Path toParse, final String name)
+ throws ParseException, FileNotFoundException {
Checks.existingFileCheck(toParse);
this.initialise();
try {
this.format = sniff(toParse);
this.cache = Zips.zipArchiveCacheInstance(toParse);
- Map badEntries = checkZipEntries();
- if (!badEntries.isEmpty()) {
- throw new ParseException(badEntries);
- }
+ checkZipEntries();
this.version = detectVersion();
+ this.mimetype = getMimeEntryValue();
} catch (final IOException e) {
// Simply catch the exception and return a sparsely populated OdfPackage
return OdfPackageImpl.Builder.builder().name(name).format(this.format).build();
}
try {
+ this.manifest = parseManifest();
this.processZipEntries();
return this.makePackage(name);
} catch (ParserConfigurationException | SAXException e) {
@@ -123,45 +125,47 @@ private final OdfPackage parsePackage(final Path toParse, final String name) thr
}
}
- private final Map checkZipEntries() {
+ private final String getMimeEntryValue() throws IOException {
+ return (this.cache.getZipEntry(OdfFormats.MIMETYPE) == null) ? ""
+ : new String(this.cache.getEntryInputStream(OdfFormats.MIMETYPE).readAllBytes(),
+ StandardCharsets.UTF_8);
+ }
+
+ private void checkZipEntries() throws ParseException {
final Map badEntries = new HashMap<>();
for (ZipEntry entry : this.cache.getZipEntries()) {
try {
this.cache.getEntryInputStream(entry.getName()).close();
} catch (UnsupportedZipFeatureException e) {
- badEntries.put(entry.getName(), String.format(badFeature, e.getFeature().toString()));
+ badEntries.put(entry.getName(), String.format(MESS_BAD_FEATURE, e.getFeature().toString()));
} catch (IOException e) {
- badEntries.put(entry.getName(), String.format(ioException, e.getMessage()));
+ badEntries.put(entry.getName(), String.format(MESS_IO_EXCEPTION, e.getMessage()));
}
}
- return badEntries;
+ if (!badEntries.isEmpty()) {
+ throw new ParseException(badEntries);
+ }
}
final Version detectVersion() throws IOException {
Version detectedVersion = Version.UNKNOWN;
- try (InputStream is = getVersionStreamName()) {
- if (is != null) {
- ParseResult result = new XmlParser().parse(is);
- return Version.fromVersion(result.getRootAttributeValue("office:version"));
+ for (final String versionPath : VERSION_FILE_PATHS) {
+ try (InputStream is = this.cache.getEntryInputStream(versionPath)) {
+ if (is != null) {
+ ParseResult result = new XmlParser().parse(is);
+ detectedVersion = Version.fromVersion(
+ result.getRootAttributeValue(String.format("%s:version", result.getRootPrefix())));
+ if (!Version.UNKNOWN.equals(detectedVersion)) {
+ return detectedVersion;
+ }
+ }
+ } catch (ParserConfigurationException | SAXException e) {
+ throw new IOException(e);
}
- } catch (ParserConfigurationException | SAXException e) {
- throw new IOException(e);
}
return detectedVersion;
}
- private final InputStream getVersionStreamName() throws IOException {
- InputStream retVal = null;
- retVal = this.cache.getEntryInputStream(Constants.NAME_MANIFEST);
- if (retVal == null) {
- retVal = this.cache.getEntryInputStream(Constants.NAME_SETTINGS);
- }
- if (retVal == null) {
- retVal = this.cache.getEntryInputStream(Constants.NAME_CONTENT);
- }
- return retVal;
- }
-
private final void processZipEntries() throws ParserConfigurationException, SAXException, IOException {
for (final ZipEntry entry : this.cache.getZipEntries()) {
processEntry(entry);
@@ -171,30 +175,31 @@ private final void processZipEntries() throws ParserConfigurationException, SAXE
private final void processEntry(final ZipEntry entry)
throws ParserConfigurationException, SAXException, IOException {
final String path = entry.getName();
- if (entry.isDirectory()) {
- // No need to process directories
- return;
- }
- if (OdfFormats.MIMETYPE.equals(path)) {
- // Grab the mimetype value from the MIMETYPE file
- this.mimetype = new String(this.cache.getEntryInputStream(entry.getName()).readAllBytes(),
- StandardCharsets.UTF_8);
- return;
- }
- if (!isOdfXml(path) && !isMetaInf(path)) {
+ if (entry.isDirectory() || (!isOdfXml(path) && !isMetaInf(path))) {
return;
}
try (InputStream is = this.cache.getEntryInputStream(path)) {
final OdfXmlDocument xmlDoc = OdfXmlDocuments.xmlDocumentFrom(is);
if (xmlDoc != null) {
this.xmlDocumentMap.put(path, xmlDoc);
- if (xmlDoc.getParseResult().isWellFormed() && Constants.PATH_MANIFEST.equals(path)) {
- this.manifest = ManifestImpl.from(this.cache.getEntryInputStream(path));
- }
}
}
}
+ private final Manifest parseManifest() throws IOException, ParserConfigurationException, SAXException {
+ final ZipEntry manifestEntry = this.cache.getZipEntry(Constants.PATH_MANIFEST);
+ if (manifestEntry == null) {
+ return null;
+ }
+ try (InputStream is = this.cache.getEntryInputStream(Constants.PATH_MANIFEST)) {
+ final OdfXmlDocument xmlDoc = OdfXmlDocuments.xmlDocumentFrom(is);
+ if (xmlDoc != null && xmlDoc.getParseResult().isWellFormed()) {
+ return ManifestImpl.from(this.cache.getEntryInputStream(Constants.PATH_MANIFEST));
+ }
+ }
+ return null;
+ }
+
private final void initialise() {
this.format = Formats.UNKNOWN;
this.mimetype = null;
diff --git a/odf-core/src/main/java/org/openpreservation/odf/validation/ValidatingParserImpl.java b/odf-core/src/main/java/org/openpreservation/odf/validation/ValidatingParserImpl.java
index 3f6bcd67..23ce9399 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/validation/ValidatingParserImpl.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/validation/ValidatingParserImpl.java
@@ -6,6 +6,7 @@
import java.io.InputStream;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -104,19 +105,29 @@ private ValidationReport validate(final OdfPackage odfPackage) {
private final Map> validateOdfXmlEntries(final OdfPackage odfPackage) {
final Map> messages = new HashMap<>();
- for (final String xmlPath : odfPackage.getXmlEntryPaths()) {
- ParseResult parseResult = odfPackage.getEntryXmlParseResult(xmlPath);
- if (parseResult == null) {
- continue;
- }
- List messageList = (parseResult.isWellFormed())
- ? validateOdfXmlDocument(odfPackage, xmlPath, parseResult)
- : parseResult.getMessages();
- messages.put(xmlPath, messageList);
+ for (final FileEntry xmlEntry : odfPackage.getXmlEntries()) {
+ messages.put(xmlEntry.getFullPath(), validateXmlEntry(xmlEntry, odfPackage));
}
return messages;
}
+ private final List validateXmlEntry(final FileEntry xmlEntry, final OdfPackage odfPackage) {
+ final String xmlPath = xmlEntry.getFullPath();
+ if (xmlPath.equals("/")) {
+ return new ArrayList<>();
+ }
+ if (xmlEntry.isEncrypted()) {
+ return Arrays.asList(FACTORY.getWarning("PKG-10", xmlPath));
+ }
+ ParseResult parseResult = odfPackage.getEntryXmlParseResult(xmlPath);
+ if (parseResult == null) {
+ return new ArrayList<>();
+ }
+ return (parseResult.isWellFormed())
+ ? validateOdfXmlDocument(odfPackage, xmlPath, parseResult)
+ : parseResult.getMessages();
+ }
+
private final List validateOdfXmlDocument(final OdfPackage odfPackage, final String xmlPath,
final ParseResult parseResult) {
List messageList = new ArrayList<>();
diff --git a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/AbstractRule.java b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/AbstractRule.java
index f6c23675..53304e29 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/AbstractRule.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/AbstractRule.java
@@ -4,6 +4,7 @@
import org.openpreservation.messages.Message.Severity;
import org.openpreservation.messages.MessageLog;
+import org.openpreservation.messages.Messages;
import org.openpreservation.odf.pkg.PackageParser.ParseException;
import org.openpreservation.odf.validation.Rule;
import org.openpreservation.odf.validation.ValidationReport;
@@ -52,7 +53,11 @@ public boolean isPrerequisite() {
@Override
public MessageLog check(ValidationReport report) throws ParseException {
- return report.document.isPackage() ? check(report.document.getPackage()) : check(report.document.getDocument().getXmlDocument());
+ if (report.document == null) {
+ return Messages.messageLogInstance();
+ }
+ return report.document.isPackage() ? check(report.document.getPackage())
+ : check(report.document.getDocument().getXmlDocument());
}
@Override
diff --git a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/MacroRule.java b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/MacroRule.java
index 23474908..82d6b7e9 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/MacroRule.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/MacroRule.java
@@ -1,6 +1,7 @@
package org.openpreservation.odf.validation.rules;
import java.io.IOException;
+import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
@@ -60,11 +61,19 @@ private MessageLog checkOdfScriptXml(final OdfPackage odfPackage) throws IOExcep
throw new IllegalStateException(e);
}
for (FileEntry entry : odfPackage.getXmlEntries()) {
- ParseResult result = checker.parse(odfPackage.getEntryStream(entry));
- if (NS_SCRIPTS.equals(result.getRootNamespace().getId().toASCIIString())
- && "module".equals(result.getRootName())) {
- messageLog.add(entry.getFullPath(), Messages.getMessageInstance(id, severity, name, description));
+ if (entry.isEncrypted()) {
+ continue;
+ }
+ try (final InputStream entryStream = odfPackage.getEntryStream(entry)) {
+ if (entryStream == null) {
+ continue;
+ }
+ ParseResult result = checker.parse(odfPackage.getEntryStream(entry));
+ if (NS_SCRIPTS.equals(result.getRootNamespace().getId().toASCIIString())
+ && "module".equals(result.getRootName())) {
+ messageLog.add(entry.getFullPath(), Messages.getMessageInstance(id, severity, name, description));
+ }
}
}
return messageLog;
diff --git a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/ProfileImpl.java b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/ProfileImpl.java
index fd2a534e..32a11f47 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/ProfileImpl.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/ProfileImpl.java
@@ -46,20 +46,21 @@ public ProfileResult check(final OdfPackage odfPackage) throws ParseException {
@Override
public ProfileResult check(final ValidationReport report) throws ParseException {
final MessageLog messages = Messages.messageLogInstance();
- messages.add(getRulesetMessages(report.document.getPackage(),
+ messages.add(getRulesetMessages(report,
this.rules.stream().filter(Rule::isPrerequisite).collect(Collectors.toList())));
if (!messages.hasErrors()) {
- messages.add(getRulesetMessages(report.document.getPackage(),
+ messages.add(getRulesetMessages(report,
this.rules.stream().filter(rule -> !rule.isPrerequisite()).collect(Collectors.toList())));
}
- return ProfileResultImpl.of(report.document.getPackage().getName(), this.name, report, messages);
+ return ProfileResultImpl.of(report.document == null ? "" : report.document.getPackage().getName(), this.name,
+ report, messages);
}
- private final Map> getRulesetMessages(final OdfPackage odfPackage,
+ private final Map> getRulesetMessages(final ValidationReport report,
final Collection rules) throws ParseException {
final MessageLog messages = Messages.messageLogInstance();
for (final Rule rule : rules) {
- final MessageLog ruleMessages = rule.check(odfPackage);
+ final MessageLog ruleMessages = rule.check(report);
messages.add(ruleMessages.getMessages());
}
return messages.getMessages();
diff --git a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/SchematronRule.java b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/SchematronRule.java
index 00ccf024..e31e71d9 100644
--- a/odf-core/src/main/java/org/openpreservation/odf/validation/rules/SchematronRule.java
+++ b/odf-core/src/main/java/org/openpreservation/odf/validation/rules/SchematronRule.java
@@ -46,7 +46,7 @@ public MessageLog check(final OdfPackage odfPackage) throws ParseException {
Objects.requireNonNull(odfPackage, "odfPackage must not be null");
final MessageLog messageLog = Messages.messageLogInstance();
for (final FileEntry entry : odfPackage.getXmlEntries()) {
- if (!OdfPackages.isOdfXml(entry.getFullPath())) {
+ if (!OdfPackages.isOdfXml(entry.getFullPath()) || entry.isEncrypted()) {
continue;
}
try (InputStream is = odfPackage.getEntryStream(entry)) {
diff --git a/odf-core/src/main/resources/org/openpreservation/odf/messages/Messages.properties b/odf-core/src/main/resources/org/openpreservation/odf/messages/Messages.properties
index c02a5728..e9a2c1ad 100644
--- a/odf-core/src/main/resources/org/openpreservation/odf/messages/Messages.properties
+++ b/odf-core/src/main/resources/org/openpreservation/odf/messages/Messages.properties
@@ -16,6 +16,7 @@ PKG-4 = An OpenDocument Package SHOULD contain a file "mimetype".
PKG-5 = An OpenDocument Package SHALL only contain the "META-INF/manifest.xml" and files containg the term "signatures" in their name in the "META-INF" folder. File %s does not meet this criteria.
PKG-7 = An OpenDocument Package SHOULD contain a preview image Thumbnails/thumbnail.png.
PKG-8 = Encrypted file entries shall be flagged as "STORED" rather than "DEFLATED" in the zip file's central directory. Zip entry %s is encrypted and flagged as "DEFLATED".
+PKG-10 = Encrypted file entry detected: %s.
MIM-1 = The "mimetype" file SHALL be the first file of the zip file.
MIM-2 = The "mimetype" file SHALL NOT be compressed.
MIM-3 = The "mimetype" file SHALL NOT use an 'extra field' in its header.
diff --git a/odf-core/src/test/java/org/openpreservation/odf/validation/ValidatingParserTest.java b/odf-core/src/test/java/org/openpreservation/odf/validation/ValidatingParserTest.java
index bfd0dd40..e9fcd3f7 100644
--- a/odf-core/src/test/java/org/openpreservation/odf/validation/ValidatingParserTest.java
+++ b/odf-core/src/test/java/org/openpreservation/odf/validation/ValidatingParserTest.java
@@ -35,14 +35,16 @@ public void testParseNullPath() throws ParserConfigurationException, SAXExceptio
}
@Test
- public void testParsePath() throws ParseException, URISyntaxException, IOException, ParserConfigurationException, SAXException {
+ public void testParsePath()
+ throws ParseException, URISyntaxException, IOException, ParserConfigurationException, SAXException {
ValidatingParser parser = Validators.getValidatingParser();
URL resourceUrl = TestFiles.EMPTY_ODS;
Path path = Paths.get(resourceUrl.toURI());
OdfPackage pkg = parser.parsePackage(path);
assertNotNull("Parsed package should not be null", pkg);
assertTrue("Package should have a mimetype entry", pkg.hasMimeEntry());
- assertEquals("Mimetype should be Spreadsheet", "application/vnd.oasis.opendocument.spreadsheet", pkg.getMimeType());
+ assertEquals("Mimetype should be Spreadsheet", "application/vnd.oasis.opendocument.spreadsheet",
+ pkg.getMimeType());
}
@Test
@@ -57,12 +59,14 @@ public void testParseNullFile() throws ParserConfigurationException, SAXExceptio
}
@Test
- public void testParseFile() throws ParseException, IOException, URISyntaxException, ParserConfigurationException, SAXException {
+ public void testParseFile()
+ throws ParseException, IOException, URISyntaxException, ParserConfigurationException, SAXException {
ValidatingParser parser = Validators.getValidatingParser();
OdfPackage pkg = parser.parsePackage(new File(TestFiles.EMPTY_ODS.toURI()));
assertNotNull("Parsed package should not be null", pkg);
assertTrue("Package should have a mimetype entry", pkg.hasMimeEntry());
- assertEquals("Mimetype should be Spreadsheet", "application/vnd.oasis.opendocument.spreadsheet", pkg.getMimeType());
+ assertEquals("Mimetype should be Spreadsheet", "application/vnd.oasis.opendocument.spreadsheet",
+ pkg.getMimeType());
}
@Test
@@ -93,7 +97,8 @@ public void testParseStream() throws ParserConfigurationException, SAXException,
OdfPackage pkg = parser.parsePackage(TestFiles.EMPTY_ODS.openStream(), TestFiles.EMPTY_ODS.toString());
assertNotNull("Parsed package should not be null", pkg);
assertTrue("Package should have a mimetype entry", pkg.hasMimeEntry());
- assertEquals("Mimetype should be Spreadsheet", "application/vnd.oasis.opendocument.spreadsheet", pkg.getMimeType());
+ assertEquals("Mimetype should be Spreadsheet", "application/vnd.oasis.opendocument.spreadsheet",
+ pkg.getMimeType());
}
@Test
@@ -114,9 +119,11 @@ public void testInValidZip() throws ParserConfigurationException, SAXException,
}
@Test
- public void testBadlyFormedPackage() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testBadlyFormedPackage()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.BADLY_FORMED_PKG.openStream(), TestFiles.BADLY_FORMED_PKG.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.BADLY_FORMED_PKG.openStream(),
+ TestFiles.BADLY_FORMED_PKG.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("BADLY_FORMED_PKG should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("PKG-4")).count() > 0);
@@ -127,52 +134,63 @@ public void testBadlyFormedPackage() throws ParserConfigurationException, SAXExc
@Test
public void testNoManifest() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.NO_MANIFEST_ODS.openStream(), TestFiles.NO_MANIFEST_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.NO_MANIFEST_ODS.openStream(),
+ TestFiles.NO_MANIFEST_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("NO_MANIFEST_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("PKG-3")).count() > 0);
}
@Test
- public void testManifestRootNoMime() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testManifestRootNoMime()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_ROOT_NO_MIME_ODS.openStream(), TestFiles.MANIFEST_ROOT_NO_MIME_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_ROOT_NO_MIME_ODS.openStream(),
+ TestFiles.MANIFEST_ROOT_NO_MIME_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_ROOT_NO_MIME_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-4")).count() > 0);
}
@Test
- public void testManifestRootRandMimetype() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testManifestRootRandMimetype()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_RAND_MIMETYPE_ODS.openStream(), TestFiles.MANIFEST_RAND_MIMETYPE_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_RAND_MIMETYPE_ODS.openStream(),
+ TestFiles.MANIFEST_RAND_MIMETYPE_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_RAND_MIMETYPE_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-5")).count() > 0);
}
@Test
- public void testManifestRandRootMime() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testManifestRandRootMime()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_RAND_ROOT_MIME_ODS.openStream(), TestFiles.MANIFEST_RAND_ROOT_MIME_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_RAND_ROOT_MIME_ODS.openStream(),
+ TestFiles.MANIFEST_RAND_ROOT_MIME_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_RAND_ROOT_MIME_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-5")).count() > 0);
}
@Test
- public void testManifestRootDiffMime() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testManifestRootDiffMime()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_DIFF_MIME_ODS.openStream(), TestFiles.MANIFEST_DIFF_MIME_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_DIFF_MIME_ODS.openStream(),
+ TestFiles.MANIFEST_DIFF_MIME_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_DIFF_MIME_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-5")).count() > 0);
}
@Test
- public void testManifestEmptyRootMime() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testManifestEmptyRootMime()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_EMPTY_ROOT_MIME_ODS.openStream(), TestFiles.MANIFEST_EMPTY_ROOT_MIME_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_EMPTY_ROOT_MIME_ODS.openStream(),
+ TestFiles.MANIFEST_EMPTY_ROOT_MIME_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_EMPTY_ROOT_MIME_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-5")).count() > 0);
@@ -181,7 +199,8 @@ public void testManifestEmptyRootMime() throws ParserConfigurationException, SAX
@Test
public void testManifestEntry() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_ENTRY_ODS.openStream(), TestFiles.MANIFEST_ENTRY_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_ENTRY_ODS.openStream(),
+ TestFiles.MANIFEST_ENTRY_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_ENTRY_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-2")).count() > 0);
@@ -190,7 +209,8 @@ public void testManifestEntry() throws ParserConfigurationException, SAXExceptio
@Test
public void testMimetypeEntry() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MIMETYPE_ENTRY_ODS.openStream(), TestFiles.MIMETYPE_ENTRY_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MIMETYPE_ENTRY_ODS.openStream(),
+ TestFiles.MIMETYPE_ENTRY_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MIMETYPE_ENTRY_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-3")).count() > 0);
@@ -199,16 +219,19 @@ public void testMimetypeEntry() throws ParserConfigurationException, SAXExceptio
@Test
public void testMetainfEntry() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.METAINF_ENTRY_ODT.openStream(), TestFiles.METAINF_ENTRY_ODT.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.METAINF_ENTRY_ODT.openStream(),
+ TestFiles.METAINF_ENTRY_ODT.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("METAINF_ENTRY_ODT should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-6")).count() > 0);
}
@Test
- public void testMissingManifestEntry() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testMissingManifestEntry()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_MISSING_ENTRY_ODS.openStream(), TestFiles.MANIFEST_MISSING_ENTRY_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_MISSING_ENTRY_ODS.openStream(),
+ TestFiles.MANIFEST_MISSING_ENTRY_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_MISSING_ENTRY_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-1")).count() > 0);
@@ -217,7 +240,8 @@ public void testMissingManifestEntry() throws ParserConfigurationException, SAXE
@Test
public void testMissingXmlEntry() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_MISSING_XML_ENTRY_ODS.openStream(), TestFiles.MANIFEST_MISSING_XML_ENTRY_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_MISSING_XML_ENTRY_ODS.openStream(),
+ TestFiles.MANIFEST_MISSING_XML_ENTRY_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_MISSING_XML_ENTRY_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-1")).count() > 0);
@@ -226,7 +250,8 @@ public void testMissingXmlEntry() throws ParserConfigurationException, SAXExcept
@Test
public void testMissingFile() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MISSING_FILE_ODS.openStream(), TestFiles.MISSING_FILE_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MISSING_FILE_ODS.openStream(),
+ TestFiles.MISSING_FILE_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MISSING_FILE_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-4")).count() > 0);
@@ -235,7 +260,8 @@ public void testMissingFile() throws ParserConfigurationException, SAXException,
@Test
public void testNoMimeWithRoot() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.NO_MIME_ROOT_ODS.openStream(), TestFiles.NO_MIME_ROOT_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.NO_MIME_ROOT_ODS.openStream(),
+ TestFiles.NO_MIME_ROOT_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("NO_MIME_ROOT_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-4")).count() > 0);
@@ -244,7 +270,8 @@ public void testNoMimeWithRoot() throws ParserConfigurationException, SAXExcepti
@Test
public void testNoRootMimeTyoe() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_NO_ROOT_MIMETYPE_ODS.openStream(), TestFiles.MANIFEST_NO_ROOT_MIMETYPE_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MANIFEST_NO_ROOT_MIMETYPE_ODS.openStream(),
+ TestFiles.MANIFEST_NO_ROOT_MIMETYPE_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MANIFEST_NO_ROOT_MIMETYPE_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MAN-5")).count() > 0);
@@ -253,7 +280,8 @@ public void testNoRootMimeTyoe() throws ParserConfigurationException, SAXExcepti
@Test
public void testNoMimeNoRoot() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.NO_MIME_NO_ROOT_ODS.openStream(), TestFiles.NO_MIME_NO_ROOT_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.NO_MIME_NO_ROOT_ODS.openStream(),
+ TestFiles.NO_MIME_NO_ROOT_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertTrue("NO_MIME_NO_ROOT_ODS should be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("PKG-4")).count() > 0);
@@ -272,16 +300,19 @@ public void testMimeLast() throws ParserConfigurationException, SAXException, IO
@Test
public void testMimeCompressed() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MIME_COMPRESSED_ODS.openStream(), TestFiles.MIME_COMPRESSED_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MIME_COMPRESSED_ODS.openStream(),
+ TestFiles.MIME_COMPRESSED_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MIME_COMPRESSED_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-2")).count() > 0);
}
@Test
- public void testMimeCompressedLast() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testMimeCompressedLast()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MIME_COMPRESSED_LAST_ODS.openStream(), TestFiles.MIME_COMPRESSED_LAST_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MIME_COMPRESSED_LAST_ODS.openStream(),
+ TestFiles.MIME_COMPRESSED_LAST_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MIME_COMPRESSED_LAST_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-1")).count() > 0);
@@ -291,7 +322,8 @@ public void testMimeCompressedLast() throws ParserConfigurationException, SAXExc
@Test
public void testMimeExtra() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.MIME_EXTRA_ODS.openStream(), TestFiles.MIME_EXTRA_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.MIME_EXTRA_ODS.openStream(),
+ TestFiles.MIME_EXTRA_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertFalse("MIME_EXTRA_ODS should NOT be valid", report.isValid());
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("MIM-3")).count() > 0);
@@ -300,7 +332,8 @@ public void testMimeExtra() throws ParserConfigurationException, SAXException, I
@Test
public void testNoThumbnail() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.NO_THUMBNAIL_ODS.openStream(), TestFiles.NO_THUMBNAIL_ODS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.NO_THUMBNAIL_ODS.openStream(),
+ TestFiles.NO_THUMBNAIL_ODS.toString());
ValidationReport report = parser.validatePackage(pkg);
assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("PKG-7")).count() > 0);
}
@@ -316,10 +349,11 @@ public void testNoEmbeddedWord() throws ParserConfigurationException, SAXExcepti
@Test
public void testPasswordEncrypted() throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
- OdfPackage pkg = parser.parsePackage(TestFiles.ENCRYPTED_PASSWORDS.openStream(), TestFiles.ENCRYPTED_PASSWORDS.toString());
+ OdfPackage pkg = parser.parsePackage(TestFiles.ENCRYPTED_PASSWORDS.openStream(),
+ TestFiles.ENCRYPTED_PASSWORDS.toString());
ValidationReport report = parser.validatePackage(pkg);
- assertFalse("ENCRYPTED_PASSWORDS should NOT be valid", report.isValid());
- assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("XML-3")).count() > 0);
+ assertTrue("ENCRYPTED_PASSWORDS should be valid", report.isValid());
+ assertTrue(report.getMessages().stream().filter(m -> m.getId().equals("PKG-10")).count() > 0);
}
@Test
@@ -328,7 +362,7 @@ public void testDsigValid() throws ParserConfigurationException, SAXException, I
InputStream is = TestFiles.DSIG_VALID.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_VALID.toString());
ValidationReport report = parser.validatePackage(pkg);
- assertTrue("Package is not valid" , report.isValid());
+ assertTrue("Package is not valid", report.isValid());
}
@Test
@@ -337,16 +371,17 @@ public void testDsigInvalid() throws ParserConfigurationException, SAXException,
InputStream is = TestFiles.DSIG_INVALID.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_INVALID.toString());
ValidationReport report = parser.validatePackage(pkg);
- assertFalse("Package should be NOT be valid, dsig file has bad version" , report.isValid());
+ assertFalse("Package should be NOT be valid, dsig file has bad version", report.isValid());
}
@Test
- public void testDsigInvalidBadName() throws ParserConfigurationException, SAXException, IOException, ParseException {
+ public void testDsigInvalidBadName()
+ throws ParserConfigurationException, SAXException, IOException, ParseException {
ValidatingParser parser = Validators.getValidatingParser();
InputStream is = TestFiles.DSIG_BADNAME.openStream();
OdfPackage pkg = parser.parsePackage(is, TestFiles.DSIG_BADNAME.toString());
ValidationReport report = parser.validatePackage(pkg);
- assertFalse("Package should be NOT be valid, badly named META-INF file." , report.isValid());
+ assertFalse("Package should be NOT be valid, badly named META-INF file.", report.isValid());
assertEquals(1, report.getMessages().stream().filter(m -> m.getId().equals("PKG-5")).count());
}
}
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/META-INF/manifest.xml b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/META-INF/manifest.xml
new file mode 100644
index 00000000..a076030a
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/META-INF/manifest.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/Thumbnails/thumbnail.png b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/Thumbnails/thumbnail.png
new file mode 100644
index 00000000..2c939f2d
Binary files /dev/null and b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/Thumbnails/thumbnail.png differ
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/content.xml b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/content.xml
new file mode 100644
index 00000000..1d74214c
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/content.xml
@@ -0,0 +1,2 @@
+
+Besøg på museum efter besøg, alder og køn efter tid, alder og køn ogbesøg2021K4Inden for de seneste 3 månederMellem 3-6 måneder sidenMellem et halvt og et helt år sidenMellem 1 og 3 år sidenMellem 3 og 5 år sidenMere end 5 år sidenAldrig været på et museumØnsker ikke at svareVed ikkeI alt29911221014401Mænd25811241115501Kvinder3391119101330116-24 år3411132011650125-34 år317122610941035-44 år2811825121140145-54 år2791222101731055-64 år3081019111740165-74 år339111861850175 år og derover22610211221504Spørgsmål til respondenter: Hvornår har du senest besøgt et museum? Pct. af befolkningen
\ No newline at end of file
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/manifest.rdf b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/manifest.rdf
new file mode 100644
index 00000000..927e206b
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/manifest.rdf
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/meta.xml b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/meta.xml
new file mode 100644
index 00000000..961b395c
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/meta.xml
@@ -0,0 +1,2 @@
+
+mariaMaria Messerschmidt2024-04-11T09:03:422024-04-30T07:54:52LibreOffice/24.2.2.2$MacOSX_AARCH64 LibreOffice_project/d56cc158d8a96260b836f100ef4b4ef25d6f1a0116.0300
\ No newline at end of file
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/mimetype b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/mimetype
new file mode 100644
index 00000000..78a49cc5
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/mimetype
@@ -0,0 +1 @@
+application/vnd.oasis.opendocument.spreadsheet
\ No newline at end of file
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/settings.xml b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/settings.xml
new file mode 100644
index 00000000..9e7935bb
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/settings.xml
@@ -0,0 +1,2 @@
+
+00157299525truetruetrue0truetruefalsetruefalse-1truetrue0falsefalsetruetruefalse3falsefalsefalse1000100011truefalsefalsetruetruetruetrue2true
\ No newline at end of file
diff --git a/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/styles.xml b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/styles.xml
new file mode 100644
index 00000000..e8d3170e
--- /dev/null
+++ b/odf-core/src/test/resources/org/openpreservation/odf/fmt/pkg/version/T104/styles.xml
@@ -0,0 +1,2 @@
+
+---- - - - - ::::???Page 1???(???)0000-00-00, 00:00:00Page 1/ 99
\ No newline at end of file
diff --git a/odf-reporting/pom.xml b/odf-reporting/pom.xml
index ea5ff00f..990bef6d 100644
--- a/odf-reporting/pom.xml
+++ b/odf-reporting/pom.xml
@@ -5,7 +5,7 @@
org.openpreservation.odf
odf-validator
- 0.14.0
+ 0.16.0
../pom.xml
diff --git a/odf-validator b/odf-validator
index d278c1d5..b307df8b 100755
--- a/odf-validator
+++ b/odf-validator
@@ -78,5 +78,5 @@ fi
exec "$JAVACMD" -Dfile.encoding=UTF8 -XX:+IgnoreUnrecognizedVMOptions \
-Dapp.name="ODF Validator" \
- -jar odf-apps/target/odf-apps-0.14.0-jar-with-dependencies.jar \
+ -jar odf-apps/target/odf-apps-0.16.0-jar-with-dependencies.jar \
"$@"
diff --git a/odf-validator.bat b/odf-validator.bat
index 5f16a8ed..92665c39 100644
--- a/odf-validator.bat
+++ b/odf-validator.bat
@@ -85,7 +85,7 @@ if NOT "%CLASSPATH_PREFIX%" == "" set CLASSPATH=%CLASSPATH_PREFIX%;%CLASSPATH%
@REM Reaching here means variables are defined and arguments have been captured
:endInit
-"%JAVACMD%" -Dfile.encoding=UTF8 -XX:+IgnoreUnrecognizedVMOptions -Dapp.name="ODF Validator" -jar .\odf-apps\target\odf-apps-0.14.0-jar-with-dependencies.jar %CMD_LINE_ARGS%
+"%JAVACMD%" -Dfile.encoding=UTF8 -XX:+IgnoreUnrecognizedVMOptions -Dapp.name="ODF Validator" -jar .\odf-apps\target\odf-apps-0.16.0-jar-with-dependencies.jar %CMD_LINE_ARGS%
if %ERRORLEVEL% NEQ 0 goto error
goto end
diff --git a/pom.xml b/pom.xml
index 70fb11a2..8d74f7a5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
org.openpreservation.odf
odf-validator
- 0.14.0
+ 0.16.0
pom