View Javadoc

1   package org.apache.maven.doxia.module.confluence;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.PrintWriter;
23  import java.io.StringWriter;
24  import java.io.Writer;
25  import java.util.Stack;
26  
27  import javax.swing.text.html.HTML.Attribute;
28  
29  import org.apache.maven.doxia.sink.AbstractTextSink;
30  import org.apache.maven.doxia.sink.SinkEventAttributes;
31  import org.apache.maven.doxia.util.HtmlTools;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  /**
35   * Confluence Sink implementation.
36   * <br/>
37   * <b>Note</b>: The encoding used is UTF-8.
38   *
39   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
40   * @version $Id: ConfluenceSink.java 1091053 2011-04-11 12:55:07Z ltheussl $
41   * @since 1.0
42   */
43  public class ConfluenceSink
44      extends AbstractTextSink
45      implements ConfluenceMarkup
46  {
47      /**  The writer to use. */
48      private final PrintWriter out;
49  
50      /**  The writer to use. */
51      private StringWriter writer;
52  
53      /** An indication on if we're in head mode. */
54      private boolean headFlag;
55  
56      private int levelList = 0;
57  
58      /**  listStyles. */
59      private final Stack<String> listStyles;
60  
61      /** An indication on if we're in verbatim box mode. */
62      private boolean verbatimBoxedFlag;
63  
64      /** An indication on if we're in table header mode. */
65      private boolean tableHeaderFlag;
66  
67      /** The link name. */
68      private String linkName;
69  
70      /**
71       * Constructor, initialize the Writer and the variables.
72       *
73       * @param writer not null writer to write the result. <b>Should</b> be an UTF-8 Writer.
74       * You could use <code>newWriter</code> methods from {@link org.codehaus.plexus.util.WriterFactory}.
75       */
76      protected ConfluenceSink( Writer writer )
77      {
78          this.out = new PrintWriter( writer );
79          this.listStyles = new Stack<String>();
80  
81          init();
82      }
83  
84      /** {@inheritDoc} */
85      public void anchor( String name )
86      {
87          write( ANCHOR_START_MARKUP + name + ANCHOR_END_MARKUP );
88      }
89  
90      /** {@inheritDoc} */
91      public void anchor( String name, SinkEventAttributes attributes )
92      {
93          anchor( name );
94      }
95  
96      /**
97       * Not used.
98       * {@inheritDoc}
99       */
100     public void anchor_()
101     {
102         // nop
103     }
104 
105     /**
106      * Not used.
107      * {@inheritDoc}
108      */
109     public void author()
110     {
111         // nop
112     }
113 
114     /** {@inheritDoc} */
115     public void author( SinkEventAttributes attributes )
116     {
117         author();
118     }
119 
120     /**
121      * Not used.
122      * {@inheritDoc}
123      */
124     public void author_()
125     {
126         // nop
127     }
128 
129     /**
130      * Not used.
131      * {@inheritDoc}
132      */
133     public void body()
134     {
135         // nop
136     }
137 
138     /** {@inheritDoc} */
139     public void body( SinkEventAttributes attributes )
140     {
141         body();
142     }
143 
144     /**
145      * Not used.
146      * {@inheritDoc}
147      */
148     public void body_()
149     {
150         // nop
151     }
152 
153     /** {@inheritDoc} */
154     public void bold()
155     {
156         write( BOLD_START_MARKUP );
157     }
158 
159     /** {@inheritDoc} */
160     public void bold_()
161     {
162         write( BOLD_END_MARKUP );
163     }
164 
165     /**
166      * Not used.
167      * {@inheritDoc}
168      */
169     public void comment( String comment )
170     {
171         // nop
172     }
173 
174     /** {@inheritDoc} */
175     public void close()
176     {
177         out.write( writer.toString() );
178         out.close();
179 
180         init();
181     }
182 
183     /**
184      * Not used.
185      * {@inheritDoc}
186      */
187     public void date()
188     {
189         // nop
190     }
191 
192     /** {@inheritDoc} */
193     public void date( SinkEventAttributes attributes )
194     {
195         date();
196     }
197 
198     /**
199      * Not used.
200      * {@inheritDoc}
201      */
202     public void date_()
203     {
204         // nop
205     }
206 
207     /** {@inheritDoc} */
208     public void definedTerm()
209     {
210         write( " " );
211     }
212 
213     /** {@inheritDoc} */
214     public void definedTerm( SinkEventAttributes attributes )
215     {
216         definedTerm();
217     }
218 
219     /**
220      * Not used.
221      * {@inheritDoc}
222      */
223     public void definedTerm_()
224     {
225         // nop
226     }
227 
228     /**
229      * Not used.
230      * {@inheritDoc}
231      */
232     public void definition()
233     {
234         // nop
235     }
236 
237     /**
238      * Not used.
239      * {@inheritDoc}
240      */
241     public void definition( SinkEventAttributes attributes )
242     {
243         // nop
244     }
245 
246     /**
247      * Not used.
248      * {@inheritDoc}
249      */
250     public void definition_()
251     {
252         // nop
253     }
254 
255     /**
256      * Not used.
257      * {@inheritDoc}
258      */
259     public void definitionList()
260     {
261         // nop
262     }
263 
264     /**
265      * Not used.
266      * {@inheritDoc}
267      */
268     public void definitionList( SinkEventAttributes attributes )
269     {
270         // nop
271     }
272 
273     /**
274      * Not used.
275      * {@inheritDoc}
276      */
277     public void definitionList_()
278     {
279         // nop
280     }
281 
282     /**
283      * Not used.
284      * {@inheritDoc}
285      */
286     public void definitionListItem()
287     {
288         // nop
289     }
290 
291     /**
292      * Not used.
293      * {@inheritDoc}
294      */
295     public void definitionListItem( SinkEventAttributes attributes )
296     {
297         // nop
298     }
299 
300     /**
301      * Not used.
302      * {@inheritDoc}
303      */
304     public void definitionListItem_()
305     {
306         // nop
307     }
308 
309     /**
310      * Not used.
311      * {@inheritDoc}
312      */
313     public void figure()
314     {
315         // nop
316     }
317 
318     /** {@inheritDoc} */
319     public void figure( SinkEventAttributes attributes )
320     {
321         figure();
322     }
323 
324     /**
325      * Not used.
326      * {@inheritDoc}
327      */
328     public void figure_()
329     {
330         // nop
331     }
332 
333     /**
334      * Not used.
335      * {@inheritDoc}
336      */
337     public void figureCaption()
338     {
339         // nop
340     }
341 
342     /** {@inheritDoc} */
343     public void figureCaption( SinkEventAttributes attributes )
344     {
345         figureCaption();
346     }
347 
348     /**
349      * Not used.
350      * {@inheritDoc}
351      */
352     public void figureCaption_()
353     {
354         // nop;
355     }
356 
357     /** {@inheritDoc} */
358     public void figureGraphics( String name )
359     {
360         writeEOL();
361         write( FIGURE_START_MARKUP + name + FIGURE_END_MARKUP );
362     }
363 
364     /** {@inheritDoc} */
365     public void figureGraphics( String src, SinkEventAttributes attributes )
366     {
367         figureGraphics( src );
368         if ( attributes != null && attributes.getAttribute( Attribute.ALT.toString() ) != null )
369         {
370             write( attributes.getAttribute( Attribute.ALT.toString() ).toString() );
371             writeEOL( true );
372         }
373     }
374 
375     /** {@inheritDoc} */
376     public void flush()
377     {
378         close();
379         writer.flush();
380     }
381 
382     /** {@inheritDoc} */
383     public void head()
384     {
385         init();
386 
387         headFlag = true;
388     }
389 
390     /** {@inheritDoc} */
391     public void head( SinkEventAttributes attributes )
392     {
393         head();
394     }
395 
396     /** {@inheritDoc} */
397     public void head_()
398     {
399         headFlag = false;
400     }
401 
402     /**
403      * Not used.
404      * {@inheritDoc}
405      */
406     public void horizontalRule()
407     {
408         // nop
409     }
410 
411     /** {@inheritDoc} */
412     public void horizontalRule( SinkEventAttributes attributes )
413     {
414         horizontalRule();
415     }
416 
417     /** {@inheritDoc} */
418     public void italic()
419     {
420         write( ITALIC_START_MARKUP );
421     }
422 
423     /** {@inheritDoc} */
424     public void italic_()
425     {
426         write( ITALIC_END_MARKUP );
427     }
428 
429     /** {@inheritDoc} */
430     public void lineBreak()
431     {
432         write( LINE_BREAK_MARKUP );
433         writeEOL();
434     }
435 
436     /** {@inheritDoc} */
437     public void lineBreak( SinkEventAttributes attributes )
438     {
439         lineBreak();
440     }
441 
442     /** {@inheritDoc} */
443     public void link( String name )
444     {
445         linkName = name;
446     }
447 
448     /** {@inheritDoc} */
449     public void link( String name, SinkEventAttributes attributes )
450     {
451         link( name );
452     }
453 
454     /** {@inheritDoc} */
455     public void link_()
456     {
457         linkName = null;
458         write( LINK_END_MARKUP );
459     }
460 
461     /** {@inheritDoc} */
462     public void list()
463     {
464         if ( !writer.toString().endsWith( EOL + EOL ) )
465         {
466             writeEOL( true );
467         }
468 
469         levelList++;
470     }
471 
472     /** {@inheritDoc} */
473     public void list( SinkEventAttributes attributes )
474     {
475         list();
476     }
477 
478     /** {@inheritDoc} */
479     public void list_()
480     {
481         levelList--;
482     }
483 
484     /** {@inheritDoc} */
485     public void listItem()
486     {
487         write( StringUtils.repeat( "*", levelList ) + " " );
488     }
489 
490     /** {@inheritDoc} */
491     public void listItem( SinkEventAttributes attributes )
492     {
493         listItem();
494     }
495 
496     /** {@inheritDoc} */
497     public void listItem_()
498     {
499         writeEOL( true );
500     }
501 
502     /** {@inheritDoc} */
503     public void monospaced()
504     {
505         write( MONOSPACED_START_MARKUP );
506     }
507 
508     /** {@inheritDoc} */
509     public void monospaced_()
510     {
511         write( MONOSPACED_END_MARKUP );
512     }
513 
514     /**
515      * Not used.
516      * {@inheritDoc}
517      */
518     public void nonBreakingSpace()
519     {
520         // nop
521     }
522 
523     /** {@inheritDoc} */
524     public void numberedList( int numbering )
525     {
526         levelList++;
527 
528         String style;
529         switch ( numbering )
530         {
531             case NUMBERING_UPPER_ALPHA:
532             case NUMBERING_LOWER_ALPHA:
533             case NUMBERING_UPPER_ROMAN:
534             case NUMBERING_LOWER_ROMAN:
535             case NUMBERING_DECIMAL:
536             default:
537                 style = NUMBERING_MARKUP;
538         }
539 
540         listStyles.push( style );
541     }
542 
543     /** {@inheritDoc} */
544     public void numberedList( int numbering, SinkEventAttributes attributes )
545     {
546         numberedList( numbering );
547     }
548 
549     /** {@inheritDoc} */
550     public void numberedList_()
551     {
552         levelList--;
553         listStyles.pop();
554     }
555 
556     /** {@inheritDoc} */
557     public void numberedListItem()
558     {
559         writeEOL( true );
560         String style = listStyles.peek();
561         write( style + SPACE );
562     }
563 
564     /** {@inheritDoc} */
565     public void numberedListItem( SinkEventAttributes attributes )
566     {
567         numberedListItem();
568     }
569 
570     /** {@inheritDoc} */
571     public void numberedListItem_()
572     {
573         writeEOL( true );
574     }
575 
576     /**
577      * Not used.
578      * {@inheritDoc}
579      */
580     public void pageBreak()
581     {
582         // nop
583     }
584 
585     /**
586      * Not used.
587      * {@inheritDoc}
588      */
589     public void paragraph()
590     {
591         // nop
592     }
593 
594     /** {@inheritDoc} */
595     public void paragraph( SinkEventAttributes attributes )
596     {
597         paragraph();
598     }
599 
600     /** {@inheritDoc} */
601     public void paragraph_()
602     {
603         writeEOL( true );
604         writeEOL();
605     }
606 
607     /**
608      * Not used.
609      * {@inheritDoc}
610      */
611     public void rawText( String text )
612     {
613         // nop
614     }
615 
616     /**
617      * Not used.
618      * {@inheritDoc}
619      */
620     public void section( int level, SinkEventAttributes attributes )
621     {
622         // nop
623     }
624 
625     /**
626      * Not used.
627      * {@inheritDoc}
628      */
629     public void section1()
630     {
631         // nop
632     }
633 
634     /**
635      * Not used.
636      * {@inheritDoc}
637      */
638     public void section1_()
639     {
640         // nop
641     }
642 
643     /**
644      * Not used.
645      * {@inheritDoc}
646      */
647     public void section2()
648     {
649         // nop
650     }
651 
652     /**
653      * Not used.
654      * {@inheritDoc}
655      */
656     public void section2_()
657     {
658         // nop
659     }
660 
661     /**
662      * Not used.
663      * {@inheritDoc}
664      */
665     public void section3()
666     {
667         // nop
668     }
669 
670     /**
671      * Not used.
672      * {@inheritDoc}
673      */
674     public void section3_()
675     {
676         // nop
677     }
678 
679     /**
680      * Not used.
681      * {@inheritDoc}
682      */
683     public void section4()
684     {
685         // nop
686     }
687 
688     /**
689      * Not used.
690      * {@inheritDoc}
691      */
692     public void section4_()
693     {
694         // nop
695     }
696 
697     /**
698      * Not used.
699      * {@inheritDoc}
700      */
701     public void section5()
702     {
703         // nop
704     }
705 
706     /**
707      * Not used.
708      * {@inheritDoc}
709      */
710     public void section5_()
711     {
712         // nop
713     }
714 
715     /**
716      * Not used.
717      * {@inheritDoc}
718      */
719     public void section_( int level )
720     {
721         // nop
722     }
723 
724     /**
725      * Not used.
726      * {@inheritDoc}
727      */
728     public void sectionTitle()
729     {
730         // nop
731     }
732 
733     /** {@inheritDoc} */
734     public void sectionTitle( int level, SinkEventAttributes attributes )
735     {
736         if ( level > 0 && level < 6 )
737         {
738             write( "h" + level + ". " );
739         }
740     }
741 
742     /** {@inheritDoc} */
743     public void sectionTitle1()
744     {
745         sectionTitle( 1, null );
746     }
747 
748     /** {@inheritDoc} */
749     public void sectionTitle1_()
750     {
751         sectionTitle_( 1 );
752     }
753 
754     /** {@inheritDoc} */
755     public void sectionTitle2()
756     {
757         sectionTitle( 2, null );
758     }
759 
760     /** {@inheritDoc} */
761     public void sectionTitle2_()
762     {
763         sectionTitle_( 2 );
764     }
765 
766     /** {@inheritDoc} */
767     public void sectionTitle3()
768     {
769         sectionTitle( 3, null );
770     }
771 
772     /** {@inheritDoc} */
773     public void sectionTitle3_()
774     {
775         sectionTitle_( 3 );
776     }
777 
778     /** {@inheritDoc} */
779     public void sectionTitle4()
780     {
781         sectionTitle( 4, null );
782     }
783 
784     /** {@inheritDoc} */
785     public void sectionTitle4_()
786     {
787         sectionTitle_( 4 );
788     }
789 
790     /** {@inheritDoc} */
791     public void sectionTitle5()
792     {
793         sectionTitle( 5, null );
794     }
795 
796     /** {@inheritDoc} */
797     public void sectionTitle5_()
798     {
799         sectionTitle_( 5 );
800     }
801 
802     /**
803      * Not used.
804      * {@inheritDoc}
805      */
806     public void sectionTitle_()
807     {
808         // nop
809     }
810 
811     /** {@inheritDoc} */
812     public void sectionTitle_( int level )
813     {
814         writeEOL( true );
815         writeEOL();
816     }
817 
818     /** {@inheritDoc} */
819     public void table()
820     {
821         // nop
822         writeEOL( true );
823         writeEOL();
824     }
825 
826     /** {@inheritDoc} */
827     public void table( SinkEventAttributes attributes )
828     {
829         table();
830     }
831 
832     /** {@inheritDoc} */
833     public void table_()
834     {
835         writeEOL( true );
836         writeEOL();
837     }
838 
839     /**
840      * Not used.
841      * {@inheritDoc}
842      */
843     public void tableCaption()
844     {
845         // nop
846     }
847 
848     /** {@inheritDoc} */
849     public void tableCaption( SinkEventAttributes attributes )
850     {
851         tableCaption();
852     }
853 
854     /**
855      * Not used.
856      * {@inheritDoc}
857      */
858     public void tableCaption_()
859     {
860         // nop
861     }
862 
863     /** {@inheritDoc} */
864     public void tableCell()
865     {
866         write( " " );
867     }
868 
869     /** {@inheritDoc} */
870     public void tableCell( SinkEventAttributes attributes )
871     {
872         tableCell();
873     }
874 
875     /** {@inheritDoc} */
876     public void tableCell( String width )
877     {
878         tableCell();
879     }
880 
881     /** {@inheritDoc} */
882     public void tableCell_()
883     {
884         write( " " );
885         write( TABLE_CELL_MARKUP );
886     }
887 
888     /** {@inheritDoc} */
889     public void tableHeaderCell()
890     {
891         tableHeaderFlag = true;
892         write( TABLE_CELL_HEADER_START_MARKUP );
893     }
894 
895     /** {@inheritDoc} */
896     public void tableHeaderCell( SinkEventAttributes attributes )
897     {
898         tableHeaderCell();
899     }
900 
901     /** {@inheritDoc} */
902     public void tableHeaderCell( String width )
903     {
904         tableHeaderCell();
905     }
906 
907     /** {@inheritDoc} */
908     public void tableHeaderCell_()
909     {
910         write( TABLE_CELL_HEADER_END_MARKUP );
911     }
912 
913     /** {@inheritDoc} */
914     public void tableRow()
915     {
916         write( TABLE_ROW_MARKUP );
917     }
918 
919     /** {@inheritDoc} */
920     public void tableRow( SinkEventAttributes attributes )
921     {
922         tableRow();
923     }
924 
925     /** {@inheritDoc} */
926     public void tableRow_()
927     {
928         if ( tableHeaderFlag )
929         {
930             tableHeaderFlag = false;
931             write( TABLE_ROW_MARKUP );
932         }
933         writeEOL( true );
934     }
935 
936     /**
937      * Not used.
938      * {@inheritDoc}
939      */
940     public void tableRows( int[] justification, boolean grid )
941     {
942         // nop
943     }
944 
945     /**
946      * Not used.
947      * {@inheritDoc}
948      */
949     public void tableRows_()
950     {
951         // nop
952     }
953 
954     /** {@inheritDoc} */
955     public void text( String text )
956     {
957         if ( headFlag )
958         {
959             return;
960         }
961 
962         if ( linkName != null )
963         {
964             write( LINK_START_MARKUP );
965         }
966 
967         content( text );
968 
969         if ( linkName != null )
970         {
971             write( LINK_MIDDLE_MARKUP + linkName );
972         }
973     }
974 
975     /** {@inheritDoc} */
976     public void text( String text, SinkEventAttributes attributes )
977     {
978         text( text );
979     }
980 
981     /**
982      * Not used.
983      * {@inheritDoc}
984      */
985     public void title()
986     {
987         // nop
988     }
989 
990     /** {@inheritDoc} */
991     public void title( SinkEventAttributes attributes )
992     {
993         title();
994     }
995 
996     /**
997      * Not used.
998      * {@inheritDoc}
999      */
1000     public void title_()
1001     {
1002         // nop
1003     }
1004 
1005     /**
1006      * Not used.
1007      * {@inheritDoc}
1008      */
1009     public void unknown( String name, Object[] requiredParams, SinkEventAttributes attributes )
1010     {
1011         // nop
1012     }
1013 
1014     /** {@inheritDoc} */
1015     public void verbatim( boolean boxed )
1016     {
1017         if ( boxed )
1018         {
1019             verbatimBoxedFlag = true;
1020         }
1021 
1022         if ( verbatimBoxedFlag )
1023         {
1024             write( "{code|borderStyle=solid}" );
1025         }
1026         else
1027         {
1028             write( "{noformat}" );
1029         }
1030         writeEOL( true );
1031     }
1032 
1033     /** {@inheritDoc} */
1034     public void verbatim_()
1035     {
1036         if ( verbatimBoxedFlag )
1037         {
1038             write( "{code}" );
1039         }
1040         else
1041         {
1042             write( "{noformat}" );
1043         }
1044 
1045         writeEOL( true );
1046         writeEOL();
1047     }
1048 
1049     // ----------------------------------------------------------------------
1050     // Private methods
1051     // ----------------------------------------------------------------------
1052 
1053     private void write( String text )
1054     {
1055         writer.write( unifyEOLs( text ) );
1056     }
1057 
1058     /**
1059      * Writes a system EOL.
1060      */
1061     private void writeEOL()
1062     {
1063         write( EOL );
1064     }
1065 
1066     /**
1067      * Writes a system EOL, with or without trim.
1068      */
1069     private void writeEOL( boolean trim )
1070     {
1071         if ( !trim )
1072         {
1073             writeEOL();
1074             return;
1075         }
1076 
1077         String tmp = writer.toString().trim();
1078         writer = new StringWriter();
1079         writer.write( tmp );
1080         write( EOL );
1081     }
1082 
1083     /**
1084      * Write HTML escaped text to output.
1085      *
1086      * @param text The text to write.
1087      */
1088     protected void content( String text )
1089     {
1090         write( escapeHTML( text ) );
1091     }
1092 
1093     /** {@inheritDoc} */
1094     protected void init()
1095     {
1096         super.init();
1097 
1098         this.writer = new StringWriter();
1099         this.headFlag = false;
1100         this.levelList = 0;
1101         this.listStyles.clear();
1102         this.verbatimBoxedFlag = false;
1103         this.tableHeaderFlag = false;
1104         this.linkName = null;
1105     }
1106 
1107     /**
1108      * Forward to HtmlTools.escapeHTML( text ).
1109      *
1110      * @param text the String to escape, may be null
1111      * @return the text escaped, "" if null String input
1112      * @see org.apache.maven.doxia.util.HtmlTools#escapeHTML(String)
1113      */
1114     protected static String escapeHTML( String text )
1115     {
1116         return HtmlTools.escapeHTML( text );
1117     }
1118 }