1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.parser.wikimodel

File DefaultXWikiGeneratorListener.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

74
219
77
1
911
625
120
0.55
2.84
77
1.56

Classes

Class Line # Actions
DefaultXWikiGeneratorListener 64 219 0% 120 22
0.9405405594.1%
 

Contributing tests

This file is covered by 1338 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.internal.parser.wikimodel;
21   
22    import java.util.ArrayDeque;
23    import java.util.Collections;
24    import java.util.Deque;
25    import java.util.HashMap;
26    import java.util.HashSet;
27    import java.util.LinkedHashMap;
28    import java.util.List;
29    import java.util.Map;
30    import java.util.Set;
31   
32    import org.apache.commons.lang3.tuple.ImmutablePair;
33    import org.apache.commons.lang3.tuple.Pair;
34    import org.xwiki.rendering.listener.CompositeListener;
35    import org.xwiki.rendering.listener.Format;
36    import org.xwiki.rendering.listener.HeaderLevel;
37    import org.xwiki.rendering.listener.ListType;
38    import org.xwiki.rendering.listener.Listener;
39    import org.xwiki.rendering.listener.MetaData;
40    import org.xwiki.rendering.listener.QueueListener;
41    import org.xwiki.rendering.listener.reference.DocumentResourceReference;
42    import org.xwiki.rendering.listener.reference.ResourceReference;
43    import org.xwiki.rendering.parser.ParseException;
44    import org.xwiki.rendering.parser.ResourceReferenceParser;
45    import org.xwiki.rendering.parser.StreamParser;
46    import org.xwiki.rendering.renderer.PrintRenderer;
47    import org.xwiki.rendering.renderer.PrintRendererFactory;
48    import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
49    import org.xwiki.rendering.syntax.Syntax;
50    import org.xwiki.rendering.util.IdGenerator;
51    import org.xwiki.rendering.wikimodel.IWemConstants;
52    import org.xwiki.rendering.wikimodel.WikiFormat;
53    import org.xwiki.rendering.wikimodel.WikiParameter;
54    import org.xwiki.rendering.wikimodel.WikiParameters;
55    import org.xwiki.rendering.wikimodel.WikiReference;
56    import org.xwiki.rendering.wikimodel.WikiStyle;
57   
58    /**
59    * Transforms WikiModel events into XWiki Rendering events.
60    *
61    * @version $Id: 532c501c5166117144ee584e05d4a7e45ef67f49 $
62    * @since 2.1RC1
63    */
 
