1 /* 2 * Copyright (c) 2007-present, Stephen Colebourne & Michael Nascimento Santos 3 * 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * * Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * * Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * * Neither the name of JSR-310 nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package org.threeten.bp.chrono; 33 34 import java.io.Externalizable; 35 import java.io.IOException; 36 import java.io.InvalidClassException; 37 import java.io.ObjectInput; 38 import java.io.ObjectOutput; 39 import java.io.StreamCorruptedException; 40 41 import org.threeten.bp.LocalDate; 42 import org.threeten.bp.LocalDateTime; 43 44 /** 45 * The shared serialization delegate for this package. 46 * 47 * <h4>Implementation notes</h4> 48 * This class wraps the object being serialized, and takes a byte representing the type of the class to 49 * be serialized. This byte can also be used for versioning the serialization format. In this case another 50 * byte flag would be used in order to specify an alternative version of the type format. 51 * For example {@code JAPANESE_DATE_TYPE_VERSION_2 = 21}. 52 * <p> 53 * In order to serialise the object it writes its byte and then calls back to the appropriate class where 54 * the serialisation is performed. In order to deserialise the object it read in the type byte, switching 55 * in order to select which class to call back into. 56 * <p> 57 * The serialisation format is determined on a per class basis. In the case of field based classes each 58 * of the fields is written out with an appropriate size format in descending order of the field's size. For 59 * example in the case of {@link LocalDate} year is written before month. Composite classes, such as 60 * {@link LocalDateTime} are serialised as one object. 61 * <p> 62 * This class is mutable and should be created once per serialization. 63 * 64 * @serial include 65 */ 66 final class Ser implements Externalizable { 67 68 /** 69 * Serialization version. 70 */ 71 private static final long serialVersionUID = 7857518227608961174L; 72 73 static final byte JAPANESE_DATE_TYPE = 1; 74 static final byte JAPANESE_ERA_TYPE = 2; 75 static final byte HIJRAH_DATE_TYPE = 3; 76 static final byte HIJRAH_ERA_TYPE = 4; 77 static final byte MINGUO_DATE_TYPE = 5; 78 static final byte MINGUO_ERA_TYPE = 6; 79 static final byte THAIBUDDHIST_DATE_TYPE = 7; 80 static final byte THAIBUDDHIST_ERA_TYPE = 8; 81 static final byte CHRONO_TYPE = 11; 82 static final byte CHRONO_LOCALDATETIME_TYPE = 12; 83 static final byte CHRONO_ZONEDDATETIME_TYPE = 13; 84 85 /** The type being serialized. */ 86 private byte type; 87 /** The object being serialized. */ 88 private Object object; 89 90 /** 91 * Constructor for deserialization. 92 */ Ser()93 public Ser() { 94 } 95 96 /** 97 * Creates an instance for serialization. 98 * 99 * @param type the type 100 * @param object the object 101 */ Ser(byte type, Object object)102 Ser(byte type, Object object) { 103 this.type = type; 104 this.object = object; 105 } 106 107 //----------------------------------------------------------------------- 108 /** 109 * Implements the {@code Externalizable} interface to write the object. 110 * 111 * @param out the data stream to write to, not null 112 */ 113 @Override writeExternal(ObjectOutput out)114 public void writeExternal(ObjectOutput out) throws IOException { 115 writeInternal(type, object, out); 116 } 117 writeInternal(byte type, Object object, ObjectOutput out)118 private static void writeInternal(byte type, Object object, ObjectOutput out) throws IOException { 119 out.writeByte(type); 120 switch (type) { 121 case JAPANESE_DATE_TYPE: 122 ((JapaneseDate) object).writeExternal(out); 123 break; 124 case JAPANESE_ERA_TYPE: 125 ((JapaneseEra) object).writeExternal(out); 126 break; 127 case HIJRAH_DATE_TYPE: 128 ((HijrahDate) object).writeExternal(out); 129 break; 130 case HIJRAH_ERA_TYPE: 131 ((HijrahEra) object).writeExternal(out); 132 break; 133 case MINGUO_DATE_TYPE: 134 ((MinguoDate) object).writeExternal(out); 135 break; 136 case MINGUO_ERA_TYPE: 137 ((MinguoEra) object).writeExternal(out); 138 break; 139 case THAIBUDDHIST_DATE_TYPE: 140 ((ThaiBuddhistDate) object).writeExternal(out); 141 break; 142 case THAIBUDDHIST_ERA_TYPE: 143 ((ThaiBuddhistEra) object).writeExternal(out); 144 break; 145 case CHRONO_TYPE: 146 ((Chronology) object).writeExternal(out); 147 break; 148 case CHRONO_LOCALDATETIME_TYPE: 149 ((ChronoLocalDateTimeImpl<?>) object).writeExternal(out); 150 break; 151 case CHRONO_ZONEDDATETIME_TYPE: 152 ((ChronoZonedDateTimeImpl<?>) object).writeExternal(out); 153 break; 154 default: 155 throw new InvalidClassException("Unknown serialized type"); 156 } 157 } 158 159 //----------------------------------------------------------------------- 160 /** 161 * Implements the {@code Externalizable} interface to read the object. 162 * 163 * @param in the data to read, not null 164 */ 165 @Override readExternal(ObjectInput in)166 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 167 type = in.readByte(); 168 object = readInternal(type, in); 169 } 170 read(ObjectInput in)171 static Object read(ObjectInput in) throws IOException, ClassNotFoundException { 172 byte type = in.readByte(); 173 return readInternal(type, in); 174 } 175 readInternal(byte type, ObjectInput in)176 private static Object readInternal(byte type, ObjectInput in) throws IOException, ClassNotFoundException { 177 switch (type) { 178 case JAPANESE_DATE_TYPE: return JapaneseDate.readExternal(in); 179 case JAPANESE_ERA_TYPE: return JapaneseEra.readExternal(in); 180 case HIJRAH_DATE_TYPE: return HijrahDate.readExternal(in); 181 case HIJRAH_ERA_TYPE: return HijrahEra.readExternal(in); 182 case MINGUO_DATE_TYPE: return MinguoDate.readExternal(in); 183 case MINGUO_ERA_TYPE: return MinguoEra.readExternal(in); 184 case THAIBUDDHIST_DATE_TYPE: return ThaiBuddhistDate.readExternal(in); 185 case THAIBUDDHIST_ERA_TYPE: return ThaiBuddhistEra.readExternal(in); 186 case CHRONO_TYPE: return Chronology.readExternal(in); 187 case CHRONO_LOCALDATETIME_TYPE: return ChronoLocalDateTimeImpl.readExternal(in); 188 case CHRONO_ZONEDDATETIME_TYPE: return ChronoZonedDateTimeImpl.readExternal(in); 189 default: 190 throw new StreamCorruptedException("Unknown serialized type"); 191 } 192 } 193 194 /** 195 * Returns the object that will replace this one. 196 * 197 * @return the read object, should never be null 198 */ readResolve()199 private Object readResolve() { 200 return object; 201 } 202 203 } 204