001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with this
004     * work for additional information regarding copyright ownership. The ASF
005     * licenses this file to you under the Apache License, Version 2.0 (the
006     * "License"); you may not use this file except in compliance with the License.
007     * You may obtain a copy of the License at
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014     * License for the specific language governing permissions and limitations under
015     * the License.
016     */
017    package org.apache.hadoop.util;
018    
019    import java.io.IOException;
020    import java.util.Arrays;
021    
022    import org.apache.hadoop.fs.FSDataInputStream;
023    import org.apache.hadoop.fs.FSDataOutputStream;
024    import org.apache.hadoop.fs.Path;
025    
026    /**
027     * This class allows generic access to variable length type-safe parameter
028     * lists.
029     */
030    public class Options {
031    
032      public static abstract class StringOption {
033        private final String value;
034        protected StringOption(String value) {
035          this.value = value;
036        }
037        public String getValue() {
038          return value;
039        }
040      }
041    
042      public static abstract class ClassOption {
043        private final Class<?> value;
044        protected ClassOption(Class<?> value) {
045          this.value = value;
046        }
047        public Class<?> getValue() {
048          return value;
049        }
050      }
051    
052      public static abstract class BooleanOption {
053        private final boolean value;
054        protected BooleanOption(boolean value) {
055          this.value = value;
056        }
057        public boolean getValue() {
058          return value;
059        }
060      }
061    
062      public static abstract class IntegerOption {
063        private final int value;
064        protected IntegerOption(int value) {
065          this.value = value;
066        }
067        public int getValue() {
068          return value;
069        }
070      }
071    
072      public static abstract class LongOption {
073        private final long value;
074        protected LongOption(long value) {
075          this.value = value;
076        }
077        public long getValue() {
078          return value;
079        }
080      }
081    
082      public static abstract class PathOption {
083        private final Path value;
084        protected PathOption(Path value) {
085          this.value = value;
086        }
087        public Path getValue() {
088          return value;
089        }
090      }
091    
092      public static abstract class FSDataInputStreamOption {
093        private final FSDataInputStream value;
094        protected FSDataInputStreamOption(FSDataInputStream value) {
095          this.value = value;
096        }
097        public FSDataInputStream getValue() {
098          return value;
099        }
100      }
101    
102      public static abstract class FSDataOutputStreamOption {
103        private final FSDataOutputStream value;
104        protected FSDataOutputStreamOption(FSDataOutputStream value) {
105          this.value = value;
106        }
107        public FSDataOutputStream getValue() {
108          return value;
109        }
110      }
111    
112      public static abstract class ProgressableOption {
113        private final Progressable value;
114        protected ProgressableOption(Progressable value) {
115          this.value = value;
116        }
117        public Progressable getValue() {
118          return value;
119        }
120      }
121    
122      /**
123       * Find the first option of the required class.
124       * @param <T> the static class to find
125       * @param <base> the parent class of the array
126       * @param cls the dynamic class to find
127       * @param opts the list of options to look through
128       * @return the first option that matches
129       * @throws IOException
130       */
131      @SuppressWarnings("unchecked")
132      public static <base, T extends base> T getOption(Class<T> cls, base [] opts
133                                                       ) throws IOException {
134        for(base o: opts) {
135          if (o.getClass() == cls) {
136            return (T) o;
137          }
138        }
139        return null;
140      }
141    
142      /**
143       * Prepend some new options to the old options
144       * @param <T> the type of options
145       * @param oldOpts the old options
146       * @param newOpts the new options
147       * @return a new array of options
148       */
149      public static <T> T[] prependOptions(T[] oldOpts, T... newOpts) {
150        // copy the new options to the front of the array
151        T[] result = Arrays.copyOf(newOpts, newOpts.length+oldOpts.length);
152        // now copy the old options
153        System.arraycopy(oldOpts, 0, result, newOpts.length, oldOpts.length);
154        return result;
155      }
156    }