001/////////////////////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code and other text files for adherence to a set of rules. 003// Copyright (C) 2001-2024 the original author or authors. 004// 005// This library is free software; you can redistribute it and/or 006// modify it under the terms of the GNU Lesser General Public 007// License as published by the Free Software Foundation; either 008// version 2.1 of the License, or (at your option) any later version. 009// 010// This library is distributed in the hope that it will be useful, 011// but WITHOUT ANY WARRANTY; without even the implied warranty of 012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013// Lesser General Public License for more details. 014// 015// You should have received a copy of the GNU Lesser General Public 016// License along with this library; if not, write to the Free Software 017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 018/////////////////////////////////////////////////////////////////////////////////////////////// 019 020package com.puppycrawl.tools.checkstyle.site; 021 022import java.io.PrintWriter; 023import java.io.Writer; 024import java.util.regex.Pattern; 025 026import javax.swing.text.MutableAttributeSet; 027 028import org.apache.maven.doxia.markup.HtmlMarkup; 029import org.apache.maven.doxia.module.xdoc.XdocSink; 030import org.apache.maven.doxia.sink.SinkEventAttributes; 031import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet; 032 033/** 034 * A sink for Checkstyle's xdoc templates. 035 * This module will be removed once 036 * <a href="https://github.com/checkstyle/checkstyle/issues/13426">#13426</a> is resolved. 037 * 038 * @see <a href="https://maven.apache.org/doxia/doxia/doxia-sink-api">Doxia Sink API</a> 039 */ 040public class XdocsTemplateSink extends XdocSink { 041 042 /** Encoding of the writer. */ 043 private final String encoding; 044 045 /** 046 * Create a new instance, initialize the Writer. 047 * 048 * @param writer not null writer to write the result. 049 * @param encoding encoding of the writer. 050 */ 051 public XdocsTemplateSink(Writer writer, String encoding) { 052 super(new CustomPrintWriter(writer)); 053 this.encoding = encoding; 054 } 055 056 /** 057 * Place the XML declaration at the top of the file. 058 */ 059 @Override 060 public void body() { 061 write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>"); 062 writeEOL(); 063 } 064 065 /** 066 * Place a newline at the end of the file, flush the writer, and reset the sink. 067 */ 068 @Override 069 public void body_() { 070 writeEOL(); 071 flush(); 072 init(); 073 } 074 075 /** 076 * Write an external link. We override this method because the default implementation 077 * adds a {@code class="external-link"} attribute to the link which we don't want. 078 * 079 * @param href the link. 080 */ 081 @Override 082 public void link(String href) { 083 final MutableAttributeSet attributes = new SinkEventAttributeSet(); 084 attributes.addAttribute(SinkEventAttributes.HREF, href); 085 writeStartTag(HtmlMarkup.A, attributes); 086 } 087 088 /** 089 * Write a table row tag. We override this method because the default implementation 090 * adds a {@code align="top"} attribute to the row which we don't want. 091 */ 092 @Override 093 public void tableRow() { 094 writeStartTag(TR); 095 } 096 097 /** 098 * Write a table tag. We override this method because the default implementation 099 * 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}