View Javadoc

1   /*
2    * Copyright The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase.util;
22  
23  import org.apache.hadoop.conf.Configuration;
24  import org.apache.hadoop.hbase.HBaseConfiguration;
25  import org.apache.hadoop.hbase.filter.Filter;
26  import org.apache.hadoop.io.WritableFactories;
27  
28  /**
29   * Utilities for class manipulation.
30   */
31  public class Classes {
32  
33    /**
34     * Dynamic class loader to load filter/comparators
35     */
36    private final static ClassLoader CLASS_LOADER;
37  
38    static {
39      ClassLoader parent = Classes.class.getClassLoader();
40      Configuration conf = HBaseConfiguration.create();
41      CLASS_LOADER = new DynamicClassLoader(conf, parent);
42    }
43  
44    /**
45     * Equivalent of {@link Class#forName(String)} which also returns classes for
46     * primitives like <code>boolean</code>, etc.
47     * 
48     * @param className
49     *          The name of the class to retrieve. Can be either a normal class or
50     *          a primitive class.
51     * @return The class specified by <code>className</code>
52     * @throws ClassNotFoundException
53     *           If the requested class can not be found.
54     */
55    public static Class<?> extendedForName(String className)
56        throws ClassNotFoundException {
57      Class<?> valueType;
58      if (className.equals("boolean")) {
59        valueType = boolean.class;
60      } else if (className.equals("byte")) {
61        valueType = byte.class;
62      } else if (className.equals("short")) {
63        valueType = short.class;
64      } else if (className.equals("int")) {
65        valueType = int.class;
66      } else if (className.equals("long")) {
67        valueType = long.class;
68      } else if (className.equals("float")) {
69        valueType = float.class;
70      } else if (className.equals("double")) {
71        valueType = double.class;
72      } else if (className.equals("char")) {
73        valueType = char.class;
74      } else {
75        valueType = Class.forName(className);
76      }
77      return valueType;
78    }
79  
80    @SuppressWarnings("rawtypes")
81    public static String stringify(Class[] classes) {
82      StringBuilder buf = new StringBuilder();
83      if (classes != null) {
84        for (Class c : classes) {
85          if (buf.length() > 0) {
86            buf.append(",");
87          }
88          buf.append(c.getName());
89        }
90      } else {
91        buf.append("NULL");
92      }
93      return buf.toString();
94    }
95  
96    /**
97     * Used to dynamically load a filter class.
98     *
99     * @param className the filter class name
100    * @return a filter class
101    * @throws ClassNotFoundException if couldn't find the class
102    */
103   @SuppressWarnings("unchecked")
104   public static Class<? extends Filter> getFilterClassByName(
105       String className) throws ClassNotFoundException {
106     return (Class<? extends Filter>) Class.forName(className, true, CLASS_LOADER);
107   }
108 
109   /**
110    * Used to dynamically load a filter class, and create a Writable filter.
111    * This filter class most likely extends Configurable.
112    *
113    * @param className the filter class name.
114    * @return a filter
115    */
116   public static Filter createWritableForName(String className) {
117     try {
118       Class<? extends Filter> clazz = getFilterClassByName(className);
119       return (Filter)WritableFactories.newInstance(clazz, new Configuration());
120     } catch (ClassNotFoundException e) {
121       throw new RuntimeException("Can't find class " + className);
122     }
123   }
124 
125   /**
126    * This method is almost the same as #createWritableForName, except
127    * that this one doesn't expect the filter class to extends Configurable.
128    *
129    * @param className the filter class name.
130    * @return a filter
131    */
132   public static Filter createForName(String className) {
133     try {
134       Class<? extends Filter> clazz = getFilterClassByName(className);
135       return (Filter)clazz.newInstance();
136     } catch (ClassNotFoundException e) {
137       throw new RuntimeException("Can't find class " + className);
138     } catch (InstantiationException e) {
139       throw new RuntimeException("Couldn't instantiate " + className, e);
140     } catch (IllegalAccessException e) {
141       throw new RuntimeException("No access to " + className, e);
142     }
143   }
144 }