1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.rendering.internal.renderer.xwiki20

File AbstractStackingInlineContentChainingListener.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart8.png
56% of files have more coverage

Code metrics

8
43
17
1
200
129
21
0.49
2.53
17
1.24

Classes

Class Line # Actions
AbstractStackingInlineContentChainingListener 41 43 0% 21 13
0.808823580.9%
 

Contributing tests

This file is covered by 42 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.renderer.xwiki20;
21   
22    import java.util.Collections;
23    import java.util.Map;
24   
25    import org.xwiki.rendering.listener.HeaderLevel;
26    import org.xwiki.rendering.listener.QueueListener;
27    import org.xwiki.rendering.listener.chaining.EventType;
28    import org.xwiki.rendering.listener.chaining.ListenerChain;
29    import org.xwiki.rendering.listener.chaining.LookaheadChainingListener;
30   
31    /**
32    * Stack events found under the current element and if there are standalone events, then wrap them in a
33    * {@link org.xwiki.rendering.block.GroupBlock}. Note that if the only top level element is a
34    * {@link org.xwiki.rendering.block.GroupBlock} then we don't consider it astandalone element.
35    * This is useful for example to handme rendering of {@link org.xwiki.rendering.block.TableCellBlock} elements in the
36    * XWiki Syntax 2.0 since they support only inline elements (except through Group Blocks).
37    *
38    * @version $Id: e57a859f4899adbf4074c5dcd048bcf6512e02ac $
39    * @since 10.5RC1
40    */
 
41    public abstract class AbstractStackingInlineContentChainingListener extends LookaheadChainingListener
42    {
43    private boolean isStacking;
44   
45    private int standaloneElementDepth;
46   
47    private int standaloneTopLevelElements;
48   
49    private boolean hasGroupTopLevelBlock;
50   
51    /**
52    * @param listenerChain the listener chain to save
53    */
 
54  183 toggle public AbstractStackingInlineContentChainingListener(ListenerChain listenerChain)
55    {
56  183 super(listenerChain, Integer.MAX_VALUE);
57  183 setListenerChain(listenerChain);
58  183 this.isStacking = true;
59    }
60   
 
61  34 toggle @Override
62    public void beginGroup(Map<String, String> parameters)
63    {
64  34 if (this.standaloneElementDepth == 0) {
65  34 this.hasGroupTopLevelBlock = true;
66    }
67  34 startStandaloneElement();
68  34 super.beginGroup(parameters);
69    }
70   
 
71  12 toggle @Override
72    public void beginHeader(HeaderLevel level, String id, Map<String, String> parameters)
73    {
74  12 startStandaloneElement();
75  12 super.beginHeader(level, id, parameters);
76    }
77   
 
78  20 toggle @Override
79    public void beginParagraph(Map<String, String> parameters)
80    {
81  20 startStandaloneElement();
82  20 super.beginParagraph(parameters);
83    }
84   
 
85  0 toggle @Override
86    public void beginQuotation(Map<String, String> parameters)
87    {
88  0 startStandaloneElement();
89  0 super.beginQuotation(parameters);
90    }
91   
 
92  2 toggle @Override
93    public void beginTable(Map<String, String> parameters)
94    {
95  2 startStandaloneElement();
96  2 super.beginTable(parameters);
97    }
98   
 
99  0 toggle @Override
100    public void beginFigure(Map<String, String> parameters)
101    {
102  0 startStandaloneElement();
103  0 super.beginFigure(parameters);
104    }
105   
 
106  34 toggle @Override
107    public void endGroup(Map<String, String> parameters)
108    {
109  34 super.endGroup(parameters);
110  34 endStandaloneElement();
111    }
112   
 
113  12 toggle @Override
114    public void endHeader(HeaderLevel level, String id, Map<String, String> parameters)
115    {
116  12 super.endHeader(level, id, parameters);
117  12 endStandaloneElement();
118    }
119   
 
120  20 toggle @Override
121    public void endParagraph(Map<String, String> parameters)
122    {
123  20 super.endParagraph(parameters);
124  20 endStandaloneElement();
125    }
126   
 
127  0 toggle @Override
128    public void endQuotation(Map<String, String> parameters)
129    {
130  0 super.endQuotation(parameters);
131  0 endStandaloneElement();
132    }
133   
 
134  2 toggle @Override
135    public void endTable(Map<String, String> parameters)
136    {
137  2 super.endTable(parameters);
138  2 endStandaloneElement();
139    }
140   
 
141  0 toggle @Override
142    public void endFigure(Map<String, String> parameters)
143    {
144  0 super.endFigure(parameters);
145  0 endStandaloneElement();
146    }
147   
148    /**
149    * Handle start of a standalone element and update states.
150    */
 
151  78 toggle protected void startStandaloneElement()
152    {
153  78 if (this.standaloneElementDepth == 0) {
154  42 this.standaloneTopLevelElements++;
155    }
156  78 this.standaloneElementDepth++;
157    }
158   
159    /**
160    * Handle end of a standalone element and update states.
161    */
 
162  78 toggle protected void endStandaloneElement()
163    {
164  78 this.standaloneElementDepth--;
165    }
166   
 
167  183 toggle private boolean shouldInsertGroupBlock()
168    {
169  183 return this.standaloneTopLevelElements > 0
170    && !(this.standaloneTopLevelElements == 1 && this.hasGroupTopLevelBlock);
171    }
172   
173    /**
174    * Stop stacking events and move them back to the {@link LookaheadChainingListener} to replay them.
175    */
 
176  330 toggle protected void stopStacking()
177    {
178  330 if (this.isStacking) {
179    // Stop stacking in this listener
180  183 setLookaheadDepth(0);
181  183 this.isStacking = false;
182   
183    // Flush all stacked events BUT flush them in the Lookahead Listener at the beginning of the stack, in order
184    // to replay them and thus not break the ordering of them since there are begin/end methods in
185    // XWikiSyntaxChainingRenderer that will check for the next event (e.g. onNewLine()).
186  183 LookaheadChainingListener listener =
187    (LookaheadChainingListener) getListenerChain().getListener(LookaheadChainingListener.class);
188  183 QueueListener previousEvents = getPreviousEvents();
189  183 if (shouldInsertGroupBlock()) {
190  8 previousEvents.offerFirst(previousEvents.new Event(EventType.BEGIN_GROUP,
191    Collections.emptyMap()));
192    // Note: we need to insert before the last element since that one is the element closing the stacking
193    // (e.g. end item list for a list item) and it's already on the stack.
194  8 previousEvents.add(previousEvents.size() - 1,
195    previousEvents.new Event(EventType.END_GROUP, Collections.emptyMap()));
196    }
197  183 listener.transferStart(previousEvents);
198    }
199    }
200    }