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, and create a Writable filter.
98     * This filter class most likely extends Configurable.
99     *
100    * @param className the filter class name.
101    * @return a filter
102    */
103   @SuppressWarnings("unchecked")
104   public static Filter createWritableForName(String className) {
105     try {
106       Class<? extends Filter> clazz =
107         (Class<? extends Filter>) Class.forName(className, true, CLASS_LOADER);
108       return (Filter)WritableFactories.newInstance(clazz, new Configuration());
109     } catch (ClassNotFoundException e) {
110       throw new RuntimeException("Can't find class " + className);
111     }
112   }
113 
114   /**
115    * This method is almost the same as #createWritableForName, except
116    * that this one doesn't expect the filter class to extends Configurable.
117    *
118    * @param className the filter class name.
119    * @return a filter
120    */
121   @SuppressWarnings("unchecked")
122   public static Filter createForName(String className) {
123     try {
124       Class<? extends Filter> clazz =
125         (Class<? extends Filter>)Class.forName(className, true, CLASS_LOADER);
126       return (Filter)clazz.newInstance();
127     } catch (ClassNotFoundException e) {
128       throw new RuntimeException("Can't find class " + className);
129     } catch (InstantiationException e) {
130       throw new RuntimeException("Couldn't instantiate " + className, e);
131     } catch (IllegalAccessException e) {
132       throw new RuntimeException("No access to " + className, e);
133     }
134   }
135 }