1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package org.xwiki.rendering.internal.parser.xhtml.wikimodel

File XHTMLXWikiGeneratorListener.java

 

Coverage histogram

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

Code metrics

30
76
11
1
281
169
32
0.42
6.91
11
2.91

Classes

Class Line # Actions
XHTMLXWikiGeneratorListener 48 76 0% 32 4
0.9658119796.6%
 

Contributing tests

This file is covered by 332 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.xhtml.wikimodel;
21   
22    import java.util.Map;
23    import java.util.regex.Matcher;
24    import java.util.regex.Pattern;
25   
26    import org.apache.commons.lang3.tuple.Pair;
27    import org.xwiki.rendering.internal.parser.wikimodel.DefaultXWikiGeneratorListener;
28    import org.xwiki.rendering.listener.Listener;
29    import org.xwiki.rendering.listener.MetaData;
30    import org.xwiki.rendering.listener.reference.ResourceReference;
31    import org.xwiki.rendering.listener.reference.ResourceType;
32    import org.xwiki.rendering.parser.ResourceReferenceParser;
33    import org.xwiki.rendering.parser.StreamParser;
34    import org.xwiki.rendering.renderer.PrintRendererFactory;
35    import org.xwiki.rendering.syntax.Syntax;
36    import org.xwiki.rendering.util.IdGenerator;
37    import org.xwiki.rendering.wikimodel.WikiFormat;
38    import org.xwiki.rendering.wikimodel.WikiParameter;
39    import org.xwiki.rendering.wikimodel.WikiParameters;
40    import org.xwiki.rendering.wikimodel.WikiReference;
41   
42    /**
43    * WikiModel listener bridge for the XHTML Syntax.
44    *
45    * @version $Id: b4eac3622e1120363cc55199b40e4f8e9993cdc8 $
46    * @since 2.5RC1
47    */
 
