XSLT report builder, with focus on the XSLT Saxon processor. @author BaseX Team, BSD License @author Christian Gruen
| 26 | * @author Christian Gruen |
| 27 | */ |
| 28 | final class XsltReport { |
| 29 | /** Saxon TransformerImpl class. */ |
| 30 | private static final Class<?> TI = Reflect.find("net.sf.saxon.jaxp.TransformerImpl"); |
| 31 | /** Saxon XsltController class. */ |
| 32 | private static final Class<?> XC = Reflect.find("net.sf.saxon.trans.XsltController"); |
| 33 | /** Saxon MessageWarner class. */ |
| 34 | private static final Class<?> MW = Reflect.find("net.sf.saxon.serialize.MessageWarner"); |
| 35 | |
| 36 | /** TransformerImpl.getUnderlyingController method. */ |
| 37 | private static final Method TI_GUC = Reflect.method(TI, "getUnderlyingController"); |
| 38 | /** MessageWarner.getWriter method. */ |
| 39 | private static final Method MW_GW = Reflect.method(MW, "getWriter"); |
| 40 | /** XsltController.setMessageFactory method. */ |
| 41 | private static final Method MW_SMW = Reflect.method(XC, "setMessageFactory", Supplier.class); |
| 42 | |
| 43 | /** Report map builder. */ |
| 44 | private final MapBuilder report = new MapBuilder(); |
| 45 | /** Saxon-specific: Message collector. */ |
| 46 | private final Stack<Object> messages = new Stack<>(); |
| 47 | /** Query context. */ |
| 48 | private final QueryContext qc; |
| 49 | |
| 50 | /** |
| 51 | * Constructor. |
| 52 | * @param qc query context |
| 53 | */ |
| 54 | XsltReport(final QueryContext qc) { |
| 55 | this.qc = qc; |
| 56 | } |
| 57 | |
| 58 | /** |
| 59 | * Registers a message factory to collect messages. |
| 60 | * @param tr transformer |
| 61 | */ |
| 62 | void register(final Transformer tr) { |
| 63 | if(tr.getClass() == TI) { |
| 64 | try { |
| 65 | final Supplier<Object> supplier = () -> { |
| 66 | final Object mw = Reflect.get(MW); |
| 67 | messages.add(mw); |
| 68 | return mw; |
| 69 | }; |
| 70 | MW_SMW.invoke(TI_GUC.invoke(tr), supplier); |
| 71 | } catch(final Exception ex) { |
| 72 | Util.stack(ex); |
| 73 | } |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | /** |
| 78 | * Adds a result. |
| 79 | * @param result transformation result |
| 80 | * @throws QueryException query exception |
| 81 | */ |
| 82 | void addResult(final byte[] result) throws QueryException { |
| 83 | report.put("result", convert(new IOContent(result), true)); |
| 84 | } |
| 85 |