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 }