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.Progressable;
024
025 /**
026 * This class contains options related to file system operations.
027 */
028 @InterfaceAudience.Public
029 @InterfaceStability.Evolving
030 public final class Options {
031 /**
032 * Class to support the varargs for create() options.
033 *
034 */
035 public static class CreateOpts {
036 private CreateOpts() { };
037 public static BlockSize blockSize(long bs) {
038 return new BlockSize(bs);
039 }
040 public static BufferSize bufferSize(int bs) {
041 return new BufferSize(bs);
042 }
043 public static ReplicationFactor repFac(short rf) {
044 return new ReplicationFactor(rf);
045 }
046 public static BytesPerChecksum bytesPerChecksum(short crc) {
047 return new BytesPerChecksum(crc);
048 }
049 public static Perms perms(FsPermission perm) {
050 return new Perms(perm);
051 }
052 public static CreateParent createParent() {
053 return new CreateParent(true);
054 }
055 public static CreateParent donotCreateParent() {
056 return new CreateParent(false);
057 }
058
059 public static class BlockSize extends CreateOpts {
060 private final long blockSize;
061 protected BlockSize(long bs) {
062 if (bs <= 0) {
063 throw new IllegalArgumentException(
064 "Block size must be greater than 0");
065 }
066 blockSize = bs;
067 }
068 public long getValue() { return blockSize; }
069 }
070
071 public static class ReplicationFactor extends CreateOpts {
072 private final short replication;
073 protected ReplicationFactor(short rf) {
074 if (rf <= 0) {
075 throw new IllegalArgumentException(
076 "Replication must be greater than 0");
077 }
078 replication = rf;
079 }
080 public short getValue() { return replication; }
081 }
082
083 public static class BufferSize extends CreateOpts {
084 private final int bufferSize;
085 protected BufferSize(int bs) {
086 if (bs <= 0) {
087 throw new IllegalArgumentException(
088 "Buffer size must be greater than 0");
089 }
090 bufferSize = bs;
091 }
092 public int getValue() { return bufferSize; }
093 }
094
095 public static class BytesPerChecksum extends CreateOpts {
096 private final int bytesPerChecksum;
097 protected BytesPerChecksum(short bpc) {
098 if (bpc <= 0) {
099 throw new IllegalArgumentException(
100 "Bytes per checksum must be greater than 0");
101 }
102 bytesPerChecksum = bpc;
103 }
104 public int getValue() { return bytesPerChecksum; }
105 }
106
107 public static class Perms extends CreateOpts {
108 private final FsPermission permissions;
109 protected Perms(FsPermission perm) {
110 if(perm == null) {
111 throw new IllegalArgumentException("Permissions must not be null");
112 }
113 permissions = perm;
114 }
115 public FsPermission getValue() { return permissions; }
116 }
117
118 public static class Progress extends CreateOpts {
119 private final Progressable progress;
120 protected Progress(Progressable prog) {
121 if(prog == null) {
122 throw new IllegalArgumentException("Progress must not be null");
123 }
124 progress = prog;
125 }
126 public Progressable getValue() { return progress; }
127 }
128
129 public static class CreateParent extends CreateOpts {
130 private final boolean createParent;
131 protected CreateParent(boolean createPar) {
132 createParent = createPar;}
133 public boolean getValue() { return createParent; }
134 }
135
136
137 /**
138 * Get an option of desired type
139 * @param theClass is the desired class of the opt
140 * @param opts - not null - at least one opt must be passed
141 * @return an opt from one of the opts of type theClass.
142 * returns null if there isn't any
143 */
144 protected static CreateOpts getOpt(Class<? extends CreateOpts> theClass, CreateOpts ...opts) {
145 if (opts == null) {
146 throw new IllegalArgumentException("Null opt");
147 }
148 CreateOpts result = null;
149 for (int i = 0; i < opts.length; ++i) {
150 if (opts[i].getClass() == theClass) {
151 if (result != null)
152 throw new IllegalArgumentException("multiple blocksize varargs");
153 result = opts[i];
154 }
155 }
156 return result;
157 }
158 /**
159 * set an option
160 * @param newValue the option to be set
161 * @param opts - the option is set into this array of opts
162 * @return updated CreateOpts[] == opts + newValue
163 */
164 protected static <T extends CreateOpts> CreateOpts[] setOpt(T newValue,
165 CreateOpts ...opts) {
166 boolean alreadyInOpts = false;
167 if (opts != null) {
168 for (int i = 0; i < opts.length; ++i) {
169 if (opts[i].getClass() == newValue.getClass()) {
170 if (alreadyInOpts)
171 throw new IllegalArgumentException("multiple opts varargs");
172 alreadyInOpts = true;
173 opts[i] = newValue;
174 }
175 }
176 }
177 CreateOpts[] resultOpt = opts;
178 if (!alreadyInOpts) { // no newValue in opt
179 CreateOpts[] newOpts = new CreateOpts[opts.length + 1];
180 System.arraycopy(opts, 0, newOpts, 0, opts.length);
181 newOpts[opts.length] = newValue;
182 resultOpt = newOpts;
183 }
184 return resultOpt;
185 }
186 }
187
188 /**
189 * Enum to support the varargs for rename() options
190 */
191 public static enum Rename {
192 NONE((byte) 0), // No options
193 OVERWRITE((byte) 1); // Overwrite the rename destination
194
195 private final byte code;
196
197 private Rename(byte code) {
198 this.code = code;
199 }
200
201 public static Rename valueOf(byte code) {
202 return code < 0 || code >= values().length ? null : values()[code];
203 }
204
205 public byte value() {
206 return code;
207 }
208 }
209 }