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.grouplens.grapht.reflect.InjectionPoint;
23 import org.grouplens.grapht.util.FieldProxy;
24 import org.grouplens.grapht.util.Preconditions;
25 import org.grouplens.grapht.util.Types;
26
27 import javax.annotation.Nonnull;
28 import javax.annotation.Nullable;
29 import java.io.InvalidObjectException;
30 import java.io.ObjectInputStream;
31 import java.io.Serializable;
32 import java.lang.annotation.Annotation;
33 import java.lang.reflect.Field;
34 import java.lang.reflect.Type;
35 import java.util.Collection;
36
37
38
39
40
41
42 public final class FieldInjectionPoint implements InjectionPoint, Serializable {
43 private static final long serialVersionUID = -1L;
44
45 private final transient Field field;
46 private final transient AnnotationHelper annotations;
47
48
49
50
51
52
53
54 public FieldInjectionPoint(@Nonnull Field field) {
55 Preconditions.notNull("field", field);
56 this.field = field;
57 annotations = new AnnotationHelper(field.getAnnotations());
58 }
59
60 @Override
61 public Type getType() {
62 return Types.box(field.getGenericType());
63 }
64
65 @Override
66 public Class<?> getErasedType() {
67 return Types.box(field.getType());
68 }
69
70 @Nullable
71 @Override
72 public Annotation getQualifier() {
73 return annotations.getQualifier();
74 }
75
76 @Nullable
77 @Override
78 public <A extends Annotation> A getAttribute(Class<A> atype) {
79 return annotations.getAttribute(atype);
80 }
81
82 @Nonnull
83 @Override
84 public Collection<Annotation> getAttributes() {
85 return annotations.getAttributes();
86 }
87
88 @Override @Nonnull
89 public Field getMember() {
90 return field;
91 }
92
93 @Override
94 public boolean isNullable() {
95 return Types.hasNullableAnnotation(field.getAnnotations());
96 }
97
98 @Override
99 public boolean equals(Object o) {
100 if (!(o instanceof FieldInjectionPoint)) {
101 return false;
102 }
103 return ((FieldInjectionPoint) o).field.equals(field);
104 }
105
106 @Override
107 public int hashCode() {
108 return field.hashCode();
109 }
110
111 @Override
112 public String toString() {
113 StringBuilder sb = new StringBuilder();
114 sb.append("field ");
115 if (getQualifier() != null) {
116 sb.append(getQualifier())
117 .append(" ");
118 }
119 sb.append(field.getType().toString())
120 .append(" ")
121 .append(field.getName());
122 return sb.toString();
123 }
124
125 private Object writeReplace() {
126 return new SerialProxy(field);
127 }
128
129 private void readObject(ObjectInputStream stream) throws InvalidObjectException {
130 throw new InvalidObjectException("Serialization proxy required");
131 }
132
133 private static class SerialProxy implements Serializable {
134 private static final long serialVersionUID = 1L;
135
136 private final FieldProxy field;
137
138 public SerialProxy(Field f) {
139 field = FieldProxy.of(f);
140 }
141
142 private Object readResolve() throws InvalidObjectException {
143 try {
144 return new FieldInjectionPoint(field.resolve());
145 } catch (ClassNotFoundException e) {
146 InvalidObjectException ex =
147 new InvalidObjectException("no class for " + field.toString());
148 ex.initCause(e);
149 throw ex;
150 } catch (NoSuchFieldException e) {
151 InvalidObjectException ex =
152 new InvalidObjectException("cannot resolve " + field.toString());
153 ex.initCause(e);
154 throw ex;
155 }
156 }
157 }
158 }