package hextostring.replacement; import java.io.Serializable; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Represents a replacement in a string. * * @author Maxime PIA */ public class Replacement implements Serializable { /** * Backward-compatible with 0.7.0 */ private static final long serialVersionUID = 00000000007000000L; private String sequence; private String replacement; private String escapedSequence; private String escapedReplacement; private boolean escapeCharacters; private boolean interpretAsPattern; private ReplacementType type; public Replacement(ReplacementType type) { this("", "", true, false, type); } public Replacement(String sequence, String replacement, boolean escapeCharacters, boolean interpretAsPattern, ReplacementType type) { this.sequence = sequence; this.replacement = replacement; this.escapedSequence = escape(sequence); this.escapedReplacement = escape(replacement); this.escapeCharacters = escapeCharacters; this.interpretAsPattern = interpretAsPattern; this.type = type; } /** * Getter on the raw sequence/pattern to be replaced. * * @return The raw sequence/pattern to be replaced. */ public String getSequence() { return sequence; } /** * Getter on the sequence/pattern to be replaced, escaped if necessary. * * @return The sequence/pattern to be replaced, escaped if necessary. */ public String getProcessedSequence() { return escapeCharacters ? escapedSequence : sequence; } /** * Setter on the sequence/pattern to be replaced. * * @param sequence * The sequence/pattern to be replaced. */ public void setSequence(String sequence) { this.sequence = sequence; this.escapedSequence = escape(sequence); } /** * Getter on the raw replacement. * * @return The raw replacement. */ public String getReplacement() { return replacement; } /** * Getter on the raw replacement, escaped if necessary. * * @return The raw replacement, escaped if necessary. */ public String getProcessedReplacement() { return escapeCharacters ? escapedReplacement : replacement; } /** * Setter on the replacement. * * @param replacement * The replacement. */ public void setReplacement(String replacement) { this.replacement = replacement; this.escapedReplacement = escape(replacement); } /** * Getter on whether or not antislashes are interpreted as escaping * characters. * * @return True if antislashes are interpreted as escaping characters. */ public boolean isEscapeCharacters() { return escapeCharacters; } /** * Setter on whether or not antislashes are interpreted as escaping * characters. * * @param escapeCharacters * True if antislashes are interpreted as escaping characters. */ public void setEscapeCharacters(boolean escapeCharacters) { this.escapeCharacters = escapeCharacters; } /** * Getter on whether or not the sequence represents a regex. * * @return True if the sequence represents a regex. */ public boolean isInterpretAsPattern() { return interpretAsPattern; } /** * Setter on whether or not the sequence represents a regex. * * @param interpretAsPattern * True if the sequence represents a regex. */ public void setInterpretAsPattern(boolean interpretAsPattern) { this.interpretAsPattern = interpretAsPattern; } /** * Getter on the respective types of the sequence and its replacement. * * @return The respective types of the sequence and its replacement. */ public ReplacementType getType() { return type; } /** * Setter on the respective types of the sequence and its replacement. * This must not be called from somewhere else than Replacements * * @param type * The respective types of the sequence and its replacement. */ void setType(ReplacementType type) { this.type = type; } /** * Applies the replacement depending on the respective types of the sequence * and its replacement. * * @param s * The string to which the replacement is applied. * @return The string to which the replacement was applied. */ public String apply(String s) { ReplacementStrategy strategy = ReplacementStrategyFactory.getStrategy(type); return interpretAsPattern ? strategy.replacePattern( s, getProcessedSequence(), getProcessedReplacement() ) : strategy.replaceSequence( s, getProcessedSequence(), getProcessedReplacement() ); } /** * Escapes escapable characters preceded by an antislash. * * @param s * The string to escape. * @return The escaped string. */ private String escape(String s) { String res = s .replace("\\b", "\b") .replace("\\t", "\t") .replace("\\n", "\n") .replace("\\f", "\f") .replace("\\r", "\r") .replace("\\\"", "\"") .replace("\\'", "'") .replace("\\\\", "\\"); Matcher m = Pattern.compile("\\\\u[0-9a-fA-F]{4}").matcher(s); String unicodeReplacedRes = new String(res); while (m.find()) { String match = res.substring(m.start(), m.end()); String replacement = new String(Character.toChars( Integer.parseInt(match.substring(2), 16) )); unicodeReplacedRes = unicodeReplacedRes.replace(match, replacement); } return unicodeReplacedRes; } }