1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht.util;
21
22 import javax.annotation.Nullable;
23 import java.io.InvalidObjectException;
24 import java.io.ObjectStreamException;
25 import java.io.Serializable;
26
27
28
29
30
31
32
33 public class InstanceProvider<T> implements TypedProvider<T>, Serializable {
34 private static final long serialVersionUID = -1L;
35
36 private final Class<?> providedType;
37 private final transient T instance;
38
39
40
41
42
43
44 @SuppressWarnings("unused")
45 @Deprecated
46 public InstanceProvider(T instance) {
47 this(instance, instance == null ? Object.class : instance.getClass());
48 }
49
50 InstanceProvider(@Nullable T instance, Class<?> type) {
51 if (instance != null && !type.isInstance(instance)) {
52 throw new IllegalArgumentException("instance not of specified type");
53 }
54 this.instance = instance;
55 providedType = type;
56 }
57
58 @Override
59 public Class<?> getProvidedType() {
60 return providedType;
61 }
62
63 @Override
64 public T get() {
65 return instance;
66 }
67
68 @Override
69 public String toString() {
70 if (instance == null) {
71 return "InstanceProvider{null<" + providedType.getName() + ">}";
72 } else {
73 return "InstanceProvider{" + instance + "}";
74 }
75 }
76
77 private Object writeReplace() {
78 return new SerialProxy(providedType, instance);
79 }
80
81 @SuppressWarnings("unused")
82 private Object readObject() throws ObjectStreamException {
83 throw new InvalidObjectException("must use serialization proxy");
84 }
85
86 private static class SerialProxy implements Serializable {
87 private static final long serialVersionUID = 1L;
88 private ClassProxy type;
89 @SuppressWarnings("squid:S1948")
90 private Object instance;
91
92 public SerialProxy(Class<?> t, Object i) {
93 type = ClassProxy.of(t);
94 instance = i;
95 }
96
97 @SuppressWarnings("unchecked")
98 private Object readResolve() throws ObjectStreamException {
99 Class<?> cls;
100 try {
101 cls = type.resolve();
102 } catch (ClassNotFoundException e) {
103 InvalidObjectException ex = new InvalidObjectException("class not found");
104 ex.initCause(e);
105 throw ex;
106 }
107 if (instance != null && !cls.isInstance(instance)) {
108 throw new InvalidObjectException("instance is not of expected type");
109 }
110 return new InstanceProvider(instance, cls);
111 }
112 }
113 }