64    public class DefaultXWikiGeneratorListener implements XWikiGeneratorListener
65    {
66    /**
67    * Identifier of the extension used to generate id blocks.
68    */
69    public static final String EXT_ID = "xwiki_id";
70   
71    private static final Map<WikiStyle, Format> STYLES_CONVERTER = new HashMap<WikiStyle, Format>();
72   
 
73  86 toggle static {
74  86 STYLES_CONVERTER.put(IWemConstants.CODE, Format.MONOSPACE);
75  86 STYLES_CONVERTER.put(IWemConstants.EM, Format.ITALIC);
76  86 STYLES_CONVERTER.put(IWemConstants.DEL, Format.STRIKEDOUT);
77  86 STYLES_CONVERTER.put(IWemConstants.INS, Format.UNDERLINED);
78  86 STYLES_CONVERTER.put(IWemConstants.MONO, Format.MONOSPACE);
79  86 STYLES_CONVERTER.put(IWemConstants.STRIKE, Format.STRIKEDOUT);
80  86 STYLES_CONVERTER.put(IWemConstants.STRONG, Format.BOLD);
81  86 STYLES_CONVERTER.put(IWemConstants.SUB, Format.SUBSCRIPT);
82  86 STYLES_CONVERTER.put(IWemConstants.SUP, Format.SUPERSCRIPT);
83  86 STYLES_CONVERTER.put(IWemConstants.TT, Format.MONOSPACE);
84   
85    // TODO: what is the best conversion for theses ?
86  86 STYLES_CONVERTER.put(IWemConstants.BIG, Format.NONE);
87  86 STYLES_CONVERTER.put(IWemConstants.CITE, Format.NONE);
88  86 STYLES_CONVERTER.put(IWemConstants.REF, Format.NONE);
89  86 STYLES_CONVERTER.put(IWemConstants.SMALL, Format.NONE);
90    }
91   
92    /**
93    * Listener(s) for the generated XWiki Events. Organized as a stack so that a buffering listener can hijack all
94    * events for a while, for example. All generated events are sent to the top of the stack.
95    */
96    private Deque<Listener> listener = new ArrayDeque<Listener>();
97   
98    private StreamParser parser;
99   
100    private ResourceReferenceParser linkReferenceParser;
101   
102    private ResourceReferenceParser imageReferenceParser;
103   
104    private IdGenerator idGenerator;
105   
106    private PrintRendererFactory plainRendererFactory;
107   
108    private int documentDepth = 0;
109   
110    private Deque<WikiFormat> currentFormatStack = new ArrayDeque<WikiFormat>();
111   
112    private WikiFormat lastEndFormat = null;
113   
114    private Syntax syntax;
115   
116    private MetaData documentMetadata;
117   
118    /**
119    * @see <a href="http://code.google.com/p/wikimodel/issues/detail?id=87">wikimodel issue 87</a>
120    * @since 3.0M3
121    */
 
122  23376 toggle public DefaultXWikiGeneratorListener(StreamParser parser, Listener listener,
123    ResourceReferenceParser linkReferenceParser, ResourceReferenceParser imageReferenceParser,
124    PrintRendererFactory plainRendererFactory, IdGenerator idGenerator, Syntax syntax)
125    {
126  23376 pushListener(listener);
127   
128  23371 this.parser = parser;
129  23373 this.linkReferenceParser = linkReferenceParser;
130  23370 this.imageReferenceParser = imageReferenceParser;
131  23372 this.idGenerator = idGenerator != null ? idGenerator : new IdGenerator();
132  23370 this.plainRendererFactory = plainRendererFactory;
133  23373 this.syntax = syntax;
134  23371 this.documentMetadata = new MetaData();
135  23373 this.documentMetadata.addMetaData(MetaData.SYNTAX, this.syntax);
136    }
137   
138    /**
139    * Returns the 'default' listener to send xwiki events to, the top of the listeners stack.
140    *
141    * @return the listener to send xwiki events to
142    */
 
143  861054 toggle @Override
144    public Listener getListener()
145    {
146  861055 return this.listener.peek();
147    }
148   
149    /**
150    * @since 2.5RC1
151    */
 
152  2056 toggle protected ResourceReferenceParser getLinkReferenceParser()
153    {
154  2056 return this.linkReferenceParser;
155    }
156   
157    /**
158    * @since 2.5RC1
159    */
 
160  1048 toggle protected ResourceReferenceParser getImageReferenceParser()
161    {
162  1048 return this.imageReferenceParser;
163    }
164   
165    /**
166    * Pushes a new listener in the listeners stack, thus making it the 'default' listener, to which all events are
167    * sent.
168    *
169    * @param listener the listener to add in the top of the stack
170    * @return the listener pushed in the top of the stack
171    */
 
172  24427 toggle private Listener pushListener(Listener listener)
173    {
174  24428 this.listener.push(listener);
175  24427 return listener;
176    }
177   
178    /**
179    * Removes the listener from the top of the stack (the current 'default' listener).
180    *
181    * @return the removed listener
182    */
 
183  1055 toggle private Listener popListener()
184    {
185  1055 return this.listener.pop();
186    }
187   
188    /**
189    * Convert Wikimodel parameters to XWiki parameters format.
190    *
191    * @param params the wikimodel parameters to convert
192    * @return the parameters in XWiki format
193    */
 
194  53223 toggle protected Map<String, String> convertParameters(WikiParameters params)
195    {
196  53223 Map<String, String> xwikiParams;
197   
198  53223 if (params.getSize() > 0) {
199  17242 xwikiParams = new LinkedHashMap<String, String>();
200  17242 for (WikiParameter wikiParameter : params.toList()) {
201  26581 xwikiParams.put(wikiParameter.getKey(), wikiParameter.getValue());
202    }
203    } else {
204  35983 xwikiParams = Listener.EMPTY_PARAMETERS;
205    }
206   
207  53224 return xwikiParams;
208    }
209   
210    /**
211    * Convert Wikimodel parameters to XWiki parameters format, separating anchor and query string parameters which we
212    * consider ResourceReference parameters from the rest which we consider generic event parameters.
213    *
214    * @param params the wikimodel parameters to convert
215    * @return the parameters in XWiki format, the left side of the pair is the ResourceReference parameters and the
216    * right side the generic event parameters
217    */
 
218  79 toggle protected Pair<Map<String, String>, Map<String, String>> convertAndSeparateParameters(WikiParameters params)
219    {
220  79 Map<String, String> resourceParameters;
221  79 Map<String, String> genericParameters;
222   
223  79 if (params.getSize() > 0) {
224  14 resourceParameters = new LinkedHashMap<String, String>();
225  14 genericParameters = new LinkedHashMap<String, String>();
226  14 for (WikiParameter wikiParameter : params.toList()) {
227  16 String key = wikiParameter.getKey();
228  16 if (key.equals(DocumentResourceReference.ANCHOR)
229    || key.equals(DocumentResourceReference.QUERY_STRING))
230    {
231  0 resourceParameters.put(key, wikiParameter.getValue());
232    } else {
233  16 genericParameters.put(key, wikiParameter.getValue());
234    }
235    }
236    } else {
237  65 resourceParameters = Listener.EMPTY_PARAMETERS;
238  65 genericParameters = Listener.EMPTY_PARAMETERS;
239    }
240   
241  79 return new ImmutablePair<Map<String, String>, Map<String, String>>(resourceParameters, genericParameters);
242    }
243   
 
244  2502 toggle private Format convertFormat(WikiStyle style)
245    {
246  2502 Format result = STYLES_CONVERTER.get(style);
247   
248  2502 if (result == null) {
249  0 result = Format.NONE;
250    }
251   
252  2502 return result;
253    }
254   
 
255  24797 toggle private void flush()
256    {
257  24798 flushInline();
258    }
259   
 
260  36093 toggle private void flushInline()
261    {
262  36095 flushFormat();
263    }
264   
 
265  598105 toggle protected void flushFormat()
266    {
267  598105 flushFormat(null, null);
268    }
269   
 
270  603820 toggle private void flushFormat(List<WikiStyle> xorStyles, List<WikiParameter> xorParameters)
271    {
272  603823 if (this.lastEndFormat != null) {
273  5717 flushFormat(this.lastEndFormat.getStyles(), this.lastEndFormat.getParams(), xorStyles, xorParameters);
274    }
275    }
276   
 
277  5717 toggle private void flushFormat(List<WikiStyle> formatStyles, List<WikiParameter> formatParameters,
278    List<WikiStyle> xorStyles, List<WikiParameter> xorParameters)
279    {
280  5717 Set<WikiStyle> stylesToClose = new HashSet<WikiStyle>();
281  5717 Set<WikiParameter> parametersToClose = new HashSet<WikiParameter>();
282   
283  5717 if (xorStyles != null) {
284  69 for (WikiStyle style : formatStyles) {
285  36 if (!xorStyles.contains(style)) {
286  12 stylesToClose.add(style);
287    }
288    }
289    } else {
290  5648 stylesToClose.addAll(formatStyles);
291    }
292   
293  5717 if (xorParameters != null) {
294  69 for (WikiParameter parameter : formatParameters) {
295  56 if (!xorParameters.contains(parameter)) {
296  30 parametersToClose.add(parameter);
297    }
298    }
299    } else {
300  5648 parametersToClose.addAll(formatParameters);
301    }
302   
303  11422 for (; !stylesToClose.isEmpty() || !parametersToClose.isEmpty(); this.currentFormatStack.pop()) {
304  5705 WikiFormat currentFormat = this.currentFormatStack.peek();
305   
306  5705 List<WikiStyle> currentFormatStyles = currentFormat.getStyles();
307  5705 WikiStyle currentFormatStyle = currentFormatStyles.isEmpty() ? null : currentFormatStyles.get(0);
308  5705 List<WikiParameter> currentFormatParameters = currentFormat.getParams();
309   
310    // XOR
311  5705 stylesToClose.remove(currentFormatStyle);
312  5705 parametersToClose.removeAll(currentFormatParameters);
313   
314    // send event
315  5705 Map<String, String> parameters;
316  5705 if (!currentFormatParameters.isEmpty()) {
317  4489 parameters = convertParameters(new WikiParameters(currentFormatParameters));
318    } else {
319  1216 parameters = Listener.EMPTY_PARAMETERS;
320    }
321   
322  5705 if (currentFormatStyle != null) {
323  1251 getListener().endFormat(convertFormat(currentFormatStyle), parameters);
324    } else {
325  4454 getListener().endFormat(Format.NONE, parameters);
326    }
327    }
328   
329  5717 for (WikiFormat format : this.currentFormatStack) {
330  35 if (xorStyles != null) {
331  35 xorStyles.removeAll(format.getStyles());
332    }
333  35 if (xorParameters != null) {
334  35 xorParameters.removeAll(format.getParams());
335    }
336    }
337   
338  5717 this.lastEndFormat = null;
339    }
340   
 
341  169 toggle @Override
342    public void beginDefinitionDescription()
343    {
344  169 getListener().beginDefinitionDescription();
345    }
346   
 
347  110 toggle @Override
348    public void beginDefinitionList(WikiParameters params)
349    {
350  110 flushInline();
351   
352  110 getListener().beginDefinitionList(convertParameters(params));
353    }
354   
 
355  152 toggle @Override
356    public void beginDefinitionTerm()
357    {
358  152 getListener().beginDefinitionTerm();
359    }
360   
 
361  24798 toggle @Override
362    public void beginDocument(WikiParameters params)
363    {
364  24797 if (this.documentDepth > 0) {
365  1424 getListener().beginGroup(convertParameters(params));
366    } else {
367  23371 getListener().beginDocument(this.documentMetadata);
368    }
369   
370  24799 ++this.documentDepth;
371    }
372   
 
373  19441 toggle @Override
374    public void beginFormat(WikiFormat format)
375    {
376  19441 List<WikiStyle> formatStyles = format.getStyles();
377  19442 List<WikiParameter> formatParameters = format.getParams();
378   
379    // If there's any style or parameter defined, do something. The reason we need to check for this is because
380    // wikimodel sends an empty begin/endFormat event before starting an inline block (such as a paragraph).
381  19442 if (formatStyles.size() > 0 || formatParameters.size() > 0) {
382  5717 flushFormat(formatStyles, formatParameters);
383   
384    // If everything is already part of the current style
385  5717 if (formatStyles.size() > 0 || formatParameters.size() > 0) {
386  5703 Map<String, String> parameters;
387  5703 if (formatParameters.size() > 0) {
388  4489 parameters = convertParameters(new WikiParameters(formatParameters));
389    } else {
390  1214 parameters = Listener.EMPTY_PARAMETERS;
391    }
392   
393  5703 if (formatStyles.size() > 0) {
394  1249 boolean parametersConsumed = false;
395  1249 for (WikiStyle style : formatStyles) {
396    // Exclude previous format styles
397  1251 if (!parametersConsumed) {
398  1249 getListener().beginFormat(convertFormat(style), parameters);
399  1249 parametersConsumed = true;
400  1249 this.currentFormatStack
401    .push(new WikiFormat(Collections.singleton(style), formatParameters));
402    } else {
403  2 getListener().beginFormat(convertFormat(style), Listener.EMPTY_PARAMETERS);
404  2 this.currentFormatStack.push(new WikiFormat(style));
405    }
406    }
407    } else {
408  4454 getListener().beginFormat(Format.NONE, parameters);
409  4454 this.currentFormatStack.push(new WikiFormat(formatParameters));
410    }
411    }
412    }
413    }
414   
 
415  26070 toggle @Override
416    public void beginSection(int docLevel, int headerLevel, WikiParameters params)
417    {
418  26071 if (headerLevel > 0) {
419  1273 getListener().beginSection(Listener.EMPTY_PARAMETERS);
420    }
421    }
422   
 
423  26069 toggle @Override
424    public void beginSectionContent(int docLevel, int headerLevel, WikiParameters params)
425    {
426    // TODO add support for it
427    }
428   
 
429  1055 toggle @Override
430    public void beginHeader(int level, WikiParameters params)
431    {
432    // Heading needs to have an id generated from a plaintext representation of its content, so the header start
433    // event will be sent at the end of the header, after reading the content inside and generating the id.
434    // For this:
435    // buffer all events in a queue until the header ends, and also send them to a print renderer to generate the ID
436  1055 CompositeListener composite = new CompositeListener();
437  1055 composite.addListener(new QueueListener());
438  1055 composite.addListener(this.plainRendererFactory.createRenderer(new DefaultWikiPrinter()));
439   
440    // These 2 listeners will receive all events from now on until the header ends
441  1055 pushListener(composite);
442    }
443   
 
444  0 toggle @Override
445    public void beginInfoBlock(String infoType, WikiParameters params)
446    {
447    // Not used by XWiki Syntax 2.0
448    }
449   
 
450  2456 toggle @Override
451    public void beginList(WikiParameters params, boolean ordered)
452    {
453  2456 flushInline();
454   
455  2456 if (ordered) {
456  75 getListener().beginList(ListType.NUMBERED, convertParameters(params));
457    } else {
458  2381 getListener().beginList(ListType.BULLETED, convertParameters(params));
459    }
460    }
461   
 
462  6083 toggle @Override
463    public void beginListItem()
464    {
465  6083 getListener().beginListItem();
466    }
467   
 
468  9155 toggle @Override
469    public void beginParagraph(WikiParameters params)
470    {
471  9155 getListener().beginParagraph(convertParameters(params));
472    }
473   
 
474  0 toggle @Override
475    public void beginPropertyBlock(String propertyUri, boolean doc)
476    {
477    // Not used by XWiki Syntax 2.0
478    }
479   
 
480  0 toggle @Override
481    public void beginPropertyInline(String str)
482    {
483    // Not used by XWiki Syntax 2.0
484    }
485   
 
486  32 toggle @Override
487    public void beginQuotation(WikiParameters params)
488    {
489  32 getListener().beginQuotation(convertParameters(params));
490    }
491   
 
492  53 toggle @Override
493    public void beginQuotationLine()
494    {
495  53 getListener().beginQuotationLine();
496    }
497   
 
498  178 toggle @Override
499    public void beginTable(WikiParameters params)
500    {
501  178 getListener().beginTable(convertParameters(params));
502    }
503   
 
504  1225 toggle @Override
505    public void beginTableCell(boolean tableHead, WikiParameters params)
506    {
507  1225 if (tableHead) {
508  315 getListener().beginTableHeadCell(convertParameters(params));
509    } else {
510  910 getListener().beginTableCell(convertParameters(params));
511    }
512    }
513   
 
514  462 toggle @Override
515    public void beginTableRow(WikiParameters params)
516    {
517  462 getListener().beginTableRow(convertParameters(params));
518    }
519   
 
520  169 toggle @Override
521    public void endDefinitionDescription()
522    {
523  169 flushInline();
524   
525  169 getListener().endDefinitionDescription();
526    }
527   
 
528  110 toggle @Override
529    public void endDefinitionList(WikiParameters params)
530    {
531  110 getListener().endDefinitionList(convertParameters(params));
532    }
533   
 
534  152 toggle @Override
535    public void endDefinitionTerm()
536    {
537  152 flushInline();
538   
539  152 getListener().endDefinitionTerm();
540    }
541   
 
542  24798 toggle @Override
543    public void endDocument(WikiParameters params)
544    {
545  24798 flush();
546   
547  24796 --this.documentDepth;
548   
549  24794 if (this.documentDepth > 0) {
550  1424 getListener().endGroup(convertParameters(params));
551    } else {
552  23373 getListener().endDocument(this.documentMetadata);
553    }
554    }
555   
 
556  19439 toggle @Override
557    public void endFormat(WikiFormat format)
558    {
559    // If there's any style or parameter defined, do something. The reason we need to check for this is because
560    // wikimodel sends an empty begin/endFormat event before starting an inline block (such as a paragraph).
561  19440 if (format.getStyles().size() > 0 || format.getParams().size() > 0) {
562  5717 this.lastEndFormat = format;
563    }
564    }
565   
 
566  1055 toggle @Override
567    public void endHeader(int level, WikiParameters params)
568    {
569    // End all formats
570  1055 flushInline();
571   
572  1055 CompositeListener composite = (CompositeListener) getListener();
573   
574    // Get the listener where events inside the header were buffered
575  1055 QueueListener queue = (QueueListener) composite.getListener(0);
576    // and the listener in which the id was generated
577  1055 PrintRenderer renderer = (PrintRenderer) composite.getListener(1);
578   
579    // Restore the 'default' listener as it was at the beginning of the header
580  1055 popListener();
581   
582  1055 HeaderLevel headerLevel = HeaderLevel.parseInt(level);
583    // Generate the id from the content inside the header written to the renderer
584  1055 String id = this.idGenerator.generateUniqueId("H", renderer.getPrinter().toString());
585  1055 Map<String, String> parameters = convertParameters(params);
586   
587    // Generate the begin header event to the 'default' listener
588  1055 getListener().beginHeader(headerLevel, id, parameters);
589    // Send all buffered events to the 'default' listener
590  1055 queue.consumeEvents(getListener());
591    // Generate the end header event to the 'default' listener
592  1055 getListener().endHeader(headerLevel, id, parameters);
593    }
594   
 
595  26066 toggle @Override
596    public void endSection(int docLevel, int headerLevel, WikiParameters params)
597    {
598  26071 if (headerLevel > 0) {
599  1273 getListener().endSection(Listener.EMPTY_PARAMETERS);
600    }
601    }
602   
 
603  26071 toggle @Override
604    public void endSectionContent(int docLevel, int headerLevel, WikiParameters params)
605    {
606    // TODO add support for it
607    }
608   
 
609  0 toggle @Override
610    public void endInfoBlock(String infoType, WikiParameters params)
611    {
612    // Not used by XWiki Syntax 2.0
613    }
614   
 
615  2456 toggle @Override
616    public void endList(WikiParameters params, boolean ordered)
617    {
618  2456 if (ordered) {
619  75 getListener().endList(ListType.NUMBERED, convertParameters(params));
620    } else {
621  2381 getListener().endList(ListType.BULLETED, convertParameters(params));
622    }
623    }
624   
 
625  6083 toggle @Override
626    public void endListItem()
627    {
628  6083 flushInline();
629   
630    // Note: This means we support Paragraphs inside lists.
631  6083 getListener().endListItem();
632    }
633   
 
634  9153 toggle @Override
635    public void endParagraph(WikiParameters params)
636    {
637  9153 flushFormat();
638   
639  9153 getListener().endParagraph(convertParameters(params));
640    }
641   
 
642  0 toggle @Override
643    public void endPropertyBlock(String propertyUri, boolean doc)
644    {
645    // Not used by XWiki Syntax 2.0
646    }
647   
 
648  0 toggle @Override
649    public void endPropertyInline(String inlineProperty)
650    {
651    // Not used by XWiki Syntax 2.0
652    }
653   
 
654  32 toggle @Override
655    public void endQuotation(WikiParameters params)
656    {
657  32 getListener().endQuotation(convertParameters(params));
658    }
659   
 
660  53 toggle @Override
661    public void endQuotationLine()
662    {
663  53 flushInline();
664   
665  53 getListener().endQuotationLine();
666    }
667   
 
668  178 toggle @Override
669    public void endTable(WikiParameters params)
670    {
671  178 getListener().endTable(convertParameters(params));
672    }
673   
 
674  1225 toggle @Override
675    public void endTableCell(boolean tableHead, WikiParameters params)
676    {
677  1225 flushInline();
678   
679  1225 if (tableHead) {
680  315 getListener().endTableHeadCell(convertParameters(params));
681    } else {
682  910 getListener().endTableCell(convertParameters(params));
683    }
684    }
685   
 
686  462 toggle @Override
687    public void endTableRow(WikiParameters params)
688    {
689  462 getListener().endTableRow(convertParameters(params));
690    }
691   
 
692  236 toggle @Override
693    public void onEmptyLines(int count)
694    {
695  236 getListener().onEmptyLines(count);
696    }
697   
 
698  0 toggle @Override
699    public void onEscape(String str)
700    {
701    // The WikiModel XWiki parser has been modified not to generate any onEscape event so do nothing here.
702    // This is because we believe that WikiModel should not have an escape event since it's the
703    // responsibility of Renderers to perform escaping as required.
704    }
705   
 
706  6 toggle @Override
707    public void onExtensionBlock(String extensionName, WikiParameters params)
708    {
709  6 if (EXT_ID.equals(extensionName)) {
710  6 getListener().onId(params.getParameter("name").getValue());
711    }
712    }
713   
 
714  0 toggle @Override
715    public void onExtensionInline(String extensionName, WikiParameters params)
716    {
717  0 if (EXT_ID.equals(extensionName)) {
718  0 getListener().onId(params.getParameter("name").getValue());
719    }
720    }
721   
 
722  49 toggle @Override
723    public void onHorizontalLine(WikiParameters params)
724    {
725  49 getListener().onHorizontalLine(convertParameters(params));
726    }
727   
 
728  48 toggle @Override
729    public void onLineBreak()
730    {
731    // Note that in XWiki we don't differentiate new lines and line breaks since it's the Renderers that decide
732    // to generate new lines or line breaks depending on the context and the target syntax.
733  48 onNewLine();
734    }
735   
736    /**
737    * A macro block was found and it's separated at least by one new line from the next block. If there's no new line
738    * with the next block then wikimodel calls {@link #onMacroInline(String, org.xwiki.rendering.wikimodel.WikiParameters, String)}
739    * instead.
740    * <p>
741    * In wikimodel block elements can be:
742    * <ul>
743    * <li>at the very beginning of the document (no "\n")</li>
744    * <li>just after at least one "\n"</li>
745    * </ul>
746    */
 
747  6925 toggle @Override
748    public void onMacroBlock(String macroName, WikiParameters params, String content)
749    {
750  6925 getListener().onMacro(macroName, convertParameters(params), content, false);
751    }
752   
 
753  4574 toggle @Override
754    public void onMacroInline(String macroName, WikiParameters params, String content)
755    {
756  4574 flushFormat();
757   
758  4574 getListener().onMacro(macroName, convertParameters(params), content, true);
759    }
760   
 
761  4128 toggle @Override
762    public void onNewLine()
763    {
764  4128 flushFormat();
765   
766    // Note that in XWiki we don't differentiate new lines and line breaks since it's the Renderers that decide
767    // to generate new lines or line breaks depending on the context and the target syntax.
768  4128 getListener().onNewLine();
769    }
770   
771    /**
772    * {@inheritDoc}
773    * <p>
774    * Called when WikiModel finds an reference (link or image) such as a URI located directly in the text
775    * (free-standing URI), as opposed to a link/image inside wiki link/image syntax delimiters.
776    * </p>
777    *
778    * @see org.xwiki.rendering.wikimodel.IWemListener#onLineBreak()
779    */
 
780  48 toggle @Override
781    public void onReference(String reference)
782    {
783  48 onReference(reference, null, true, Listener.EMPTY_PARAMETERS);
784    }
785   
 
786  980 toggle @Override
787    public void onReference(WikiReference reference)
788    {
789  980 onReference(reference.getLink(), reference.getLabel(), false, convertParameters(reference.getParameters()));
790    }
791   
 
792  1028 toggle protected void onReference(String reference, String label, boolean freestanding, Map<String, String> parameters)
793    {
794  1028 flushFormat();
795   
796    // If there's no resource reference parser defined, don't handle links...
797  1028 if (getLinkReferenceParser() != null) {
798  1028 onReference(getLinkReferenceParser().parse(reference), label, freestanding, parameters);
799    }
800    }
801   
 
802  1028 toggle protected void onReference(ResourceReference reference, String label, boolean freestanding,
803    Map<String, String> parameters)
804    {
805  1028 onReference(reference, label, freestanding, parameters, true);
806    }
807   
808    /**
809    * @since 6.0RC1
810    * @since 5.4.5
811    */
 
812  1107 toggle protected void onReference(ResourceReference reference, String label, boolean freestanding,
813    Map<String, String> parameters, boolean prefix)
814    {
815    // Since WikiModel doesn't handle syntax in link labels and thus doesn't have begin/end events for links, we
816    // need to call the XWiki events and use an inline parser to parse the syntax in the label.
817  1107 getListener().beginLink(reference, freestanding, parameters);
818  1107 if (label != null) {
819  838 try {
820    // TODO: Use an inline parser. See http://jira.xwiki.org/jira/browse/XWIKI-2748
821  838 WikiModelParserUtils parserUtils = new WikiModelParserUtils();
822  838 parserUtils.parseInline(this.parser, label, getListener(), prefix);
823    } catch (ParseException e) {
824    // TODO what should we do here ?
825    }
826    }
827  1107 getListener().endLink(reference, freestanding, parameters);
828    }
829   
 
830  75 toggle @Override
831    public void onImage(String reference)
832    {
833  75 onImage(reference, true, Listener.EMPTY_PARAMETERS);
834    }
835   
 
836  449 toggle @Override
837    public void onImage(WikiReference reference)
838    {
839  449 onImage(reference.getLink(), false, convertParameters(reference.getParameters()));
840    }
841   
842    /**
843    * @since 2.5RC1
844    */
 
845  524 toggle protected void onImage(String reference, boolean freestanding, Map<String, String> parameters)
846    {
847  524 flushFormat();
848   
849    // If there's no resource reference parser defined, don't handle images...
850  524 if (getImageReferenceParser() != null) {
851  524 onImage(getImageReferenceParser().parse(reference), freestanding, parameters);
852    }
853    }
854   
855    /**
856    * @since 2.5RC1
857    */
 
858  607 toggle protected void onImage(ResourceReference reference, boolean freestanding, Map<String, String> parameters)
859    {
860  607 getListener().onImage(reference, freestanding, parameters);
861    }
862   
 
863  91254 toggle @Override
864    public void onSpace(String spaces)
865    {
866  91254 flushFormat();
867   
868    // We want one space event per space.
869  373265 for (int i = 0; i < spaces.length(); i++) {
870  282011 getListener().onSpace();
871    }
872    }
873   
 
874  250150 toggle @Override
875    public void onSpecialSymbol(String symbol)
876    {
877  250150 flushFormat();
878   
879  500300 for (int i = 0; i < symbol.length(); i++) {
880  250150 getListener().onSpecialSymbol(symbol.charAt(i));
881    }
882    }
883   
 
884  0 toggle @Override
885    public void onTableCaption(String str)
886    {
887    // Not used by XWiki Syntax 2.0
888    }
889   
 
890  44 toggle @Override
891    public void onVerbatimBlock(String protectedString, WikiParameters params)
892    {
893  44 getListener().onVerbatim(protectedString, false, convertParameters(params));
894    }
895   
 
896  67 toggle @Override
897    public void onVerbatimInline(String protectedString, WikiParameters params)
898    {
899  67 flushFormat();
900   
901  67 getListener().onVerbatim(protectedString, true, convertParameters(params));
902    }
903   
 
904  201051 toggle @Override
905    public void onWord(String str)
906    {
907  201051 flushFormat();
908   
909  201051 getListener().onWord(str);
910    }
911    }