001package net.bramp.commons.lang3.math.gson; 002 003import com.google.errorprone.annotations.Immutable; 004import com.google.gson.TypeAdapter; 005import com.google.gson.stream.JsonReader; 006import com.google.gson.stream.JsonToken; 007import com.google.gson.stream.JsonWriter; 008import java.io.IOException; 009import org.apache.commons.lang3.math.Fraction; 010 011/** 012 * GSON TypeAdapter for Apache Commons Math Fraction Object. 013 * 014 * @author bramp 015 */ 016@Immutable 017public class FractionAdapter extends TypeAdapter<Fraction> { 018 019 /** If set, 0/0 returns this value, instead of throwing a ArithmeticException. */ 020 @SuppressWarnings( 021 "Immutable") // TODO Remove when https://github.com/google/error-prone/issues/512 is fixed 022 private final Fraction zeroByZero; 023 024 /** If set, N/0 returns this value, instead of throwing a ArithmeticException. */ 025 @SuppressWarnings( 026 "Immutable") // TODO Remove when https://github.com/google/error-prone/issues/512 is fixed 027 private final Fraction divideByZero; 028 029 /** Constructs a FractionAdapter with default zero values for edge cases. */ 030 public FractionAdapter() { 031 this(Fraction.ZERO, Fraction.ZERO); 032 } 033 034 private FractionAdapter(Fraction zeroByZero, Fraction divideByZero) { 035 this.zeroByZero = zeroByZero; 036 this.divideByZero = divideByZero; 037 } 038 039 @Override 040 public Fraction read(JsonReader reader) throws IOException { 041 JsonToken next = reader.peek(); 042 043 if (next == JsonToken.NULL) { 044 reader.nextNull(); 045 return null; 046 } 047 048 if (next == JsonToken.NUMBER) { 049 return Fraction.getFraction(reader.nextDouble()); 050 } 051 052 String fraction = reader.nextString().trim(); 053 054 // Ambiguous as to what 0/0 is, but FFmpeg seems to think it's zero 055 if (zeroByZero != null && "0/0".equals(fraction)) { 056 return zeroByZero; 057 } 058 059 // Another edge cases is invalid files sometimes output 1/0. 060 if (divideByZero != null && fraction.endsWith("/0")) { 061 return divideByZero; 062 } 063 064 return Fraction.getFraction(fraction); 065 } 066 067 @Override 068 public void write(JsonWriter writer, Fraction value) throws IOException { 069 if (value == null) { 070 writer.nullValue(); 071 return; 072 } 073 writer.value(value.toProperString()); 074 } 075}