1   package nl.dedicon.pipeline.braille.calabash.impl;
2   
3   import com.xmlcalabash.core.XProcException;
4   import com.xmlcalabash.core.XProcRuntime;
5   import com.xmlcalabash.core.XProcStep;
6   import com.xmlcalabash.io.ReadablePipe;
7   import com.xmlcalabash.io.WritablePipe;
8   import com.xmlcalabash.library.DefaultStep;
9   import com.xmlcalabash.runtime.XAtomicStep;
10  import java.io.InputStream;
11  import java.net.URL;
12  import net.sf.saxon.s9api.QName;
13  import net.sf.saxon.s9api.SaxonApiException;
14  import net.sf.saxon.s9api.XQueryCompiler;
15  import net.sf.saxon.s9api.XQueryEvaluator;
16  import net.sf.saxon.s9api.XQueryExecutable;
17  import net.sf.saxon.s9api.XdmNode;
18  import net.sf.saxon.s9api.XdmValue;
19  import nl.dedicon.pipeline.braille.step.Utils;
20  import org.daisy.common.xproc.calabash.XProcStepProvider;
21  import org.osgi.service.component.annotations.Component;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  import org.w3c.dom.Document;
25  
26  /**
27   * XProc step to make sure that the back cover of a volume has no braille
28   * 
29   * @author Paul Rambags
30   */
31  public class EmptyBackCoverStep extends DefaultStep {
32  
33      private static final Logger logger = LoggerFactory.getLogger(EmptyBackCoverStep.class);
34  
35      private static final QName _xquery = new QName("xquery");
36  
37      private ReadablePipe source = null;
38      private WritablePipe result = null;
39      
40      private EmptyBackCoverStep(XProcRuntime runtime, XAtomicStep step) {
41          super(runtime, step);
42      }
43  
44      @Override
45      public void setInput(String port, ReadablePipe pipe) {
46          source = pipe;
47      }
48  
49      @Override
50      public void setOutput(String port, WritablePipe pipe) {
51          result = pipe;
52      }
53  
54      @Override
55      public void reset() {
56          source.resetReader();
57          result.resetWriter();
58      }
59  
60      @Override
61      public void run() throws SaxonApiException {
62          
63          super.run();
64  
65          try {
66  
67              XdmNode pef = source.read();
68  
69              String xquery = getOption(_xquery, "");
70  
71              // convert the immutable XdmNode to a modifiable Document
72              Document document = Utils.convertToDocument(pef);
73  
74              InputStream query = new URL(xquery).openConnection().getInputStream();
75              
76              XQueryCompiler xqCompiler = runtime.getProcessor().newXQueryCompiler();
77              XQueryExecutable xqExecutable = xqCompiler.compile(query);
78              XQueryEvaluator xqEvaluator = xqExecutable.load();
79  
80              xqEvaluator.setSource(pef.asSource());
81              XdmValue xqResult = xqEvaluator.evaluate();
82  
83              // get the first node from the result
84              XdmNode newPef = null;
85              for (XdmValue xqValue : xqResult) {
86                  if (xqValue instanceof XdmNode) {
87                      newPef = (XdmNode)xqValue;
88                      break;
89                  }
90              };
91  
92              result.write(newPef);
93              
94          } catch (Exception e) {
95  
96              logger.error("dedicon:empty-back-cover failed", e);
97              throw new XProcException(step.getNode(), e);
98  
99          }
100     }
101 
102     @Component(
103             name = "dedicon:empty-back-cover",
104             service = {XProcStepProvider.class},
105             property = {"type:String={http://www.dedicon.nl}empty-back-cover"}
106     )
107     public static class Provider implements XProcStepProvider {
108 
109         @Override
110         public XProcStep newStep(XProcRuntime runtime, XAtomicStep step) {
111             return new EmptyBackCoverStep(runtime, step);
112         }
113 
114     }
115 }