PageRenderTime 54ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/release-0.1-rc2/hive/external/serde/src/java/org/apache/hadoop/hive/serde2/objectinspector/ObjectInspectorFactory.java

#
Java | 295 lines | 203 code | 32 blank | 60 comment | 28 complexity | dd532b5c8863f18cc604528c1c94f7bd MD5 | raw file
Possible License(s): Apache-2.0, BSD-3-Clause, JSON, CPL-1.0
  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.hadoop.hive.serde2.objectinspector;
  19. import java.lang.reflect.Field;
  20. import java.lang.reflect.GenericArrayType;
  21. import java.lang.reflect.ParameterizedType;
  22. import java.lang.reflect.Type;
  23. import java.util.ArrayList;
  24. import java.util.Arrays;
  25. import java.util.HashMap;
  26. import java.util.List;
  27. import java.util.Map;
  28. import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
  29. import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
  30. import org.apache.hadoop.io.Text;
  31. /**
  32. * ObjectInspectorFactory is the primary way to create new ObjectInspector
  33. * instances.
  34. *
  35. * SerDe classes should call the static functions in this library to create an
  36. * ObjectInspector to return to the caller of SerDe2.getObjectInspector().
  37. *
  38. * The reason of having caches here is that ObjectInspector is because
  39. * ObjectInspectors do not have an internal state - so ObjectInspectors with the
  40. * same construction parameters should result in exactly the same
  41. * ObjectInspector.
  42. */
  43. public final class ObjectInspectorFactory {
  44. /**
  45. * ObjectInspectorOptions describes what ObjectInspector to use. JAVA is to
  46. * use pure JAVA reflection. THRIFT is to use JAVA reflection and filter out
  47. * __isset fields, PROTOCOL_BUFFERS filters out has*.
  48. * New ObjectInspectorOptions can be added here when available.
  49. *
  50. * We choose to use a single HashMap objectInspectorCache to cache all
  51. * situations for efficiency and code simplicity. And we don't expect a case
  52. * that a user need to create 2 or more different types of ObjectInspectors
  53. * for the same Java type.
  54. */
  55. public enum ObjectInspectorOptions {
  56. JAVA, THRIFT, PROTOCOL_BUFFERS
  57. };
  58. private static HashMap<Type, ObjectInspector> objectInspectorCache = new HashMap<Type, ObjectInspector>();
  59. public static ObjectInspector getReflectionObjectInspector(Type t,
  60. ObjectInspectorOptions options) {
  61. ObjectInspector oi = objectInspectorCache.get(t);
  62. if (oi == null) {
  63. oi = getReflectionObjectInspectorNoCache(t, options);
  64. objectInspectorCache.put(t, oi);
  65. }
  66. verifyObjectInspector(options, oi, ObjectInspectorOptions.JAVA, new Class[]{ThriftStructObjectInspector.class,
  67. ProtocolBuffersStructObjectInspector.class});
  68. verifyObjectInspector(options, oi, ObjectInspectorOptions.THRIFT, new Class[]{ReflectionStructObjectInspector.class,
  69. ProtocolBuffersStructObjectInspector.class});
  70. verifyObjectInspector(options, oi, ObjectInspectorOptions.PROTOCOL_BUFFERS, new Class[]{ThriftStructObjectInspector.class,
  71. ReflectionStructObjectInspector.class});
  72. return oi;
  73. }
  74. /**
  75. * Verify that we don't have an unexpected type of object inspector.
  76. * @param option The option to verify
  77. * @param oi The ObjectInspector to verify
  78. * @param checkOption We're only interested in this option type
  79. * @param classes ObjectInspector should not be of these types
  80. */
  81. private static void verifyObjectInspector(ObjectInspectorOptions option, ObjectInspector oi,
  82. ObjectInspectorOptions checkOption, Class[] classes) {
  83. if (option.equals(checkOption)) {
  84. for (Class checkClass : classes) {
  85. if (oi.getClass().equals(checkClass)) {
  86. throw new RuntimeException(
  87. "Cannot call getObjectInspectorByReflection with more then one of " +
  88. Arrays.toString(ObjectInspectorOptions.values()) + "!");
  89. }
  90. }
  91. }
  92. }
  93. private static ObjectInspector getReflectionObjectInspectorNoCache(Type t,
  94. ObjectInspectorOptions options) {
  95. if (t instanceof GenericArrayType) {
  96. GenericArrayType at = (GenericArrayType) t;
  97. return getStandardListObjectInspector(getReflectionObjectInspector(at
  98. .getGenericComponentType(), options));
  99. }
  100. if (t instanceof ParameterizedType) {
  101. ParameterizedType pt = (ParameterizedType) t;
  102. // List?
  103. if (List.class.isAssignableFrom((Class<?>) pt.getRawType())) {
  104. return getStandardListObjectInspector(getReflectionObjectInspector(pt
  105. .getActualTypeArguments()[0], options));
  106. }
  107. // Map?
  108. if (Map.class.isAssignableFrom((Class<?>) pt.getRawType())) {
  109. return getStandardMapObjectInspector(getReflectionObjectInspector(pt
  110. .getActualTypeArguments()[0], options),
  111. getReflectionObjectInspector(pt.getActualTypeArguments()[1],
  112. options));
  113. }
  114. // Otherwise convert t to RawType so we will fall into the following if
  115. // block.
  116. t = pt.getRawType();
  117. }
  118. // Must be a class.
  119. if (!(t instanceof Class)) {
  120. throw new RuntimeException(ObjectInspectorFactory.class.getName()
  121. + " internal error:" + t);
  122. }
  123. Class<?> c = (Class<?>) t;
  124. // Java Primitive Type?
  125. if (PrimitiveObjectInspectorUtils.isPrimitiveJavaType(c)) {
  126. return PrimitiveObjectInspectorFactory
  127. .getPrimitiveJavaObjectInspector(PrimitiveObjectInspectorUtils
  128. .getTypeEntryFromPrimitiveJavaType(c).primitiveCategory);
  129. }
  130. // Java Primitive Class?
  131. if (PrimitiveObjectInspectorUtils.isPrimitiveJavaClass(c)) {
  132. return PrimitiveObjectInspectorFactory
  133. .getPrimitiveJavaObjectInspector(PrimitiveObjectInspectorUtils
  134. .getTypeEntryFromPrimitiveJavaClass(c).primitiveCategory);
  135. }
  136. // Primitive Writable class?
  137. if (PrimitiveObjectInspectorUtils.isPrimitiveWritableClass(c)) {
  138. return PrimitiveObjectInspectorFactory
  139. .getPrimitiveWritableObjectInspector(PrimitiveObjectInspectorUtils
  140. .getTypeEntryFromPrimitiveWritableClass(c).primitiveCategory);
  141. }
  142. // Must be struct because List and Map need to be ParameterizedType
  143. assert (!List.class.isAssignableFrom(c));
  144. assert (!Map.class.isAssignableFrom(c));
  145. // Create StructObjectInspector
  146. ReflectionStructObjectInspector oi;
  147. switch (options) {
  148. case JAVA:
  149. oi = new ReflectionStructObjectInspector();
  150. break;
  151. case THRIFT:
  152. oi = new ThriftStructObjectInspector();
  153. break;
  154. case PROTOCOL_BUFFERS:
  155. oi = new ProtocolBuffersStructObjectInspector();
  156. break;
  157. default:
  158. throw new RuntimeException(ObjectInspectorFactory.class.getName()
  159. + ": internal error.");
  160. }
  161. // put it into the cache BEFORE it is initialized to make sure we can catch
  162. // recursive types.
  163. objectInspectorCache.put(t, oi);
  164. Field[] fields = ObjectInspectorUtils.getDeclaredNonStaticFields(c);
  165. ArrayList<ObjectInspector> structFieldObjectInspectors = new ArrayList<ObjectInspector>(
  166. fields.length);
  167. for (int i = 0; i < fields.length; i++) {
  168. if (!oi.shouldIgnoreField(fields[i].getName())) {
  169. structFieldObjectInspectors.add(getReflectionObjectInspector(fields[i]
  170. .getGenericType(), options));
  171. }
  172. }
  173. oi.init(c, structFieldObjectInspectors);
  174. return oi;
  175. }
  176. static HashMap<ObjectInspector, StandardListObjectInspector> cachedStandardListObjectInspector = new HashMap<ObjectInspector, StandardListObjectInspector>();
  177. public static StandardListObjectInspector getStandardListObjectInspector(
  178. ObjectInspector listElementObjectInspector) {
  179. StandardListObjectInspector result = cachedStandardListObjectInspector
  180. .get(listElementObjectInspector);
  181. if (result == null) {
  182. result = new StandardListObjectInspector(listElementObjectInspector);
  183. cachedStandardListObjectInspector.put(listElementObjectInspector, result);
  184. }
  185. return result;
  186. }
  187. static HashMap<List<ObjectInspector>, StandardMapObjectInspector> cachedStandardMapObjectInspector = new HashMap<List<ObjectInspector>, StandardMapObjectInspector>();
  188. public static StandardMapObjectInspector getStandardMapObjectInspector(
  189. ObjectInspector mapKeyObjectInspector,
  190. ObjectInspector mapValueObjectInspector) {
  191. ArrayList<ObjectInspector> signature = new ArrayList<ObjectInspector>(2);
  192. signature.add(mapKeyObjectInspector);
  193. signature.add(mapValueObjectInspector);
  194. StandardMapObjectInspector result = cachedStandardMapObjectInspector
  195. .get(signature);
  196. if (result == null) {
  197. result = new StandardMapObjectInspector(mapKeyObjectInspector,
  198. mapValueObjectInspector);
  199. cachedStandardMapObjectInspector.put(signature, result);
  200. }
  201. return result;
  202. }
  203. static HashMap<List<ObjectInspector>, StandardUnionObjectInspector>
  204. cachedStandardUnionObjectInspector =
  205. new HashMap<List<ObjectInspector>, StandardUnionObjectInspector>();
  206. public static StandardUnionObjectInspector getStandardUnionObjectInspector(
  207. List<ObjectInspector> unionObjectInspectors) {
  208. StandardUnionObjectInspector result = cachedStandardUnionObjectInspector
  209. .get(unionObjectInspectors);
  210. if (result == null) {
  211. result = new StandardUnionObjectInspector(unionObjectInspectors);
  212. cachedStandardUnionObjectInspector.put(unionObjectInspectors, result);
  213. }
  214. return result;
  215. }
  216. static HashMap<ArrayList<List<?>>, StandardStructObjectInspector> cachedStandardStructObjectInspector = new HashMap<ArrayList<List<?>>, StandardStructObjectInspector>();
  217. public static StandardStructObjectInspector getStandardStructObjectInspector(
  218. List<String> structFieldNames,
  219. List<ObjectInspector> structFieldObjectInspectors) {
  220. ArrayList<List<?>> signature = new ArrayList<List<?>>();
  221. signature.add(structFieldNames);
  222. signature.add(structFieldObjectInspectors);
  223. StandardStructObjectInspector result = cachedStandardStructObjectInspector
  224. .get(signature);
  225. if (result == null) {
  226. result = new StandardStructObjectInspector(structFieldNames,
  227. structFieldObjectInspectors);
  228. cachedStandardStructObjectInspector.put(signature, result);
  229. }
  230. return result;
  231. }
  232. static HashMap<List<StructObjectInspector>, UnionStructObjectInspector> cachedUnionStructObjectInspector = new HashMap<List<StructObjectInspector>, UnionStructObjectInspector>();
  233. public static UnionStructObjectInspector getUnionStructObjectInspector(
  234. List<StructObjectInspector> structObjectInspectors) {
  235. UnionStructObjectInspector result = cachedUnionStructObjectInspector
  236. .get(structObjectInspectors);
  237. if (result == null) {
  238. result = new UnionStructObjectInspector(structObjectInspectors);
  239. cachedUnionStructObjectInspector.put(structObjectInspectors, result);
  240. }
  241. return result;
  242. }
  243. static HashMap<ArrayList<Object>, ColumnarStructObjectInspector> cachedColumnarStructObjectInspector = new HashMap<ArrayList<Object>, ColumnarStructObjectInspector>();
  244. public static ColumnarStructObjectInspector getColumnarStructObjectInspector(
  245. List<String> structFieldNames,
  246. List<ObjectInspector> structFieldObjectInspectors, Text nullSequence) {
  247. ArrayList<Object> signature = new ArrayList<Object>();
  248. signature.add(structFieldNames);
  249. signature.add(structFieldObjectInspectors);
  250. signature.add(nullSequence.toString());
  251. ColumnarStructObjectInspector result = cachedColumnarStructObjectInspector
  252. .get(signature);
  253. if (result == null) {
  254. result = new ColumnarStructObjectInspector(structFieldNames,
  255. structFieldObjectInspectors, nullSequence);
  256. cachedColumnarStructObjectInspector.put(signature, result);
  257. }
  258. return result;
  259. }
  260. private ObjectInspectorFactory() {
  261. // prevent instantiation
  262. }
  263. }