Skip to content

Commit

Permalink
Adds a new validation UI based on the streamline-api validator (fixes #…
Browse files Browse the repository at this point in the history
…12, fixes #13)
  • Loading branch information
Joel Håkansson committed Jan 4, 2018
1 parent 8d388df commit 77d0be0
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 167 deletions.
85 changes: 44 additions & 41 deletions src/org/daisy/dotify/cli/Convert.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,21 @@
import org.daisy.braille.utils.api.embosser.EmbosserCatalog;
import org.daisy.braille.utils.api.embosser.EmbosserFactoryException;
import org.daisy.braille.utils.pef.PEFConverterFacade;
import org.daisy.braille.utils.pef.PEFValidator;
import org.daisy.braille.utils.pef.UnsupportedWidthException;
import org.daisy.dotify.Dotify;
import org.daisy.dotify.SystemKeys;
import org.daisy.streamline.api.config.ConfigurationDetails;
import org.daisy.streamline.api.tasks.InternalTaskException;
import org.daisy.streamline.api.tasks.TaskGroupInformation;
import org.daisy.dotify.api.translator.BrailleTranslatorFactoryMaker;
import org.daisy.dotify.api.translator.TranslatorSpecification;
import org.daisy.dotify.common.text.FilterLocale;
import org.daisy.streamline.api.config.ConfigurationDetails;
import org.daisy.streamline.api.config.ConfigurationsCatalog;
import org.daisy.streamline.api.identity.IdentityProvider;
import org.daisy.streamline.api.media.AnnotatedFile;
import org.daisy.streamline.api.tasks.InternalTaskException;
import org.daisy.streamline.api.tasks.TaskGroupFactoryMaker;
import org.daisy.dotify.api.translator.BrailleTranslatorFactoryMaker;
import org.daisy.streamline.engine.DefaultTempFileWriter;
import org.daisy.streamline.api.tasks.TaskGroupInformation;
import org.daisy.streamline.api.validity.Validator;
import org.daisy.streamline.api.validity.ValidatorFactoryMaker;
import org.daisy.streamline.cli.Argument;
import org.daisy.streamline.cli.CommandDetails;
import org.daisy.streamline.cli.CommandParser;
Expand All @@ -41,6 +43,7 @@
import org.daisy.streamline.cli.OptionalArgument;
import org.daisy.streamline.cli.SwitchArgument;
import org.daisy.streamline.cli.SwitchMap;
import org.daisy.streamline.engine.DefaultTempFileWriter;
import org.xml.sax.SAXException;

/**
Expand Down Expand Up @@ -216,41 +219,41 @@ private void runDotify(File input, File output, String context, HashMap<String,
ExitCode.MISSING_RESOURCE.exitSystem("Cannot find input file: " + input);
}
Dotify.run(input, output, FilterLocale.parse(context), props);
int i = output.getName().lastIndexOf(".");
String format = "";
if (output.getName().length()>i) {
format = output.getName().substring(i+1);
}
if (format.equalsIgnoreCase(SystemKeys.PEF_FORMAT)) {
logger.info("Validating output...");
PEFValidator validator = new PEFValidator();
if (!validator.validate(output.toURI().toURL())) {
logger.warning("Validation failed: " + output);
} else {
logger.info("Output is valid.");
if (props.containsKey(PEFConverterFacade.KEY_TABLE)) {
// create brl
HashMap<String, String> p = new HashMap<String, String>();
p.put(PEFConverterFacade.KEY_TABLE, props.get(PEFConverterFacade.KEY_TABLE));
try {
brailleInfo.getShortFormResolver().expandShortForm(p, PEFConverterFacade.KEY_TABLE);
} catch (IllegalArgumentException e) {
ExitCode.ILLEGAL_ARGUMENT_VALUE.exitSystem(e.getMessage());
}
File f = new File(output.getParentFile(), output.getName() + ".brl");
logger.info("Writing brl to " + f.getAbsolutePath());
try (FileOutputStream os = new FileOutputStream(f)) {
new PEFConverterFacade(EmbosserCatalog.newInstance()).parsePefFile(output, os, null, p);
} catch (ParserConfigurationException e) {
logger.log(Level.FINE, "Parse error when converting to brl", e);
} catch (SAXException e) {
logger.log(Level.FINE, "SAX error when converting to brl", e);
} catch (UnsupportedWidthException e) {
logger.log(Level.FINE, "Width error when converting to brl", e);
} catch (NumberFormatException e) {
logger.log(Level.FINE, "Number format error when converting to brl", e);
} catch (EmbosserFactoryException e) {
logger.log(Level.FINE, "Embosser error when converting to brl", e);
if (output.exists()) {
AnnotatedFile ao = IdentityProvider.newInstance().identify(output);
String mediaType = ao.getMediaType();
ValidatorFactoryMaker validatorFactory = ValidatorFactoryMaker.newInstance();
Validator validator;
if (mediaType!=null && (validator = validatorFactory.newValidator(mediaType))!=null) {
logger.info(String.format("Validating output using %s", validator.getClass().getName()));
if (!validator.validate(output.toURI().toURL()).isValid()) {
logger.warning("Validation failed: " + output);
} else {
logger.info("Output is valid.");
if (mediaType.equals("application/x-pef+xml") && props.containsKey(PEFConverterFacade.KEY_TABLE)) {
// create brl
HashMap<String, String> p = new HashMap<String, String>();
p.put(PEFConverterFacade.KEY_TABLE, props.get(PEFConverterFacade.KEY_TABLE));
try {
brailleInfo.getShortFormResolver().expandShortForm(p, PEFConverterFacade.KEY_TABLE);
} catch (IllegalArgumentException e) {
ExitCode.ILLEGAL_ARGUMENT_VALUE.exitSystem(e.getMessage());
}
File f = new File(output.getParentFile(), output.getName() + ".brl");
logger.info("Writing brl to " + f.getAbsolutePath());
try (FileOutputStream os = new FileOutputStream(f)) {
new PEFConverterFacade(EmbosserCatalog.newInstance()).parsePefFile(output, os, null, p);
} catch (ParserConfigurationException e) {
logger.log(Level.FINE, "Parse error when converting to brl", e);
} catch (SAXException e) {
logger.log(Level.FINE, "SAX error when converting to brl", e);
} catch (UnsupportedWidthException e) {
logger.log(Level.FINE, "Width error when converting to brl", e);
} catch (NumberFormatException e) {
logger.log(Level.FINE, "Number format error when converting to brl", e);
} catch (EmbosserFactoryException e) {
logger.log(Level.FINE, "Embosser error when converting to brl", e);
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/org/daisy/dotify/cli/DotifyCLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public DotifyCLI(String[] args) {
// Main commands
putCommand(CONVERT, "formats and translates a document into braille", Convert.class);
putCommand(EMBOSS, "embosses a PEF-file", EmbossPEF.class);
putCommand(VALIDATE, "validates a PEF-file", ValidatePEF.class);
putCommand(VALIDATE, "validates a file", ValidateCLI.class);
putCommand(INSPECT, "lists metadata about a PEF-file", PEFInfo.class);
putCommand(FIND, "finds PEF-files based on file metadata", FindPEF.class);

Expand Down
3 changes: 1 addition & 2 deletions src/org/daisy/dotify/cli/EmbossPEF.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import org.daisy.braille.utils.pef.FileDevice;
import org.daisy.braille.utils.pef.PEFConverterFacade;
import org.daisy.braille.utils.pef.PEFHandler;
import org.daisy.braille.utils.pef.PEFValidatorFacade;
import org.daisy.braille.utils.pef.PrinterDevice;
import org.daisy.braille.utils.pef.Range;
import org.daisy.braille.utils.pef.UnsupportedWidthException;
Expand Down Expand Up @@ -301,7 +300,7 @@ public static void main(String[] args) throws BackingStoreException {
throw new RuntimeException("Cannot find input file: " + firstArg);
}
try {
boolean ok = new PEFValidatorFacade(ValidatorFactory.newInstance()).validate(input, System.out);
boolean ok = new ValidatorFacade().validate(input, System.out);
if (!ok) {
ExitCode.UNEXPECTED_RESOURCE_CONTENTS.exitSystem("Validation failed, exiting...");
}
Expand Down
3 changes: 1 addition & 2 deletions src/org/daisy/dotify/cli/PEFParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
import org.daisy.braille.utils.api.table.TableCatalog;
import org.daisy.braille.utils.api.validator.ValidatorFactory;
import org.daisy.braille.utils.pef.PEFConverterFacade;
import org.daisy.braille.utils.pef.PEFValidatorFacade;
import org.daisy.streamline.cli.Argument;
import org.daisy.streamline.cli.CommandDetails;
import org.daisy.streamline.cli.CommandParser;
Expand Down Expand Up @@ -105,7 +104,7 @@ public static void main(String[] args) {
File output = new File(""+p.remove(ARG_PREFIX+1));

// validate input
boolean ok = new PEFValidatorFacade(ValidatorFactory.newInstance()).validate(input, System.out);
boolean ok = new ValidatorFacade().validate(input, System.out);
if (!ok) {
ExitCode.UNEXPECTED_RESOURCE_CONTENTS.exitSystem("Validation failed, exiting...");
}
Expand Down
3 changes: 1 addition & 2 deletions src/org/daisy/dotify/cli/TextParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.daisy.braille.utils.api.factory.FactoryProperties;
import org.daisy.braille.utils.api.table.TableCatalog;
import org.daisy.braille.utils.api.validator.ValidatorFactory;
import org.daisy.braille.utils.pef.PEFValidatorFacade;
import org.daisy.braille.utils.pef.TextConverterFacade;
import org.daisy.streamline.cli.Argument;
import org.daisy.streamline.cli.CommandDetails;
Expand Down Expand Up @@ -106,7 +105,7 @@ public static void main(String[] args) {
// run
new TextConverterFacade(TableCatalog.newInstance()).parseTextFile(input, output, p);
System.out.println("Validating result...");
boolean ok = new PEFValidatorFacade(ValidatorFactory.newInstance()).validate(output, System.out);
boolean ok = new ValidatorFacade().validate(output, System.out);
if (!ok) {
System.out.println("Warning: Validation failed for " + output);
}
Expand Down
114 changes: 114 additions & 0 deletions src/org/daisy/dotify/cli/ValidateCLI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.daisy.dotify.cli;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.daisy.streamline.api.identity.IdentityProvider;
import org.daisy.streamline.api.media.AnnotatedFile;
import org.daisy.streamline.api.option.UserOption;
import org.daisy.streamline.api.validity.ValidationReport;
import org.daisy.streamline.api.validity.Validator;
import org.daisy.streamline.api.validity.ValidatorFactoryMaker;
import org.daisy.streamline.cli.Argument;
import org.daisy.streamline.cli.CommandDetails;
import org.daisy.streamline.cli.CommandParser;
import org.daisy.streamline.cli.CommandParserResult;
import org.daisy.streamline.cli.Definition;
import org.daisy.streamline.cli.ExitCode;
import org.daisy.streamline.cli.OptionalArgument;

class ValidateCLI implements CommandDetails {
public static final String MEDIA_TYPE = "mediaType";
private final CommandParser parser;

public ValidateCLI() {
this.parser = CommandParser.create(this);
}

public static void main(String[] args) throws IOException {
ValidateCLI ui = new ValidateCLI();
if (args.length<1) {
System.out.println("Expected one more argument: input [options ...]");
System.out.println();
ui.parser.displayHelp(System.out);
ExitCode.MISSING_ARGUMENT.exitSystem();
}
File in = new File(args[0]);
if (!in.exists()) {
ExitCode.MISSING_RESOURCE.exitSystem("File does not exist: " + in);
}
CommandParserResult result = ui.parser.parse(args);
String mediaType = result.getOptional().get(MEDIA_TYPE);
if (mediaType == null) {
AnnotatedFile an = IdentityProvider.newInstance().identify(in);
mediaType = an.getMediaType();
}
if (mediaType == null) {
ExitCode.INTERNAL_ERROR.exitSystem(String.format("Could not determine media type for %s", in.getName()));
}
ValidatorFactoryMaker factoryMaker = ValidatorFactoryMaker.newInstance();
Validator pv = factoryMaker.newValidator(mediaType);
if (pv == null) {
ExitCode.INTERNAL_ERROR.exitSystem(String.format("Could not find validator for '%s'", mediaType));
}
System.out.println("Validating " + in + " using \"" + pv.getClass().getName() + "\""
+ (result.getOptional().isEmpty()?"":" with options " + result.getOptional())
);
Map<String, Object> options = new HashMap<>();
options.putAll(result.getOptional());
ValidationReport report = pv.validate(in.toURI().toURL(), options);
System.out.println("Validation was " + (report.isValid() ? "succcessful" : "unsuccessful"));
if (!report.isValid()) {
System.out.println("Messages returned by the validator:");
report.getMessages().stream().forEach(System.out::println);
}
}

@Override
public String getName() {
return DotifyCLI.VALIDATE;
}

@Override
public String getDescription() {
return "Validates a file.";
}

@Override
public List<Argument> getRequiredArguments() {
ArrayList<Argument> ret = new ArrayList<Argument>();
ret.add(new Argument("input_file", "Path to the input file"));
return ret;
}

@Override
public List<OptionalArgument> getOptionalArguments() {
ValidatorFactoryMaker factoryMaker = ValidatorFactoryMaker.newInstance();
ArrayList<OptionalArgument> ret = new ArrayList<OptionalArgument>();
ret.add(new OptionalArgument(MEDIA_TYPE, "The media type for the file.",
factoryMaker.listIdentifiers().stream()
.map(v->new Definition(v, ""))
.collect(Collectors.toList()),
"[detect]"));
for (String identifier : factoryMaker.listIdentifiers()) {
Validator v = factoryMaker.newValidator(identifier);
for (UserOption u : v.listOptions()) {
if (u.hasValues()) {
List<Definition> values = u.getValues().stream()
.map(uov->new Definition(uov.getName(), uov.getDescription()))
.collect(Collectors.toList());
ret.add(new OptionalArgument(u.getKey(), String.format("%s (applies to media type '%s')", u.getDescription(), identifier), values, u.getDefaultValue()));
} else {
ret.add(new OptionalArgument(u.getKey(), String.format("%s (applies to media type '%s')", u.getDescription(), identifier), u.getDefaultValue()));
}
}
}
return ret;
}

}
Loading

0 comments on commit 77d0be0

Please sign in to comment.