001package com.monochromeroad.grails.plugins.xwiki; 002 003import groovy.lang.Closure; 004import org.xwiki.rendering.block.XDOM; 005import org.xwiki.rendering.parser.ParseException; 006import org.xwiki.rendering.parser.StreamParser; 007import org.xwiki.rendering.renderer.Renderer; 008import org.xwiki.rendering.syntax.Syntax; 009import org.xwiki.rendering.transformation.Transformation; 010 011import java.io.Reader; 012import java.util.Collections; 013 014/** 015 * XWiki Rendering System -- streaming based 016 * 017 * <p> 018 * If you use some macros or transformations, it needs to create a XDOM that represents the whole document structure in a memory. 019 * </p> 020 * 021 * <dl> 022 * <dt>Default Syntax</dt> 023 * <dd>xwiki/2.1</dd> 024 * <dt>Output</dt> 025 * <dd>xhtml/1.0</dd> 026 * </dl> 027 * 028 * @author Masatoshi Hayashi 029 */ 030public class XWikiStreamRenderer extends XWikiRenderingSystem { 031 032 public XWikiStreamRenderer(XWikiComponentManager componentManager, XWikiConfigurationProvider configuration) { 033 super(componentManager, configuration); 034 } 035 036 /** 037 * For the Grails Default XWiki Rendering System. 038 * It need to be initialized after construction. 039 */ 040 XWikiStreamRenderer() {} 041 042 /** 043 * XWiki rendering 044 * 045 * @param source source text reader 046 * @param inputSyntax inputSyntax 047 * @param outputSyntax outputSyntax 048 * @param preTransformations transforms applied before macros 049 * @param postTransformations transforms applied after macros 050 * @param callback a callback function processed on parsing a text 051 */ 052 public void render(Reader source, Syntax inputSyntax, Syntax outputSyntax, Iterable<Transformation> preTransformations, Iterable<Transformation> postTransformations, Closure callback) { 053 if (configurationProvider.isMacrosEnabled() || preTransformations.iterator().hasNext() || postTransformations.iterator().hasNext()) { 054 renderOnXDOM(source, inputSyntax, outputSyntax, preTransformations, postTransformations, callback); 055 } else { 056 renderOnStream(source, inputSyntax, outputSyntax, callback); 057 } 058 } 059 060 /** 061 * XWiki rendering 062 * 063 * @param source source text reader 064 * @param inputSyntax inputSyntax 065 * @param outputSyntax outputSyntax 066 * @param callback a callback function processed on parsing a text 067 */ 068 public void render(Reader source, Syntax inputSyntax, Syntax outputSyntax, Closure callback) { 069 render(source, inputSyntax, outputSyntax, Collections.<Transformation>emptyList(), Collections.<Transformation>emptyList(), callback); 070 } 071 072 /** 073 * XWiki XHTML rendering 074 * 075 * @param source source text reader 076 * @param inputSyntax inputSyntax 077 * @param callback a callback function processed on parsing a text 078 */ 079 public void render(Reader source, Syntax inputSyntax, Closure callback) { 080 Syntax outputSyntax = configurationProvider.getDefaultOutputSyntax(); 081 render(source, inputSyntax, outputSyntax, callback); 082 } 083 084 /** 085 * XWiki XHTML rendering using the default syntax 086 * 087 * @param source source text reader 088 * @param callback a callback function processed on parsing a text 089 */ 090 public void render(Reader source, Closure callback) { 091 Syntax inputSyntax = configurationProvider.getDefaultInputSyntax(); 092 Syntax outputSyntax = configurationProvider.getDefaultOutputSyntax(); 093 render(source, inputSyntax, outputSyntax, callback); 094 } 095 096 /** 097 * XWiki rendering 098 * 099 * @param source source text reader 100 * @param inputSyntax inputSyntax 101 * @param outputSyntax outputSyntax 102 * @param transformations transforms applied after macros 103 * @param callback a callback function processed on parsing a text 104 */ 105 public void render(Reader source, Syntax inputSyntax, Syntax outputSyntax, Iterable<Transformation> transformations, Closure callback) { 106 render(source, inputSyntax, outputSyntax, Collections.<Transformation>emptyList(), transformations, callback); 107 } 108 109 /** 110 * XWiki XHTML rendering 111 * 112 * @param source source text reader 113 * @param inputSyntax inputSyntax 114 * @param transformations transforms applied after macros 115 * @param callback a callback function processed on parsing a text 116 */ 117 public void render(Reader source, Syntax inputSyntax, Iterable<Transformation> transformations, Closure callback) { 118 Syntax outputSyntax = configurationProvider.getDefaultOutputSyntax(); 119 render(source, inputSyntax, outputSyntax, transformations, callback); 120 } 121 122 /** 123 * XWiki XHTML rendering 124 * 125 * @param source source text reader 126 * @param inputSyntax inputSyntax 127 * @param preTransformations transforms applied before macros 128 * @param postTransformations transforms applied after macros 129 * @param callback a callback function processed on parsing a text 130 */ 131 public void render(Reader source, Syntax inputSyntax, Iterable<Transformation> preTransformations, Iterable<Transformation> postTransformations, Closure callback) { 132 Syntax outputSyntax = configurationProvider.getDefaultOutputSyntax(); 133 render(source, inputSyntax, outputSyntax, preTransformations, postTransformations, callback); 134 } 135 136 /** 137 * XWiki XHTML rendering using the default syntax 138 * 139 * @param source source text reader 140 * @param transformations transforms applied after macros 141 * @param callback a callback function processed on parsing a text 142 */ 143 public void render(Reader source, Iterable<Transformation> transformations, Closure callback) { 144 Syntax inputSyntax = configurationProvider.getDefaultInputSyntax(); 145 Syntax outputSyntax = configurationProvider.getDefaultOutputSyntax(); 146 render(source, inputSyntax, outputSyntax, transformations, callback); 147 } 148 149 /** 150 * XWiki XHTML rendering using the default syntax 151 * 152 * @param source source text reader 153 * @param preTransformations transforms applied before macros 154 * @param postTransformations transforms applied after macros 155 * @param callback a callback function processed on parsing a text 156 */ 157 public void render(Reader source, Iterable<Transformation> preTransformations, Iterable<Transformation> postTransformations, Closure callback) { 158 Syntax inputSyntax = configurationProvider.getDefaultInputSyntax(); 159 Syntax outputSyntax = configurationProvider.getDefaultOutputSyntax(); 160 render(source, inputSyntax, outputSyntax, preTransformations, postTransformations, callback); 161 } 162 163 private void renderOnXDOM(Reader source, Syntax inputSyntax, Syntax outputSyntax, Iterable<Transformation> preTransformations, Iterable<Transformation> postTransformations, Closure callback) { 164 XDOM xdom = buildXDOM(source, inputSyntax); 165 transform(xdom, inputSyntax, preTransformations, postTransformations); 166 applyRenderer(xdom, outputSyntax, new XWikiCallbackPrinter(callback)); 167 } 168 169 private void renderOnStream(Reader source, Syntax inputSyntax, Syntax outputSyntax, Closure callback) { 170 StreamParser streamParser = componentManager.getInstance(StreamParser.class, inputSyntax.toIdString()); 171 XWikiCallbackPrinter printer = new XWikiCallbackPrinter(callback); 172 Renderer renderer = createRenderer(outputSyntax, printer); 173 try { 174 streamParser.parse(source, renderer); 175 } catch (ParseException e) { 176 throw new IllegalStateException(e); 177 } 178 } 179} 180