package com.fasterxml.jackson.databind.util; /** * Helper class used to encapsulate details of name mangling, transforming * of names using different strategies (prefixes, suffixes). * Default implementation is "no-operation" (aka identity transformation). */ public abstract class NameTransformer { /** * Singleton "no-operation" transformer which simply returns given * name as is. Used commonly as placeholder or marker. */ public final static NameTransformer NOP = new NopTransformer(); protected final static class NopTransformer extends NameTransformer implements java.io.Serializable { private static final long serialVersionUID = 1L; @Override public String transform(String name) { return name; } @Override public String reverse(String transformed) { // identity transformation is always reversible: return transformed; } } protected NameTransformer() { } /** * Factory method for constructing a simple transformer based on * prefix and/or suffix. */ public static NameTransformer simpleTransformer(final String prefix, final String suffix) { boolean hasPrefix = (prefix != null) && (prefix.length() > 0); boolean hasSuffix = (suffix != null) && (suffix.length() > 0); if (hasPrefix) { if (hasSuffix) { return new NameTransformer() { @Override public String transform(String name) { return prefix + name + suffix; } @Override public String reverse(String transformed) { if (transformed.startsWith(prefix)) { String str = transformed.substring(prefix.length()); if (str.endsWith(suffix)) { return str.substring(0, str.length() - suffix.length()); } } return null; } @Override public String toString() { return "[PreAndSuffixTransformer('"+prefix+"','"+suffix+"')]"; } }; } return new NameTransformer() { @Override public String transform(String name) { return prefix + name; } @Override public String reverse(String transformed) { if (transformed.startsWith(prefix)) { return transformed.substring(prefix.length()); } return null; } @Override public String toString() { return "[PrefixTransformer('"+prefix+"')]"; } }; } if (hasSuffix) { return new NameTransformer() { @Override public String transform(String name) { return name + suffix; } @Override public String reverse(String transformed) { if (transformed.endsWith(suffix)) { return transformed.substring(0, transformed.length() - suffix.length()); } return null; } @Override public String toString() { return "[SuffixTransformer('"+suffix+"')]"; } }; } return NOP; } /** * Method that constructs transformer that applies given transformers * as a sequence; essentially combines separate transform operations * into one logical transformation. */ public static NameTransformer chainedTransformer(NameTransformer t1, NameTransformer t2) { return new Chained(t1, t2); } /** * Method called when (forward) transformation is needed. */ public abstract String transform(String name); /** * Method called when reversal of transformation is needed; should return * null if this is not possible, that is, given name can not have been * result of calling {@link #transform} of this object. */ public abstract String reverse(String transformed); public static class Chained extends NameTransformer implements java.io.Serializable { private static final long serialVersionUID = 1L; protected final NameTransformer _t1, _t2; public Chained(NameTransformer t1, NameTransformer t2) { _t1 = t1; _t2 = t2; } @Override public String transform(String name) { return _t1.transform(_t2.transform(name)); } @Override public String reverse(String transformed) { transformed = _t1.reverse(transformed); if (transformed != null) { transformed = _t2.reverse(transformed); } return transformed; } @Override public String toString() { return "[ChainedTransformer("+_t1+", "+_t2+")]"; } } }