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

File XhtmlHandler.java

 

Coverage histogram

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

Code metrics

12
86
16
1
311
214
23
0.27
5.38
16
1.44

Classes

Class Line # Actions
XhtmlHandler 74 86 0% 23 5
0.9561403495.6%
 

Contributing tests

This file is covered by 351 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.wikimodel.xhtml.impl;
21   
22    import java.util.ArrayList;
23    import java.util.HashMap;
24    import java.util.List;
25    import java.util.Map;
26   
27    import org.htmlcleaner.BelongsTo;
28    import org.htmlcleaner.CloseTag;
29    import org.htmlcleaner.ContentType;
30    import org.htmlcleaner.Display;
31    import org.htmlcleaner.TagInfo;
32    import org.xml.sax.Attributes;
33    import org.xml.sax.SAXException;
34    import org.xml.sax.ext.Attributes2;
35    import org.xml.sax.ext.LexicalHandler;
36    import org.xml.sax.helpers.DefaultHandler;
37    import org.xwiki.rendering.wikimodel.WikiParameter;
38    import org.xwiki.rendering.wikimodel.WikiParameters;
39    import org.xwiki.rendering.wikimodel.impl.WikiScannerContext;
40    import org.xwiki.rendering.wikimodel.xhtml.handler.BlockTagHandler;
41    import org.xwiki.rendering.wikimodel.xhtml.handler.BoldTagHandler;
42    import org.xwiki.rendering.wikimodel.xhtml.handler.BreakTagHandler;
43    import org.xwiki.rendering.wikimodel.xhtml.handler.CommentHandler;
44    import org.xwiki.rendering.wikimodel.xhtml.handler.DefinitionDescriptionTagHandler;
45    import org.xwiki.rendering.wikimodel.xhtml.handler.DefinitionTermTagHandler;
46    import org.xwiki.rendering.wikimodel.xhtml.handler.DivisionTagHandler;
47    import org.xwiki.rendering.wikimodel.xhtml.handler.HeaderTagHandler;
48    import org.xwiki.rendering.wikimodel.xhtml.handler.HorizontalLineTagHandler;
49    import org.xwiki.rendering.wikimodel.xhtml.handler.ImgTagHandler;
50    import org.xwiki.rendering.wikimodel.xhtml.handler.ItalicTagHandler;
51    import org.xwiki.rendering.wikimodel.xhtml.handler.ListItemTagHandler;
52    import org.xwiki.rendering.wikimodel.xhtml.handler.ListTagHandler;
53    import org.xwiki.rendering.wikimodel.xhtml.handler.ParagraphTagHandler;
54    import org.xwiki.rendering.wikimodel.xhtml.handler.PreserveTagHandler;
55    import org.xwiki.rendering.wikimodel.xhtml.handler.QuoteTagHandler;
56    import org.xwiki.rendering.wikimodel.xhtml.handler.ReferenceTagHandler;
57    import org.xwiki.rendering.wikimodel.xhtml.handler.SpanTagHandler;
58    import org.xwiki.rendering.wikimodel.xhtml.handler.StrikedOutTagHandler;
59    import org.xwiki.rendering.wikimodel.xhtml.handler.SubScriptTagHandler;
60    import org.xwiki.rendering.wikimodel.xhtml.handler.SuperScriptTagHandler;
61    import org.xwiki.rendering.wikimodel.xhtml.handler.TableDataTagHandler;
62    import org.xwiki.rendering.wikimodel.xhtml.handler.TableRowTagHandler;
63    import org.xwiki.rendering.wikimodel.xhtml.handler.TableTagHandler;
64    import org.xwiki.rendering.wikimodel.xhtml.handler.TagHandler;
65    import org.xwiki.rendering.wikimodel.xhtml.handler.TeletypeTagHandler;
66    import org.xwiki.rendering.wikimodel.xhtml.handler.UnderlineTagHandler;
67   
68    /**
69    * SAX2 event and extension handler to parse XHTML into wikimodel events
70    *
71    * @version $Id: 6f850164460aa0d30c2f00c1cda0be1d937d3eab $
72    * @since 4.0M1
73    */
 
