• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.core;
17 
18 import java.nio.channels.AsynchronousChannelGroup;
19 import java.nio.file.FileAlreadyExistsException;
20 import java.nio.file.Path;
21 import java.util.Objects;
22 import java.util.Optional;
23 import java.util.concurrent.ExecutorService;
24 import software.amazon.awssdk.annotations.SdkPublicApi;
25 import software.amazon.awssdk.core.async.AsyncResponseTransformer;
26 import software.amazon.awssdk.utils.Validate;
27 import software.amazon.awssdk.utils.builder.CopyableBuilder;
28 import software.amazon.awssdk.utils.builder.ToCopyableBuilder;
29 
30 /**
31  * Configuration options for {@link AsyncResponseTransformer#toFile(Path, FileTransformerConfiguration)} to configure how the SDK
32  * should write the file and if the SDK should delete the file when an exception occurs.
33  *
34  * @see #builder()
35  * @see FileWriteOption
36  * @see FailureBehavior
37  */
38 @SdkPublicApi
39 public final class FileTransformerConfiguration implements ToCopyableBuilder<FileTransformerConfiguration.Builder,
40     FileTransformerConfiguration> {
41     private final FileWriteOption fileWriteOption;
42     private final FailureBehavior failureBehavior;
43     private final ExecutorService executorService;
44 
FileTransformerConfiguration(DefaultBuilder builder)45     private FileTransformerConfiguration(DefaultBuilder builder) {
46         this.fileWriteOption = Validate.paramNotNull(builder.fileWriteOption, "fileWriteOption");
47         this.failureBehavior = Validate.paramNotNull(builder.failureBehavior, "failureBehavior");
48         this.executorService = builder.executorService;
49     }
50 
51     /**
52      * The configured {@link FileWriteOption}
53      */
fileWriteOption()54     public FileWriteOption fileWriteOption() {
55         return fileWriteOption;
56     }
57 
58     /**
59      * The configured {@link FailureBehavior}
60      */
failureBehavior()61     public FailureBehavior failureBehavior() {
62         return failureBehavior;
63     }
64 
65     /**
66      * The configured {@link ExecutorService} the writes should be executed on.
67      * <p>
68      * If not set, the default thread pool defined by the underlying {@link java.nio.file.spi.FileSystemProvider} will be used.
69      * This will typically be the thread pool defined by the {@link AsynchronousChannelGroup}.
70      */
executorService()71     public Optional<ExecutorService> executorService() {
72         return Optional.ofNullable(executorService);
73     }
74 
75     /**
76      * Create a {@link Builder}, used to create a {@link FileTransformerConfiguration}.
77      */
builder()78     public static Builder builder() {
79         return new DefaultBuilder();
80     }
81 
82     /**
83      * Returns the default {@link FileTransformerConfiguration} for {@link FileWriteOption#CREATE_NEW}
84      * <p>
85      * Always create a new file. If the file already exists, {@link FileAlreadyExistsException} will be thrown.
86      * In the event of an error, the SDK will attempt to delete the file (whatever has been written to it so far).
87      */
defaultCreateNew()88     public static FileTransformerConfiguration defaultCreateNew() {
89         return builder().fileWriteOption(FileWriteOption.CREATE_NEW)
90                         .failureBehavior(FailureBehavior.DELETE)
91                         .build();
92     }
93 
94     /**
95      * Returns the default {@link FileTransformerConfiguration} for {@link FileWriteOption#CREATE_OR_REPLACE_EXISTING}
96      * <p>
97      * Create a new file if it doesn't exist, otherwise replace the existing file.
98      * In the event of an error, the SDK will NOT attempt to delete the file, leaving it as-is
99      */
defaultCreateOrReplaceExisting()100     public static FileTransformerConfiguration defaultCreateOrReplaceExisting() {
101         return builder().fileWriteOption(FileWriteOption.CREATE_OR_REPLACE_EXISTING)
102                         .failureBehavior(FailureBehavior.LEAVE)
103                         .build();
104     }
105 
106     /**
107      * Returns the default {@link FileTransformerConfiguration} for {@link FileWriteOption#CREATE_OR_APPEND_TO_EXISTING}
108      * <p>
109      * Create a new file if it doesn't exist, otherwise append to the existing file.
110      * In the event of an error, the SDK will NOT attempt to delete the file, leaving it as-is
111      */
defaultCreateOrAppend()112     public static FileTransformerConfiguration defaultCreateOrAppend() {
113         return builder().fileWriteOption(FileWriteOption.CREATE_OR_APPEND_TO_EXISTING)
114                         .failureBehavior(FailureBehavior.LEAVE)
115                         .build();
116     }
117 
118     @Override
toBuilder()119     public Builder toBuilder() {
120         return new DefaultBuilder(this);
121     }
122 
123     @Override
equals(Object o)124     public boolean equals(Object o) {
125         if (this == o) {
126             return true;
127         }
128         if (o == null || getClass() != o.getClass()) {
129             return false;
130         }
131 
132         FileTransformerConfiguration that = (FileTransformerConfiguration) o;
133 
134         if (fileWriteOption != that.fileWriteOption) {
135             return false;
136         }
137         if (failureBehavior != that.failureBehavior) {
138             return false;
139         }
140         return Objects.equals(executorService, that.executorService);
141     }
142 
143     @Override
hashCode()144     public int hashCode() {
145         int result = fileWriteOption != null ? fileWriteOption.hashCode() : 0;
146         result = 31 * result + (failureBehavior != null ? failureBehavior.hashCode() : 0);
147         result = 31 * result + (executorService != null ? executorService.hashCode() : 0);
148         return result;
149     }
150 
151     /**
152      * Defines how the SDK should write the file
153      */
154     public enum FileWriteOption {
155         /**
156          * Always create a new file. If the file already exists, {@link FileAlreadyExistsException} will be thrown.
157          */
158         CREATE_NEW,
159 
160         /**
161          * Create a new file if it doesn't exist, otherwise replace the existing file.
162          */
163         CREATE_OR_REPLACE_EXISTING,
164 
165         /**
166          * Create a new file if it doesn't exist, otherwise append to the existing file.
167          */
168         CREATE_OR_APPEND_TO_EXISTING
169     }
170 
171     /**
172      * Defines how the SDK should handle the file if there is an exception
173      */
174     public enum FailureBehavior {
175         /**
176          * In the event of an error, the SDK will attempt to delete the file and whatever has been written to it so far.
177          */
178         DELETE,
179 
180         /**
181          * In the event of an error, the SDK will NOT attempt to delete the file and leave the file as-is (with whatever has been
182          * written to it so far)
183          */
184         LEAVE
185     }
186 
187     public interface Builder extends CopyableBuilder<Builder, FileTransformerConfiguration> {
188 
189         /**
190          * Configures how to write the file
191          *
192          * @param fileWriteOption the file write option
193          * @return This object for method chaining.
194          */
fileWriteOption(FileWriteOption fileWriteOption)195         Builder fileWriteOption(FileWriteOption fileWriteOption);
196 
197         /**
198          * Configures the {@link FailureBehavior} in the event of an error
199          *
200          * @param failureBehavior the failure behavior
201          * @return This object for method chaining.
202          */
failureBehavior(FailureBehavior failureBehavior)203         Builder failureBehavior(FailureBehavior failureBehavior);
204 
205         /**
206          * Configures the {@link ExecutorService} the writes should be executed on.
207          *
208          * @param executorService the executor service to use, or null if using the default thread pool.
209          * @return This object for method chaining.
210          */
executorService(ExecutorService executorService)211         Builder executorService(ExecutorService executorService);
212     }
213 
214     private static final class DefaultBuilder implements Builder {
215         private FileWriteOption fileWriteOption;
216         private FailureBehavior failureBehavior;
217         private ExecutorService executorService;
218 
DefaultBuilder()219         private DefaultBuilder() {
220         }
221 
DefaultBuilder(FileTransformerConfiguration fileTransformerConfiguration)222         private DefaultBuilder(FileTransformerConfiguration fileTransformerConfiguration) {
223             this.fileWriteOption = fileTransformerConfiguration.fileWriteOption;
224             this.failureBehavior = fileTransformerConfiguration.failureBehavior;
225             this.executorService = fileTransformerConfiguration.executorService;
226         }
227 
228         @Override
fileWriteOption(FileWriteOption fileWriteOption)229         public Builder fileWriteOption(FileWriteOption fileWriteOption) {
230             this.fileWriteOption = fileWriteOption;
231             return this;
232         }
233 
234         @Override
failureBehavior(FailureBehavior failureBehavior)235         public Builder failureBehavior(FailureBehavior failureBehavior) {
236             this.failureBehavior = failureBehavior;
237             return this;
238         }
239 
240         @Override
executorService(ExecutorService executorService)241         public Builder executorService(ExecutorService executorService) {
242             this.executorService = executorService;
243             return this;
244         }
245 
246         @Override
build()247         public FileTransformerConfiguration build() {
248             return new FileTransformerConfiguration(this);
249         }
250     }
251 
252 }