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