1 package com.fasterxml.jackson.databind.util; 2 3 /** 4 * Helper class used to encapsulate details of name mangling, transforming 5 * of names using different strategies (prefixes, suffixes). 6 * Default implementation is "no-operation" (aka identity transformation). 7 */ 8 public abstract class NameTransformer 9 { 10 /** 11 * Singleton "no-operation" transformer which simply returns given 12 * name as is. Used commonly as placeholder or marker. 13 */ 14 public final static NameTransformer NOP = new NopTransformer(); 15 16 protected final static class NopTransformer 17 extends NameTransformer 18 implements java.io.Serializable 19 { 20 private static final long serialVersionUID = 1L; 21 22 @Override transform(String name)23 public String transform(String name) { 24 return name; 25 } 26 @Override reverse(String transformed)27 public String reverse(String transformed) { 28 // identity transformation is always reversible: 29 return transformed; 30 } 31 } 32 NameTransformer()33 protected NameTransformer() { } 34 35 /** 36 * Factory method for constructing a simple transformer based on 37 * prefix and/or suffix. 38 */ simpleTransformer(final String prefix, final String suffix)39 public static NameTransformer simpleTransformer(final String prefix, final String suffix) 40 { 41 boolean hasPrefix = (prefix != null) && (prefix.length() > 0); 42 boolean hasSuffix = (suffix != null) && (suffix.length() > 0); 43 44 if (hasPrefix) { 45 if (hasSuffix) { 46 return new NameTransformer() { 47 @Override 48 public String transform(String name) { return prefix + name + suffix; } 49 @Override 50 public String reverse(String transformed) { 51 if (transformed.startsWith(prefix)) { 52 String str = transformed.substring(prefix.length()); 53 if (str.endsWith(suffix)) { 54 return str.substring(0, str.length() - suffix.length()); 55 } 56 } 57 return null; 58 } 59 @Override 60 public String toString() { return "[PreAndSuffixTransformer('"+prefix+"','"+suffix+"')]"; } 61 }; 62 } 63 return new NameTransformer() { 64 @Override 65 public String transform(String name) { return prefix + name; } 66 @Override 67 public String reverse(String transformed) { 68 if (transformed.startsWith(prefix)) { 69 return transformed.substring(prefix.length()); 70 } 71 return null; 72 } 73 @Override 74 public String toString() { return "[PrefixTransformer('"+prefix+"')]"; } 75 }; 76 } 77 if (hasSuffix) { 78 return new NameTransformer() { 79 @Override 80 public String transform(String name) { return name + suffix; } 81 @Override 82 public String reverse(String transformed) { 83 if (transformed.endsWith(suffix)) { 84 return transformed.substring(0, transformed.length() - suffix.length()); 85 } 86 return null; 87 } 88 @Override 89 public String toString() { return "[SuffixTransformer('"+suffix+"')]"; } 90 }; 91 } 92 return NOP; 93 } 94 95 /** 96 * Method that constructs transformer that applies given transformers 97 * as a sequence; essentially combines separate transform operations 98 * into one logical transformation. 99 */ 100 public static NameTransformer chainedTransformer(NameTransformer t1, NameTransformer t2) { 101 return new Chained(t1, t2); 102 } 103 104 /** 105 * Method called when (forward) transformation is needed. 106 */ 107 public abstract String transform(String name); 108 109 /** 110 * Method called when reversal of transformation is needed; should return 111 * null if this is not possible, that is, given name cannot have been 112 * result of calling {@link #transform} of this object. 113 */ 114 public abstract String reverse(String transformed); 115 116 public static class Chained extends NameTransformer 117 implements java.io.Serializable 118 { 119 private static final long serialVersionUID = 1L; 120 121 protected final NameTransformer _t1, _t2; 122 123 public Chained(NameTransformer t1, NameTransformer t2) { 124 _t1 = t1; 125 _t2 = t2; 126 } 127 128 @Override 129 public String transform(String name) { 130 return _t1.transform(_t2.transform(name)); 131 } 132 133 @Override 134 public String reverse(String transformed) { 135 transformed = _t1.reverse(transformed); 136 if (transformed != null) { 137 transformed = _t2.reverse(transformed); 138 } 139 return transformed; 140 } 141 142 @Override 143 public String toString() { return "[ChainedTransformer("+_t1+", "+_t2+")]"; } 144 } 145 } 146