1 package com.fasterxml.jackson.databind.type;
2
3 import com.fasterxml.jackson.databind.JavaType;
4
5 /**
6  * Internal placeholder type used for self-references.
7  *
8  * @since 2.7
9  */

10 public class ResolvedRecursiveType extends TypeBase
11 {
12     private static final long serialVersionUID = 1L;
13
14     protected JavaType _referencedType;
15
16     public ResolvedRecursiveType(Class<?> erasedType, TypeBindings bindings) {
17         super(erasedType, bindings, nullnull, 0, nullnullfalse);
18     }
19
20     public void setReference(JavaType ref)
21     {
22         // sanity check; should not be called multiple times
23         if (_referencedType != null) {
24             throw new IllegalStateException("Trying to re-set self reference; old value = "+_referencedType+", new = "+ref);
25         }
26         _referencedType = ref;
27     }
28    
29     @Override
30     public JavaType getSuperClass() {
31         if (_referencedType != null) {
32             return _referencedType.getSuperClass();
33         }
34         return super.getSuperClass();
35     }
36
37     public JavaType getSelfReferencedType() { return _referencedType; }
38
39     // 23-Jul-2019, tatu: [databind#2331] Need to also delegate this...
40     @Override
41     public TypeBindings getBindings() {
42         if (_referencedType != null) { // `null` before resolution [databind#2395]
43             return _referencedType.getBindings();
44         }
45         return super.getBindings();
46     }
47
48     @Override
49     public StringBuilder getGenericSignature(StringBuilder sb) {
50         // 30-Oct-2019, tatu: Alas, need to break recursion, otherwise we'll
51         //    end up in StackOverflowError... two choices; '?' for "not known",
52         //    or erased signature.
53         if (_referencedType != null) {
54 //            return _referencedType.getGenericSignature(sb);
55             return _referencedType.getErasedSignature(sb);
56         }
57         return sb.append("?");
58     }
59
60     @Override
61     public StringBuilder getErasedSignature(StringBuilder sb) {
62         if (_referencedType != null) {
63             return _referencedType.getErasedSignature(sb);
64         }
65         return sb;
66     }
67
68     @Override
69     public JavaType withContentType(JavaType contentType) {
70         return this;
71     }
72     
73     @Override
74     public JavaType withTypeHandler(Object h) {
75         return this;
76     }
77
78     @Override
79     public JavaType withContentTypeHandler(Object h) {
80         return this;
81     }
82
83     @Override
84     public JavaType withValueHandler(Object h) {
85         return this;
86     }
87
88     @Override
89     public JavaType withContentValueHandler(Object h) {
90         return this;
91     }
92
93     @Override
94     public JavaType withStaticTyping() {
95         return this;
96     }
97
98     @Deprecated // since 2.7
99     @Override
100     protected JavaType _narrow(Class<?> subclass) {
101         return this;
102     }
103
104     @Override
105     public JavaType refine(Class<?> rawType, TypeBindings bindings,
106             JavaType superClass, JavaType[] superInterfaces) {
107         return null;
108     }
109
110     @Override
111     public boolean isContainerType() {
112         return false;
113     }
114
115     @Override
116     public String toString() {
117         StringBuilder sb = new StringBuilder(40)
118                 .append("[recursive type; ");
119         if (_referencedType == null) {
120             sb.append("UNRESOLVED");
121         } else {
122             // [databind#1301]: Typically resolves to a loop so short-cut
123             //   and only include type-erased class
124             sb.append(_referencedType.getRawClass().getName());
125         }
126         return sb.toString();
127     }
128
129     @Override
130     public boolean equals(Object o) {
131         if (o == thisreturn true;
132         if (o == nullreturn false;
133         if (o.getClass() == getClass()) {
134             // 16-Jun-2017, tatu: as per [databind#1658], cannot do recursive call since
135             //    there is likely to be a cycle...
136
137             // but... true or false?
138             return false;
139             
140             /*
141             // Do NOT ever match unresolved references
142             if (_referencedType == null) {
143                 return false;
144             }
145             return (o.getClass() == getClass()
146                     && _referencedType.equals(((ResolvedRecursiveType) o).getSelfReferencedType()));
147                     */

148         }
149         return false;
150     }
151 }
152