Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package com.fasterxml.jackson.databind.type;
  
  import java.util.*;
  
Helper class used for resolving type parameters for given class
 
 public class TypeBindings
 {
     private final static JavaType[] NO_TYPES = new JavaType[0];
    
    
Marker to use for (temporarily) unbound references.
 
     public final static JavaType UNBOUND = new SimpleType(Object.class);

    
Factory to use for constructing resolved related types.
 
     protected final TypeFactory _typeFactory;
    
    
Context type used for resolving all types, if specified. May be null, in which case _contextClass is used instead.
 
     protected final JavaType _contextType;

    
Specific class to use for resolving all types, for methods and fields class and its superclasses and -interfaces contain.
 
     protected final Class<?> _contextClass;

    
Lazily-instantiated bindings of resolved type parameters
 
     protected Map<String,JavaType_bindings;

    
Also: we may temporarily want to mark certain named types as resolved (but without exact type); if so, we'll just store names here.
 
     protected HashSet<String_placeholders;

    
Sometimes it is necessary to allow hierarchic resolution of types: specifically in cases where there are local bindings (for methods, constructors). If so, we'll just use simple delegation model.
 
     private final TypeBindings _parentBindings;
 
     /*
     /**********************************************************
     /* Construction
     /**********************************************************
      */
     
     public TypeBindings(TypeFactory typeFactoryClass<?> cc)
     {
         this(typeFactorynullccnull);
     }
 
     public TypeBindings(TypeFactory typeFactoryJavaType type)
     {
         this(typeFactorynulltype.getRawClass(), type);
     }

    
Constructor used to create "child" instances; mostly to allow delegation from explicitly defined local overrides (local type variables for methods, constructors) to contextual (class-defined) ones.
 
     public TypeBindings childInstance() {
         return new TypeBindings(this);
     }
 
     private TypeBindings(TypeFactory tfTypeBindings parent,
             Class<?> ccJavaType type)
     {
          = tf;
          = parent;
          = cc;
          = type;
     }
 
     /*
     /**********************************************************
     /* Pass-through type resolution methods
     /**********************************************************
      */
 
     public JavaType resolveType(Class<?> cls) {
         return ._constructType(clsthis);
     }
    public JavaType resolveType(Type type) {
        return ._constructType(typethis);
    }
    
    /*
    /**********************************************************
    /* Accesors
    /**********************************************************
     */
    public int getBindingCount() {
        if ( == null) {
            _resolve();
        }
        return .size();
    }
    
    public JavaType findType(String name)
    {
        if ( == null) {
            _resolve();
        }
        JavaType t = .get(name);
        if (t != null) {
            return t;
        }
        if ( != null && .contains(name)) {
            return ;
        }
        if ( != null) {
            return .findType(name);
        }
        // nothing found, so...
        // Should we throw an exception or just return null?
        
        /* [JACKSON-499] 18-Feb-2011, tatu: There are some tricky type bindings within
         *   java.util, such as HashMap$KeySet; so let's punt the problem
         *   (honestly not sure what to do -- they are unbound for good, I think)
         */
        if ( != null) {
            Class<?> enclosing = .getEnclosingClass();
            if (enclosing != null) {
                // [JACKSON-572]: Actually, let's skip this for all non-static inner classes
                //   (which will also cover 'java.util' type cases...
                if (!Modifier.isStatic(.getModifiers())) {
                    return ;
                }
                // ... so this piece of code should not be needed any more
                /*
                Package pkg = enclosing.getPackage();
                if (pkg != null) {
                    // as per [JACKSON-533], also include "java.util.concurrent":
                    if (pkg.getName().startsWith("java.util")) {
                        return UNBOUND;
                    }
                }
                */
            }
        }
        
        String className;
        if ( != null) {
            className = .getName();
        } else if ( != null) {
            className = .toString();
        } else {
            className = "UNKNOWN";
        }
        throw new IllegalArgumentException("Type variable '"+name
                +"' can not be resolved (with context of class "+className+")");
        //t = UNBOUND;                
    }
    public void addBinding(String nameJavaType type)
    {
        // note: emptyMap() is unmodifiable, hence second check is needed:
        if ( == null || .size() == 0) {
             = new LinkedHashMap<String,JavaType>();
        }
        .put(nametype);
    }
    public JavaType[] typesAsArray()
    {
        if ( == null) {
            _resolve();
        }
        if (.size() == 0) {
            return ;
        }
        return .values().toArray(new JavaType[.size()]);
    }
    
    /*
    /**********************************************************
    /* Internal methods
    /**********************************************************
     */
    
    protected void _resolve()
    {
        // finally: may have root level type info too
        if ( != null) {
            int count = .containedTypeCount();
            if (count > 0) {
                for (int i = 0; i < count; ++i) {
                    String name = .containedTypeName(i);
                    JavaType type = .containedType(i);
                    addBinding(nametype);
                }
            }
        }
        // nothing bound? mark with empty map to prevent further calls
        if ( == null) {
             = Collections.emptyMap();
        }
    }
    public void _addPlaceholder(String name) {
        if ( == null) {
             = new HashSet<String>();
        }
        .add(name);
    }
    protected void _resolveBindings(Type t)
    {
        if (t == nullreturn;
        
        Class<?> raw;
        if (t instanceof ParameterizedType) {
            ParameterizedType pt = (ParameterizedTypet;
            Type[] args = pt.getActualTypeArguments();
            if (args  != null && args.length > 0) {
                Class<?> rawType = (Class<?>) pt.getRawType();    
                TypeVariable<?>[] vars = rawType.getTypeParameters();
                if (vars.length != args.length) {
                    throw new IllegalArgumentException("Strange parametrized type (in class "+rawType.getName()+"): number of type arguments != number of type parameters ("+args.length+" vs "+vars.length+")");
                }
                for (int i = 0, len = args.lengthi < len; ++i) {
                    TypeVariable<?> var = vars[i];
                    String name = var.getName();
                    if ( == null) {
                         = new LinkedHashMap<String,JavaType>();
                    } else {
                        /* 24-Mar-2010, tatu: Better ensure that we do not overwrite something
                         *  collected earlier (since we descend towards super-classes):
                         */
                        if (.containsKey(name)) continue;
                    }
                    // first: add a placeholder to prevent infinite loops
                    _addPlaceholder(name);
                    // then resolve type
                    .put(name._constructType(args[i], this));
                }
            }
            raw = (Class<?>)pt.getRawType();
        } else if (t instanceof Class<?>) {
            raw = (Class<?>) t;
            /* [JACKSON-677]: If this is an inner class then the generics are defined on the 
             * enclosing class so we have to check there as well.  We don't
             * need to call getEnclosingClass since anonymous classes declare 
             * generics
             */
            Class<?> decl = raw.getDeclaringClass();
            /* 08-Feb-2013, tatu: Except that if context is also super-class, we must
             *   skip it; context will be checked anyway, and we'd get StackOverflow if
             *   we went there.
             */
            if (decl != null && !decl.isAssignableFrom(raw)) {
                _resolveBindings(raw.getDeclaringClass());
            }
            /* 24-Mar-2010, tatu: Can not have true generics definitions, but can
             *   have lower bounds ("<T extends BeanBase>") in declaration itself
             */
            TypeVariable<?>[] vars = raw.getTypeParameters();
            if (vars != null && vars.length > 0) {
                JavaType[] typeParams = null;
                if ( != null && raw.isAssignableFrom(.getRawClass())) {
                    typeParams = .findTypeParameters(raw);
                }
                for (int i = 0; i < vars.lengthi++) {
                    TypeVariable<?> var = vars[i];
                    String name = var.getName();
                    Type varType = var.getBounds()[0];
                    if (varType != null) {
                        if ( == null) {
                             = new LinkedHashMap<String,JavaType>();
                        } else { // and no overwriting...
                            if (.containsKey(name)) continue;
                        }
                        _addPlaceholder(name); // to prevent infinite loops
                        if (typeParams != null) {
                            .put(nametypeParams[i]);
                        } else {
                            .put(name._constructType(varTypethis));
                        }
                    }
                }
            }
        } else { // probably can't be any of these... so let's skip for now
            //if (type instanceof GenericArrayType) {
            //if (type instanceof TypeVariable<?>) {
            // if (type instanceof WildcardType) {
            return;
        }
        // but even if it's not a parameterized type, its super types may be:
        for (Type intType : raw.getGenericInterfaces()) {
            _resolveBindings(intType);
        }
    }
    @Override
    public String toString()
    {
        if ( == null) {
            _resolve();
        }
        StringBuilder sb = new StringBuilder("[TypeBindings for ");
        if ( != null) {
            sb.append(.toString());
        } else {
            sb.append(.getName());
        }
        sb.append(": ").append().append("]");
        return sb.toString();
    }
New to GrepCode? Check out our FAQ X