001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.hadoop.fs;
019
020 import org.apache.hadoop.classification.InterfaceAudience;
021 import org.apache.hadoop.classification.InterfaceStability;
022 import org.apache.hadoop.fs.permission.FsPermission;
023 import org.apache.hadoop.util.DataChecksum;
024 import org.apache.hadoop.util.Progressable;
025
026 /**
027 * This class contains options related to file system operations.
028 */
029 @InterfaceAudience.Public
030 @InterfaceStability.Evolving
031 public final class Options {
032 /**
033 * Class to support the varargs for create() options.
034 *
035 */
036 public static class CreateOpts {
037 private CreateOpts() { };
038 public static BlockSize blockSize(long bs) {
039 return new BlockSize(bs);
040 }
041 public static BufferSize bufferSize(int bs) {
042 return new BufferSize(bs);
043 }
044 public static ReplicationFactor repFac(short rf) {
045 return new ReplicationFactor(rf);
046 }
047 public static BytesPerChecksum bytesPerChecksum(short crc) {
048 return new BytesPerChecksum(crc);
049 }
050 public static ChecksumParam checksumParam(
051 ChecksumOpt csumOpt) {
052 return new ChecksumParam(csumOpt);
053 }
054 public static Perms perms(FsPermission perm) {
055 return new Perms(perm);
056 }
057 public static CreateParent createParent() {
058 return new CreateParent(true);
059 }
060 public static CreateParent donotCreateParent() {
061 return new CreateParent(false);
062 }
063
064 public static class BlockSize extends CreateOpts {
065 private final long blockSize;
066 protected BlockSize(long bs) {
067 if (bs <= 0) {
068 throw new IllegalArgumentException(
069 "Block size must be greater than 0");
070 }
071 blockSize = bs;
072 }
073 public long getValue() { return blockSize; }
074 }
075
076 public static class ReplicationFactor extends CreateOpts {
077 private final short replication;
078 protected ReplicationFactor(short rf) {
079 if (rf <= 0) {
080 throw new IllegalArgumentException(
081 "Replication must be greater than 0");
082 }
083 replication = rf;
084 }
085 public short getValue() { return replication; }
086 }
087
088 public static class BufferSize extends CreateOpts {
089 private final int bufferSize;
090 protected BufferSize(int bs) {
091 if (bs <= 0) {
092 throw new IllegalArgumentException(
093 "Buffer size must be greater than 0");
094 }
095 bufferSize = bs;
096 }
097 public int getValue() { return bufferSize; }
098 }
099
100 /** This is not needed if ChecksumParam is specified. **/
101 public static class BytesPerChecksum extends CreateOpts {
102 private final int bytesPerChecksum;
103 protected BytesPerChecksum(short bpc) {
104 if (bpc <= 0) {
105 throw new IllegalArgumentException(
106 "Bytes per checksum must be greater than 0");
107 }
108 bytesPerChecksum = bpc;
109 }
110 public int getValue() { return bytesPerChecksum; }
111 }
112
113 public static class ChecksumParam extends CreateOpts {
114 private final ChecksumOpt checksumOpt;
115 protected ChecksumParam(ChecksumOpt csumOpt) {
116 checksumOpt = csumOpt;
117 }
118 public ChecksumOpt getValue() { return checksumOpt; }
119 }
120
121 public static class Perms extends CreateOpts {
122 private final FsPermission permissions;
123 protected Perms(FsPermission perm) {
124 if(perm == null) {
125 throw new IllegalArgumentException("Permissions must not be null");
126 }
127 permissions = perm;
128 }
129 public FsPermission getValue() { return permissions; }
130 }
131
132 public static class Progress extends CreateOpts {
133 private final Progressable progress;
134 protected Progress(Progressable prog) {
135 if(prog == null) {
136 throw new IllegalArgumentException("Progress must not be null");
137 }
138 progress = prog;
139 }
140 public Progressable getValue() { return progress; }
141 }
142
143 public static class CreateParent extends CreateOpts {
144 private final boolean createParent;
145 protected CreateParent(boolean createPar) {
146 createParent = createPar;}
147 public boolean getValue() { return createParent; }
148 }
149
150
151 /**
152 * Get an option of desired type
153 * @param clazz is the desired class of the opt
154 * @param opts - not null - at least one opt must be passed
155 * @return an opt from one of the opts of type theClass.
156 * returns null if there isn't any
157 */
158 static <T extends CreateOpts> T getOpt(Class<T> clazz, CreateOpts... opts) {
159 if (opts == null) {
160 throw new IllegalArgumentException("Null opt");
161 }
162 T result = null;
163 for (int i = 0; i < opts.length; ++i) {
164 if (opts[i].getClass() == clazz) {
165 if (result != null) {
166 throw new IllegalArgumentException("multiple opts varargs: " + clazz);
167 }
168
169 @SuppressWarnings("unchecked")
170 T t = (T)opts[i];
171 result = t;
172 }
173 }
174 return result;
175 }
176 /**
177 * set an option
178 * @param newValue the option to be set
179 * @param opts - the option is set into this array of opts
180 * @return updated CreateOpts[] == opts + newValue
181 */
182 static <T extends CreateOpts> CreateOpts[] setOpt(final T newValue,
183 final CreateOpts... opts) {
184 final Class<?> clazz = newValue.getClass();
185 boolean alreadyInOpts = false;
186 if (opts != null) {
187 for (int i = 0; i < opts.length; ++i) {
188 if (opts[i].getClass() == clazz) {
189 if (alreadyInOpts) {
190 throw new IllegalArgumentException("multiple opts varargs: " + clazz);
191 }
192 alreadyInOpts = true;
193 opts[i] = newValue;
194 }
195 }
196 }
197 CreateOpts[] resultOpt = opts;
198 if (!alreadyInOpts) { // no newValue in opt
199 final int oldLength = opts == null? 0: opts.length;
200 CreateOpts[] newOpts = new CreateOpts[oldLength + 1];
201 if (oldLength > 0) {
202 System.arraycopy(opts, 0, newOpts, 0, oldLength);
203 }
204 newOpts[oldLength] = newValue;
205 resultOpt = newOpts;
206 }
207 return resultOpt;
208 }
209 }
210
211 /**
212 * Enum to support the varargs for rename() options
213 */
214 public static enum Rename {
215 NONE((byte) 0), // No options
216 OVERWRITE((byte) 1); // Overwrite the rename destination
217
218 private final byte code;
219
220 private Rename(byte code) {
221 this.code = code;
222 }
223
224 public static Rename valueOf(byte code) {
225 return code < 0 || code >= values().length ? null : values()[code];
226 }
227
228 public byte value() {
229 return code;
230 }
231 }
232
233 /**
234 * This is used in FileSystem and FileContext to specify checksum options.
235 */
236 public static class ChecksumOpt {
237 private final DataChecksum.Type checksumType;
238 private final int bytesPerChecksum;
239
240 /**
241 * Create a uninitialized one
242 */
243 public ChecksumOpt() {
244 this(DataChecksum.Type.DEFAULT, -1);
245 }
246
247 /**
248 * Normal ctor
249 * @param type checksum type
250 * @param size bytes per checksum
251 */
252 public ChecksumOpt(DataChecksum.Type type, int size) {
253 checksumType = type;
254 bytesPerChecksum = size;
255 }
256
257 public int getBytesPerChecksum() {
258 return bytesPerChecksum;
259 }
260
261 public DataChecksum.Type getChecksumType() {
262 return checksumType;
263 }
264
265 @Override
266 public String toString() {
267 return checksumType + ":" + bytesPerChecksum;
268 }
269
270 /**
271 * Create a ChecksumOpts that disables checksum
272 */
273 public static ChecksumOpt createDisabled() {
274 return new ChecksumOpt(DataChecksum.Type.NULL, -1);
275 }
276
277 /**
278 * A helper method for processing user input and default value to
279 * create a combined checksum option. This is a bit complicated because
280 * bytesPerChecksum is kept for backward compatibility.
281 *
282 * @param defaultOpt Default checksum option
283 * @param userOpt User-specified checksum option. Ignored if null.
284 * @param userBytesPerChecksum User-specified bytesPerChecksum
285 * Ignored if < 0.
286 */
287 public static ChecksumOpt processChecksumOpt(ChecksumOpt defaultOpt,
288 ChecksumOpt userOpt, int userBytesPerChecksum) {
289 final boolean useDefaultType;
290 final DataChecksum.Type type;
291 if (userOpt != null
292 && userOpt.getChecksumType() != DataChecksum.Type.DEFAULT) {
293 useDefaultType = false;
294 type = userOpt.getChecksumType();
295 } else {
296 useDefaultType = true;
297 type = defaultOpt.getChecksumType();
298 }
299
300 // bytesPerChecksum - order of preference
301 // user specified value in bytesPerChecksum
302 // user specified value in checksumOpt
303 // default.
304 if (userBytesPerChecksum > 0) {
305 return new ChecksumOpt(type, userBytesPerChecksum);
306 } else if (userOpt != null && userOpt.getBytesPerChecksum() > 0) {
307 return !useDefaultType? userOpt
308 : new ChecksumOpt(type, userOpt.getBytesPerChecksum());
309 } else {
310 return useDefaultType? defaultOpt
311 : new ChecksumOpt(type, defaultOpt.getBytesPerChecksum());
312 }
313 }
314
315 /**
316 * A helper method for processing user input and default value to
317 * create a combined checksum option.
318 *
319 * @param defaultOpt Default checksum option
320 * @param userOpt User-specified checksum option
321 */
322 public static ChecksumOpt processChecksumOpt(ChecksumOpt defaultOpt,
323 ChecksumOpt userOpt) {
324 return processChecksumOpt(defaultOpt, userOpt, -1);
325 }
326 }
327 }