1   package org.daisy.pipeline.common.calabash.impl;
2   
3   import java.util.Map;
4   
5   import javax.xml.namespace.QName;
6   
7   import com.google.common.collect.ImmutableMap;
8   
9   import com.xmlcalabash.core.XProcRuntime;
10  import com.xmlcalabash.io.ReadablePipe;
11  import com.xmlcalabash.library.Identity;
12  import com.xmlcalabash.runtime.XAtomicStep;
13  
14  import net.sf.saxon.s9api.SaxonApiException;
15  
16  import org.daisy.common.xproc.calabash.XMLCalabashInputValue;
17  import org.daisy.common.xproc.calabash.XProcStep;
18  import org.daisy.common.xproc.calabash.XProcStepProvider;
19  import org.daisy.common.xproc.XProcError;
20  import org.daisy.common.xproc.XProcMonitor;
21  
22  import org.osgi.service.component.annotations.Component;
23  
24  import org.slf4j.Logger;
25  import org.slf4j.LoggerFactory;
26  
27  @Component(
28  	name = "px:log-error",
29  	service = { XProcStepProvider.class },
30  	property = { "type:String={http://www.daisy.org/ns/pipeline/xproc}log-error" }
31  )
32  public class LogError implements XProcStepProvider {
33  
34  	private static final Logger LOGGER = LoggerFactory.getLogger(LogError.class);
35  
36  	public XProcStep newStep(XProcRuntime runtime, XAtomicStep step, XProcMonitor monitor, Map<String,String> properties) {
37  		return new LogErrorStep(runtime, step);
38  	}
39  
40  	public static class LogErrorStep extends Identity implements XProcStep {
41  
42  		private static final net.sf.saxon.s9api.QName _severity = new net.sf.saxon.s9api.QName("severity");
43  		private ReadablePipe errorPipe = null;
44  
45  		private LogErrorStep(XProcRuntime runtime, XAtomicStep step) {
46  			super(runtime, step);
47  		}
48  
49  		@Override
50  		public void setInput(String port, ReadablePipe pipe) {
51  			if ("source".equals(port))
52  				super.setInput(port, pipe);
53  			else
54  				errorPipe = pipe;
55  		}
56  
57  		@Override
58  		public void reset() {
59  			super.reset();
60  			errorPipe.resetReader();
61  		}
62  		
63  		@Override
64  		public void run() throws SaxonApiException {
65  			String severity = getOption(_severity, "INFO");
66  			super.run();
67  			try {
68  				new ErrorReporter(e -> log(severity, e))
69  					.transform(
70  						ImmutableMap.of(new QName("source"), new XMLCalabashInputValue(errorPipe)),
71  						ImmutableMap.of())
72  					.run();
73  			} catch (Throwable e) {
74  				throw XProcStep.raiseError(e, step);
75  			}
76  		}
77  
78  		private static void log(String severity, XProcError error) {
79  			String message = error.getMessage();
80  			if (error.getLocation().length > 0 || error.getCause() != null) {
81  				message += " (Please see detailed log for more info.)";
82  				LOGGER.debug(error.toString());
83  			}
84  			if ("TRACE".equals(severity))
85  				LOGGER.trace(message);
86  			else if ("DEBUG".equals(severity))
87  				LOGGER.debug(message);
88  			else if ("INFO".equals(severity))
89  				LOGGER.info(message);
90  			else if ("WARN".equals(severity))
91  				LOGGER.warn(message);
92  			else if ("ERROR".equals(severity))
93  				LOGGER.error(message);
94  		}
95  	}
96  }