• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.type;
2 
3 import java.lang.reflect.Array;
4 
5 import com.fasterxml.jackson.databind.JavaType;
6 
7 /**
8  * Array types represent Java arrays, both primitive and object valued.
9  * Further, Object-valued arrays can have element type of any other
10  * legal {@link JavaType}.
11  */
12 public final class ArrayType
13     extends TypeBase
14 {
15     private static final long serialVersionUID = 1L;
16 
17     /**
18      * Type of elements in the array.
19      */
20     protected final JavaType _componentType;
21 
22     /**
23      * We will also keep track of shareable instance of empty array,
24      * since it usually needs to be constructed any way; and because
25      * it is essentially immutable and thus can be shared.
26      */
27     protected final Object _emptyArray;
28 
ArrayType(JavaType componentType, TypeBindings bindings, Object emptyInstance, Object valueHandler, Object typeHandler, boolean asStatic)29     protected ArrayType(JavaType componentType, TypeBindings bindings, Object emptyInstance,
30             Object valueHandler, Object typeHandler, boolean asStatic)
31     {
32         // No super-class, interfaces, for now
33         super(emptyInstance.getClass(), bindings, null, null,
34                 componentType.hashCode(),
35                 valueHandler, typeHandler, asStatic);
36         _componentType = componentType;
37         _emptyArray = emptyInstance;
38     }
39 
construct(JavaType componentType, TypeBindings bindings)40     public static ArrayType construct(JavaType componentType, TypeBindings bindings) {
41         return construct(componentType, bindings, null, null);
42     }
43 
construct(JavaType componentType, TypeBindings bindings, Object valueHandler, Object typeHandler)44     public static ArrayType construct(JavaType componentType, TypeBindings bindings,
45             Object valueHandler, Object typeHandler) {
46         // Figuring out raw class for generic array is actually bit tricky...
47         Object emptyInstance = Array.newInstance(componentType.getRawClass(), 0);
48         return new ArrayType(componentType, bindings, emptyInstance, valueHandler, typeHandler, false);
49     }
50 
51     @Override
withContentType(JavaType contentType)52     public JavaType withContentType(JavaType contentType) {
53         Object emptyInstance = Array.newInstance(contentType.getRawClass(), 0);
54         return new ArrayType(contentType, _bindings, emptyInstance,
55                 _valueHandler, _typeHandler, _asStatic);
56     }
57 
58     @Override
withTypeHandler(Object h)59     public ArrayType withTypeHandler(Object h)
60     {
61         if (h == _typeHandler) {
62             return this;
63         }
64         return new ArrayType(_componentType, _bindings, _emptyArray, _valueHandler, h, _asStatic);
65     }
66 
67     @Override
withContentTypeHandler(Object h)68     public ArrayType withContentTypeHandler(Object h)
69     {
70         if (h == _componentType.<Object>getTypeHandler()) {
71             return this;
72         }
73         return new ArrayType(_componentType.withTypeHandler(h), _bindings, _emptyArray,
74                 _valueHandler, _typeHandler, _asStatic);
75     }
76 
77     @Override
withValueHandler(Object h)78     public ArrayType withValueHandler(Object h) {
79         if (h == _valueHandler) {
80             return this;
81         }
82         return new ArrayType(_componentType, _bindings, _emptyArray, h, _typeHandler,_asStatic);
83     }
84 
85     @Override
withContentValueHandler(Object h)86     public ArrayType withContentValueHandler(Object h) {
87         if (h == _componentType.<Object>getValueHandler()) {
88             return this;
89         }
90         return new ArrayType(_componentType.withValueHandler(h), _bindings, _emptyArray,
91                 _valueHandler, _typeHandler, _asStatic);
92     }
93 
94     @Override
withStaticTyping()95     public ArrayType withStaticTyping() {
96         if (_asStatic) {
97             return this;
98         }
99         return new ArrayType(_componentType.withStaticTyping(), _bindings,
100                 _emptyArray, _valueHandler, _typeHandler, true);
101     }
102 
103     /*
104     /**********************************************************
105     /* Methods for narrowing conversions
106     /**********************************************************
107      */
108 
109     /**
110      * Handling of narrowing conversions for arrays is trickier: for now,
111      * it is not even allowed.
112      */
113     @Override
114     @Deprecated // since 2.7
_narrow(Class<?> subclass)115     protected JavaType _narrow(Class<?> subclass) {
116         return _reportUnsupported();
117     }
118 
119     // Should not be called, as array types in Java are not extensible; but
120     // let's not freak out even if it is called?
121     @Override
refine(Class<?> contentClass, TypeBindings bindings, JavaType superClass, JavaType[] superInterfaces)122     public JavaType refine(Class<?> contentClass, TypeBindings bindings,
123             JavaType superClass, JavaType[] superInterfaces) {
124         return null;
125     }
126 
_reportUnsupported()127     private JavaType _reportUnsupported() {
128         throw new UnsupportedOperationException("Cannot narrow or widen array types");
129     }
130 
131     /*
132     /**********************************************************
133     /* Overridden methods
134     /**********************************************************
135      */
136 
137     @Override
isArrayType()138     public boolean isArrayType() { return true; }
139 
140     /**
141      * For some odd reason, modifiers for array classes would
142      * claim they are abstract types. Not so, at least for our
143      * purposes.
144      */
145     @Override
isAbstract()146     public boolean isAbstract() { return false; }
147 
148     /**
149      * For some odd reason, modifiers for array classes would
150      * claim they are abstract types. Not so, at least for our
151      * purposes.
152      */
153     @Override
isConcrete()154     public boolean isConcrete() { return true; }
155 
156     @Override
hasGenericTypes()157     public boolean hasGenericTypes() {
158         // arrays are not parameterized, but element type may be:
159         return _componentType.hasGenericTypes();
160     }
161 
162     /*
163     /**********************************************************
164     /* Public API
165     /**********************************************************
166      */
167 
168     @Override
isContainerType()169     public boolean isContainerType() { return true; }
170 
171     @Override
getContentType()172     public JavaType getContentType() { return  _componentType; }
173 
174     @Override
getContentValueHandler()175     public Object getContentValueHandler() {
176         return _componentType.getValueHandler();
177     }
178 
179     @Override
getContentTypeHandler()180     public Object getContentTypeHandler() {
181         return _componentType.getTypeHandler();
182     }
183 
184     @Override
hasHandlers()185     public boolean hasHandlers() {
186         return super.hasHandlers() || _componentType.hasHandlers();
187     }
188 
189     @Override
getGenericSignature(StringBuilder sb)190     public StringBuilder getGenericSignature(StringBuilder sb) {
191         sb.append('[');
192         return _componentType.getGenericSignature(sb);
193     }
194 
195     @Override
getErasedSignature(StringBuilder sb)196     public StringBuilder getErasedSignature(StringBuilder sb) {
197         sb.append('[');
198         return _componentType.getErasedSignature(sb);
199     }
200 
201     /*
202     /**********************************************************
203     /* Extended API
204     /**********************************************************
205      */
206 
207     /**
208      * @since 2.12
209      */
getEmptyArray()210     public Object[] getEmptyArray() {
211         return  (Object[]) _emptyArray;
212     }
213 
214     /*
215     /**********************************************************
216     /* Standard methods
217     /**********************************************************
218      */
219 
220     @Override
toString()221     public String toString()
222     {
223         return "[array type, component type: "+_componentType+"]";
224     }
225 
226     @Override
equals(Object o)227     public boolean equals(Object o)
228     {
229         if (o == this) return true;
230         if (o == null) return false;
231         if (o.getClass() != getClass()) return false;
232 
233         ArrayType other = (ArrayType) o;
234         return _componentType.equals(other._componentType);
235     }
236 }
237