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    }