1 /////////////////////////////////////////////////////////////////////////////////////////////// 2 // checkstyle: Checks Java source code and other text files for adherence to a set of rules. 3 // Copyright (C) 2001-2024 the original author or authors. 4 // 5 // This library is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 2.1 of the License, or (at your option) any later version. 9 // 10 // This library 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 library; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 /////////////////////////////////////////////////////////////////////////////////////////////// 19 20 package com.puppycrawl.tools.checkstyle.site; 21 22 import java.io.PrintWriter; 23 import java.io.Writer; 24 import java.util.regex.Pattern; 25 26 import javax.swing.text.MutableAttributeSet; 27 28 import org.apache.maven.doxia.markup.HtmlMarkup; 29 import org.apache.maven.doxia.module.xdoc.XdocSink; 30 import org.apache.maven.doxia.sink.SinkEventAttributes; 31 import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; 32 33 /** 34 * A sink for Checkstyle's xdoc templates. 35 * This module will be removed once 36 * <a href="https://github.com/checkstyle/checkstyle/issues/13426">#13426</a> is resolved. 37 * 38 * @see <a href="https://maven.apache.org/doxia/doxia/doxia-sink-api">Doxia Sink API</a> 39 */ 40 public class XdocsTemplateSink extends XdocSink { 41 42 /** Encoding of the writer. */ 43 private final String encoding; 44 45 /** 46 * Create a new instance, initialize the Writer. 47 * 48 * @param writer not null writer to write the result. 49 * @param encoding encoding of the writer. 50 */ 51 public XdocsTemplateSink(Writer writer, String encoding) { 52 super(new CustomPrintWriter(writer)); 53 this.encoding = encoding; 54 } 55 56 /** 57 * Place the XML declaration at the top of the file. 58 */ 59 @Override 60 public void body() { 61 write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>"); 62 writeEOL(); 63 } 64 65 /** 66 * Place a newline at the end of the file, flush the writer, and reset the sink. 67 */ 68 @Override 69 public void body_() { 70 writeEOL(); 71 flush(); 72 init(); 73 } 74 75 /** 76 * Write an external link. We override this method because the default implementation 77 * adds a {@code class="external-link"} attribute to the link which we don't want. 78 * 79 * @param href the link. 80 */ 81 @Override 82 public void link(String href) { 83 final MutableAttributeSet attributes = new SinkEventAttributeSet(); 84 attributes.addAttribute(SinkEventAttributes.HREF, href); 85 writeStartTag(HtmlMarkup.A, attributes); 86 } 87 88 /** 89 * Write a table row tag. We override this method because the default implementation 90 * adds a {@code align="top"} attribute to the row which we don't want. 91 */ 92 @Override 93 public void tableRow() { 94 writeStartTag(TR); 95 } 96 97 /** 98 * Write a table tag. We override this method because the default implementation 99 * adds different attributes which we don't want. We ignore the parameters 100 * because we don't need them, but the default implementation will take them 101 * into account once this class is removed. 102 * 103 * @param justification ignored 104 * @param grid ignored 105 */ 106 @Override 107 public void tableRows(int[] justification, boolean grid) { 108 writeStartTag(HtmlMarkup.TABLE); 109 } 110 111 /** 112 * A Custom writer that only prints Unix-style newline character. 113 */ 114 private static final class CustomPrintWriter extends PrintWriter { 115 116 /** A Regex pattern to represent all kinds of newline character. */ 117 private static final Pattern LINE_BREAK_ESCAPE = Pattern.compile("\\R"); 118 119 /** Unix-Style newline character. */ 120 private static final String NEWLINE = "\n"; 121 122 /** 123 * Creates a new instance of this custom writer. 124 * 125 * @param writer not null writer to write the result 126 */ 127 private CustomPrintWriter(Writer writer) { 128 super(writer); 129 } 130 131 /** 132 * Enforces Unix-style newline character. 133 */ 134 @Override 135 public void println() { 136 write(NEWLINE, 0, NEWLINE.length()); 137 } 138 139 /** 140 * Unifies all newline characters to Unix-Style Newline character. 141 * 142 * @param line text that is to be written in the output file. 143 * @param offset starting offset value for writing data. 144 * @param length total length of string to be written. 145 */ 146 @Override 147 public void write(String line, int offset, int length) { 148 final String lineBreakReplacedLine = 149 LINE_BREAK_ESCAPE.matcher(line).replaceAll(NEWLINE); 150 super.write(lineBreakReplacedLine, 0, lineBreakReplacedLine.length()); 151 } 152 } 153 }