001/////////////////////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code and other text files for adherence to a set of rules. 003// Copyright (C) 2001-2026 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 javax.annotation.Nullable; 023 024/** 025 * Represents a single entry in the client-side search index. 026 * 027 * @param title display name 028 * @param url relative URL 029 * @param category category label 030 * @param type document type 031 * @param description short description 032 * @param keywords comma-separated keywords 033 * @param since the version this module/property was introduced (can be empty) 034 * @param weight ranking weight for search results 035 */ 036public record SearchIndexEntry(String title, String url, String category, 037 String type, String description, String keywords, 038 String since, int weight) { 039 040 /** String literal for comma. */ 041 private static final String COMMA = ","; 042 043 /** Maximum ASCII value for the lookup table. */ 044 private static final int ASCII_MAX = 128; 045 046 /** Lookup table for JSON escape sequences for characters < 128 (ASCII range). */ 047 private static final String[] JSON_ESCAPES; 048 049 static { 050 JSON_ESCAPES = new String[ASCII_MAX]; 051 JSON_ESCAPES['\\'] = "\\\\"; 052 JSON_ESCAPES['\"'] = "\\\""; 053 JSON_ESCAPES['\n'] = "\\n"; 054 JSON_ESCAPES['\r'] = "\\r"; 055 JSON_ESCAPES['\t'] = "\\t"; 056 } 057 058 /** 059 * Serialises this entry to a compact JSON object string. 060 * 061 * @return JSON object string 062 */ 063 public String toJson() { 064 return "{" 065 + "\"title\":" + jsonString(title) + COMMA 066 + "\"url\":" + jsonString(url) + COMMA 067 + "\"category\":" + jsonString(category) + COMMA 068 + "\"type\":" + jsonString(type) + COMMA 069 + "\"description\":" + jsonString(description) + COMMA 070 + "\"since\":" + jsonString(since) + COMMA 071 + "\"weight\":" + weight + COMMA 072 + "\"keywords\":" + jsonString(keywords) 073 + "}"; 074 } 075 076 /** 077 * Wraps a string value in JSON double quotes and escapes special characters. 078 * 079 * @param value the raw string to encode 080 * @return JSON-safe quoted string, or {@code ""} if value is null 081 */ 082 private static String jsonString(@Nullable String value) { 083 String result = "\"\""; 084 if (value != null) { 085 final int length = value.length(); 086 final StringBuilder sb = new StringBuilder(length + 2); 087 sb.append('\"'); 088 for (int index = 0; index < length; index++) { 089 final char ch = value.charAt(index); 090 final String escape; 091 if (ch < ASCII_MAX) { 092 escape = JSON_ESCAPES[ch]; 093 } 094 else { 095 escape = null; 096 } 097 if (escape == null) { 098 sb.append(ch); 099 } 100 else { 101 sb.append(escape); 102 } 103 } 104 sb.append('\"'); 105 result = sb.toString(); 106 } 107 return result; 108 } 109 110}