View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 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 javax.annotation.Nullable;
23  
24  /**
25   * Represents a single entry in the client-side search index.
26   *
27   * @param title display name
28   * @param url relative URL
29   * @param category category label
30   * @param type document type
31   * @param description short description
32   * @param keywords comma-separated keywords
33   * @param since the version this module/property was introduced (can be empty)
34   * @param weight ranking weight for search results
35   */
36  public record SearchIndexEntry(String title, String url, String category,
37                              String type, String description, String keywords,
38                              String since, int weight) {
39  
40      /** String literal for comma. */
41      private static final String COMMA = ",";
42  
43      /** Maximum ASCII value for the lookup table. */
44      private static final int ASCII_MAX = 128;
45  
46      /** Lookup table for JSON escape sequences for characters {@literal <} 128 (ASCII range). */
47      private static final String[] JSON_ESCAPES;
48  
49      static {
50          JSON_ESCAPES = new String[ASCII_MAX];
51          JSON_ESCAPES['\\'] = "\\\\";
52          JSON_ESCAPES['\"'] = "\\\"";
53          JSON_ESCAPES['\n'] = "\\n";
54          JSON_ESCAPES['\r'] = "\\r";
55          JSON_ESCAPES['\t'] = "\\t";
56      }
57  
58      /**
59       * Serialises this entry to a compact JSON object string.
60       *
61       * @return JSON object string
62       */
63      public String toJson() {
64          return "{"
65              + "\"title\":" + jsonString(title) + COMMA
66              + "\"url\":" + jsonString(url) + COMMA
67              + "\"category\":" + jsonString(category) + COMMA
68              + "\"type\":" + jsonString(type) + COMMA
69              + "\"description\":" + jsonString(description) + COMMA
70              + "\"since\":" + jsonString(since) + COMMA
71              + "\"weight\":" + weight + COMMA
72              + "\"keywords\":" + jsonString(keywords)
73              + "}";
74      }
75  
76      /**
77       * Wraps a string value in JSON double quotes and escapes special characters.
78       *
79       * @param value the raw string to encode
80       * @return JSON-safe quoted string, or {@code ""} if value is null
81       */
82      private static String jsonString(@Nullable String value) {
83          String result = "\"\"";
84          if (value != null) {
85              final int length = value.length();
86              final StringBuilder sb = new StringBuilder(length + 2);
87              sb.append('\"');
88              for (int index = 0; index < length; index++) {
89                  final char ch = value.charAt(index);
90                  final String escape;
91                  if (ch < ASCII_MAX) {
92                      escape = JSON_ESCAPES[ch];
93                  }
94                  else {
95                      escape = null;
96                  }
97                  if (escape == null) {
98                      sb.append(ch);
99                  }
100                 else {
101                     sb.append(escape);
102                 }
103             }
104             sb.append('\"');
105             result = sb.toString();
106         }
107         return result;
108     }
109 
110 }