Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Align messages with draft specification #106

Merged
merged 5 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ static final MessageLog of() {
static final MessageLog of(final List<Message> messages) {
return new MessageLogImpl(messages);
}

@Override
public int size() {
return this.messages.size();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,18 @@ public interface OdfPackage {
* @return the OdfDocument for the sub-document
*/
public OdfPackageDocument getSubDocument(final String path);

/**
* Retrieve the Map of String path keys and ParseResult values for files below the META-INF directory.
*
* @return the Map of META-INF file parse results.
*/
public Map<String, ParseResult> getMetaInfMap();

/**
* Returns true if the META-INF directory or sub-directories contain files with the term "signatures" in their name.
*
* @return the Map of META-INF file parse results.
*/
public boolean hasDsigEntries();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.openpreservation.format.xml.ParseResult;
import org.openpreservation.format.zip.ZipArchive;
import org.openpreservation.format.zip.ZipArchiveCache;
import org.openpreservation.format.zip.ZipEntry;
import org.openpreservation.odf.fmt.Formats;
import org.openpreservation.odf.fmt.OdfFormats;
import org.openpreservation.odf.xml.OdfXmlDocument;
Expand Down Expand Up @@ -123,22 +124,22 @@ public String getMimeType() {

@Override
public boolean hasMimeEntry() {
return this.archive.getZipEntry(OdfFormats.MIMETYPE) != null;
return (this.archive != null) && this.archive.getZipEntry(OdfFormats.MIMETYPE) != null;
}

@Override
public boolean isMimeFirst() {
return this.archive.getFirstEntry().getName().equals(OdfFormats.MIMETYPE);
return (this.archive != null) && this.archive.getFirstEntry().getName().equals(OdfFormats.MIMETYPE);
}

@Override
public boolean hasManifest() {
return this.archive.getZipEntry(Constants.PATH_MANIFEST) != null;
return (this.archive != null) && this.archive.getZipEntry(Constants.PATH_MANIFEST) != null;
}

@Override
public boolean hasThumbnail() {
return this.archive.getZipEntry(Constants.PATH_THUMBNAIL) != null;
return (this.archive != null) && this.archive.getZipEntry(Constants.PATH_THUMBNAIL) != null;
}

@Override
Expand All @@ -163,7 +164,7 @@ public Formats getDetectedFormat() {

@Override
public InputStream getEntryXmlStream(final String path) throws IOException {
return this.archive.getEntryInputStream(path);
return (this.archive != null) ? this.archive.getEntryInputStream(path) : null;
}

@Override
Expand Down Expand Up @@ -195,7 +196,7 @@ public List<String> getXmlEntryPaths() {

@Override
public InputStream getEntryStream(final FileEntry entry) throws IOException {
return this.archive.getEntryInputStream(entry.getFullPath());
return (this.archive != null) ? this.archive.getEntryInputStream(entry.getFullPath()) : null;
}

@Override
Expand Down Expand Up @@ -276,4 +277,22 @@ public Map<String, OdfPackageDocument> getDocumentMap() {
public OdfPackageDocument getSubDocument(String path) {
return this.documentMap.get(path);
}

@Override
public Map<String, ParseResult> getMetaInfMap() {
return Collections.unmodifiableMap(this.metaInfMap);
}

@Override
public boolean hasDsigEntries() {
if (this.archive == null) {
return false;
}
for (ZipEntry entry : this.archive.getZipEntries()) {
if (PackageParserImpl.isDsig(entry.getName())) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.openpreservation.odf.validation;

import java.io.IOException;

import org.openpreservation.messages.MessageLog;
import org.openpreservation.odf.pkg.OdfPackage;
import org.openpreservation.odf.xml.OdfXmlDocument;

public interface Rule {
public String getId();
public String getName();
public String getDescription();
public MessageLog check(final OdfXmlDocument document) throws IOException;
public MessageLog check(final OdfPackage odfPackage) throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ private List<Message> checkManifestEntries(final OdfPackage odfPackage) {
} else {
ZipEntry zipEntry = odfPackage.getZipArchive().getZipEntry(entryPath);
if (zipEntry == null) {
messages.add(FACTORY.getError("MAN-1", entryPath));
messages.add(FACTORY.getError("MAN-4", entryPath));
}
}
}
Expand All @@ -243,7 +243,7 @@ private final Map<String, List<Message>> auditZipEntries(final OdfPackage odfPac
continue;
}
if (manifest != null && odfPackage.getManifest().getEntry(zipEntry.getName()) == null) {
messages.add(FACTORY.getError("MAN-4", zipEntry.getName()));
messages.add(FACTORY.getError("MAN-1", zipEntry.getName()));
}
messageMap.put(zipEntry.getName(), messages);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.openpreservation.odf.validation.rules;

import org.openpreservation.odf.validation.Rule;

abstract class AbstractRule implements Rule {
final String id;
final String name;
final String description;

AbstractRule(final String id, final String name, final String description) {
super();
this.id = id;
this.name = name;
this.description = description;
}

@Override
public String getId() {
return this.id;
}

@Override
public String getName() {
return this.name;
}

@Override
public String getDescription() {
return this.description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.openpreservation.odf.validation.rules;

import java.io.IOException;
import java.util.Objects;

import org.openpreservation.messages.Message;
import org.openpreservation.messages.MessageLog;
import org.openpreservation.messages.Messages;
import org.openpreservation.odf.pkg.OdfPackage;
import org.openpreservation.odf.xml.OdfXmlDocument;

final class DigitalSignaturesRule extends AbstractRule {

private DigitalSignaturesRule(String id, String name, String description) {
super(id, name, description);
}

@Override
public MessageLog check(OdfXmlDocument document) {
throw new UnsupportedOperationException("Unimplemented method 'check'");
}

@Override
public MessageLog check(OdfPackage odfPackage) throws IOException {
Objects.requireNonNull(odfPackage, "odfPackage must not be null");
MessageLog messageLog = Messages.messageLogInstance();
if (odfPackage.hasDsigEntries()) {
messageLog.add(Messages.getMessageInstance(this.id, Message.Severity.ERROR, this.getName(),
this.getDescription()));
}
return messageLog;
}

static final DigitalSignaturesRule getInstance() {
return new DigitalSignaturesRule("ODF_9", "Digital Signatures",
"The package MUST NOT contain any digital signatures.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.openpreservation.odf.validation.rules;

import java.io.IOException;
import java.util.Objects;

import org.openpreservation.messages.Message;
import org.openpreservation.messages.MessageLog;
import org.openpreservation.messages.Messages;
import org.openpreservation.odf.pkg.OdfPackage;
import org.openpreservation.odf.xml.OdfXmlDocument;

final class ExtensionMimeTypeRule extends AbstractRule {

private ExtensionMimeTypeRule(String id, String name, String description) {
super(id, name, description);
}

@Override
public MessageLog check(OdfXmlDocument document) {
throw new UnsupportedOperationException("Unimplemented method 'check'");
}

@Override
public MessageLog check(OdfPackage odfPackage) throws IOException {
Objects.requireNonNull(odfPackage, "odfPackage must not be null");
MessageLog messageLog = Messages.messageLogInstance();
if (!odfPackage.hasMimeEntry()
|| !"application/vnd.oasis.opendocument.spreadsheet".equals(odfPackage.getMimeType())
|| !odfPackage.getName().endsWith(".ods")) {
messageLog.add(Messages.getMessageInstance(this.id, Message.Severity.ERROR, this.getName(),
this.getDescription()));
}
return messageLog;
}

static final ExtensionMimeTypeRule getInstance() {
return new ExtensionMimeTypeRule("ODF_4", "Extension and MIME type",
"The MIME type value MUST be: \"application/vnd.oasis.opendocument.spreadsheet\" and the file extension MUST be \".ods\"."
+ //
"");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.openpreservation.odf.validation.rules;

import java.io.IOException;
import java.util.Objects;

import org.openpreservation.messages.Message;
import org.openpreservation.messages.MessageLog;
import org.openpreservation.messages.Messages;
import org.openpreservation.odf.pkg.OdfPackage;
import org.openpreservation.odf.xml.OdfXmlDocument;

final class PackageMimeTypeRule extends AbstractRule {

private PackageMimeTypeRule(String id, String name, String description) {
super(id, name, description);
}

@Override
public MessageLog check(OdfXmlDocument document) {
throw new UnsupportedOperationException("Unimplemented method 'check'");
}

@Override
public MessageLog check(OdfPackage odfPackage) throws IOException {
Objects.requireNonNull(odfPackage, "odfPackage must not be null");
MessageLog messageLog = Messages.messageLogInstance();
if (!odfPackage.hasMimeEntry()) {
messageLog.add(Messages.getMessageInstance(this.id, Message.Severity.ERROR, this.getName(), this.getDescription()));
}
return messageLog;
}

static final PackageMimeTypeRule getInstance() {
return new PackageMimeTypeRule("ODF_3", "Package mimetype entry", "An ODF package MUST have a mimetype entry as specified in the Section 3.3 of the ODF specification v1.3.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package org.openpreservation.odf.validation.rules;

import javax.xml.parsers.ParserConfigurationException;

import org.openpreservation.odf.validation.Rule;
import org.xml.sax.SAXException;

public class Rules {
private Rules() {
throw new AssertionError("Utility class must not be instantiated");
}

public static final Rule odf2() throws ParserConfigurationException, SAXException {
return ValidPackageRule.getInstance();
}

public static final Rule odf3() {
return PackageMimeTypeRule.getInstance();
}

public static final Rule odf4() {
return ExtensionMimeTypeRule.getInstance();
}

public static final Rule odf9() {
return DigitalSignaturesRule.getInstance();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.openpreservation.odf.validation.rules;

import java.io.IOException;
import java.util.Objects;

import javax.xml.parsers.ParserConfigurationException;

import org.openpreservation.messages.Message;
import org.openpreservation.messages.MessageLog;
import org.openpreservation.messages.Messages;
import org.openpreservation.odf.pkg.OdfPackage;
import org.openpreservation.odf.validation.ValidatingParser;
import org.openpreservation.odf.validation.ValidationReport;
import org.openpreservation.odf.validation.Validators;
import org.openpreservation.odf.xml.OdfXmlDocument;
import org.xml.sax.SAXException;

class ValidPackageRule extends AbstractRule {
private final ValidatingParser validatingParser = Validators.getValidatingParser();

private ValidPackageRule(String id, String name, String description) throws ParserConfigurationException, SAXException {
super(id, name, description);
}

@Override
public MessageLog check(OdfXmlDocument document) {
throw new UnsupportedOperationException("Unimplemented method 'check'");
}

@Override
public MessageLog check(OdfPackage odfPackage) throws IOException {
Objects.requireNonNull(odfPackage, "odfPackage must not be null");
MessageLog messageLog = Messages.messageLogInstance();
ValidationReport validationReport = validatingParser.validatePackage(odfPackage);
if (!validationReport.isValid()) {
messageLog.add(validationReport.getMessages());
messageLog.add(Messages.getMessageInstance(this.id, Message.Severity.ERROR, this.getName(), this.getDescription()));
}
return messageLog;
}

static final ValidPackageRule getInstance() throws ParserConfigurationException, SAXException {
return new ValidPackageRule("ODF_2", "Standard Compliance", "The file MUST comply with the standard \"OASIS Open Document Format for Office Applications (OpenDocument) v1.3\".");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ MIM-3 = The "mimetype" file SHALL NOT use an 'extra field' in its header.
MIM-4 = An OpenDocument package SHALL contain a mimetype file IF the manifest contains a <manifest:file-entry> element whose manifest:full-path attribute has the value \"/\".
MIM-5 = An OpenDocument package mimetype file content SHALL be equal to the manifest:media-type attribute of the manifest <manifest:file-entry> element whose manifest:full-path attribute has the value \"/\".
MIM-6 = The content of the "mimetype" file SHALL be ASCII encoded.
MAN-1 = The manifest SHALL contain an entry for every file in the package, manifest file entry %s has no corresponding zip entry.
MAN-1 = The manifest SHALL contain an entry for every file in the package, zip entry %s has no corresponding manifest file entry.
MAN-2 = An OpenDocument package manifest SHALL NOT contain a file entry for itself.
MAN-3 = An OpenDocument package manifest SHALL NOT contain a file entry the mimetype file.
MAN-4 = The manifest SHALL contain an entry for every file in the package, zip entry %s has no corresponding manifest file entry.
MAN-4 = The manifest SHALL contain an entry for every file in the package, manifest file entry %s has no corresponding zip entry.
MAN-5 = An OpenDocument package manifest SHALL contain a <manifest:file-entry> element whose manifest:full-path attribute has the value \"/\" if a mimetype file is present.
MAN-6 = The OpenDocument package manifest NEED NOT contain entries for file paths starting with META-INF/, %s.
MAN-7 = An OpenDocument package SHOULD contain a <manifest:file-entry> element whose manifest:full-path attribute has the value \"/\"".
Expand Down
Loading