1919import static com .google .gcloud .RetryHelper .runWithRetries ;
2020
2121import com .google .api .services .storage .model .StorageObject ;
22+ import com .google .common .base .MoreObjects ;
23+ import com .google .gcloud .RestorableState ;
2224import com .google .gcloud .RetryHelper ;
2325import com .google .gcloud .spi .StorageRpc ;
2426
2527import java .io .IOException ;
26- import java .io .ObjectInputStream ;
27- import java .io .ObjectOutputStream ;
28+ import java .io .Serializable ;
2829import java .nio .ByteBuffer ;
2930import java .util .Map ;
31+ import java .util .Objects ;
3032import java .util .concurrent .Callable ;
3133
3234/**
3537class BlobReadChannelImpl implements BlobReadChannel {
3638
3739 private static final int DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024 ;
38- private static final long serialVersionUID = 4821762590742862669L ;
3940
4041 private final StorageOptions serviceOptions ;
4142 private final BlobId blob ;
@@ -45,38 +46,33 @@ class BlobReadChannelImpl implements BlobReadChannel {
4546 private boolean endOfStream ;
4647 private int chunkSize = DEFAULT_CHUNK_SIZE ;
4748
48- private transient StorageRpc storageRpc ;
49- private transient StorageObject storageObject ;
50- private transient int bufferPos ;
51- private transient byte [] buffer ;
49+ private final StorageRpc storageRpc ;
50+ private final StorageObject storageObject ;
51+ private int bufferPos ;
52+ private byte [] buffer ;
5253
5354 BlobReadChannelImpl (StorageOptions serviceOptions , BlobId blob ,
5455 Map <StorageRpc .Option , ?> requestOptions ) {
5556 this .serviceOptions = serviceOptions ;
5657 this .blob = blob ;
5758 this .requestOptions = requestOptions ;
5859 isOpen = true ;
59- initTransients ();
60+ storageRpc = serviceOptions .storageRpc ();
61+ storageObject = blob .toPb ();
6062 }
6163
62- private void writeObject (ObjectOutputStream out ) throws IOException {
64+ @ Override
65+ public RestorableState <BlobReadChannel > save () {
66+ StateImpl .Builder builder = StateImpl .builder (serviceOptions , blob , requestOptions )
67+ .position (position )
68+ .isOpen (isOpen )
69+ .endOfStream (endOfStream )
70+ .chunkSize (chunkSize );
6371 if (buffer != null ) {
64- position += bufferPos ;
65- buffer = null ;
66- bufferPos = 0 ;
67- endOfStream = false ;
72+ builder .position (position + bufferPos );
73+ builder .endOfStream (false );
6874 }
69- out .defaultWriteObject ();
70- }
71-
72- private void readObject (ObjectInputStream in ) throws IOException , ClassNotFoundException {
73- in .defaultReadObject ();
74- initTransients ();
75- }
76-
77- private void initTransients () {
78- storageRpc = serviceOptions .storageRpc ();
79- storageObject = blob .toPb ();
75+ return builder .build ();
8076 }
8177
8278 @ Override
@@ -148,4 +144,116 @@ public byte[] call() {
148144 }
149145 return toWrite ;
150146 }
147+
148+ static class StateImpl implements RestorableState <BlobReadChannel >, Serializable {
149+
150+ private static final long serialVersionUID = 3889420316004453706L ;
151+
152+ private final StorageOptions serviceOptions ;
153+ private final BlobId blob ;
154+ private final Map <StorageRpc .Option , ?> requestOptions ;
155+ private final int position ;
156+ private final boolean isOpen ;
157+ private final boolean endOfStream ;
158+ private final int chunkSize ;
159+
160+ StateImpl (Builder builder ) {
161+ this .serviceOptions = builder .serviceOptions ;
162+ this .blob = builder .blob ;
163+ this .requestOptions = builder .requestOptions ;
164+ this .position = builder .position ;
165+ this .isOpen = builder .isOpen ;
166+ this .endOfStream = builder .endOfStream ;
167+ this .chunkSize = builder .chunkSize ;
168+ }
169+
170+ static class Builder {
171+ private final StorageOptions serviceOptions ;
172+ private final BlobId blob ;
173+ private final Map <StorageRpc .Option , ?> requestOptions ;
174+ private int position ;
175+ private boolean isOpen ;
176+ private boolean endOfStream ;
177+ private int chunkSize ;
178+
179+ private Builder (StorageOptions options , BlobId blob , Map <StorageRpc .Option , ?> reqOptions ) {
180+ this .serviceOptions = options ;
181+ this .blob = blob ;
182+ this .requestOptions = reqOptions ;
183+ }
184+
185+ Builder position (int position ) {
186+ this .position = position ;
187+ return this ;
188+ }
189+
190+ Builder isOpen (boolean isOpen ) {
191+ this .isOpen = isOpen ;
192+ return this ;
193+ }
194+
195+ Builder endOfStream (boolean endOfStream ) {
196+ this .endOfStream = endOfStream ;
197+ return this ;
198+ }
199+
200+ Builder chunkSize (int chunkSize ) {
201+ this .chunkSize = chunkSize ;
202+ return this ;
203+ }
204+
205+ RestorableState <BlobReadChannel > build () {
206+ return new StateImpl (this );
207+ }
208+ }
209+
210+ static Builder builder (
211+ StorageOptions options , BlobId blob , Map <StorageRpc .Option , ?> reqOptions ) {
212+ return new Builder (options , blob , reqOptions );
213+ }
214+
215+ @ Override
216+ public BlobReadChannel restore () {
217+ BlobReadChannelImpl channel = new BlobReadChannelImpl (serviceOptions , blob , requestOptions );
218+ channel .position = position ;
219+ channel .isOpen = isOpen ;
220+ channel .endOfStream = endOfStream ;
221+ channel .chunkSize = chunkSize ;
222+ return channel ;
223+ }
224+
225+ @ Override
226+ public int hashCode () {
227+ return Objects .hash (serviceOptions , blob , requestOptions , position , isOpen , endOfStream ,
228+ chunkSize );
229+ }
230+
231+ @ Override
232+ public boolean equals (Object obj ) {
233+ if (obj == null ) {
234+ return false ;
235+ }
236+ if (!(obj instanceof StateImpl )) {
237+ return false ;
238+ }
239+ final StateImpl other = (StateImpl ) obj ;
240+ return Objects .equals (this .serviceOptions , other .serviceOptions )
241+ && Objects .equals (this .blob , other .blob )
242+ && Objects .equals (this .requestOptions , other .requestOptions )
243+ && this .position == other .position
244+ && this .isOpen == other .isOpen
245+ && this .endOfStream == other .endOfStream
246+ && this .chunkSize == other .chunkSize ;
247+ }
248+
249+ @ Override
250+ public String toString () {
251+ return MoreObjects .toStringHelper (this )
252+ .add ("blob" , blob )
253+ .add ("position" , position )
254+ .add ("isOpen" , isOpen )
255+ .add ("endOfStream" , endOfStream )
256+ .toString ();
257+ }
258+ }
151259}
0 commit comments