48    public class XHTMLXWikiGeneratorListener extends DefaultXWikiGeneratorListener
49    {
50    /**
51    * Defines the class to use when an element represents a MetaData block.
52    *
53    * @since 10.9
54    */
55    public static final String METADATA_CONTAINER_CLASS = "xwiki-metadata-container";
56   
57    /**
58    * Defines the prefix to use for attribute which contain a metadata.
59    *
60    * @since 10.9
61    */
62    public static final String METADATA_ATTRIBUTE_PREFIX = "data-xwiki-";
63   
64    /**
65    * URL matching pattern.
66    */
67    private static final Pattern URL_SCHEME_PATTERN = Pattern.compile("[a-zA-Z0-9+.-]*://");
68   
69    private static final String CLASS_ATTRIBUTE = "class";
70   
71    /**
72    * @param parser the parser to use to parse link labels
73    * @param listener the XWiki listener to which to forward WikiModel events
74    * @param linkReferenceParser the parser to parse link references
75    * @param imageReferenceParser the parser to parse image references
76    * @param plainRendererFactory used to generate header ids
77    * @param idGenerator used to generate header ids
78    * @param syntax the syntax of the parsed source
79    * @since 3.0M3
80    */
 
81  422 toggle public XHTMLXWikiGeneratorListener(StreamParser parser, Listener listener,
82    ResourceReferenceParser linkReferenceParser, ResourceReferenceParser imageReferenceParser,
83    PrintRendererFactory plainRendererFactory, IdGenerator idGenerator, Syntax syntax)
84    {
85  422 super(parser, listener, linkReferenceParser, imageReferenceParser, plainRendererFactory, idGenerator, syntax);
86    }
87   
 
88  74 toggle @Override
89    public void onReference(WikiReference reference)
90    {
91    // We need to handle 2 cases:
92    // - when the passed reference is an instance of XWikiWikiReference, i.e. when a XHTML comment defining a XWiki
93    // link has been specified and the XHTML parser has recognized it and thus is passing a typed reference to us.
94    // - when the passed reference is not an instance of XWikiWikiReference which will happen if there's no special
95    // XHTML comment defining a XWiki link. In this case, we need to figure out what how to consider the passed
96    // reference.
97   
98  74 ResourceReference resourceReference;
99  74 boolean isFreeStanding;
100  74 if (!(reference instanceof XWikiWikiReference)) {
101  17 resourceReference = computeResourceReference(reference.getLink());
102  17 isFreeStanding = false;
103    } else {
104  57 XWikiWikiReference xwikiReference = (XWikiWikiReference) reference;
105  57 resourceReference = xwikiReference.getReference();
106  57 isFreeStanding = xwikiReference.isFreeStanding();
107   
108  57 flushFormat();
109    }
110   
111    // Consider query string and anchor as ResourceReference parameters and the rest as generic parameters
112  74 Pair<Map<String, String>, Map<String, String>> parameters =
113    convertAndSeparateParameters(reference.getParameters());
114   
115  74 resourceReference.setParameters(parameters.getLeft());
116  74 onReference(resourceReference, reference.getLabel(), isFreeStanding, parameters.getRight(), false);
117    }
118   
 
119  29 toggle @Override
120    public void onImage(WikiReference reference)
121    {
122    // We need to handle 2 cases:
123    // - when the passed reference is an instance of XWikiWikiReference, i.e. when a XHTML comment defining a XWiki
124    // image has been specified
125    // - when the passed reference is not an instance of XWikiWikiReference which will happen if there's no special
126    // XHTML comment defining a XWiki image
127  29 if (!(reference instanceof XWikiWikiReference)) {
128  6 super.onImage(reference);
129    } else {
130  23 XWikiWikiReference xwikiReference = (XWikiWikiReference) reference;
131  23 ResourceReference resourceReference = xwikiReference.getReference();
132   
133  23 flushFormat();
134   
135  23 onImage(resourceReference, xwikiReference.isFreeStanding(),
136    convertParameters(xwikiReference.getParameters()));
137    }
138    }
139   
140    /**
141    * Recognize the passed reference and figure out what type of link it should be:
142    * <ul>
143    * <li>UC1: the reference points to a valid URL, we return a reference of type "url",
144    * e.g. {@code http://server/path/reference#anchor}</li>
145    * <li>UC2: the reference is not a valid URL, we return a reference of type "path",
146    * e.g. {@code path/reference#anchor}</li>
147    * </ul>
148    *
149    * @param rawReference the full reference (e.g. "/some/path/something#other")
150    * @return the properly typed {@link ResourceReference} matching the use cases
151    */
 
152  17 toggle private ResourceReference computeResourceReference(String rawReference)
153    {
154  17 ResourceReference reference;
155   
156    // Do we have a valid URL?
157  17 Matcher matcher = URL_SCHEME_PATTERN.matcher(rawReference);
158  17 if (matcher.lookingAt()) {
159    // We have UC1
160  6 reference = new ResourceReference(rawReference, ResourceType.URL);
161    } else {
162    // We have UC2
163  11 reference = new ResourceReference(rawReference, ResourceType.PATH);
164    }
165   
166  17 return reference;
167    }
168   
 
169  1843 toggle static boolean isMetaDataElement(WikiParameters parameters)
170    {
171  1843 return parameters.getParameter(CLASS_ATTRIBUTE) != null
172    && METADATA_CONTAINER_CLASS.equals(parameters.getParameter(CLASS_ATTRIBUTE).getValue());
173    }
174   
 
175  26 toggle static MetaData createMetaData(WikiParameters parameters)
176    {
177  26 MetaData metaData = new MetaData();
178   
179  26 int prefixSize = METADATA_ATTRIBUTE_PREFIX.length();
180  26 for (WikiParameter parameter : parameters) {
181  60 if (parameter.getKey().startsWith(METADATA_ATTRIBUTE_PREFIX)) {
182  34 String metaDataKey = parameter.getKey().substring(prefixSize).toLowerCase();
183  34 metaData.addMetaData(metaDataKey, parameter.getValue());
184    }
185    }
186   
187  26 return metaData;
188    }
189   
 
190  1626 toggle private static WikiParameters cleanParametersFromMetadata(WikiParameters parameters)
191    {
192  1626 WikiParameters wikiParameters = new WikiParameters();
193   
194  1626 for (WikiParameter parameter : parameters) {
195  84 boolean acceptParameter = !(parameter.getKey().startsWith(METADATA_ATTRIBUTE_PREFIX)
196    || (
197    parameter.getKey().equals(CLASS_ATTRIBUTE) && parameter.getValue().equals(METADATA_CONTAINER_CLASS)
198    ));
199  84 if (acceptParameter) {
200  68 wikiParameters = wikiParameters.addParameter(parameter.getKey(), parameter.getValue());
201    }
202    }
203   
204  1626 return wikiParameters;
205    }
206   
 
207  62 toggle @Override
208    protected void beginGroup(WikiParameters parameters)
209    {
210  62 boolean withoutMetadata = true;
211  62 if (isMetaDataElement(parameters)) {
212  3 MetaData metaData = createMetaData(parameters);
213  3 getListener().beginMetaData(metaData);
214  3 withoutMetadata = false;
215    }
216   
217  62 WikiParameters cleanParameters = cleanParametersFromMetadata(parameters);
218  62 if (withoutMetadata || cleanParameters.getSize() > 0) {
219  59 super.beginGroup(cleanParameters);
220    }
221    }
222   
 
223  62 toggle @Override
224    protected void endGroup(WikiParameters parameters)
225    {
226  62 boolean withoutMetadata = true;
227  62 if (isMetaDataElement(parameters)) {
228  3 getListener().endMetaData(createMetaData(parameters));
229  3 withoutMetadata = false;
230    }
231   
232  62 WikiParameters cleanParameters = cleanParametersFromMetadata(parameters);
233  62 if (withoutMetadata || cleanParameters.getSize() > 0) {
234  59 super.endGroup(cleanParameters);
235    }
236    }
237   
 
238  751 toggle @Override
239    public void beginFormat(WikiFormat format)
240    {
241  751 WikiParameters wikiParameters = new WikiParameters(format.getParams());
242   
243  751 boolean withoutMetadata = true;
244  751 if (isMetaDataElement(wikiParameters)) {
245  1 getListener().beginMetaData(createMetaData(wikiParameters));
246  1 withoutMetadata = false;
247    }
248   
249  751 WikiParameters cleanParameters = cleanParametersFromMetadata(wikiParameters);
250  751 if (withoutMetadata || cleanParameters.getSize() > 0 || !format.getStyles().isEmpty()) {
251  750 WikiFormat newFormat = format;
252  750 if (wikiParameters.getSize() != cleanParameters.getSize()) {
253  0 newFormat = format.setParameters(cleanParameters.toList());
254    }
255   
256  750 super.beginFormat(newFormat);
257    }
258    }
259   
 
260  751 toggle @Override
261    public void endFormat(WikiFormat format)
262    {
263  751 WikiParameters wikiParameters = new WikiParameters(format.getParams());
264   
265  751 boolean withoutMetadata = true;
266  751 if (isMetaDataElement(wikiParameters)) {
267  1 getListener().endMetaData(createMetaData(wikiParameters));
268  1 withoutMetadata = false;
269    }
270   
271  751 WikiParameters cleanParameters = cleanParametersFromMetadata(wikiParameters);
272  751 if (withoutMetadata || cleanParameters.getSize() > 0 || !format.getStyles().isEmpty()) {
273  750 WikiFormat newFormat = format;
274  750 if (wikiParameters.getSize() != cleanParameters.getSize()) {
275  0 newFormat = format.setParameters(cleanParameters.toList());
276    }
277   
278  750 super.endFormat(newFormat);
279    }
280    }
281    }