xref: /aosp_15_r20/external/jackson-databind/src/main/java/com/fasterxml/jackson/databind/util/NameTransformer.java (revision 0ed15c778abdfe0f5f51f6133673e1619d6e56e4)
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