Skip to content

Commit

Permalink
Refactor: extract TextUtils from StringUtils
Browse files Browse the repository at this point in the history
The TextUtils class has been extracted from StringUtils to handle
methods specific to text management, enhancing class segregation.
Additionally, the inline code delimiter ("`") and the code delimiter
sequence ("```") have been centralized within TextUtils to enhance code
maintainability.

Jira-Id: IT-103
Change-Id: I54b39220376a91d86e41a02ea232c019e5de075b
Signed-off-by: Patrizio <[email protected]>
  • Loading branch information
sixtyfourer committed Mar 18, 2024
1 parent 23ec4cf commit 146afcd
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,21 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.joinWithNewLine;
import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.prettyStringifyObject;
import static com.googlesource.gerrit.plugins.chatgpt.utils.TextUtils.*;

public class DebugComment {
private static final String OPENING_TITLE = "DEBUGGING DETAILS";
private static final String COMMENT_OPENING = "\n\n```\n" + OPENING_TITLE + "\n";
private static final String COMMENT_OPENING = CODE_DELIMITER_BEGIN + OPENING_TITLE + "\n";
private static final String HIDDEN_REPLY = "hidden: %s";
private static final String COMMENT_CLOSING = "```";
private static final Pattern DEBUG_MESSAGE_PATTERN = Pattern.compile("\\s+```\\s*" + OPENING_TITLE + ".*```\\s*",
Pattern.DOTALL);
private static final Pattern DEBUG_MESSAGE_PATTERN = Pattern.compile("\\s+" + CODE_DELIMITER +"\\s*" +
OPENING_TITLE + ".*" + CODE_DELIMITER + "\\s*", Pattern.DOTALL);

public static String getDebugMessage(ChatGptReplyItem replyItem, boolean isHidden) {
return joinWithNewLine(new ArrayList<>() {{
add(COMMENT_OPENING);
add(String.format(HIDDEN_REPLY, isHidden));
add(prettyStringifyObject(replyItem));
add(COMMENT_CLOSING);
add(CODE_DELIMITER);
}});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.List;
import java.util.Optional;

import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.joinWithNewLine;
import static com.googlesource.gerrit.plugins.chatgpt.utils.TextUtils.joinWithNewLine;

@Slf4j
public class InlineCode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.util.List;
import java.util.TreeMap;

import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.joinWithNewLine;
import static com.googlesource.gerrit.plugins.chatgpt.utils.TextUtils.joinWithNewLine;

@Slf4j
public class FileDiffProcessed {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@
import java.util.*;
import java.util.stream.Collectors;

import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.*;
import static com.googlesource.gerrit.plugins.chatgpt.utils.TextUtils.*;

@Slf4j
public class ChatGptPrompt {
public static final String SPACE = " ";
public static final String DOT = ". ";
public static final String BACKTICK = "`";

// Reply attributes
public static final String ATTRIBUTE_ID = "id";
Expand Down Expand Up @@ -143,7 +142,7 @@ private static String buildFieldSpecifications(List<String> filterFields) {
Map<String, String> attributes = DEFAULT_GPT_REPLIES_ATTRIBUTES.entrySet().stream()
.filter(entry -> orderedFilterFields.contains(entry.getKey()))
.collect(Collectors.toMap(
entry -> BACKTICK + entry.getKey() + BACKTICK,
entry -> INLINE_CODE_DELIMITER + entry.getKey() + INLINE_CODE_DELIMITER,
Map.Entry::getValue,
(oldValue, newValue) -> oldValue,
LinkedHashMap::new
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.parseOutOfDelimiters;
import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.backslashEachChar;
import static com.googlesource.gerrit.plugins.chatgpt.utils.TextUtils.*;

public class MessageSanitizer {
private static final Pattern SANITIZE_BOLD_REGEX = Pattern.compile("(\\*{1,2}|(?<!\\w)_{1,2})(.+?)\\1",
Pattern.DOTALL);
private static final Pattern SANITIZE_NUM_REGEX = Pattern.compile("^(\\s*)(#+)(?=\\s)", Pattern.MULTILINE);

public static String sanitizeChatGptMessage(String message) {
// Sanitize code blocks (delimited by "```") by stripping out the language for syntax highlighting and ensuring
// that is preceded by two "\n" chars. Additionally, sanitize the content outside these blocks.
return parseOutOfDelimiters(message, "\\s*```\\w*\\s*", MessageSanitizer::sanitizeOutsideInlineCodeBlocks,
"\n\n```\n", "\n```\n");
// Sanitize code blocks (delimited by CODE_DELIMITER) by stripping out the language for syntax highlighting and
// ensuring that is preceded by two "\n" chars. Additionally, sanitize the content outside these blocks.
return parseOutOfDelimiters(message, "\\s*" + CODE_DELIMITER + "\\w*\\s*",
MessageSanitizer::sanitizeOutsideInlineCodeBlocks, CODE_DELIMITER_BEGIN, CODE_DELIMITER_END);
}

private static String sanitizeOutsideInlineCodeBlocks(String message) {
// Sanitize the content outside the inline code blocks (delimited by a single "`").
return parseOutOfDelimiters(message, "`", MessageSanitizer::sanitizeGerritComment);
// Sanitize the content outside the inline code blocks (delimited by INLINE_CODE_DELIMITER).
return parseOutOfDelimiters(message, INLINE_CODE_DELIMITER, MessageSanitizer::sanitizeGerritComment);
}

private static String sanitizeGerritComment(String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,10 @@

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
public class StringUtils {
private static final String COMMA = ", ";
private static final String SEMICOLON = "; ";

public static String parseOutOfDelimiters(String body, String splitDelim, Function<String, String> processMessage,
String leftDelimReplacement, String rightDelimReplacement) {
String[] chunks = body.split(splitDelim, -1);
List<String> resultChunks = new ArrayList<>();
int lastChunk = chunks.length -1;
for (int i = 0; i <= lastChunk; i++) {
String chunk = chunks[i];
if (i % 2 == 0 || i == lastChunk) {
resultChunks.add(processMessage.apply(chunk));
}
else {
resultChunks.addAll(Arrays.asList(leftDelimReplacement, chunk, rightDelimReplacement));
}
}
return concatenate(resultChunks);
}

public static String parseOutOfDelimiters(String body, String splitDelim, Function<String, String> processMessage) {
return parseOutOfDelimiters(body, splitDelim, processMessage, splitDelim, splitDelim);
}

public static String backslashEachChar(String body) {
StringBuilder slashedBody = new StringBuilder();

Expand All @@ -50,39 +19,4 @@ public static String concatenate(List<String> components) {
return String.join("", components);
}

public static String joinWithNewLine(List<String> components) {
return String.join("\n", components);
}

public static String joinWithComma(Set<String> components) {
return String.join(COMMA, components);
}

public static String joinWithSemicolon(List<String> components) {
return String.join(SEMICOLON, components);
}

public static List<String> getNumberedList(List<String> components) {
return IntStream.range(0, components.size())
.mapToObj(i -> (i + 1) + ". " + components.get(i))
.collect(Collectors.toList());
}

public static String getNumberedListString(List<String> components) {
return joinWithSemicolon(getNumberedList(components));
}

public static String prettyStringifyObject(Object object) {
List<String> lines = new ArrayList<>();
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
lines.add(field.getName() + ": " + field.get(object));
} catch (IllegalAccessException e) {
log.debug("Error while accessing field {} in {}", field.getName(), object, e);
}
}
return joinWithNewLine(lines);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.googlesource.gerrit.plugins.chatgpt.utils;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
public class TextUtils extends StringUtils {
public static final String INLINE_CODE_DELIMITER = "`";
public static final String CODE_DELIMITER = "```";
public static final String CODE_DELIMITER_BEGIN ="\n\n" + CODE_DELIMITER + "\n";
public static final String CODE_DELIMITER_END ="\n" + CODE_DELIMITER + "\n";

private static final String COMMA = ", ";
private static final String SEMICOLON = "; ";

public static String parseOutOfDelimiters(String body, String splitDelim, Function<String, String> processMessage,
String leftDelimReplacement, String rightDelimReplacement) {
String[] chunks = body.split(splitDelim, -1);
List<String> resultChunks = new ArrayList<>();
int lastChunk = chunks.length -1;
for (int i = 0; i <= lastChunk; i++) {
String chunk = chunks[i];
if (i % 2 == 0 || i == lastChunk) {
resultChunks.add(processMessage.apply(chunk));
}
else {
resultChunks.addAll(Arrays.asList(leftDelimReplacement, chunk, rightDelimReplacement));
}
}
return concatenate(resultChunks);
}

public static String parseOutOfDelimiters(String body, String splitDelim, Function<String, String> processMessage) {
return parseOutOfDelimiters(body, splitDelim, processMessage, splitDelim, splitDelim);
}

public static String joinWithNewLine(List<String> components) {
return String.join("\n", components);
}

public static String joinWithComma(Set<String> components) {
return String.join(COMMA, components);
}

public static String joinWithSemicolon(List<String> components) {
return String.join(SEMICOLON, components);
}

public static List<String> getNumberedList(List<String> components) {
return IntStream.range(0, components.size())
.mapToObj(i -> (i + 1) + ". " + components.get(i))
.collect(Collectors.toList());
}

public static String getNumberedListString(List<String> components) {
return joinWithSemicolon(getNumberedList(components));
}

public static String prettyStringifyObject(Object object) {
List<String> lines = new ArrayList<>();
for (Field field : object.getClass().getDeclaredFields()) {
field.setAccessible(true);
try {
lines.add(field.getName() + ": " + field.get(object));
} catch (IllegalAccessException e) {
log.debug("Error while accessing field {} in {}", field.getName(), object, e);
}
}
return joinWithNewLine(lines);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

import static com.google.gerrit.extensions.client.ChangeKind.REWORK;
import static com.googlesource.gerrit.plugins.chatgpt.client.UriResourceLocator.*;
import static com.googlesource.gerrit.plugins.chatgpt.utils.StringUtils.joinWithNewLine;
import static com.googlesource.gerrit.plugins.chatgpt.utils.TextUtils.joinWithNewLine;
import static java.net.HttpURLConnection.HTTP_OK;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
Expand Down

0 comments on commit 146afcd

Please sign in to comment.