This project has retired. For details please refer to its Attic page.
ClassConfOption xref
View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.giraph.conf;
19  
20  import org.apache.giraph.utils.ReflectionUtils;
21  import org.apache.hadoop.conf.Configuration;
22  import org.apache.log4j.Logger;
23  
24  import com.google.common.base.Objects;
25  
26  /**
27   * Class configuration option
28   *
29   * @param <C> interface of class
30   */
31  public class ClassConfOption<C> extends AbstractConfOption {
32    /** Logger */
33    private static final Logger LOG = Logger.getLogger(ClassConfOption.class);
34  
35    /** Base interface for class */
36    private final Class<C> interfaceClass;
37    /** Default class if not set in configuration */
38    private final Class<? extends C> defaultClass;
39  
40    /**
41     * Private constructor
42     *
43     * @param key Key
44     * @param defaultClass default class
45     * @param interfaceClass interface class
46     * @param description configuration description
47     */
48    private ClassConfOption(String key, Class<? extends C> defaultClass,
49        Class<C> interfaceClass, String description) {
50      super(key, description);
51      this.defaultClass = defaultClass;
52      this.interfaceClass = interfaceClass;
53    }
54  
55    /**
56     * Static create method
57     *
58     * @param key key
59     * @param defaultClass default class
60     * @param interfaceClass interface class
61     * @param description configuration description
62     * @param <T> type of class
63     * @return ClassConfOption
64     */
65    public static <T> ClassConfOption<T> create(String key,
66        Class<? extends T> defaultClass, Class<T> interfaceClass,
67        String description) {
68      return new ClassConfOption<T>(key, defaultClass, interfaceClass,
69                                    description);
70    }
71  
72    public Class<? extends C> getDefaultClass() {
73      return defaultClass;
74    }
75  
76    public Class<C> getInterfaceClass() {
77      return interfaceClass;
78    }
79  
80    @Override public boolean isDefaultValue(Configuration conf) {
81      return Objects.equal(get(conf), defaultClass);
82    }
83  
84    @Override public String getDefaultValueStr() {
85      return defaultClass == null ? "null" : defaultClass.getSimpleName();
86    }
87  
88    @Override public ConfOptionType getType() {
89      return ConfOptionType.CLASS;
90    }
91  
92    @Override public String toString() {
93      StringBuilder sb = new StringBuilder(30);
94      sb.append("  ");
95      sb.append(getKey()).append(" => ").append(getDefaultValueStr());
96      sb.append(" [").append(interfaceClass.getSimpleName()).append("] ");
97      sb.append(" (").append(getType().toString().toLowerCase()).append(")\n");
98      return sb.toString();
99    }
100 
101   /**
102    * Create a new instance
103    *
104    * @param conf Configuration
105    * @return new instance of class held by this key
106    */
107   public C newInstance(Configuration conf) {
108     Class<? extends C> klass = get(conf);
109     if (klass == null) {
110       return null;
111     }
112     if (conf instanceof ImmutableClassesGiraphConfiguration) {
113       return ReflectionUtils.newInstance(klass,
114           (ImmutableClassesGiraphConfiguration) conf);
115     } else {
116       return org.apache.hadoop.util.ReflectionUtils.newInstance(klass, conf);
117     }
118   }
119 
120   /**
121    * Lookup value
122    *
123    * @param conf Configuration
124    * @return Class set for key, or defaultClass
125    */
126   public Class<? extends C> get(Configuration conf) {
127     return conf.getClass(getKey(), defaultClass, interfaceClass);
128   }
129 
130   /**
131    * Lookup array of classes for key
132    *
133    * @param conf Configuration
134    * @return array of classes
135    */
136   public Class<? extends C>[] getArray(Configuration conf) {
137     return getClassesOfType(conf, getKey(), interfaceClass);
138   }
139 
140   /**
141    * Get classes from a property that all implement a given interface.
142    *
143    * @param conf Configuration
144    * @param name String name of property to fetch.
145    * @param xface interface classes must implement.
146    * @param defaultValue If not found, return this
147    * @param <T> Generic type of interface class
148    * @return array of Classes implementing interface specified.
149    */
150   public static <T> Class<? extends T>[] getClassesOfType(Configuration conf,
151       String name, Class<T> xface, Class<? extends T> ... defaultValue) {
152     Class<?>[] klasses = conf.getClasses(name, defaultValue);
153     for (Class<?> klass : klasses) {
154       if (!xface.isAssignableFrom(klass)) {
155         throw new RuntimeException(klass + " is not assignable from " +
156             xface.getName());
157       }
158     }
159     return (Class<? extends T>[]) klasses;
160   }
161 
162   /**
163    * Lookup with user specified default value
164    *
165    * @param conf Configuration
166    * @param defaultValue default value
167    * @return Class
168    */
169   public Class<? extends C> getWithDefault(Configuration conf,
170       Class<? extends C> defaultValue) {
171     return conf.getClass(getKey(), defaultValue, interfaceClass);
172   }
173 
174   /**
175    * Set value for key
176    *
177    * @param conf Configuration
178    * @param klass Class to set
179    */
180   public void set(Configuration conf, Class<? extends C> klass) {
181     conf.setClass(getKey(), klass, interfaceClass);
182   }
183 
184   /**
185    * Set value for key if it is not already set
186    *
187    * @param conf Configuration
188    * @param klass Class to set
189    */
190   public void setIfUnset(Configuration conf, Class<? extends C> klass) {
191     if (!contains(conf)) {
192       set(conf, klass);
193     }
194   }
195 
196   /**
197    * Set classes for this key
198    *
199    * @param conf Configuration
200    * @param klasses Classes to set
201    */
202   public void setMany(Configuration conf, Class<? extends C> ... klasses) {
203     String[] klassNames = new String[klasses.length];
204     for (int i = 0; i < klasses.length; ++i) {
205       Class<?> klass = klasses[i];
206       if (!interfaceClass.isAssignableFrom(klass)) {
207         throw new RuntimeException(klass + " does not implement " +
208             interfaceClass.getName());
209       }
210       klassNames[i] = klasses[i].getName();
211     }
212     conf.setStrings(getKey(), klassNames);
213   }
214 
215   /**
216    * Add class to list for key
217    *
218    * @param conf Configuration
219    * @param klass Class to add
220    */
221   public void add(Configuration conf, Class<? extends C> klass) {
222     addToClasses(conf, getKey(), klass, interfaceClass);
223   }
224 
225   /**
226    * Add a class to a property that is a list of classes. If the property does
227    * not exist it will be created.
228    *
229    * @param <T> type of class
230    * @param conf Configuration
231    * @param name String name of property.
232    * @param klass interface of the class being set.
233    * @param xface Class to add to the list.
234    */
235   public static <T> void addToClasses(Configuration conf, String name,
236       Class<? extends T> klass, Class<T> xface) {
237     if (!xface.isAssignableFrom(klass)) {
238       throw new RuntimeException(klass + " does not implement " +
239           xface.getName());
240     }
241     String value;
242     String klasses = conf.get(name);
243     if (klasses == null) {
244       value = klass.getName();
245     } else {
246       value = klasses + "," + klass.getName();
247     }
248     conf.set(name, value);
249   }
250 }