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 }