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

File XWikiSerializer2.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart0.png
83% of files have more coverage

Code metrics

62
209
48
4
652
470
83
0.4
4.35
12
1.73

Classes

Class Line # Actions
XWikiSerializer2 53 197 0% 74 297
0.00%
XWikiSerializer2.ListOrdering 568 0 - 0 0
-1.0 -
XWikiSerializer2.XWiki2ReferenzeHandler 577 8 0% 5 14
0.00%
XWikiSerializer2.Table 614 4 0% 4 8
0.00%
 

Contributing tests

No tests hitting this source file were found.

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.xwiki.xwiki20;
21   
22    import java.util.ArrayDeque;
23    import java.util.Deque;
24    import java.util.Stack;
25    import java.util.logging.Logger;
26   
27    import org.xwiki.rendering.wikimodel.IWemConstants;
28    import org.xwiki.rendering.wikimodel.IWikiPrinter;
29    import org.xwiki.rendering.wikimodel.PrintTextListener;
30    import org.xwiki.rendering.wikimodel.ReferenceHandler;
31    import org.xwiki.rendering.wikimodel.WikiFormat;
32    import org.xwiki.rendering.wikimodel.WikiPageUtil;
33    import org.xwiki.rendering.wikimodel.WikiParameter;
34    import org.xwiki.rendering.wikimodel.WikiParameters;
35    import org.xwiki.rendering.wikimodel.WikiReference;
36   
37    /**
38    * Serializing XWiki 2.0 syntax ... <br>
39    * <br>
40    * Implementation hints:
41    * <ul>
42    * <li>This serializer is only tested with transformed MediaWiki sources</li>
43    * <li>To support nested tables, we're using a stack of tables.</li>
44    * <li>To get the table caption in front of a table definition, we're using a
45    * simple model for, see nested Table class</li>
46    * <li>Nested definition lists are NOT supported</li>
47    * </ul>
48    *
49    * @version $Id: 63b78ed902bdce385b9d42889e6be4ad86bb7ca3 $
50    * @since 4.0M1
51    * @see org.xwiki.rendering.wikimodel.xwiki.xwiki10.XWikiSerializer
52    */
 
