/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
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.apache.hadoop.hive.serde2.objectinspector;
- import java.lang.reflect.Field;
- import java.lang.reflect.GenericArrayType;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
- import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorUtils;
- import org.apache.hadoop.io.Text;
- /**
- * ObjectInspectorFactory is the primary way to create new ObjectInspector
- * instances.
- *
- * SerDe classes should call the static functions in this library to create an
- * ObjectInspector to return to the caller of SerDe2.getObjectInspector().
- *
- * The reason of having caches here is that ObjectInspector is because
- * ObjectInspectors do not have an internal state - so ObjectInspectors with the
- * same construction parameters should result in exactly the same
- * ObjectInspector.
- */
- public final class ObjectInspectorFactory {
- /**
- * ObjectInspectorOptions describes what ObjectInspector to use. JAVA is to
- * use pure JAVA reflection. THRIFT is to use JAVA reflection and filter out
- * __isset fields, PROTOCOL_BUFFERS filters out has*.
- * New ObjectInspectorOptions can be added here when available.
- *
- * We choose to use a single HashMap objectInspectorCache to cache all
- * situations for efficiency and code simplicity. And we don't expect a case
- * that a user need to create 2 or more different types of ObjectInspectors
- * for the same Java type.
- */
- public enum ObjectInspectorOptions {
- JAVA, THRIFT, PROTOCOL_BUFFERS
- };
- private static HashMap<Type, ObjectInspector> objectInspectorCache = new HashMap<Type, ObjectInspector>();
- public static ObjectInspector getReflectionObjectInspector(Type t,
- ObjectInspectorOptions options) {
- ObjectInspector oi = objectInspectorCache.get(t);
- if (oi == null) {
- oi = getReflectionObjectInspectorNoCache(t, options);
- objectInspectorCache.put(t, oi);
- }
- verifyObjectInspector(options, oi, ObjectInspectorOptions.JAVA, new Class[]{ThriftStructObjectInspector.class,
- ProtocolBuffersStructObjectInspector.class});
- verifyObjectInspector(options, oi, ObjectInspectorOptions.THRIFT, new Class[]{ReflectionStructObjectInspector.class,
- ProtocolBuffersStructObjectInspector.class});
- verifyObjectInspector(options, oi, ObjectInspectorOptions.PROTOCOL_BUFFERS, new Class[]{ThriftStructObjectInspector.class,
- ReflectionStructObjectInspector.class});
- return oi;
- }
- /**
- * Verify that we don't have an unexpected type of object inspector.
- * @param option The option to verify
- * @param oi The ObjectInspector to verify
- * @param checkOption We're only interested in this option type
- * @param classes ObjectInspector should not be of these types
- */
- private static void verifyObjectInspector(ObjectInspectorOptions option, ObjectInspector oi,
- ObjectInspectorOptions checkOption, Class[] classes) {
- if (option.equals(checkOption)) {
- for (Class checkClass : classes) {
- if (oi.getClass().equals(checkClass)) {
- throw new RuntimeException(
- "Cannot call getObjectInspectorByReflection with more then one of " +
- Arrays.toString(ObjectInspectorOptions.values()) + "!");
- }
- }
- }
- }
- private static ObjectInspector getReflectionObjectInspectorNoCache(Type t,
- ObjectInspectorOptions options) {
- if (t instanceof GenericArrayType) {
- GenericArrayType at = (GenericArrayType) t;
- return getStandardListObjectInspector(getReflectionObjectInspector(at
- .getGenericComponentType(), options));
- }
- if (t instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) t;
- // List?
- if (List.class.isAssignableFrom((Class<?>) pt.getRawType())) {
- return getStandardListObjectInspector(getReflectionObjectInspector(pt
- .getActualTypeArguments()[0], options));
- }
- // Map?
- if (Map.class.isAssignableFrom((Class<?>) pt.getRawType())) {
- return getStandardMapObjectInspector(getReflectionObjectInspector(pt
- .getActualTypeArguments()[0], options),
- getReflectionObjectInspector(pt.getActualTypeArguments()[1],
- options));
- }
- // Otherwise convert t to RawType so we will fall into the following if
- // block.
- t = pt.getRawType();
- }
- // Must be a class.
- if (!(t instanceof Class)) {
- throw new RuntimeException(ObjectInspectorFactory.class.getName()
- + " internal error:" + t);
- }
- Class<?> c = (Class<?>) t;
- // Java Primitive Type?
- if (PrimitiveObjectInspectorUtils.isPrimitiveJavaType(c)) {
- return PrimitiveObjectInspectorFactory
- .getPrimitiveJavaObjectInspector(PrimitiveObjectInspectorUtils
- .getTypeEntryFromPrimitiveJavaType(c).primitiveCategory);
- }
- // Java Primitive Class?
- if (PrimitiveObjectInspectorUtils.isPrimitiveJavaClass(c)) {
- return PrimitiveObjectInspectorFactory
- .getPrimitiveJavaObjectInspector(PrimitiveObjectInspectorUtils
- .getTypeEntryFromPrimitiveJavaClass(c).primitiveCategory);
- }
- // Primitive Writable class?
- if (PrimitiveObjectInspectorUtils.isPrimitiveWritableClass(c)) {
- return PrimitiveObjectInspectorFactory
- .getPrimitiveWritableObjectInspector(PrimitiveObjectInspectorUtils
- .getTypeEntryFromPrimitiveWritableClass(c).primitiveCategory);
- }
- // Must be struct because List and Map need to be ParameterizedType
- assert (!List.class.isAssignableFrom(c));
- assert (!Map.class.isAssignableFrom(c));
- // Create StructObjectInspector
- ReflectionStructObjectInspector oi;
- switch (options) {
- case JAVA:
- oi = new ReflectionStructObjectInspector();
- break;
- case THRIFT:
- oi = new ThriftStructObjectInspector();
- break;
- case PROTOCOL_BUFFERS:
- oi = new ProtocolBuffersStructObjectInspector();
- break;
- default:
- throw new RuntimeException(ObjectInspectorFactory.class.getName()
- + ": internal error.");
- }
- // put it into the cache BEFORE it is initialized to make sure we can catch
- // recursive types.
- objectInspectorCache.put(t, oi);
- Field[] fields = ObjectInspectorUtils.getDeclaredNonStaticFields(c);
- ArrayList<ObjectInspector> structFieldObjectInspectors = new ArrayList<ObjectInspector>(
- fields.length);
- for (int i = 0; i < fields.length; i++) {
- if (!oi.shouldIgnoreField(fields[i].getName())) {
- structFieldObjectInspectors.add(getReflectionObjectInspector(fields[i]
- .getGenericType(), options));
- }
- }
- oi.init(c, structFieldObjectInspectors);
- return oi;
- }
- static HashMap<ObjectInspector, StandardListObjectInspector> cachedStandardListObjectInspector = new HashMap<ObjectInspector, StandardListObjectInspector>();
- public static StandardListObjectInspector getStandardListObjectInspector(
- ObjectInspector listElementObjectInspector) {
- StandardListObjectInspector result = cachedStandardListObjectInspector
- .get(listElementObjectInspector);
- if (result == null) {
- result = new StandardListObjectInspector(listElementObjectInspector);
- cachedStandardListObjectInspector.put(listElementObjectInspector, result);
- }
- return result;
- }
- static HashMap<List<ObjectInspector>, StandardMapObjectInspector> cachedStandardMapObjectInspector = new HashMap<List<ObjectInspector>, StandardMapObjectInspector>();
- public static StandardMapObjectInspector getStandardMapObjectInspector(
- ObjectInspector mapKeyObjectInspector,
- ObjectInspector mapValueObjectInspector) {
- ArrayList<ObjectInspector> signature = new ArrayList<ObjectInspector>(2);
- signature.add(mapKeyObjectInspector);
- signature.add(mapValueObjectInspector);
- StandardMapObjectInspector result = cachedStandardMapObjectInspector
- .get(signature);
- if (result == null) {
- result = new StandardMapObjectInspector(mapKeyObjectInspector,
- mapValueObjectInspector);
- cachedStandardMapObjectInspector.put(signature, result);
- }
- return result;
- }
- static HashMap<List<ObjectInspector>, StandardUnionObjectInspector>
- cachedStandardUnionObjectInspector =
- new HashMap<List<ObjectInspector>, StandardUnionObjectInspector>();
- public static StandardUnionObjectInspector getStandardUnionObjectInspector(
- List<ObjectInspector> unionObjectInspectors) {
- StandardUnionObjectInspector result = cachedStandardUnionObjectInspector
- .get(unionObjectInspectors);
- if (result == null) {
- result = new StandardUnionObjectInspector(unionObjectInspectors);
- cachedStandardUnionObjectInspector.put(unionObjectInspectors, result);
- }
- return result;
- }
- static HashMap<ArrayList<List<?>>, StandardStructObjectInspector> cachedStandardStructObjectInspector = new HashMap<ArrayList<List<?>>, StandardStructObjectInspector>();
- public static StandardStructObjectInspector getStandardStructObjectInspector(
- List<String> structFieldNames,
- List<ObjectInspector> structFieldObjectInspectors) {
- ArrayList<List<?>> signature = new ArrayList<List<?>>();
- signature.add(structFieldNames);
- signature.add(structFieldObjectInspectors);
- StandardStructObjectInspector result = cachedStandardStructObjectInspector
- .get(signature);
- if (result == null) {
- result = new StandardStructObjectInspector(structFieldNames,
- structFieldObjectInspectors);
- cachedStandardStructObjectInspector.put(signature, result);
- }
- return result;
- }
- static HashMap<List<StructObjectInspector>, UnionStructObjectInspector> cachedUnionStructObjectInspector = new HashMap<List<StructObjectInspector>, UnionStructObjectInspector>();
- public static UnionStructObjectInspector getUnionStructObjectInspector(
- List<StructObjectInspector> structObjectInspectors) {
- UnionStructObjectInspector result = cachedUnionStructObjectInspector
- .get(structObjectInspectors);
- if (result == null) {
- result = new UnionStructObjectInspector(structObjectInspectors);
- cachedUnionStructObjectInspector.put(structObjectInspectors, result);
- }
- return result;
- }
- static HashMap<ArrayList<Object>, ColumnarStructObjectInspector> cachedColumnarStructObjectInspector = new HashMap<ArrayList<Object>, ColumnarStructObjectInspector>();
- public static ColumnarStructObjectInspector getColumnarStructObjectInspector(
- List<String> structFieldNames,
- List<ObjectInspector> structFieldObjectInspectors, Text nullSequence) {
- ArrayList<Object> signature = new ArrayList<Object>();
- signature.add(structFieldNames);
- signature.add(structFieldObjectInspectors);
- signature.add(nullSequence.toString());
- ColumnarStructObjectInspector result = cachedColumnarStructObjectInspector
- .get(signature);
- if (result == null) {
- result = new ColumnarStructObjectInspector(structFieldNames,
- structFieldObjectInspectors, nullSequence);
- cachedColumnarStructObjectInspector.put(signature, result);
- }
- return result;
- }
- private ObjectInspectorFactory() {
- // prevent instantiation
- }
- }