1 package org.daisy.pipeline.epub.ace.impl;
2
3 import java.io.File;
4 import java.net.URI;
5 import java.nio.file.Files;
6 import java.util.Map;
7 import java.util.Optional;
8
9 import javax.xml.transform.stream.StreamSource;
10
11 import com.xmlcalabash.core.XProcRuntime;
12 import com.xmlcalabash.io.WritablePipe;
13 import com.xmlcalabash.library.DefaultStep;
14 import com.xmlcalabash.runtime.XAtomicStep;
15
16 import net.sf.saxon.s9api.QName;
17 import net.sf.saxon.s9api.SaxonApiException;
18
19 import org.daisy.common.shell.BinaryFinder;
20 import org.daisy.common.shell.CommandRunner;
21 import org.daisy.common.xproc.calabash.XProcStep;
22 import org.daisy.common.xproc.calabash.XProcStepProvider;
23 import org.daisy.common.xproc.XProcMonitor;
24 import static org.daisy.pipeline.file.FileUtils.cResultDocument;
25
26 import org.osgi.service.component.annotations.Activate;
27 import org.osgi.service.component.annotations.Component;
28
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33
34
35
36
37
38 @Component(
39 name = "pxi:ace",
40 service = { XProcStepProvider.class },
41 property = { "type:String={http://www.daisy.org/ns/pipeline/xproc/internal}ace" }
42 )
43 public class AceProvider implements XProcStepProvider {
44
45 public XProcStep newStep(XProcRuntime runtime, XAtomicStep step, XProcMonitor monitor, Map<String,String> properties) {
46 return new AceStep(runtime, step);
47 }
48
49 private static File aceProgram = null;
50
51
52
53
54
55
56 @Activate
57 public void init() {
58 Optional<String> lpath = BinaryFinder.find("ace");
59 if (lpath.isPresent())
60 aceProgram = new File(lpath.get());
61 else
62 throw new RuntimeException("Ace was not found on your system");
63 }
64
65 public static class AceStep extends DefaultStep implements XProcStep {
66
67 private final static Logger mLogger = LoggerFactory.getLogger(AceStep.class);
68
69 private static final QName _epubFile = new QName("epub");
70 private static final QName _tempDir = new QName("temp-dir");
71 private static final QName _lang = new QName("lang");
72
73 private WritablePipe htmlReport = null;
74 private WritablePipe jsonReport = null;
75
76 private AceStep(XProcRuntime runtime, XAtomicStep step) {
77 super(runtime, step);
78 }
79
80 @Override
81 public void setOutput(String port, WritablePipe pipe) {
82 if ("html-report-uri".equals(port)) {
83 htmlReport = pipe;
84 } else {
85 jsonReport = pipe;
86 }
87 }
88
89 @Override
90 public void reset() {
91 htmlReport.resetWriter();
92 jsonReport.resetWriter();
93 }
94
95 @Override
96 public void run() throws SaxonApiException {
97 super.run();
98 try {
99 URI epubURI = new URI(getOption(_epubFile).getString());
100 File epubFile = new File(epubURI);
101
102
103 if (aceProgram == null) throw new Exception("Ace was not found on your system");
104
105
106 File tempDir;
107 if (getOption(_tempDir).getString().equals("")) {
108 tempDir = Files.createTempDirectory("ace-").toFile();
109 tempDir.deleteOnExit();
110 } else
111 tempDir = new File(new URI(getOption(_tempDir).getString()));
112
113 String language = getOption(_lang).getString();
114
115 String[] cmd = new String[] {
116 aceProgram.getAbsolutePath(),
117 "-o", tempDir.getAbsolutePath(),
118 "-t", tempDir.getAbsolutePath(),
119 "-l", language.equals("") ? "en" : language,
120 epubFile.getCanonicalPath()
121 };
122
123 new CommandRunner(cmd)
124 .consumeError(mLogger)
125 .run();
126
127 File htmlReportFile = new File(tempDir.getAbsolutePath() + File.separator + "report.html");
128 File jsonReportFile = new File(tempDir.getAbsolutePath() + File.separator + "report.json");
129
130 if (getOption(_tempDir).getString().equals("")) {
131 htmlReportFile.deleteOnExit();
132 jsonReportFile.deleteOnExit();
133 }
134
135
136 writeCResult(htmlReport, htmlReportFile.toURI());
137 writeCResult(jsonReport, jsonReportFile.toURI());
138
139 } catch (Throwable e) {
140 throw XProcStep.raiseError(e, step);
141 }
142 }
143
144 private void writeCResult(WritablePipe port, URI uri) throws SaxonApiException {
145 port.write(runtime.getProcessor().newDocumentBuilder().build(new StreamSource(cResultDocument(uri.toString()))));
146 }
147 }
148 }