aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/fasterxml/jackson/databind/type/ResolvedRecursiveType.java
blob: 7f733878997d0095ade8755dff447f1e56ed71a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.fasterxml.jackson.databind.type;

import com.fasterxml.jackson.databind.JavaType;

/**
 * Internal placeholder type used for self-references.
 *
 * @since 2.7
 */
public class ResolvedRecursiveType extends TypeBase
{
    private static final long serialVersionUID = 1L;

    protected JavaType _referencedType;

    public ResolvedRecursiveType(Class<?> erasedType, TypeBindings bindings) {
        super(erasedType, bindings, null, null, 0, null, null, false);
    }

    public void setReference(JavaType ref)
    {
        // sanity check; should not be called multiple times
        if (_referencedType != null) {
            throw new IllegalStateException("Trying to re-set self reference; old value = "+_referencedType+", new = "+ref);
        }
        _referencedType = ref;
    }
   
    @Override
    public JavaType getSuperClass() {
        if (_referencedType != null) {
            return _referencedType.getSuperClass();
        }
        return super.getSuperClass();
    }

    public JavaType getSelfReferencedType() { return _referencedType; }

    // 23-Jul-2019, tatu: [databind#2331] Need to also delegate this...
    @Override
    public TypeBindings getBindings() {
        if (_referencedType != null) { // `null` before resolution [databind#2395]
            return _referencedType.getBindings();
        }
        return super.getBindings();
    }

    @Override
    public StringBuilder getGenericSignature(StringBuilder sb) {
        // 30-Oct-2019, tatu: Alas, need to break recursion, otherwise we'll
        //    end up in StackOverflowError... two choices; '?' for "not known",
        //    or erased signature.
        if (_referencedType != null) {
//            return _referencedType.getGenericSignature(sb);
            return _referencedType.getErasedSignature(sb);
        }
        return sb.append("?");
    }

    @Override
    public StringBuilder getErasedSignature(StringBuilder sb) {
        if (_referencedType != null) {
            return _referencedType.getErasedSignature(sb);
        }
        return sb;
    }

    @Override
    public JavaType withContentType(JavaType contentType) {
        return this;
    }
    
    @Override
    public JavaType withTypeHandler(Object h) {
        return this;
    }

    @Override
    public JavaType withContentTypeHandler(Object h) {
        return this;
    }

    @Override
    public JavaType withValueHandler(Object h) {
        return this;
    }

    @Override
    public JavaType withContentValueHandler(Object h) {
        return this;
    }

    @Override
    public JavaType withStaticTyping() {
        return this;
    }

    @Deprecated // since 2.7
    @Override
    protected JavaType _narrow(Class<?> subclass) {
        return this;
    }

    @Override
    public JavaType refine(Class<?> rawType, TypeBindings bindings,
            JavaType superClass, JavaType[] superInterfaces) {
        return null;
    }

    @Override
    public boolean isContainerType() {
        return false;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(40)
                .append("[recursive type; ");
        if (_referencedType == null) {
            sb.append("UNRESOLVED");
        } else {
            // [databind#1301]: Typically resolves to a loop so short-cut
            //   and only include type-erased class
            sb.append(_referencedType.getRawClass().getName());
        }
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (o == null) return false;
        if (o.getClass() == getClass()) {
            // 16-Jun-2017, tatu: as per [databind#1658], cannot do recursive call since
            //    there is likely to be a cycle...

            // but... true or false?
            return false;
            
            /*
            // Do NOT ever match unresolved references
            if (_referencedType == null) {
                return false;
            }
            return (o.getClass() == getClass()
                    && _referencedType.equals(((ResolvedRecursiveType) o).getSelfReferencedType()));
                    */
        }
        return false;
    }
}