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

FEAT: Extended checking profiles #111

Merged
merged 2 commits into from
Nov 30, 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 @@ -6,6 +6,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

Expand Down Expand Up @@ -65,10 +66,12 @@ private Integer results() {
Integer retStatus = 0;
for (Map.Entry<Path, ValidationReport> entry : validationReports.entrySet()) {
if (this.appMessages.containsKey(entry.getKey())) {
for (Message message : this.appMessages.get(entry.getKey()).getMessages()) {
ConsoleFormatter.colourise(message);
if (message.isError() || message.isFatal()) {
retStatus = 1;
for (List<Message> messages : this.appMessages.get(entry.getKey()).getMessages().values()) {
for (Message message : messages) {
ConsoleFormatter.colourise(message);
if (message.isError() || message.isFatal()) {
retStatus = 1;
}
}
}
}
Expand All @@ -85,36 +88,30 @@ private Integer results(final Path path, final ValidationReport report) {
if (report.getMessages().isEmpty()) {
ConsoleFormatter.info(FACTORY.getInfo("APP-3").getMessage());
}
int packageErrors = 0;
int packageWarnings = 0;
int packageInfos = 0;
for (Map.Entry<String, MessageLog> entry : report.documentMessages.entrySet()) {
for (Message message : entry.getValue().getMessages()) {
for (Map.Entry<String, List<Message>> entry : report.documentMessages.getMessages().entrySet()) {
for (Message message : entry.getValue()) {
ConsoleFormatter.colourise(Paths.get(entry.getKey()), message);
if (message.isError() || message.isFatal()) {
retStatus = 1;
}
}
packageErrors += entry.getValue().getErrors().size();
packageWarnings += entry.getValue().getWarnings().size();
packageInfos += entry.getValue().getInfos().size();
}
if (packageErrors > 0) {
if (report.documentMessages.hasErrors()) {
ConsoleFormatter.error(String.format("NOT VALID, %d errors, %d warnings and %d info messages.",
packageErrors, packageWarnings, packageInfos));
} else if (packageWarnings > 0) {
report.documentMessages.getErrorCount(), report.documentMessages.getWarningCount(), report.documentMessages.getInfoCount()));
} else if (report.documentMessages.hasWarnings()) {
ConsoleFormatter.warn(String.format("VALID, no errors, %d warnings found and %d info messages.",
packageWarnings, packageInfos));
report.documentMessages.getWarningCount(), report.documentMessages.getInfoCount()));
} else {
ConsoleFormatter
.info(String.format("VALID, no errors, no warnings and %d info message found.", packageInfos));
.info(String.format("VALID, no errors, no warnings and %d info message found.", report.documentMessages.getInfoCount()));
}
ConsoleFormatter.newline();
return retStatus;
}

private final void logMessage(final Path path, final Message message) {
this.appMessages.putIfAbsent(path, Messages.messageLogInstance());
this.appMessages.get(path).add(message);
this.appMessages.get(path).add(path.toString(), message);
}
}
11 changes: 11 additions & 0 deletions odf-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@
<artifactId>equalsverifier</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.helger.schematron</groupId>
<artifactId>ph-schematron-pure</artifactId>
<version>7.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE -->
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>Saxon-HE</artifactId>
<version>12.3</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,25 @@

import java.util.Collection;
import java.util.List;
import java.util.Map;

public interface MessageLog {
public int size();
public boolean isEmpty();
public int add(final Message message);
public int add(final Collection<? extends Message> messages);
public List<Message> getErrors();
public List<Message> getWarnings();
public List<Message> getInfos();
public List<Message> getMessages();
public List<Message> getMessages(Message.Severity severity);
public List<Message> getMessages(String id);
public int add(final String path, final Message message);
public int add(final String path, final Collection<? extends Message> messages);
public int add(final Map<String, List<Message>> messages);
public Map<String, List<Message>> getErrors();
public Map<String, List<Message>> getWarnings();
public Map<String, List<Message>> getInfos();
public Map<String, List<Message>> getMessages();
public Map<String, List<Message>> getMessagesBySeverity(Message.Severity severity);
public Map<String, List<Message>> getMessagesById(String id);
public List<Message> getMessagesForPath(String path);
public boolean hasErrors();
public boolean hasWarnings();
public boolean hasInfos();
public int getErrorCount();
public int getWarningCount();
public int getInfoCount();
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,94 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

final class MessageLogImpl implements MessageLog {
private final List<Message> messages;

private MessageLogImpl() {
this(new ArrayList<>());
static final MessageLog of() {
return new MessageLogImpl();
}

private MessageLogImpl(final List<Message> messages) {
super();
this.messages = new ArrayList<>(messages);
static final MessageLog of(final String path, final List<Message> messages) {
final Map<String, List<Message>> messageMap = new HashMap<>();
messageMap.put(path, messages);
return new MessageLogImpl(messageMap);
}

static final MessageLog of() {
return new MessageLogImpl();
private final Map<String, List<Message>> messageMap;

private MessageLogImpl() {
this(new HashMap<>());
}

static final MessageLog of(final List<Message> messages) {
return new MessageLogImpl(messages);
private MessageLogImpl(final Map<String, List<Message>> messageMap) {
super();
this.messageMap = new HashMap<>(messageMap);
}

@Override
public int size() {
return this.messages.size();
return this.messageMap.values().stream().mapToInt(List::size).sum();
}

@Override
public boolean isEmpty() {
return this.messages.isEmpty();
return this.size() == 0;
}

@Override
public int add(final Message message) {
this.messages.add(message);
public int add(final String path, final Message message) {
messageMap.putIfAbsent(path, new ArrayList<>());
this.messageMap.get(path).add(message);
return this.size();
}

@Override
public int add(final Collection<? extends Message> messages) {
this.messages.addAll(messages);
public int add(final String path, final Collection<? extends Message> messages) {
if (!messages.isEmpty()) {
messageMap.putIfAbsent(path, new ArrayList<>());
this.messageMap.get(path).addAll(messages);
}
return this.size();
}

@Override
public List<Message> getErrors() {
return getMessages(Message.Severity.ERROR);
public Map<String, List<Message>> getErrors() {
return getMessagesBySeverity(Message.Severity.ERROR);
}

@Override
public List<Message> getWarnings() {
return getMessages(Message.Severity.WARNING);
public Map<String, List<Message>> getWarnings() {
return getMessagesBySeverity(Message.Severity.WARNING);
}

@Override
public List<Message> getInfos() {
return getMessages(Message.Severity.INFO);
public Map<String, List<Message>> getInfos() {
return getMessagesBySeverity(Message.Severity.INFO);
}

@Override
public List<Message> getMessages(final Message.Severity severity) {
return this.messages.stream().filter(m -> m.getSeverity() == severity).collect(Collectors.toUnmodifiableList());
public Map<String, List<Message>> getMessagesBySeverity(final Message.Severity severity) {
return this.messageMap.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey,
e -> e.getValue().stream().filter(m -> m.getSeverity().equals(severity))
.collect(Collectors.toUnmodifiableList())))
.entrySet().stream().filter(e -> !e.getValue().isEmpty())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}

@Override
public List<Message> getMessages() {
return Collections.unmodifiableList(this.messages);
public Map<String, List<Message>> getMessages() {
return Collections.unmodifiableMap(this.messageMap);
}

@Override
public List<Message> getMessages(final String id) {
return this.messages.stream().filter(m -> m.getId().equals(id)).collect(Collectors.toUnmodifiableList());
public Map<String, List<Message>> getMessagesById(final String id) {
return this.messageMap.entrySet().stream().collect(Collectors.toMap(Entry::getKey,
e -> e.getValue().stream().filter(m -> m.getId().equals(id)).collect(Collectors.toUnmodifiableList())));
}

@Override
Expand All @@ -93,7 +108,33 @@ public boolean hasInfos() {
return containsSeverity(Message.Severity.INFO);
}

@Override
public List<Message> getMessagesForPath(final String path) {
return Collections.unmodifiableList(this.messageMap.getOrDefault(path, new ArrayList<>()));
}

private boolean containsSeverity(final Message.Severity severity) {
return this.messages.stream().anyMatch((m -> m.getSeverity() == severity));
return this.getMessagesBySeverity(severity).size() > 0;
}

@Override
public int add(Map<String, List<Message>> messages) {
messages.forEach(this::add);
return this.size();
}

@Override
public int getErrorCount() {
return this.getErrors().values().stream().mapToInt(List::size).sum();
}

@Override
public int getWarningCount() {
return this.getWarnings().values().stream().mapToInt(List::size).sum();
}

@Override
public int getInfoCount() {
return this.getInfos().values().stream().mapToInt(List::size).sum();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public static MessageLog messageLogInstance() {
return MessageLogImpl.of();
}

public static MessageLog messageLogInstance(final List<Message> messages) {
return MessageLogImpl.of(messages);
public static MessageLog messageLogInstance(final String path, final List<Message> messages) {
return MessageLogImpl.of(path, messages);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.openpreservation.format.xml.ParseResult;
import org.openpreservation.format.zip.ZipArchive;
Expand Down Expand Up @@ -115,6 +116,15 @@ public interface OdfPackage {
*/
public List<String> getXmlEntryPaths();

/**
* Get the paths to all of the identified ODF XML documents in the package,
* including content, styles, metadata and the manifest
*
* @return a List of all of the String internal paths to the packge ODF XML
* documents
*/
public Set<FileEntry> getXmlEntries();

/**
* Get the InputStream for any item from the document's Manifest
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;

import org.openpreservation.format.xml.ParseResult;
import org.openpreservation.format.zip.ZipArchive;
Expand Down Expand Up @@ -194,6 +196,15 @@ public List<String> getXmlEntryPaths() {
return paths;
}

@Override
public Set<FileEntry> getXmlEntries() {
Set<FileEntry> entries = new HashSet<>();
for (FileEntry entry : this.manifest.getEntriesByMediaType("text/xml")) {
entries.add(entry);
}
return entries;
}

@Override
public InputStream getEntryStream(final FileEntry entry) throws IOException {
return (this.archive != null) ? this.archive.getEntryInputStream(entry.getFullPath()) : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public static final boolean isDsig(final String path) {
return PackageParserImpl.isDsig(path);
}

public static final boolean isOdfXml(final String entrypath) {
return PackageParserImpl.isOdfXml(entrypath);
}

private OdfPackages() {
throw new AssertionError("Utility class 'OdfPackages' should not be instantiated");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ private final void processEntry(final ZipEntry entry)
}
}

private final boolean isOdfXml(final String entrypath) {
static final boolean isOdfXml(final String entrypath) {
return Constants.ODF_XML.contains(new File(entrypath).getName());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.openpreservation.odf.validation;

import java.io.IOException;
import java.util.SortedSet;

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

public interface Profile {
public String getId();
public String getName();
public String getDescription();
public ProfileResult check(final OdfXmlDocument document) throws IOException;
public ProfileResult check(final OdfPackage odfPackage) throws IOException;
public SortedSet<Rule> getRules();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.openpreservation.odf.validation;

import java.util.List;
import java.util.Map;

import org.openpreservation.messages.MessageLog;

public interface ProfileResult {
public ValidationReport getValidationReport();
public Map<String, MessageLog> getPackageMessageLogMap();
public MessageLog getMessageLogForPath(final String path);
public List<String> getLogPaths();
}
Loading