From f742a3353efc7edf6c6d9a68e8550ea8a0a1a9c8 Mon Sep 17 00:00:00 2001 From: Daniel Persson Date: Fri, 17 Apr 2020 13:46:14 +0200 Subject: [PATCH] Move task code to the task project. --- build.gradle | 1 + ...aisy.streamline.api.tasks.TaskGroupFactory | 3 +- .../dotify/tasks/impl/input/obfl/Keys.java | 39 ++ .../tasks/impl/input/obfl/LayoutEngine.java | 78 ++++ .../impl/input/obfl/LayoutEngineFactory.java | 152 ++++++++ .../impl/input/obfl/LayoutEngineTask.java | 368 ++++++++++++++++++ .../tasks/impl/input/obfl/package-info.java | 10 + 7 files changed, 650 insertions(+), 1 deletion(-) create mode 100644 src/org/daisy/dotify/tasks/impl/input/obfl/Keys.java create mode 100644 src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngine.java create mode 100644 src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineFactory.java create mode 100644 src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineTask.java create mode 100644 src/org/daisy/dotify/tasks/impl/input/obfl/package-info.java diff --git a/build.gradle b/build.gradle index ce198cd..2920925 100644 --- a/build.gradle +++ b/build.gradle @@ -52,6 +52,7 @@ repositories { dependencies { compileOnly 'org.osgi:org.osgi.service.component.annotations:1.3.0' + compile "org.daisy.dotify:dotify.api:5.0.2" compile 'org.daisy.streamline:streamline-api:1.5.0' compile 'org.daisy.dotify:dotify.common:4.4.1' compile (group: 'org.daisy.libs', name: 'jing', version: '20120724.0.0') { diff --git a/src/META-INF/services/org.daisy.streamline.api.tasks.TaskGroupFactory b/src/META-INF/services/org.daisy.streamline.api.tasks.TaskGroupFactory index 92c1726..478b8af 100644 --- a/src/META-INF/services/org.daisy.streamline.api.tasks.TaskGroupFactory +++ b/src/META-INF/services/org.daisy.streamline.api.tasks.TaskGroupFactory @@ -1,3 +1,4 @@ org.daisy.dotify.tasks.impl.input.xml.XMLInputManagerFactory org.daisy.dotify.tasks.impl.input.text.TextInputManagerFactory -org.daisy.dotify.tasks.impl.input.epub.Epub3InputManagerFactory \ No newline at end of file +org.daisy.dotify.tasks.impl.input.epub.Epub3InputManagerFactory +org.daisy.dotify.tasks.impl.input.obfl.LayoutEngineFactory diff --git a/src/org/daisy/dotify/tasks/impl/input/obfl/Keys.java b/src/org/daisy/dotify/tasks/impl/input/obfl/Keys.java new file mode 100644 index 0000000..5374532 --- /dev/null +++ b/src/org/daisy/dotify/tasks/impl/input/obfl/Keys.java @@ -0,0 +1,39 @@ +package org.daisy.dotify.tasks.impl.input.obfl; + +/** + * Provides a set of keys commonly used within this bundle. + * + * @author Joel Håkansson + */ +class Keys { + + /** + * Provides a format name for pef files. + */ + static final String PEF_FORMAT = "pef"; + /** + * Provides a format name for text files. + */ + static final String FORMATTED_TEXT_FORMAT = "formatted-text"; + /** + * Provides a format name for obfl files. + */ + static final String OBFL_FORMAT = "obfl"; + /** + * Defines a key for the input file. + */ + static final String INPUT = "input"; + /** + * Defines a key for input uri. + */ + static final String INPUT_URI = "input-uri"; + + /** + * Defines a key for temp files directory. + */ + static final String TEMP_FILES_DIRECTORY = "tempFilesDirectory"; + + private Keys() { + } + +} diff --git a/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngine.java b/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngine.java new file mode 100644 index 0000000..7abc5e6 --- /dev/null +++ b/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngine.java @@ -0,0 +1,78 @@ +package org.daisy.dotify.tasks.impl.input.obfl; + +import org.daisy.dotify.api.engine.FormatterEngineFactoryService; +import org.daisy.dotify.api.translator.BrailleTranslatorFactoryMakerService; +import org.daisy.dotify.api.writer.PagedMediaWriterFactoryMakerService; +import org.daisy.streamline.api.tasks.InternalTask; +import org.daisy.streamline.api.tasks.TaskGroup; +import org.daisy.streamline.api.tasks.TaskGroupSpecification; +import org.daisy.streamline.api.tasks.TaskSystemException; +import org.daisy.streamline.api.validity.ValidatorFactoryMakerService; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Provides a task group for running the Dotify formatter. + * + * @author Joel Håkansson + */ +public class LayoutEngine implements TaskGroup { + + private final TaskGroupSpecification spec; + private final PagedMediaWriterFactoryMakerService pmw; + private final FormatterEngineFactoryService fe; + private final ValidatorFactoryMakerService vf; + private final BrailleTranslatorFactoryMakerService translatorFactory; + + /** + * Creates a new layout engine with the specified parameters. + * + * @param spec the task group specification + * @param pmw a paged media writer factory maker service + * @param fe a formatter engine factory service + * @param vf a validator factory service + * @param translatorFactory a translator factory maker service + */ + public LayoutEngine( + TaskGroupSpecification spec, + PagedMediaWriterFactoryMakerService pmw, + FormatterEngineFactoryService fe, + ValidatorFactoryMakerService vf, + BrailleTranslatorFactoryMakerService translatorFactory + ) { + this.spec = spec; + this.pmw = pmw; + this.fe = fe; + this.vf = vf; + this.translatorFactory = translatorFactory; + } + + @Override + public String getName() { + return "Layout Engine"; + } + + @Override + public List compile(Map parameters) throws TaskSystemException { + + ArrayList ret = new ArrayList<>(); + Properties p2 = new Properties(); + p2.putAll(parameters); + // Layout FLOW as PEF + + // Customize which parameters are sent to the PEFMediaWriter, as it + // outputs all parameters for future reference + // System file paths should be concealed for security reasons + p2.remove(Keys.INPUT); + p2.remove(Keys.INPUT_URI); + p2.remove("output"); + p2.remove("obfl-output-location"); + p2.remove(Keys.TEMP_FILES_DIRECTORY); + ret.add(new LayoutEngineTask(p2, spec, pmw, fe, vf, translatorFactory)); + return ret; + } + +} diff --git a/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineFactory.java b/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineFactory.java new file mode 100644 index 0000000..3d07701 --- /dev/null +++ b/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineFactory.java @@ -0,0 +1,152 @@ +package org.daisy.dotify.tasks.impl.input.obfl; + +import org.daisy.dotify.api.engine.FormatterEngineFactoryService; +import org.daisy.dotify.api.engine.FormatterEngineMaker; +import org.daisy.dotify.api.translator.BrailleTranslatorFactoryMaker; +import org.daisy.dotify.api.translator.BrailleTranslatorFactoryMakerService; +import org.daisy.dotify.api.writer.PagedMediaWriterFactoryMaker; +import org.daisy.dotify.api.writer.PagedMediaWriterFactoryMakerService; +import org.daisy.streamline.api.tasks.TaskGroup; +import org.daisy.streamline.api.tasks.TaskGroupFactory; +import org.daisy.streamline.api.tasks.TaskGroupInformation; +import org.daisy.streamline.api.tasks.TaskGroupSpecification; +import org.daisy.streamline.api.validity.ValidatorFactoryMaker; +import org.daisy.streamline.api.validity.ValidatorFactoryMakerService; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * Provides a task group factory for running the Dotify formatter. + * + * @author Joel Håkansson + */ +@Component +public class LayoutEngineFactory implements TaskGroupFactory { + private final Set information; + private PagedMediaWriterFactoryMakerService pmw; + private FormatterEngineFactoryService fe; + private ValidatorFactoryMakerService vf; + private BrailleTranslatorFactoryMakerService translatorFactory; + + /** + * Creates a new layout engine factory. + */ + public LayoutEngineFactory() { + Set tmp = new HashSet<>(); + tmp.add(TaskGroupInformation.newConvertBuilder("obfl", Keys.PEF_FORMAT).build()); + tmp.add(TaskGroupInformation.newConvertBuilder("obfl", Keys.FORMATTED_TEXT_FORMAT).build()); + information = Collections.unmodifiableSet(tmp); + } + + @Override + public boolean supportsSpecification(TaskGroupInformation spec) { + return listAll().contains(spec); + } + + @Override + public TaskGroup newTaskGroup(TaskGroupSpecification spec) { + return new LayoutEngine(spec, pmw, fe, vf, translatorFactory); + } + + @Override + public Set listAll() { + return information; + } + + public void setCreatedWithSPI() { + if (pmw == null) { + pmw = PagedMediaWriterFactoryMaker.newInstance(); + } + if (fe == null) { + fe = FormatterEngineMaker.newInstance().getFactory(); + } + if (vf == null) { + vf = ValidatorFactoryMaker.newInstance(); + } + if (translatorFactory == null) { + translatorFactory = BrailleTranslatorFactoryMaker.newInstance(); + } + } + + /** + * Sets a factory dependency. + * + * @param service the dependency + */ + @Reference(cardinality = ReferenceCardinality.MANDATORY) + public void setPagedMediaWriterFactory(PagedMediaWriterFactoryMakerService service) { + this.pmw = service; + } + + /** + * Removes a factory dependency. + * + * @param service the dependency to remove + */ + public void unsetPagedMediaWriterFactory(PagedMediaWriterFactoryMakerService service) { + this.pmw = null; + } + + /** + * Sets a factory dependency. + * + * @param service the dependency + */ + @Reference(cardinality = ReferenceCardinality.MANDATORY) + public void setFormatterEngineFactory(FormatterEngineFactoryService service) { + this.fe = service; + } + + /** + * Removes a factory dependency. + * + * @param service the dependency to remove + */ + public void unsetFormatterEngineFactory(FormatterEngineFactoryService service) { + this.fe = null; + } + + /** + * Sets a factory dependency. + * + * @param service the dependency + */ + @Reference(cardinality = ReferenceCardinality.MANDATORY) + public void setValidatorFactory(ValidatorFactoryMakerService service) { + this.vf = service; + } + + /** + * Removes a factory dependency. + * + * @param service the dependency to remove + */ + public void unsetValidatorFactory(ValidatorFactoryMakerService service) { + this.vf = null; + } + + /** + * Sets a factory dependency. + * + * @param service the dependency + */ + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + public void setTranslator(BrailleTranslatorFactoryMakerService service) { + this.translatorFactory = service; + } + + /** + * Removes a factory dependency. + * + * @param service the dependency to remove + */ + public void unsetTranslator(BrailleTranslatorFactoryMakerService service) { + this.translatorFactory = null; + } + +} diff --git a/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineTask.java b/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineTask.java new file mode 100644 index 0000000..459d431 --- /dev/null +++ b/src/org/daisy/dotify/tasks/impl/input/obfl/LayoutEngineTask.java @@ -0,0 +1,368 @@ +package org.daisy.dotify.tasks.impl.input.obfl; + +import org.daisy.dotify.api.engine.FormatterEngine; +import org.daisy.dotify.api.engine.FormatterEngineFactoryService; +import org.daisy.dotify.api.engine.LayoutEngineException; +import org.daisy.dotify.api.formatter.FormatterConfiguration; +import org.daisy.dotify.api.translator.BrailleTranslatorFactoryMakerService; +import org.daisy.dotify.api.translator.TranslatorType; +import org.daisy.dotify.api.writer.AttributeItem; +import org.daisy.dotify.api.writer.MediaTypes; +import org.daisy.dotify.api.writer.MetaDataItem; +import org.daisy.dotify.api.writer.PagedMediaWriter; +import org.daisy.dotify.api.writer.PagedMediaWriterConfigurationException; +import org.daisy.dotify.api.writer.PagedMediaWriterFactory; +import org.daisy.dotify.api.writer.PagedMediaWriterFactoryMakerService; +import org.daisy.streamline.api.media.AnnotatedFile; +import org.daisy.streamline.api.media.DefaultAnnotatedFile; +import org.daisy.streamline.api.media.FormatIdentifier; +import org.daisy.streamline.api.option.UserOption; +import org.daisy.streamline.api.option.UserOptionValue; +import org.daisy.streamline.api.tasks.InternalTaskException; +import org.daisy.streamline.api.tasks.ReadWriteTask; +import org.daisy.streamline.api.tasks.TaskGroupSpecification; +import org.daisy.streamline.api.tasks.TaskSystemException; +import org.daisy.streamline.api.validity.ValidationReport; +import org.daisy.streamline.api.validity.Validator; +import org.daisy.streamline.api.validity.ValidatorFactoryMakerService; +import org.daisy.streamline.api.validity.ValidatorMessage; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.file.Files; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Optional; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.xml.namespace.QName; + +/** + *

+ * The LayoutEngineTask converts an OBFL-file into a file format defined by the + * supplied {@link PagedMediaWriter}.

+ * + *

The LayoutEngineTask is an advanced text-only layout system.

+ *

Input file must be of type OBFL.

+ * + * @author Joel Håkansson + */ +public class LayoutEngineTask extends ReadWriteTask { + private static final String MARK_CAPITAL_LETTERS = "mark-capital-letters"; + private static final String HYPHENATE = "hyphenate"; + private static final String TRANSLATE = "translate"; + private static final String REMOVE_STYLES = "remove-styles"; + private static final String DATE_FORMAT = "dateFormat"; + private static final String DATE = "date"; + private static final String IDENTIFIER = "identifier"; + private static final String ALLOWS_ENDING_VOLUME_ON_HYPHEN = "allows-ending-volume-on-hyphen"; + private static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; + private static final QName ENTRY = new QName("http://www.daisy.org/ns/2015/dotify", "entry", "generator"); + private final FormatterConfiguration config; + private final PagedMediaWriter writer; + private final FormatterEngineFactoryService fe; + private final ValidatorFactoryMakerService vf; + private final BrailleTranslatorFactoryMakerService translatorFactory; + private final TaskGroupSpecification spec; + private static final Logger logger = Logger.getLogger(LayoutEngineTask.class.getCanonicalName()); + private List options; + + /** + * Creates a new instance. + * + * @param p2 the options + * @param spec the specification + * @param pmw the paged media writer factory maker service + * @param fe the formatter engine factory service + * @param vf a validator factory service + * @param translatorFactory a translator factory maker service + * @throws TaskSystemException if the instance could not be created + */ + public LayoutEngineTask( + Properties p2, + TaskGroupSpecification spec, + PagedMediaWriterFactoryMakerService pmw, + FormatterEngineFactoryService fe, + ValidatorFactoryMakerService vf, + BrailleTranslatorFactoryMakerService translatorFactory + ) throws TaskSystemException { + super(buildName(spec.getOutputType().getIdentifier().toUpperCase().replace('-', ' '))); + addDefaults(p2); + String translatorMode = getTranslationMode(p2, spec.getOutputType(), spec.getLocale(), translatorFactory); + this.spec = spec; + this.writer = getWriter(p2, spec, pmw); + this.config = getFormatterConfig(p2, translatorMode, spec.getLocale()); + this.fe = fe; + this.vf = vf; + this.translatorFactory = translatorFactory; + this.options = null; + } + + static String buildName(String outputFormat) { + return "OBFL to " + outputFormat + " converter"; + } + + private static PagedMediaWriter getWriter( + Properties p2, + TaskGroupSpecification spec, + PagedMediaWriterFactoryMakerService pmw + ) throws TaskSystemException { + try { + PagedMediaWriterFactory pmf = pmw.getFactory(mediaTypeForFormat(spec.getOutputType())); + PagedMediaWriter paged = pmf.newPagedMediaWriter(); + paged.prepare(asMetadata(p2)); + return paged; + } catch (PagedMediaWriterConfigurationException e) { + throw new TaskSystemException(e); + } + } + + private static String getTranslationMode( + Properties p2, + FormatIdentifier out, + String locale, + BrailleTranslatorFactoryMakerService translatorFactory + ) throws TaskSystemException { + switch (out.getIdentifier()) { + case Keys.PEF_FORMAT: + return Optional.ofNullable( + Optional.ofNullable(p2.getProperty(TRANSLATE)).orElseGet( + () -> getDefaultMode(listSupportedModes(translatorFactory, locale) + .collect(Collectors.toSet())) + .orElse(null) + ) + ).orElseThrow(() -> new TaskSystemException("No supported translator for " + locale)); + case Keys.FORMATTED_TEXT_FORMAT: + return p2.getProperty(TRANSLATE, TranslatorType.BYPASS.toString()); + default: + throw new TaskSystemException("Unknown format: " + out); + } + } + + private static String mediaTypeForFormat(FormatIdentifier ext) throws TaskSystemException { + switch (ext.getIdentifier()) { + case Keys.PEF_FORMAT: + return MediaTypes.PEF_MEDIA_TYPE; + case Keys.FORMATTED_TEXT_FORMAT: + return MediaTypes.TEXT_MEDIA_TYPE; + default: + throw new TaskSystemException("Unknown format: " + ext); + } + } + + private static FormatterConfiguration getFormatterConfig( + Properties p2, + String translatorMode, + String locale + ) { + boolean markCapitals = !p2.getProperty(MARK_CAPITAL_LETTERS, "true").equalsIgnoreCase("false"); + boolean hyphenate = !p2.getProperty(HYPHENATE, "true").equalsIgnoreCase("false"); + boolean allowsEndingVolumeOnHyphen = !p2.getProperty(ALLOWS_ENDING_VOLUME_ON_HYPHEN, "true") + .equalsIgnoreCase("false"); + + FormatterConfiguration.Builder config = FormatterConfiguration.with(locale, translatorMode) + .markCapitalLetters(markCapitals) + .hyphenate(hyphenate) + .allowsEndingVolumeOnHyphen(allowsEndingVolumeOnHyphen); + if (p2.getProperty(REMOVE_STYLES, "false").equalsIgnoreCase("true")) { + config.ignoreStyle("em").ignoreStyle("strong"); + } + return config.build(); + } + + private static void addDefaults(Properties p2) { + String dateFormat = p2.getProperty(DATE_FORMAT); + if (dateFormat == null || "".equals(dateFormat)) { + dateFormat = DEFAULT_DATE_FORMAT; + p2.put(DATE_FORMAT, dateFormat); + } + if (p2.getProperty(DATE) == null || "".equals(p2.getProperty(DATE))) { + p2.put(DATE, getDefaultDate(dateFormat)); + } + if (p2.getProperty(IDENTIFIER) == null || "".equals(p2.getProperty(IDENTIFIER))) { + String id = Double.toHexString(Math.random()); + id = id.substring(id.indexOf('.') + 1); + id = id.substring(0, id.indexOf('p')); + p2.put(IDENTIFIER, "dummy-id-" + id); + } + } + + private static List asMetadata(Properties p2) { + ArrayList meta = new ArrayList<>(); + + String ident = p2.getProperty(IDENTIFIER); + if (ident != null) { + meta.add(asDCItem(IDENTIFIER, ident)); + } + String date = p2.getProperty(DATE); + if (date != null) { + meta.add(asDCItem(DATE, date)); + } + for (Object key : p2.keySet()) { + meta.add(new MetaDataItem.Builder( + ENTRY, + p2.get(key).toString()).attribute(new AttributeItem("key", key.toString()) + ).build()); + } + return meta; + } + + private static MetaDataItem asDCItem(String name, String value) { + return new MetaDataItem.Builder(new QName("http://purl.org/dc/elements/1.1/", name, "dc"), value).build(); + } + + private List buildOptions(TaskGroupSpecification spec) { + List ret = new ArrayList<>(); + ret.add(withBooleanValues( + new UserOption.Builder(MARK_CAPITAL_LETTERS) + .description("Specifies if capital letters should be marked in braille.")) + .defaultValue("true") + .build()); + ret.add(withBooleanValues( + new UserOption.Builder(REMOVE_STYLES) + .description("Specifies if em/strong styles should be removed.")) + .defaultValue("false") + .build()); + ret.add(withBooleanValues( + new UserOption.Builder(HYPHENATE) + .description("Specifies if hyphenation should be used.")) + .defaultValue("true") + .build()); + + //PEF supports additional options + if (Keys.PEF_FORMAT.equals(spec.getOutputType().getIdentifier())) { + UserOption.Builder tr = new UserOption.Builder(TRANSLATE) + .description("Specifies a translation mode."); + List specs = listSupportedModes(translatorFactory, spec.getLocale()) + .sorted() + .collect(Collectors.toList()); + getDefaultMode(specs).ifPresent(v -> tr.defaultValue(v)); + specs.forEach(v -> tr.addValue(new UserOptionValue.Builder(v).build())); + ret.add(new UserOption.Builder(IDENTIFIER) + .description("Sets identifier in meta data.") + .build()); + ret.add(new UserOption.Builder(DATE) + .description("Sets date in meta data.") + .defaultValue(getDefaultDate(DEFAULT_DATE_FORMAT)) + .build()); + ret.add(tr.build()); + } + + return ret; + } + + private static Optional getDefaultMode(Collection specs) { + if (specs.contains(TranslatorType.UNCONTRACTED.toString())) { + return Optional.of(TranslatorType.UNCONTRACTED.toString()); + } else if (specs.contains(TranslatorType.CONTRACTED.toString())) { + return Optional.of(TranslatorType.CONTRACTED.toString()); + } else if (!specs.isEmpty()) { + return Optional.of(specs.iterator().next()); + } + return Optional.empty(); + } + + private static Stream listSupportedModes( + BrailleTranslatorFactoryMakerService translatorFactory, + String locale + ) { + return translatorFactory.listSpecifications().stream() + .filter( + v -> v.getLocale().equals(locale) && + v.getModeDetails().getType().map(x -> !(x == TranslatorType.BYPASS || + x == TranslatorType.PRE_TRANSLATED)).orElse(true).booleanValue() + ) + .map(v -> v.getMode()) + .distinct(); + } + + private static UserOption.Builder withBooleanValues(UserOption.Builder builder) { + return builder.addValue(new UserOptionValue.Builder("true").build()) + .addValue(new UserOptionValue.Builder("false").build()); + } + + private static String getDefaultDate(String dateFormat) { + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + SimpleDateFormat sdf = new SimpleDateFormat(dateFormat); + return sdf.format(c.getTime()); + } + + @Override + public AnnotatedFile execute(AnnotatedFile input, File output) throws InternalTaskException { + try { + + logger.info(String.format("Validating input (%s)...", input.getPath())); + Validator v = vf.newValidator("application/x-obfl+xml"); + if (v != null) { + try { + ValidationReport vr = v.validate(input.getPath().toUri().toURL()); + for (ValidatorMessage m : vr.getMessages()) { + switch (m.getType()) { + case ERROR: + case FATAL_ERROR: + case WARNING: + // Using Level.WARNING for all validation messages + // (reserving Level.SEVERE for system errors) + logger.log(Level.WARNING, m.toString()); + break; + case NOTICE: + default: + if (logger.isLoggable(Level.INFO)) { + logger.log(Level.INFO, m.toString()); + } + break; + } + } + if (!vr.isValid()) { + logger.warning( + "The OBFL-file isn't valid! If this is systematic, " + + "please consider fixing your code. Invalid input will be rejected in future versions." + ); + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new InternalTaskException(e); + } + } + } catch (MalformedURLException e) { + throw new InternalTaskException("Input validation failed.", e); + } + } else { + throw new InternalTaskException("Could not find a validator for OBFL."); + } + FormatterEngine engine = fe.newFormatterEngine(config, writer); + engine.convert(Files.newInputStream(input.getPath()), new FileOutputStream(output)); + + } catch (LayoutEngineException | IOException e) { + throw new InternalTaskException(e); + } + return new DefaultAnnotatedFile.Builder(output.toPath()).build(); + } + + @Override + @Deprecated + public void execute(File input, File output) throws InternalTaskException { + execute(new DefaultAnnotatedFile.Builder(input).build(), output); + } + + @Override + public List getOptions() { + if (options == null) { + options = Collections.unmodifiableList(buildOptions(spec)); + } + return options; + } + +} diff --git a/src/org/daisy/dotify/tasks/impl/input/obfl/package-info.java b/src/org/daisy/dotify/tasks/impl/input/obfl/package-info.java new file mode 100644 index 0000000..723b528 --- /dev/null +++ b/src/org/daisy/dotify/tasks/impl/input/obfl/package-info.java @@ -0,0 +1,10 @@ +/** + *

Provides {@link org.daisy.streamline.api.tasks.TaskGroupFactory} implementations.

+ * + *

IMPORTANT: This package contains implementations that should only be + * accessed using the Java SPI or OSGi. Additional classes in this package + * should only be used by the implementations herein. + *

+ * @author Joel Håkansson + */ +package org.daisy.dotify.tasks.impl.input.obfl;