001/* 002 * Copyright (C) 2008 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.base; 018 019import static com.google.common.base.Preconditions.checkNotNull; 020 021import com.google.common.annotations.Beta; 022import com.google.common.annotations.GwtCompatible; 023 024import java.io.Serializable; 025import java.util.Iterator; 026 027import javax.annotation.Nullable; 028 029/** 030 * A function from {@code A} to {@code B} with an associated <i>reverse</i> function from {@code B} 031 * to {@code A}; used for converting back and forth between <i>different representations of the same 032 * information</i>. 033 * 034 * <h3>Invertibility</h3> 035 * 036 * <p>The reverse operation <b>may</b> be a strict <i>inverse</i> (meaning that {@code 037 * converter.reverse().convert(converter.convert(a)).equals(a)} is always true). However, it is 038 * very common (perhaps <i>more</i> common) for round-trip conversion to be <i>lossy</i>. Consider 039 * an example round-trip using {@link com.google.common.primitives.Doubles#stringConverter}: 040 * 041 * <ol> 042 * <li>{@code stringConverter().convert("1.00")} returns the {@code Double} value {@code 1.0} 043 * <li>{@code stringConverter().reverse().convert(1.0)} returns the string {@code "1.0"} -- 044 * <i>not</i> the same string ({@code "1.00"}) we started with 045 * </ol> 046 * 047 * <p>Note that it should still be the case that the round-tripped and original objects are 048 * <i>similar</i>. 049 * 050 * <h3>Nullability</h3> 051 * 052 * <p>A converter always converts {@code null} to {@code null} and non-null references to non-null 053 * references. It would not make sense to consider {@code null} and a non-null reference to be 054 * "different representations of the same information", since one is distinguishable from 055 * <i>missing</i> information and the other is not. The {@link #convert} method handles this null 056 * behavior for all converters; implementations of {@link #doForward} and {@link #doBackward} are 057 * guaranteed to never be passed {@code null}, and must never return {@code null}. 058 * 059 060 * <h3>Common ways to use</h3> 061 * 062 * <p>Creating a converter: 063 * 064 * <ul> 065 * <li>Extend this class and override {@link #doForward} and {@link #doBackward} 066 * </ul> 067 * 068 * <p>Using a converter: 069 * 070 * <ul> 071 * <li>Convert one instance in the "forward" direction using {@code converter.convert(a)} 072 * <li>Convert multiple instances "forward" using {@code converter.convertAll(as)} 073 * <li>Convert in the "backward" direction using {@code converter.reverse().convert(b)} or {@code 074 * converter.reverse().convertAll(bs)} 075 * <li>Use {@code converter} or {@code converter.reverse()} anywhere a {@link Function} is accepted 076 * </ul> 077 * 078 * @author Mike Ward 079 * @author Kurt Alfred Kluever 080 * @author Gregory Kick 081 * @since 16.0 082 */ 083@Beta 084@GwtCompatible 085public abstract class Converter<A, B> implements Function<A, B> { 086 private final boolean handleNullAutomatically; 087 088 /** Constructor for use by subclasses. */ 089 protected Converter() { 090 this( 091 true 092 ); 093 } 094 095 /** 096 * Constructor used only by {@code LegacyConverter} to suspend automatic null-handling. 097 */ 098 Converter(boolean handleNullAutomatically) { 099 this.handleNullAutomatically = handleNullAutomatically; 100 } 101 102 // SPI methods (what subclasses must implement) 103 104 /** 105 * Returns a representation of {@code a} as an instance of type {@code B}. 106 * 107 * @param a the instance to convert; will never be null 108 * @return the converted instance; <b>must not</b> be null 109 */ 110 protected abstract B doForward(A a); 111 112 /** 113 * Returns a representation of {@code b} as an instance of type {@code A}. 114 * 115 * @param b the instance to convert; will never be null 116 * @return the converted instance; <b>must not</b> be null 117 * @throws RuntimeException if {@code b} is not an instance this converter can convert; this 118 * should typically be an {@code IllegalArgumentException} 119 * @throws UnsupportedOperationException if this converter cannot convert in the reverse 120 * direction. This should be very rare. Note that if backward conversion is not only 121 * unimplemented but unimplement<i>able</i> (for example, consider a {@code 122 * Converter<Chicken, ChickenNugget>}), then this is not logically a converter at all, and it 123 * would be misleading to extend this class. 124 */ 125 protected abstract A doBackward(B b); 126 127 // API (consumer-side) methods 128 129 /** 130 * Returns a representation of {@code a} as an instance of type {@code B}. 131 * 132 * @return the converted value; is null <i>if and only if</i> {@code a} is null 133 */ 134 @Nullable public final B convert(@Nullable A a) { 135 return correctedDoForward(a); 136 } 137 138 B correctedDoForward(A a) { 139 if (handleNullAutomatically) { 140 return a == null ? null : checkNotNull(doForward(a)); 141 } else { 142 return doForward(a); 143 } 144 } 145 146 A correctedDoBackward(B b) { 147 if (handleNullAutomatically) { 148 return b == null ? null : checkNotNull(doBackward(b)); 149 } else { 150 return doBackward(b); 151 } 152 } 153 154 /** 155 * Returns an iterable that applies {@code convert} to each element of {@code fromIterable}. The 156 * conversion is done lazily. 157 * 158 * <p>The returned iterable's iterator supports {@code remove()} if the input iterator does. After 159 * a successful {@code remove()} call, {@code fromIterable} no longer contains the corresponding 160 * element. 161 */ 162 public Iterable<B> convertAll(final Iterable<? extends A> fromIterable) { 163 checkNotNull(fromIterable, "fromIterable"); 164 return new Iterable<B>() { 165 @Override public Iterator<B> iterator() { 166 return new Iterator<B>() { 167 private final Iterator<? extends A> fromIterator = fromIterable.iterator(); 168 @Override public boolean hasNext() { 169 return fromIterator.hasNext(); 170 } 171 @Override public B next() { 172 return convert(fromIterator.next()); 173 } 174 @Override public void remove() { 175 fromIterator.remove(); 176 } 177 }; 178 } 179 }; 180 } 181 182 /** 183 * Returns the reversed view of this converter, which converts {@code this.convert(a)} back to a 184 * value roughly equivalent to {@code a}. 185 * 186 * <p>The returned converter is serializable if {@code this} converter is. 187 */ 188 public Converter<B, A> reverse() { 189 return new ReverseConverter<A, B>(this); 190 } 191 192 private static final class ReverseConverter<A, B> 193 extends Converter<B, A> implements Serializable { 194 final Converter<A, B> original; 195 196 ReverseConverter(Converter<A, B> original) { 197 // Rely on backing converter to handle null if desired, not us. 198 // Actually, since we override correctedDo*, nothing will use this field now anyway. 199 super(false); 200 this.original = original; 201 } 202 203 /* 204 * These gymnastics are a little confusing. Basically this class has neither legacy nor 205 * non-legacy behavior; it just needs to let the behavior of the backing converter shine 206 * through. So, we override the correctedDo* methods, after which the do* methods should never 207 * be reached. 208 */ 209 210 @Override protected A doForward(@Nullable B b) { 211 throw new AssertionError(); 212 } 213 214 @Override protected B doBackward(@Nullable A a) { 215 throw new AssertionError(); 216 } 217 218 @Override A correctedDoForward(B b) { 219 return original.correctedDoBackward(b); 220 } 221 222 @Override B correctedDoBackward(A a) { 223 return original.correctedDoForward(a); 224 } 225 226 @Override public Converter<A, B> reverse() { 227 return original; 228 } 229 230 @Override public boolean equals(@Nullable Object object) { 231 if (object instanceof ReverseConverter) { 232 ReverseConverter<?, ?> that = (ReverseConverter<?, ?>) object; 233 return this.original.equals(that.original); 234 } 235 return false; 236 } 237 238 @Override public int hashCode() { 239 return ~original.hashCode(); 240 } 241 242 @Override public String toString() { 243 return original + ".reverse()"; 244 } 245 246 private static final long serialVersionUID = 0L; 247 } 248 249 /** 250 * Returns a converter whose {@code convert} method applies {@code secondConverter} to the result 251 * of this converter. Its {@code reverse} method applies the converters in reverse order. 252 * 253 * <p>The returned converter is serializable if {@code this} converter and {@code secondConverter} 254 * are. 255 */ 256 public <C> Converter<A, C> andThen(Converter<B, C> secondConverter) { 257 return ConverterComposition.of(this, checkNotNull(secondConverter, "secondConverter")); 258 } 259 260 private static final class ConverterComposition<A, B, C> 261 extends Converter<A, C> implements Serializable { 262 final Converter<A, B> first; 263 final Converter<B, C> second; 264 265 ConverterComposition(Converter<A, B> first, Converter<B, C> second) { 266 // Rely on backing converter to handle null if desired, not us. 267 // Actually, since we override correctedDo*, nothing will use this field now anyway. 268 super(false); 269 this.first = first; 270 this.second = second; 271 } 272 273 /* 274 * These gymnastics are a little confusing. Basically this class has neither legacy nor 275 * non-legacy behavior; it just needs to let the behaviors of the backing converters shine 276 * through (which might even differ from each other!). So, we override the correctedDo* methods, 277 * after which the do* methods should never be reached. 278 */ 279 280 @Override protected C doForward(@Nullable A a) { 281 throw new AssertionError(); 282 } 283 284 @Override protected A doBackward(@Nullable C c) { 285 throw new AssertionError(); 286 } 287 288 @Override C correctedDoForward(@Nullable A a) { 289 return second.correctedDoForward(first.correctedDoForward(a)); 290 } 291 292 @Override A correctedDoBackward(@Nullable C c) { 293 return first.correctedDoBackward(second.correctedDoBackward(c)); 294 } 295 296 @Override public boolean equals(@Nullable Object object) { 297 if (object instanceof ConverterComposition) { 298 ConverterComposition<?, ?, ?> that = (ConverterComposition<?, ?, ?>) object; 299 return this.first.equals(that.first) 300 && this.second.equals(that.second); 301 } 302 return false; 303 } 304 305 @Override public int hashCode() { 306 return 31 * first.hashCode() + second.hashCode(); 307 } 308 309 @Override public String toString() { 310 return first + ".andThen(" + second + ")"; 311 } 312 313 static <A, B, C> Converter<A, C> of(Converter<A, B> first, Converter<B, C> second) { 314 return new ConverterComposition<A, B, C>(first, second); 315 } 316 317 private static final long serialVersionUID = 0L; 318 } 319 320 /** 321 * @deprecated Provided to satisfy the {@code Function} interface; use {@link #convert} instead. 322 */ 323 @Deprecated 324 @Override 325 @Nullable public final B apply(@Nullable A a) { 326 return convert(a); 327 } 328 329 /** 330 * Indicates whether another object is equal to this converter. 331 * 332 * <p>Most implementations will have no reason to override the behavior of {@link Object#equals}. 333 * However, an implementation may also choose to return {@code true} whenever {@code object} is a 334 * {@link Converter} that it considers <i>interchangeable</i> with this one. "Interchangeable" 335 * <i>typically</i> means that {@code Objects.equal(this.convert(a), that.convert(a))} is true for 336 * all {@code a} of type {@code A} (and similarly for {@code reverse}). Note that a {@code false} 337 * result from this method does not imply that the converters are known <i>not</i> to be 338 * interchangeable. 339 */ 340 @Override 341 public boolean equals(@Nullable Object object) { 342 return super.equals(object); 343 } 344 345 // Static singleton converters 346 347 /** 348 * Returns a serializable converter that always converts or reverses an object to itself. 349 */ 350 @SuppressWarnings("unchecked") // implementation is "fully variant" 351 public static <T> Converter<T, T> identity() { 352 return (IdentityConverter<T>) IdentityConverter.INSTANCE; 353 } 354 355 /** 356 * A converter that always converts or reverses an object to itself. Note that T is now a 357 * "pass-through type". 358 */ 359 private static final class IdentityConverter<T> extends Converter<T, T> implements Serializable { 360 static final IdentityConverter INSTANCE = new IdentityConverter(); 361 362 @Override protected T doForward(@Nullable T t) { 363 return t; 364 } 365 366 @Override protected T doBackward(@Nullable T t) { 367 return t; 368 } 369 370 @Override public IdentityConverter<T> reverse() { 371 return this; 372 } 373 374 @Override public <S> Converter<T, S> andThen(Converter<T, S> otherConverter) { 375 return checkNotNull(otherConverter, "otherConverter"); 376 } 377 378 /* 379 * We *could* override convertAll() to return its input, but it's a rather pointless 380 * optimization and opened up a weird type-safety problem. 381 */ 382 383 @Override public String toString() { 384 return "Converter.identity()"; 385 } 386 387 private Object readResolve() { 388 return INSTANCE; 389 } 390 391 private static final long serialVersionUID = 0L; 392 } 393}