1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.grouplens.grapht.reflect.internal;
21
22 import org.apache.commons.lang3.builder.EqualsBuilder;
23 import org.apache.commons.lang3.builder.HashCodeBuilder;
24 import org.grouplens.grapht.reflect.Desires;
25 import org.grouplens.grapht.reflect.InjectionPoint;
26 import org.grouplens.grapht.util.ClassProxy;
27 import org.grouplens.grapht.util.Preconditions;
28
29 import javax.annotation.Nonnull;
30 import javax.annotation.Nullable;
31 import java.io.InvalidObjectException;
32 import java.io.ObjectInputStream;
33 import java.io.ObjectStreamException;
34 import java.io.Serializable;
35 import java.lang.annotation.Annotation;
36 import java.lang.reflect.Member;
37 import java.util.Collection;
38 import java.util.Collections;
39
40
41
42
43
44
45
46 public final class SimpleInjectionPoint implements InjectionPoint, Serializable {
47 private static final long serialVersionUID = -1L;
48
49 private final transient Annotation qualifier;
50 private final transient Class<?> type;
51 private final transient boolean nullable;
52
53 public SimpleInjectionPoint(@Nullable Annotation qualifier, Class<?> type, boolean nullable) {
54 Preconditions.notNull("type", type);
55 if (qualifier != null) {
56 Preconditions.isQualifier(qualifier.annotationType());
57 }
58 this.qualifier = qualifier;
59 this.type = type;
60 this.nullable = nullable;
61 }
62
63 @Override
64 public Class<?> getErasedType() {
65 return type;
66 }
67
68 @Override
69 public Member getMember() {
70 return null;
71 }
72
73 @Override
74 public boolean isNullable() {
75 return nullable;
76 }
77
78 @Override
79 public Class<?> getType() {
80 return type;
81 }
82
83 @Nullable
84 @Override
85 public Annotation getQualifier() {
86 return qualifier;
87 }
88
89 @Nullable
90 @Override
91 public <A extends Annotation> A getAttribute(Class<A> atype) {
92 return null;
93 }
94
95 @Nonnull
96 @Override
97 public Collection<Annotation> getAttributes() {
98 return Collections.emptyList();
99 }
100
101 @Override
102 public int hashCode() {
103 return new HashCodeBuilder().append(type).append(qualifier).toHashCode();
104 }
105
106 @Override
107 public boolean equals(Object o) {
108 if (!(o instanceof SimpleInjectionPoint)) {
109 return false;
110 }
111 SimpleInjectionPoint p = (SimpleInjectionPoint) o;
112 EqualsBuilder eqb = new EqualsBuilder();
113 return eqb.append(type, p.type)
114 .append(qualifier, p.qualifier)
115 .append(nullable, p.nullable)
116 .isEquals();
117 }
118
119 @Override
120 public String toString() {
121 StringBuilder sb = new StringBuilder();
122 sb.append("synthetic ");
123 if (qualifier != null) {
124 sb.append(qualifier)
125 .append(" ");
126 }
127 return sb.append(type.getName()).toString();
128 }
129
130 private Object writeReplace() {
131 return new SerialProxy(type, nullable, qualifier);
132 }
133
134 private void readObject(ObjectInputStream stream) throws InvalidObjectException {
135 throw new InvalidObjectException("Serialization proxy required");
136 }
137
138
139
140
141 private static class SerialProxy implements Serializable {
142 private static final long serialVersionUID = 1L;
143 private ClassProxy type;
144 private boolean nullable;
145 @Nullable
146 @SuppressWarnings("squid:S1948")
147 private Annotation qualifier;
148
149 private SerialProxy(Class<?> t, boolean isNullable, @Nullable Annotation qual) {
150 type = ClassProxy.of(t);
151 nullable = isNullable;
152 qualifier = qual;
153 }
154
155 public Object readResolve() throws ObjectStreamException {
156 try {
157 return Desires.createInjectionPoint(qualifier, type.resolve(), nullable);
158 } catch (ClassNotFoundException e) {
159 InvalidObjectException ex =
160 new InvalidObjectException("cannot resolve class " + type.getClassName());
161 ex.initCause(e);
162 throw ex;
163 }
164 }
165 }
166 }