74    public class XhtmlHandler extends DefaultHandler implements LexicalHandler
75    {
76    private TagStack fStack;
77   
 
78  0 toggle public XhtmlHandler(
79    WikiScannerContext context,
80    Map<String, TagHandler> extraHandlers)
81    {
82  0 this(context, extraHandlers, new CommentHandler());
83    }
84   
85    /**
86    * @param context
87    */
 
88  433 toggle public XhtmlHandler(
89    WikiScannerContext context,
90    Map<String, TagHandler> extraHandlers,
91    CommentHandler commentHandler)
92    {
93  433 Map<String, TagHandler> handlers = new HashMap<String, TagHandler>();
94   
95    // Prepare default handlers
96  433 handlers.put("p", new ParagraphTagHandler());
97  433 handlers.put("table", new TableTagHandler());
98  433 handlers.put("tr", new TableRowTagHandler());
99  433 TagHandler handler = new TableDataTagHandler();
100  433 handlers.put("td", handler);
101  433 handlers.put("th", handler);
102  433 handler = new ListTagHandler();
103  433 handlers.put("ul", handler);
104  433 handlers.put("ol", handler);
105  433 handlers.put("dl", handler);
106  433 handler = new ListItemTagHandler();
107  433 handlers.put("li", handler);
108  433 handlers.put("dt", new DefinitionTermTagHandler());
109  433 handlers.put("dd", new DefinitionDescriptionTagHandler());
110  433 handler = new HeaderTagHandler();
111  433 handlers.put("h1", handler);
112  433 handlers.put("h2", handler);
113  433 handlers.put("h3", handler);
114  433 handlers.put("h4", handler);
115  433 handlers.put("h5", handler);
116  433 handlers.put("h6", handler);
117  433 handlers.put("hr", new HorizontalLineTagHandler());
118  433 handlers.put("pre", new PreserveTagHandler());
119  433 handlers.put("a", new ReferenceTagHandler());
120  433 handlers.put("img", new ImgTagHandler());
121  433 handler = new BoldTagHandler();
122  433 handlers.put("strong", handler);
123  433 handlers.put("b", handler);
124  433 handler = new UnderlineTagHandler();
125  433 handlers.put("ins", handler);
126  433 handlers.put("u", handler);
127  433 handler = new StrikedOutTagHandler();
128  433 handlers.put("del", handler);
129  433 handlers.put("strike", handler);
130  433 handlers.put("s", handler);
131  433 handler = new ItalicTagHandler();
132  433 handlers.put("em", handler);
133  433 handlers.put("i", handler);
134  433 handlers.put("sup", new SuperScriptTagHandler());
135  433 handlers.put("sub", new SubScriptTagHandler());
136  433 handlers.put("tt", new TeletypeTagHandler());
137  433 handlers.put("br", new BreakTagHandler());
138  433 handlers.put("div", new DivisionTagHandler());
139  433 handler = new QuoteTagHandler();
140  433 handlers.put("blockquote", handler);
141  433 handlers.put("quote", handler);
142  433 handlers.put("span", new SpanTagHandler());
143   
144  433 handler = extraHandlers.get("div");
145  433 if (handler != null) {
146  334 handler = new BlockTagHandler(((BlockTagHandler) handler).getDocumentClass());
147    } else {
148  99 handler = new BlockTagHandler();
149    }
150   
151    // Basic handling of HTML5 block tags
152    // There is no intend here to provide real HTML5 support which deserve its own independent parser,
153    // but only to handle some HTML5 tags like divs to avoid potentially unexpected merging of separate text nodes.
154  433 handlers.put("aside", handler);
155  433 handlers.put("section", handler);
156  433 handlers.put("article", handler);
157  433 handlers.put("main", handler);
158  433 handlers.put("nav", handler);
159  433 handlers.put("details", handler);
160  433 handlers.put("summary", handler);
161  433 handlers.put("figure", handler);
162  433 handlers.put("figcaption", handler);
163  433 handlers.put("header", handler);
164  433 handlers.put("footer", handler);
165   
166    // Prepare extra handlers
167  433 handlers.putAll(extraHandlers);
168   
169    // Initialize the TagStack and handlers
170  433 fStack = new TagStack(context, handlers, commentHandler);
171    }
172   
173    /**
174    * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
175    */
 
176  1118 toggle @Override
177    public void characters(char[] array, int start, int length)
178    throws SAXException
179    {
180  1118 fStack.onCharacters(new String(array, start, length));
181    }
182   
183    /**
184    * @see org.xml.sax.helpers.DefaultHandler#endDocument()
185    */
 
186  433 toggle @Override
187    public void endDocument() throws SAXException
188    {
189  433 TagHandler.sendEmptyLines(fStack);
190  433 fStack.endElement();
191    }
192   
193    /**
194    * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String,
195    * java.lang.String, java.lang.String)
196    */
 
197  2340 toggle @Override
198    public void endElement(String uri, String localName, String qName)
199    throws SAXException
200    {
201  2340 fStack.endElement();
202    }
203   
204    /**
205    * @see org.xml.sax.helpers.DefaultHandler#startDocument()
206    */
 
207  433 toggle @Override
208    public void startDocument() throws SAXException
209    {
210  433 fStack.beginElement(null, null);
211    }
212   
213    /**
214    * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String,
215    * java.lang.String, java.lang.String, org.xml.sax.Attributes)
216    */
 
217  2340 toggle @Override
218    public void startElement(
219    String uri,
220    String localName,
221    String qName,
222    Attributes attributes) throws SAXException
223    {
224  2340 fStack.beginElement(
225    getLocalName(localName, qName, false),
226    getParameters(attributes));
227    }
228   
229    // Lexical handler methods
230   
 
231  303 toggle public void comment(char[] array, int start, int length)
232    throws SAXException
233    {
234  303 fStack.onComment(array, start, length);
235    }
236   
 
237  3 toggle public void endCDATA() throws SAXException
238    {
239    // Nothing to do
240    }
241   
 
242  298 toggle public void endDTD() throws SAXException
243    {
244    // Nothing to do
245    }
246   
 
247  5169 toggle public void endEntity(String arg0) throws SAXException
248    {
249    // Nothing to do
250    }
251   
 
252  3 toggle public void startCDATA() throws SAXException
253    {
254    // Nothing to do
255    }
256   
 
257  298 toggle public void startDTD(String arg0, String arg1, String arg2)
258    throws SAXException
259    {
260    // Nothing to do
261    }
262   
 
263  5169 toggle public void startEntity(String arg0) throws SAXException
264    {
265    // Nothing to do
266    }
267   
 
268  3009 toggle private String getLocalName(
269    String localName,
270    String name,
271    boolean upperCase)
272    {
273  3009 String result = (localName != null && !"".equals(localName))
274    ? localName
275    : name;
276  3009 return upperCase ? result.toUpperCase() : result;
277    }
278   
 
279  2340 toggle private WikiParameters getParameters(Attributes attributes)
280    {
281  2340 List<WikiParameter> params = new ArrayList<WikiParameter>();
282  3009 for (int i = 0; i < attributes.getLength(); i++) {
283  669 String key = getLocalName(attributes.getQName(i), attributes.getLocalName(i), false);
284  669 String value = attributes.getValue(i);
285  669 WikiParameter param = new WikiParameter(key, value);
286   
287    // The XHTML DTD specifies some default value for some attributes.
288    // For example for a TD element
289    // it defines colspan=1 and rowspan=1. Thus we'll get a colspan and
290    // rowspan attribute passed to
291    // the current method even though they are not defined in the source
292    // XHTML content.
293    // However with SAX2 it's possible to check if an attribute is
294    // defined in the source or not using
295    // the Attributes2 class.
296    // See
297    // http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description
298  669 if (attributes instanceof Attributes2) {
299  324 Attributes2 attributes2 = (Attributes2) attributes;
300    // If the attribute is present in the XHTML source file then add
301    // it, otherwise skip it.
302  324 if (attributes2.isSpecified(i)) {
303  324 params.add(param);
304    }
305    } else {
306  345 params.add(param);
307    }
308    }
309  2340 return new WikiParameters(params);
310    }
311    }