3232import java .util .concurrent .Callable ;
3333
3434/**
35- * Google Storage blob copy writer. This class holds the result of a copy request. If source and
35+ * Google Storage blob copy writer. A {@code CopyWriter} object allows to copy both blob's data and
36+ * information. To override source blob's information supply a {@code BlobInfo} to the
37+ * {@code CopyRequest} using either
38+ * {@link Storage.CopyRequest.Builder#target(BlobInfo, Storage.BlobTargetOption...)} or
39+ * {@link Storage.CopyRequest.Builder#target(BlobInfo, Iterable)}.
40+ *
41+ * <p>This class holds the result of a copy request. If source and
3642 * destination blobs share the same location and storage class the copy is completed in one RPC call
3743 * otherwise one or more {@link #copyChunk} calls are necessary to complete the copy. In addition,
3844 * {@link CopyWriter#result()} can be used to automatically complete the copy and return information
@@ -65,11 +71,11 @@ public class CopyWriter implements Restorable<CopyWriter> {
6571 *
6672 * @throws StorageException upon failure
6773 */
68- public BlobInfo result () {
74+ public Blob result () {
6975while (!isDone ()) {
7076copyChunk ();
7177 }
72- return BlobInfo .fromPb (rewriteResponse .result );
78+ return Blob .fromPb (serviceOptions . service (), rewriteResponse .result );
7379 }
7480
7581/**
@@ -120,8 +126,10 @@ public RestorableState<CopyWriter> capture() {
120126serviceOptions ,
121127BlobId .fromPb (rewriteResponse .rewriteRequest .source ),
122128rewriteResponse .rewriteRequest .sourceOptions ,
129+ rewriteResponse .rewriteRequest .overrideInfo ,
123130BlobInfo .fromPb (rewriteResponse .rewriteRequest .target ),
124131rewriteResponse .rewriteRequest .targetOptions )
132+ .result (rewriteResponse .result !=null ?BlobInfo .fromPb (rewriteResponse .result ) :null )
125133 .blobSize (blobSize ())
126134 .isDone (isDone ())
127135 .megabytesCopiedPerChunk (rewriteResponse .rewriteRequest .megabytesRewrittenPerCall )
@@ -132,11 +140,12 @@ public RestorableState<CopyWriter> capture() {
132140
133141static class StateImpl implements RestorableState <CopyWriter >,Serializable {
134142
135- private static final long serialVersionUID =8279287678903181701L ;
143+ private static final long serialVersionUID =1693964441435822700L ;
136144
137145private final StorageOptions serviceOptions ;
138146private final BlobId source ;
139147private final Map <StorageRpc .Option , ?>sourceOptions ;
148+ private final boolean overrideInfo ;
140149private final BlobInfo target ;
141150private final Map <StorageRpc .Option , ?>targetOptions ;
142151private final BlobInfo result ;
@@ -150,6 +159,7 @@ static class StateImpl implements RestorableState<CopyWriter>, Serializable {
150159this .serviceOptions =builder .serviceOptions ;
151160this .source =builder .source ;
152161this .sourceOptions =builder .sourceOptions ;
162+ this .overrideInfo =builder .overrideInfo ;
153163this .target =builder .target ;
154164this .targetOptions =builder .targetOptions ;
155165this .result =builder .result ;
@@ -165,6 +175,7 @@ static class Builder {
165175private final StorageOptions serviceOptions ;
166176private final BlobId source ;
167177private final Map <StorageRpc .Option , ?>sourceOptions ;
178+ private final boolean overrideInfo ;
168179private final BlobInfo target ;
169180private final Map <StorageRpc .Option , ?>targetOptions ;
170181private BlobInfo result ;
@@ -175,11 +186,12 @@ static class Builder {
175186private Long megabytesCopiedPerChunk ;
176187
177188private Builder (StorageOptions options ,BlobId source ,
178- Map <StorageRpc .Option , ?>sourceOptions ,
179- BlobInfo target , Map <StorageRpc .Option , ?>targetOptions ) {
189+ Map <StorageRpc .Option , ?>sourceOptions ,boolean overrideInfo , BlobInfo target ,
190+ Map <StorageRpc .Option , ?>targetOptions ) {
180191this .serviceOptions =options ;
181192this .source =source ;
182193this .sourceOptions =sourceOptions ;
194+ this .overrideInfo =overrideInfo ;
183195this .target =target ;
184196this .targetOptions =targetOptions ;
185197 }
@@ -220,15 +232,15 @@ RestorableState<CopyWriter> build() {
220232 }
221233
222234static Builder builder (StorageOptions options ,BlobId source ,
223- Map <StorageRpc .Option , ?>sourceOptions ,BlobInfo target ,
235+ Map <StorageRpc .Option , ?>sourceOptions ,boolean overrideInfo , BlobInfo target ,
224236Map <StorageRpc .Option , ?>targetOptions ) {
225- return new Builder (options ,source ,sourceOptions ,target ,targetOptions );
237+ return new Builder (options ,source ,sourceOptions ,overrideInfo , target ,targetOptions );
226238 }
227239
228240@ Override
229241public CopyWriter restore () {
230- RewriteRequest rewriteRequest =new RewriteRequest (
231- source . toPb (), sourceOptions ,target .toPb (),targetOptions ,megabytesCopiedPerChunk );
242+ RewriteRequest rewriteRequest =new RewriteRequest (source . toPb (), sourceOptions ,
243+ overrideInfo ,target .toPb (),targetOptions ,megabytesCopiedPerChunk );
232244RewriteResponse rewriteResponse =new RewriteResponse (rewriteRequest ,
233245result !=null ?result .toPb () :null ,blobSize ,isDone ,rewriteToken ,
234246totalBytesCopied );
@@ -237,8 +249,9 @@ public CopyWriter restore() {
237249
238250@ Override
239251public int hashCode () {
240- return Objects .hash (serviceOptions ,source ,sourceOptions ,target ,targetOptions ,result ,
241- blobSize ,isDone ,megabytesCopiedPerChunk ,rewriteToken ,totalBytesCopied );
252+ return Objects .hash (serviceOptions ,source ,sourceOptions ,overrideInfo ,target ,
253+ targetOptions ,result ,blobSize ,isDone ,megabytesCopiedPerChunk ,rewriteToken ,
254+ totalBytesCopied );
242255 }
243256
244257@ Override
@@ -253,6 +266,7 @@ public boolean equals(Object obj) {
253266return Objects .equals (this .serviceOptions ,other .serviceOptions )
254267 &&Objects .equals (this .source ,other .source )
255268 &&Objects .equals (this .sourceOptions ,other .sourceOptions )
269+ &&Objects .equals (this .overrideInfo ,other .overrideInfo )
256270 &&Objects .equals (this .target ,other .target )
257271 &&Objects .equals (this .targetOptions ,other .targetOptions )
258272 &&Objects .equals (this .result ,other .result )
@@ -267,10 +281,14 @@ public boolean equals(Object obj) {
267281public String toString () {
268282return MoreObjects .toStringHelper (this )
269283 .add ("source" ,source )
284+ .add ("overrideInfo" ,overrideInfo )
270285 .add ("target" ,target )
271- .add ("isDone" ,isDone )
272- .add ("totalBytesRewritten" ,totalBytesCopied )
286+ .add ("result" ,result )
273287 .add ("blobSize" ,blobSize )
288+ .add ("isDone" ,isDone )
289+ .add ("rewriteToken" ,rewriteToken )
290+ .add ("totalBytesCopied" ,totalBytesCopied )
291+ .add ("megabytesCopiedPerChunk" ,megabytesCopiedPerChunk )
274292 .toString ();
275293 }
276294 }