53    public class XWikiSerializer2 extends PrintTextListener
54    {
55    private static final String[] HEADERS = {"", "=", "==", "===", "====", "=====", "======"};
56   
57    private Deque<ListOrdering> listOrdering = new ArrayDeque<ListOrdering>();
58   
59    private Stack<Table> tables = new Stack<Table>();
60   
61    private boolean listItemWritten = false;
62   
63    private boolean firstTableRow = false;
64   
65    private boolean withinTableCell = false;
66   
67    private Logger logger;
68   
 
69  0 toggle public XWikiSerializer2(IWikiPrinter printer)
70    {
71  0 super(printer);
72  0 logger = Logger.getLogger(this.getClass().getCanonicalName());
73    }
74   
75    // ------------------------------------------------------------------------
76   
 
77  0 toggle @Override
78    public void beginHeader(int headerLevel, WikiParameters params)
79    {
80  0 println();
81  0 print(HEADERS[headerLevel] + " ");
82    }
83   
 
84  0 toggle @Override
85    public void endHeader(int headerLevel, WikiParameters params)
86    {
87  0 print(" " + HEADERS[headerLevel]);
88  0 println();
89    }
90   
91    // ------------------------------------------------------------------------
92   
 
93  0 toggle @Override
94    public void beginList(WikiParameters params, boolean ordered)
95    {
96  0 if (ordered) {
97  0 listOrdering.push(ListOrdering.ORDERED);
98    } else {
99  0 listOrdering.push(ListOrdering.UNORDERED);
100    }
101  0 if (listItemWritten) { // new line for each new list
102  0 println();
103    }
104    }
105   
 
106  0 toggle @Override
107    public void endList(WikiParameters params, boolean ordered)
108    {
109  0 listOrdering.pop();
110  0 listItemWritten = false;
111    }
112   
 
113  0 toggle @Override
114    public void beginListItem()
115    {
116  0 final ListOrdering[] orders = listOrdering.toArray(new ListOrdering[listOrdering.size()]);
117  0 StringBuilder sb = new StringBuilder();
118  0 boolean isordered = false;
119  0 for (int i = 0; i < orders.length; i++) {
120  0 if (orders[i] == ListOrdering.ORDERED) {
121  0 sb.append("1");
122  0 isordered = true;
123    } else {
124  0 sb.append("*");
125    }
126    }
127  0 if (isordered) {
128  0 sb.append(".");
129    }
130  0 sb.append(" ");
131  0 print(sb.toString());
132  0 listItemWritten = true;
133    }
134   
 
135  0 toggle @Override
136    public void endListItem()
137    {
138  0 if (listItemWritten) { // don't split related lists
139  0 println();
140    }
141    }
142   
143    // ------------------------------------------------------------------------
144   
 
145  0 toggle @Override
146    public void onImage(String ref)
147    {
148  0 throw new UnsupportedOperationException("Not implemented yet!");
149    }
150   
 
151  0 toggle @Override
152    public void onImage(WikiReference ref)
153    {
154  0 WikiParameters params = ref.getParameters();
155  0 final WikiParameter format = params.getParameter("format");
156  0 if (format != null && "thumb".equals(format.getValue())) {
157  0 onImageThumbnail(ref);
158    } else {
159  0 print("[[image:");
160  0 String link = ref.getLink();
161  0 final int dotidx = link.indexOf(':');
162  0 if (dotidx > 0) {
163  0 link = link.substring(dotidx + 1);
164    }
165  0 link = clearName(link);
166  0 print(link);
167    // add title attribute - the easy way ;-)
168  0 if (ref.getLabel() != null) {
169  0 params = params.addParameter("title", ref.getLabel());
170    }
171    // put the parameters
172  0 if (params != null && params.getSize() > 0) {
173    // print parameters ...
174  0 print("||");
175  0 for (int i = 0, len = params.getSize(); i < len; i++) {
176  0 print(" ");
177  0 final WikiParameter param = params.getParameter(i);
178  0 String val = WikiPageUtil.escapeXmlAttribute(param.getValue());
179  0 print(param.getKey() + "=\"" + val + "\"");
180    }
181    }
182  0 print("]]");
183    }
184    }
185   
186    /**
187    * Special case when detected, that there are image thumbnail. Thus it's
188    * possible to insert something like XWiki "LightBox" macro. (Default
189    * implementation will set "width:200px")
190    */
 
191  0 toggle protected void onImageThumbnail(WikiReference ref)
192    {
193  0 WikiParameters params = ref.getParameters();
194  0 final WikiParameter oldstyle = params.getParameter("style");
195  0 if (oldstyle != null) {
196    // remove existing
197  0 params.remove("style");
198  0 params = params.addParameter("style", oldstyle.getValue() + ";" + "float: right; width:"
199    + getImageThumbwidth());
200    } else {
201  0 params = params.addParameter("style", "float: right; width:" + getImageThumbwidth());
202    }
203  0 params = params.remove("format");
204  0 WikiReference newimgref = new WikiReference(ref.getLink(), ref.getLabel(), params);
205  0 onImage(newimgref);
206    }
207   
208    // ------------------------------------------------------------------------
209   
 
210  0 toggle @Override
211    public void onVerbatimBlock(String str, WikiParameters params)
212    {
213  0 print("{{code language=none}}");
214  0 print(str);
215  0 print("{{/code}}");
216    }
217   
 
218  0 toggle @Override
219    public void onVerbatimInline(String str, WikiParameters params)
220    {
221  0 println("{{code language=none}}");
222  0 println(str);
223  0 println("{{/code}}");
224    }
225   
226    // ------------------------------------------------------------------------
227   
 
228  0 toggle @Override
229    public void onTableCaption(String str)
230    {
231  0 tables.peek().setCaption(str);
232    }
233   
 
234  0 toggle @Override
235    public void beginTable(WikiParameters params)
236    {
237  0 Table t = new Table();
238  0 if (params != null && params.getSize() > 0) {
239  0 t.appendText("(% style=\"");
240  0 for (WikiParameter param : params) {
241  0 t.appendText(param.getKey() + ":" + param.getValue() + ";");
242    }
243  0 t.appendText("\" %)");
244  0 t.appendText(getEol());
245    }
246  0 tables.push(t);
247  0 firstTableRow = true;
248    }
249   
 
250  0 toggle @Override
251    public void endTable(WikiParameters params)
252    {
253  0 final Table table = tables.pop();
254  0 if (table.getCaption() != null) {
255  0 print("**");
256  0 print(table.getCaption());
257  0 print("**");
258  0 println();
259    }
260  0 println(table.getText());
261    }
262   
 
263  0 toggle @Override
264    public void beginTableCell(boolean tableHead, WikiParameters params)
265    {
266  0 final Table t = tables.peek();
267  0 if (firstTableRow) {
268  0 t.appendText("|= ");
269    } else {
270  0 t.appendText("| ");
271    }
272  0 withinTableCell = true;
273    }
274   
 
275  0 toggle @Override
276    public void endTableCell(boolean tableHead, WikiParameters params)
277    {
278  0 final Table t = tables.peek();
279  0 t.appendText(" ");
280  0 withinTableCell = false;
281    }
282   
 
283  0 toggle @Override
284    public void beginTableRow(WikiParameters params)
285    {
286    // nothing
287    }
288   
 
289  0 toggle @Override
290    public void endTableRow(WikiParameters params)
291    {
292  0 final Table t = tables.peek();
293  0 t.appendText(getEol());
294  0 firstTableRow = false;
295    }
296   
297    // ------------------------------------------------------------------------
298   
 
299  0 toggle @Override
300    public void beginFormat(WikiFormat format)
301    {
302  0 if (format.hasStyle(IWemConstants.STRONG)) {
303  0 print("**");
304  0 } else if (format.hasStyle(IWemConstants.EM)) {
305  0 print("//");
306  0 } else if (format.hasStyle(IWemConstants.MONO)) {
307  0 print("##");
308  0 } else if (format.hasStyle(IWemConstants.TT)) {
309  0 print("##");
310    } else {
311  0 super.beginFormat(format);
312    }
313    }
314   
 
315  0 toggle @Override
316    public void endFormat(WikiFormat format)
317    {
318  0 if (format.hasStyle(IWemConstants.TT)) {
319  0 print("##");
320  0 } else if (format.hasStyle(IWemConstants.MONO)) {
321  0 print("##");
322  0 } else if (format.hasStyle(IWemConstants.EM)) {
323  0 print("//");
324  0 } else if (format.hasStyle(IWemConstants.STRONG)) {
325  0 print("**");
326    } else {
327  0 super.beginFormat(format);
328    }
329    }
330   
331    // ------------------------------------------------------------------------
332   
 
333  0 toggle @Override
334    public void endParagraph(WikiParameters params)
335    {
336  0 println();
337  0 println();
338    }
339   
 
340  0 toggle @Override
341    protected void endBlock()
342    {
343  0 println();
344    }
345   
 
346  0 toggle protected String getEol()
347    {
348  0 return "\n";
349    }
350   
 
351  0 toggle @Override
352    public void onLineBreak()
353    {
354  0 print("\\\\");
355    }
356   
 
357  0 toggle @Override
358    public void onNewLine()
359    {
360  0 super.onNewLine();
361    }
362   
 
363  0 toggle @Override
364    public void onSpecialSymbol(String str)
365    {
366  0 if (withinTableCell && "|".equals(str)) {
367  0 print("~");
368    }
369  0 print(str);
370    }
371   
372    // ------------------------------------------------------------------------
373   
 
374  0 toggle @Override
375    public void beginDefinitionTerm()
376    {
377  0 print("; ");
378    }
379   
 
380  0 toggle @Override
381    public void endDefinitionTerm()
382    {
383  0 println();
384    }
385   
 
386  0 toggle @Override
387    public void beginDefinitionDescription()
388    {
389  0 print(": ");
390    }
391   
 
392  0 toggle @Override
393    public void endDefinitionDescription()
394    {
395  0 println();
396    }
397   
398    /*
399    * ========================================================================
400    */
401   
402    /**
403    * @return The wisth information for a thumbnail image
404    */
 
405  0 toggle protected String getImageThumbwidth()
406    {
407  0 return "200px";
408    }
409   
 
410  0 toggle @Override
411    protected void print(String str)
412    {
413  0 if (!tables.isEmpty()) {
414  0 tables.peek().appendText(str);
415    } else {
416  0 super.print(str);
417    }
418    }
419   
 
420  0 toggle @Override
421    protected void println()
422    {
423  0 if (!tables.isEmpty()) {
424  0 tables.peek().appendText(getEol());
425    } else {
426  0 super.println();
427    }
428    }
429   
 
430  0 toggle @Override
431    protected void println(String str)
432    {
433  0 if (!tables.isEmpty()) {
434  0 tables.peek().appendText(str + getEol());
435    } else {
436  0 super.println(str);
437    }
438    }
439   
440    /*
441    * (non-Javadoc)
442    *
443    * @see PrintTextListener#newReferenceHandler()
444    */
 
445  0 toggle @Override
446    protected ReferenceHandler newReferenceHandler()
447    {
448  0 return new XWiki2ReferenzeHandler();
449    }
450   
451    /*
452    * ========================================================================
453    */
454   
455    /**
456    * @return the logger
457    */
 
458  0 toggle public Logger getLogger()
459    {
460  0 return logger;
461    }
462   
463    /**
464    * @param logger the logger to set
465    */
 
466  0 toggle public void setLogger(Logger logger)
467    {
468  0 this.logger = logger;
469    }
470   
471    /**
472    * @see #clearName(String)
473    */
 
474  0 toggle public final static String clearName(String name, boolean stripDots, boolean ascii)
475    {
476  0 String temp = name;
477  0 temp = temp.replaceAll(
478    "[\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u0100\u0102\u0104\u01cd\u01de\u01e0\u01fa\u0200\u0202\u0226]", "A");
479  0 temp = temp.replaceAll(
480    "[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u0101\u0103\u0105\u01ce\u01df\u01e1\u01fb\u0201\u0203\u0227]", "a");
481  0 temp = temp.replaceAll("[\u00c6\u01e2\u01fc]", "AE");
482  0 temp = temp.replaceAll("[\u00e6\u01e3\u01fd]", "ae");
483  0 temp = temp.replaceAll("[\u008c\u0152]", "OE");
484  0 temp = temp.replaceAll("[\u009c\u0153]", "oe");
485  0 temp = temp.replaceAll("[\u00c7\u0106\u0108\u010a\u010c]", "C");
486  0 temp = temp.replaceAll("[\u00e7\u0107\u0109\u010b\u010d]", "c");
487  0 temp = temp.replaceAll("[\u00d0\u010e\u0110]", "D");
488  0 temp = temp.replaceAll("[\u00f0\u010f\u0111]", "d");
489  0 temp = temp.replaceAll("[\u00c8\u00c9\u00ca\u00cb\u0112\u0114\u0116\u0118\u011a\u0204\u0206\u0228]", "E");
490  0 temp = temp.replaceAll("[\u00e8\u00e9\u00ea\u00eb\u0113\u0115\u0117\u0119\u011b\u01dd\u0205\u0207\u0229]", "e");
491  0 temp = temp.replaceAll("[\u011c\u011e\u0120\u0122\u01e4\u01e6\u01f4]", "G");
492  0 temp = temp.replaceAll("[\u011d\u011f\u0121\u0123\u01e5\u01e7\u01f5]", "g");
493  0 temp = temp.replaceAll("[\u0124\u0126\u021e]", "H");
494  0 temp = temp.replaceAll("[\u0125\u0127\u021f]", "h");
495  0 temp = temp.replaceAll("[\u00cc\u00cd\u00ce\u00cf\u0128\u012a\u012c\u012e\u0130\u01cf\u0208\u020a]", "I");
496  0 temp = temp.replaceAll("[\u00ec\u00ed\u00ee\u00ef\u0129\u012b\u012d\u012f\u0131\u01d0\u0209\u020b]", "i");
497  0 temp = temp.replaceAll("[\u0132]", "IJ");
498  0 temp = temp.replaceAll("[\u0133]", "ij");
499  0 temp = temp.replaceAll("[\u0134]", "J");
500  0 temp = temp.replaceAll("[\u0135]", "j");
501  0 temp = temp.replaceAll("[\u0136\u01e8]", "K");
502  0 temp = temp.replaceAll("[\u0137\u0138\u01e9]", "k");
503  0 temp = temp.replaceAll("[\u0139\u013b\u013d\u013f\u0141]", "L");
504  0 temp = temp.replaceAll("[\u013a\u013c\u013e\u0140\u0142\u0234]", "l");
505  0 temp = temp.replaceAll("[\u00d1\u0143\u0145\u0147\u014a\u01f8]", "N");
506  0 temp = temp.replaceAll("[\u00f1\u0144\u0146\u0148\u0149\u014b\u01f9\u0235]", "n");
507  0 temp = temp.replaceAll(
508    "[\u00d2\u00d3\u00d4\u00d5\u00d6\u00d8\u014c\u014e\u0150\u01d1\u01ea\u01ec\u01fe\u020c\u020e\u022a\u022c"
509    + "\u022e\u0230]", "O");
510  0 temp = temp.replaceAll(
511    "[\u00f2\u00f3\u00f4\u00f5\u00f6\u00f8\u014d\u014f\u0151\u01d2\u01eb\u01ed\u01ff\u020d\u020f\u022b\u022d"
512    + "\u022f\u0231]", "o");
513  0 temp = temp.replaceAll("[\u0156\u0158\u0210\u0212]", "R");
514  0 temp = temp.replaceAll("[\u0157\u0159\u0211\u0213]", "r");
515  0 temp = temp.replaceAll("[\u015a\u015c\u015e\u0160\u0218]", "S");
516  0 temp = temp.replaceAll("[\u015b\u015d\u015f\u0161\u0219]", "s");
517  0 temp = temp.replaceAll("[\u00de\u0162\u0164\u0166\u021a]", "T");
518  0 temp = temp.replaceAll("[\u00fe\u0163\u0165\u0167\u021b\u0236]", "t");
519  0 temp = temp.replaceAll(
520    "[\u00d9\u00da\u00db\u00dc\u0168\u016a\u016c\u016e\u0170\u0172\u01d3\u01d5\u01d7\u01d9\u01db\u0214\u0216]",
521    "U");
522  0 temp = temp.replaceAll(
523    "[\u00f9\u00fa\u00fb\u00fc\u0169\u016b\u016d\u016f\u0171\u0173\u01d4\u01d6\u01d8\u01da\u01dc\u0215\u0217]",
524    "u");
525  0 temp = temp.replaceAll("[\u0174]", "W");
526  0 temp = temp.replaceAll("[\u0175]", "w");
527  0 temp = temp.replaceAll("[\u00dd\u0176\u0178\u0232]", "Y");
528  0 temp = temp.replaceAll("[\u00fd\u00ff\u0177\u0233]", "y");
529  0 temp = temp.replaceAll("[\u0179\u017b\u017d]", "Z");
530  0 temp = temp.replaceAll("[\u017a\u017c\u017e]", "z");
531  0 temp = temp.replaceAll("[\u00df]", "SS");
532  0 temp = temp.replaceAll("[_':,;\\\\/]", " ");
533  0 name = temp;
534  0 name = name.replaceAll("\\s+", "");
535  0 name = name.replaceAll("[\\(\\)]", " ");
536   
537  0 if (stripDots) {
538  0 name = name.replaceAll("[\\.]", "");
539    }
540   
541  0 if (ascii) {
542  0 name = name.replaceAll("[^a-zA-Z0-9\\-_\\.]", "");
543    }
544   
545  0 if (name.length() > 250) {
546  0 name = name.substring(0, 250);
547    }
548   
549  0 return name;
550    }
551   
552    /**
553    * Clears the name of files; used while uploading attachments within XWiki
554    *
555    * RECOMMENDED FOR NAMES OF UPLOADED FILES. (boolean stripDots = false;
556    * boolean ascii = true;)
557    */
 
558  0 toggle public final static String clearName(String name)
559    {
560  0 boolean stripDots = false;
561  0 boolean ascii = true;
562  0 return clearName(name, stripDots, ascii);
563    }
564   
565    /*
566    * ========================================================================
567    */
 
568    private enum ListOrdering
569    {
570    ORDERED, UNORDERED
571    }
572   
573    /*
574    * ========================================================================
575    */
576   
 
577    private class XWiki2ReferenzeHandler extends ReferenceHandler
578    {
 
579  0 toggle XWiki2ReferenzeHandler()
580    {
581  0 this(false, false);
582    }
583   
 
584  0 toggle protected XWiki2ReferenzeHandler(boolean supportImage, boolean supportDownload)
585    {
586  0 super(supportImage, supportDownload);
587    }
588   
 
589  0 toggle @Override
590    protected void handleImage(String ref, String label, WikiParameters params)
591    {
592  0 handleReference("image:" + ref, label, params); // TODO: testing ...
593    }
594   
 
595  0 toggle @Override
596    protected void handleReference(String ref, String label, WikiParameters params)
597    {
598  0 print("[[");
599  0 if (label != null) {
600  0 print(label + ">>");
601    }
602  0 print(ref);
603  0 print("]]");
604    }
605    }
606   
607    /*
608    * ========================================================================
609    */
610   
611    /**
612    * Workaround to put a caption in front of a table.
613    */
 
614    private static class Table
615    {
616    private StringBuilder text = new StringBuilder();
617   
618    private String caption;
619   
620    /**
621    * @param caption the caption to set
622    */
 
623  0 toggle public void setCaption(String caption)
624    {
625  0 this.caption = caption;
626    }
627   
628    /**
629    * @see java.lang.StringBuilder#append(java.lang.CharSequence)
630    */
 
631  0 toggle public StringBuilder appendText(CharSequence s)
632    {
633  0 return text.append(s);
634    }
635   
636    /**
637    * @see java.lang.StringBuilder#toString()
638    */
 
639  0 toggle public String getText()
640    {
641  0 return text.toString();
642    }
643   
644    /**
645    * @return the caption
646    */
 
647  0 toggle public String getCaption()
648    {
649  0 return caption;
650    }
651    }
652    }