ViolationMessagesMacro.java
///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code and other text files for adherence to a set of rules.
// Copyright (C) 2001-2024 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
///////////////////////////////////////////////////////////////////////////////////////////////
package com.puppycrawl.tools.checkstyle.site;
import java.util.Set;
import org.apache.maven.doxia.macro.AbstractMacro;
import org.apache.maven.doxia.macro.Macro;
import org.apache.maven.doxia.macro.MacroExecutionException;
import org.apache.maven.doxia.macro.MacroRequest;
import org.apache.maven.doxia.module.xdoc.XdocSink;
import org.apache.maven.doxia.sink.Sink;
import org.codehaus.plexus.component.annotations.Component;
/**
* A macro that inserts a list of the violation messages.
*/
@Component(role = Macro.class, hint = "violation-messages")
public class ViolationMessagesMacro extends AbstractMacro {
@Override
public void execute(Sink sink, MacroRequest request) throws MacroExecutionException {
// until https://github.com/checkstyle/checkstyle/issues/13426
if (!(sink instanceof XdocSink)) {
throw new MacroExecutionException("Expected Sink to be an XdocSink.");
}
final String checkName = (String) request.getParameter("checkName");
final Object instance = SiteUtil.getModuleInstance(checkName);
final Class<?> clss = instance.getClass();
final Set<String> messageKeys = SiteUtil.getMessageKeys(clss);
createListOfMessages((XdocSink) sink, clss, messageKeys);
}
/**
* Iterates through the fields of the class and creates an unordered list.
*
* @param sink the sink to write to.
* @param clss the class of the fields.
* @param messageKeys the List of message keys to iterate through.
*/
private static void createListOfMessages(
XdocSink sink, Class<?> clss, Set<String> messageKeys) {
final String indentLevel8 = SiteUtil.getNewlineAndIndentSpaces(8);
// This is a hack to prevent a newline from being inserted by the default sink.
// Once we get rid of the custom parser, we can remove this.
// until https://github.com/checkstyle/checkstyle/issues/13426
sink.setInsertNewline(false);
sink.list();
sink.setInsertNewline(true);
for (String messageKey : messageKeys) {
createListItem(sink, clss, messageKey);
}
sink.rawText(indentLevel8);
sink.list_();
}
/**
* Creates a list item for the given field.
*
* @param sink the sink to write to.
* @param clss the class of the field.
* @param messageKey the message key.
*/
private static void createListItem(XdocSink sink, Class<?> clss, String messageKey) {
final String messageKeyUrl = constructMessageKeyUrl(clss, messageKey);
final String indentLevel10 = SiteUtil.getNewlineAndIndentSpaces(10);
final String indentLevel12 = SiteUtil.getNewlineAndIndentSpaces(12);
final String indentLevel14 = SiteUtil.getNewlineAndIndentSpaces(14);
// Place the <li>.
sink.rawText(indentLevel10);
// This is a hack to prevent a newline from being inserted by the default sink.
// Once we get rid of the custom parser, we can remove this.
// until https://github.com/checkstyle/checkstyle/issues/13426
sink.setInsertNewline(false);
sink.listItem();
sink.setInsertNewline(true);
// Place an <a>.
sink.rawText(indentLevel12);
sink.link(messageKeyUrl);
// Further indent the text.
sink.rawText(indentLevel14);
sink.rawText(messageKey);
// Place closing </a> and </li> tags.
sink.rawText(indentLevel12);
sink.link_();
sink.rawText(indentLevel10);
sink.listItem_();
}
/**
* Constructs a URL to GitHub that searches for the message key.
*
* @param clss the class of the module.
* @param messageKey the message key.
* @return the URL to GitHub.
*/
private static String constructMessageKeyUrl(Class<?> clss, String messageKey) {
return "https://github.com/search?q="
+ "path%3Asrc%2Fmain%2Fresources%2F"
+ clss.getPackage().getName().replace(".", "%2F")
+ "%20path%3A**%2Fmessages*.properties+repo%3Acheckstyle%2F"
+ "checkstyle+%22" + messageKey + "%22";
}
}