1818package com .github .robtimus .obfuscation ;
1919
2020import java .util .Objects ;
21+ import java .util .function .Function ;
2122import java .util .function .Supplier ;
2223
2324/**
3031public abstract class Obfuscated <T > {
3132
3233 private final T value ;
34+ private final Obfuscator obfuscator ;
3335
34- private Obfuscated (T value ) {
36+ private Obfuscated (T value , Obfuscator obfuscator ) {
3537 this .value = Objects .requireNonNull (value );
38+ this .obfuscator = Objects .requireNonNull (obfuscator );
3639 }
3740
3841 private Obfuscated (Obfuscated <T > other ) {
3942 this .value = other .value ;
43+ this .obfuscator = other .obfuscator ;
4044 }
4145
4246 static <T > Obfuscated <T > of (T value , Obfuscator obfuscator , Supplier <? extends CharSequence > representation ) {
@@ -52,6 +56,10 @@ public final T value() {
5256 return value ;
5357 }
5458
59+ final Obfuscator obfuscator () {
60+ return obfuscator ;
61+ }
62+
5563 @ Override
5664 public final boolean equals (Object o ) {
5765 if (this == o ) {
@@ -72,6 +80,56 @@ public final int hashCode() {
7280 @ Override
7381 public abstract String toString ();
7482
83+ /**
84+ * Applies a mapping function to the obfuscated value.
85+ * The result is similar to calling {@link Obfuscator#obfuscateObject(Object)} on the obfuscator that created this object, passing the result of
86+ * applying the given mapping function to the obfuscated value.
87+ *
88+ * @param <U> The result type of the mapping function.
89+ * @param mapper The mapping function to apply.
90+ * @return An {@code Obfuscated} object wrapping the result of applying the given mapping function to this object's value.
91+ * @throws NullPointerException If the mapping function is {@code null},
92+ * or if the mapping function returns a {@code null} value when applied to this object's value.
93+ * @since 1.1
94+ */
95+ public final <U > Obfuscated <U > map (Function <? super T , ? extends U > mapper ) {
96+ U mapped = mapper .apply (value );
97+ return obfuscator ().obfuscateObject (mapped );
98+ }
99+
100+ /**
101+ * Applies a mapping function to the obfuscated value.
102+ * The result is similar to calling {@link Obfuscator#obfuscateObject(Object, Supplier)} on the obfuscator that created this object, passing the
103+ * result of applying the given mapping function to the obfuscated value.
104+ *
105+ * @param <U> The result type of the mapping function.
106+ * @param mapper The mapping function to apply.
107+ * @param representation A supplier for the string representation that will be used to obfuscate the value.
108+ * This can be used for values that don't have a sensible {@link Object#toString() string representation} of their own.
109+ * @return An {@code Obfuscated} object wrapping the result of applying the given mapping function to this object's value.
110+ * @throws NullPointerException If the mapping function or supplier is {@code null},
111+ * or if the mapping function returns a {@code null} value when applied to this object's value.
112+ * @since 1.1
113+ */
114+ public final <U > Obfuscated <U > map (Function <? super T , ? extends U > mapper , Supplier <? extends CharSequence > representation ) {
115+ U mapped = mapper .apply (value );
116+ return obfuscator ().obfuscateObject (mapped , representation );
117+ }
118+
119+ /**
120+ * Applies a mapping function to the obfuscating value.
121+ * Unlike {@link #map(Function)} and {@link #map(Function, Supplier)}, the result will use the same representation to obfuscate as this object.
122+ * If this object {@link #cached() caches} the results of obfuscating, so will the result.
123+ *
124+ * @param <U> The result type of the mapping function.
125+ * @param mapper The mapping function to apply.
126+ * @return An {@code Obfuscated} object wrapping the result of applying the given mapping function to this object's value.
127+ * @throws NullPointerException If the mapping function is {@code null},
128+ * or if the mapping function returns a {@code null} value when applied to this object's value.
129+ * @since 1.1
130+ */
131+ public abstract <U > Obfuscated <U > mapWithSameRepresentation (Function <? super T , ? extends U > mapper );
132+
75133 /**
76134 * Returns an obfuscated object that caches the results of obfuscating.
77135 * This can be used when the result of obfuscation never changes, for example when obfuscating immutable objects.
@@ -82,18 +140,22 @@ public final int hashCode() {
82140
83141 private static final class Obfuscating <T > extends Obfuscated <T > {
84142
85- private final Obfuscator obfuscator ;
86143 private final Supplier <? extends CharSequence > representation ;
87144
88- Obfuscating (T obfuscated , Obfuscator obfuscator , Supplier <? extends CharSequence > representation ) {
89- super (obfuscated );
90- this .obfuscator = Objects .requireNonNull (obfuscator );
145+ private Obfuscating (T obfuscated , Obfuscator obfuscator , Supplier <? extends CharSequence > representation ) {
146+ super (obfuscated , obfuscator );
91147 this .representation = Objects .requireNonNull (representation );
92148 }
93149
94150 @ Override
95151 public String toString () {
96- return obfuscator .obfuscateText (representation .get ()).toString ();
152+ return obfuscator ().obfuscateText (representation .get ()).toString ();
153+ }
154+
155+ @ Override
156+ public <U > Obfuscated <U > mapWithSameRepresentation (Function <? super T , ? extends U > mapper ) {
157+ U mapped = mapper .apply (value ());
158+ return new Obfuscating <>(mapped , obfuscator (), representation );
97159 }
98160
99161 @ Override
@@ -111,11 +173,22 @@ private Cached(Obfuscated<T> obfuscated, String stringValue) {
111173 this .stringValue = Objects .requireNonNull (stringValue );
112174 }
113175
176+ private Cached (T obfuscated , Obfuscator obfuscator , String stringValue ) {
177+ super (obfuscated , obfuscator );
178+ this .stringValue = Objects .requireNonNull (stringValue );
179+ }
180+
114181 @ Override
115182 public String toString () {
116183 return stringValue ;
117184 }
118185
186+ @ Override
187+ public <U > Obfuscated <U > mapWithSameRepresentation (Function <? super T , ? extends U > mapper ) {
188+ U mapped = mapper .apply (value ());
189+ return new Cached <>(mapped , obfuscator (), stringValue );
190+ }
191+
119192 @ Override
120193 public Obfuscated <T > cached () {
121194 return this ;
0 commit comments