-
Notifications
You must be signed in to change notification settings - Fork 53
/
TypeProxy.java
executable file
·164 lines (138 loc) · 4.48 KB
/
TypeProxy.java
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
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
* Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package org.glassfish.hk2.classmodel.reflect.impl;
import org.glassfish.hk2.classmodel.reflect.*;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
/**
* Proxy for types, used in place until the type can be properly instantiated.
* Proxy type also holds all incoming reference to the type.
*
* @author Jerome Dochez
*/
public class TypeProxy<T extends Type> {
private T value = null;
private volatile boolean visited = false;
private final String name;
private final Notifier<T> notifier;
private final List<Member> fieldRefs = new ArrayList<Member>();
private final List<Type> subTypeRefs = new ArrayList<Type>();
private final List<ClassModel> implementations = new ArrayList<ClassModel>();
// Referenced also by TypesImpl
final ReentrantLock lock = new ReentrantLock();
/**
* Creates a new type proxy, this ctor is package private as many
* other activities must be performed when a new proxy type is created.
*
* @param notifier notification handle to notify receiver the proxied
* type has been resolved
* @param name type name
*/
TypeProxy(Notifier<T> notifier, String name) {
this.notifier = notifier;
this.name = name;
}
@Override
public String toString() {
return "TypeProxy:" + name;
}
public void set(T value) {
this.value = value;
if (notifier!=null) {
notifier.valueSet(value);
}
}
public T get() {
return value;
}
public String getName() {
if (value!=null) return value.getName();
return name;
}
public interface Notifier<T> {
public void valueSet(T value);
}
public void addFieldRef(FieldModel field) {
lock.lock();
try {
fieldRefs.add(field);
} finally {
lock.unlock();
}
}
public List<Member> getRefs() {
return Collections.unmodifiableList(fieldRefs);
}
public void addSubTypeRef(Type subType) {
lock.lock();
try {
subTypeRefs.add(subType);
} finally {
lock.unlock();
}
}
public List<Type> getSubTypeRefs() {
return Collections.unmodifiableList(subTypeRefs);
}
public void addImplementation(ClassModel classModel) {
lock.lock();
try {
implementations.add(classModel);
} finally {
lock.unlock();
}
}
public List<ClassModel> getImplementations() {
return Collections.unmodifiableList(implementations);
}
public static <U extends Type> Collection<U> adapter(final Collection<TypeProxy<U>> source) {
return new AbstractCollection<U>() {
@Override
public Iterator<U> iterator() {
final Iterator<TypeProxy<U>> itr = source.iterator();
return new Iterator<U>() {
@Override
public boolean hasNext() {
return itr.hasNext();
}
@Override
public U next() {
TypeProxy<U> next = itr.next();
if (next!=null) {
return next.get();
} else {
return null;
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
@Override
public int size() {
return source.size();
}
};
}
public void visited() {
visited=true;
}
public boolean isVisited() {
return visited;
}
}