1 | |
package com.lexicalscope.fluentreflection; |
2 | |
|
3 | |
import static ch.lambdaj.Lambda.*; |
4 | |
import static com.lexicalscope.fluentreflection.ReflectionMatcher.allOf; |
5 | |
import static com.lexicalscope.fluentreflection.ReflectionMatchers.*; |
6 | |
|
7 | |
import java.lang.annotation.Annotation; |
8 | |
import java.lang.reflect.Type; |
9 | |
import java.util.List; |
10 | |
|
11 | |
import org.hamcrest.Matcher; |
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
|
19 | |
|
20 | |
|
21 | |
|
22 | |
|
23 | |
|
24 | |
|
25 | |
|
26 | |
|
27 | |
|
28 | |
|
29 | |
final class FluentObjectImpl<T> implements FluentObject<T> { |
30 | |
private final FluentClass<T> reflect; |
31 | |
private final T instance; |
32 | |
private final ReflectedTypeFactory reflectedTypeFactory; |
33 | 774 | |
34 | 264 | public FluentObjectImpl( |
35 | |
final ReflectedTypeFactory reflectedTypeFactory, |
36 | |
final FluentClass<T> reflect, |
37 | 774 | final T instance) { |
38 | 1038 | this.reflectedTypeFactory = reflectedTypeFactory; |
39 | 1038 | this.reflect = reflect; |
40 | 1038 | this.instance = instance; |
41 | 264 | } |
42 | |
|
43 | 6 | @Override public Class<T> classUnderReflection() { |
44 | 2 | return reflect.classUnderReflection(); |
45 | |
} |
46 | |
|
47 | 6 | @Override public FluentClass<T> reflectedClass() { |
48 | 2 | return reflect; |
49 | |
} |
50 | |
|
51 | 126 | @Override public FluentMethod method(final Matcher<? super FluentMethod> methodMatcher) { |
52 | 172 | final FluentMethod method = selectFirst(boundMethods(), methodMatcher); |
53 | 46 | if(method == null) { |
54 | 0 | throw new MethodNotFoundException(reflect.classUnderReflection(), methodMatcher); |
55 | 126 | } |
56 | 46 | return method; |
57 | |
} |
58 | |
|
59 | 36 | @Override public FluentMethod method(final String name) { |
60 | 12 | return method(hasName(name)); |
61 | |
} |
62 | |
|
63 | 18 | @Override public List<FluentMethod> methods() { |
64 | 6 | return boundMethods(); |
65 | |
} |
66 | |
|
67 | 0 | @Override public List<FluentMethod> declaredMethods() { |
68 | 0 | return boundDeclaredMethods(); |
69 | |
} |
70 | |
|
71 | 732 | @Override public List<FluentMethod> methods(final Matcher<? super FluentMethod> methodMatcher) { |
72 | 244 | return select(boundMethods(), methodMatcher); |
73 | |
} |
74 | |
|
75 | 876 | private List<FluentMethod> boundMethods() { |
76 | 296 | return bind(reflect.methods()); |
77 | |
} |
78 | |
|
79 | 720 | private List<FluentMethod> bind(final List<FluentMethod> methods) { |
80 | 964 | return convert( |
81 | 964 | select(methods, isNotStatic()), |
82 | 244 | new ConvertReflectedMethodToBoundReflectedMethod(reflectedTypeFactory, instance)); |
83 | |
} |
84 | |
|
85 | 0 | private List<FluentMethod> boundDeclaredMethods() { |
86 | 0 | return bind(reflect.declaredMethods()); |
87 | |
} |
88 | |
|
89 | 42 | @Override public FluentObject<?> call(final String name, final Object ... args) { |
90 | 14 | final ReflectionMatcher<FluentMember> methodMatcher = hasName(name); |
91 | 14 | return call(methodMatcher, args); |
92 | |
} |
93 | 12 | |
94 | |
@Override public FluentObject<?> call(final Matcher<? super FluentMethod> methodMatcher, final Object... args) { |
95 | 18 | return method(allOf(methodMatcher, canBeCalledWithArguments(args))).call(args); |
96 | |
} |
97 | 0 | |
98 | |
@Override public List<FluentField> fields(final ReflectionMatcher<? super FluentField> fieldMatcher) { |
99 | 4 | return select(boundFields(), fieldMatcher); |
100 | |
} |
101 | 150 | |
102 | |
@Override public List<FluentField> declaredFields() { |
103 | 0 | return boundDeclaredFields(); |
104 | |
} |
105 | 0 | |
106 | |
private List<FluentField> boundFields() { |
107 | 50 | return bindFields(reflect.fields()); |
108 | |
} |
109 | 150 | |
110 | 150 | private List<FluentField> boundDeclaredFields() { |
111 | 150 | return bindFields(reflect.declaredFields()); |
112 | |
} |
113 | |
|
114 | |
private List<FluentField> bindFields(final List<FluentField> fields) { |
115 | 188 | return convert( |
116 | 50 | select(fields, isNotStatic()), |
117 | 50 | new ConvertReflectedFieldToBoundReflectedField(reflectedTypeFactory, instance)); |
118 | |
} |
119 | 138 | |
120 | 138 | @Override public List<FluentField> fields() { |
121 | 52 | return boundFields(); |
122 | |
} |
123 | 132 | |
124 | |
@Override public FluentField field(final ReflectionMatcher<FluentMember> fieldMatcher) { |
125 | 46 | final FluentField selectedField = selectFirst(fields(), fieldMatcher); |
126 | 46 | if (selectedField == null) { |
127 | 2 | throw new FieldNotFoundException(instance.getClass(), fieldMatcher); |
128 | |
} |
129 | 44 | return selectedField; |
130 | |
} |
131 | 0 | |
132 | |
@Override public boolean canBeBoxed(final Class<?> from) { |
133 | 0 | return reflect.canBeBoxed(from); |
134 | |
} |
135 | 0 | |
136 | |
@Override public boolean canBeUnboxed(final Class<?> from) { |
137 | 0 | return reflect.canBeUnboxed(from); |
138 | |
} |
139 | 0 | |
140 | |
@Override public FluentClass<?> annotation(final Matcher<? super FluentClass<?>> annotationMatcher) { |
141 | 0 | return reflect.annotation(annotationMatcher); |
142 | |
} |
143 | 0 | |
144 | |
@Override public <A extends Annotation> A annotation(final Class<A> annotationClass) { |
145 | 0 | return reflect.annotation(annotationClass); |
146 | |
} |
147 | 0 | |
148 | |
@Override public boolean annotatedWith(final Class<? extends Annotation> annotationClass) { |
149 | 0 | return reflect.annotatedWith(annotationClass); |
150 | |
} |
151 | 0 | |
152 | |
@Override public boolean annotatedWith(final Matcher<? super FluentClass<?>> annotationMatcher) { |
153 | 0 | return reflect.annotatedWith(annotationMatcher); |
154 | |
} |
155 | 0 | |
156 | |
@Override public boolean isPrimitive() { |
157 | 0 | return reflect.isPrimitive(); |
158 | |
} |
159 | 0 | |
160 | |
@Override public boolean isUnboxable() { |
161 | 0 | return reflect.isUnboxable(); |
162 | |
} |
163 | 0 | |
164 | |
@Override public FluentClass<T> boxedType() { |
165 | 0 | return reflect.boxedType(); |
166 | |
} |
167 | 0 | |
168 | |
@Override public FluentClass<T> unboxedType() { |
169 | 0 | return reflect.unboxedType(); |
170 | |
} |
171 | 0 | |
172 | |
@Override public boolean assignableFromObject(final Object value) { |
173 | 0 | return reflect.assignableFromObject(value); |
174 | |
} |
175 | 0 | |
176 | |
@Override public boolean assignableTo(final Class<?> klass) { |
177 | 0 | return reflect.assignableTo(klass); |
178 | |
} |
179 | 0 | |
180 | |
@Override public FluentClass<?> typeArgument(final int typeParameter) { |
181 | 0 | return reflect.typeArgument(typeParameter); |
182 | |
} |
183 | 0 | |
184 | |
@Override public String name() { |
185 | 0 | return reflect.name(); |
186 | |
} |
187 | 0 | |
188 | |
@Override public String simpleName() { |
189 | 0 | return reflect.simpleName(); |
190 | |
} |
191 | 0 | |
192 | |
@Override public Type type() { |
193 | 0 | return reflect.type(); |
194 | |
} |
195 | 0 | |
196 | |
@Override public List<FluentClass<?>> interfaces() { |
197 | 0 | return reflect.interfaces(); |
198 | |
} |
199 | 0 | |
200 | |
@Override public List<FluentClass<?>> superclasses() { |
201 | 0 | return reflect.superclasses(); |
202 | |
} |
203 | 24 | |
204 | |
@Override public boolean isType(final ReflectionMatcher<FluentClass<?>> typeMatcher) { |
205 | 0 | return reflect.isType(typeMatcher); |
206 | |
} |
207 | 24 | |
208 | |
@Override public T value() { |
209 | 10 | return instance; |
210 | |
} |
211 | |
|
212 | |
@Override public <V> V as(final Class<V> asType) { |
213 | 10 | return asType.cast(value()); |
214 | |
} |
215 | |
} |