View Javadoc

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   * Copyright 2011 Tim Wood
15   *
16   * Licensed under the Apache License, Version 2.0 (the "License");
17   * you may not use this file except in compliance with the License.
18   * You may obtain a copy of the License at
19   *
20   * http://www.apache.org/licenses/LICENSE-2.0
21   *
22   * Unless required by applicable law or agreed to in writing, software
23   * distributed under the License is distributed on an "AS IS" BASIS,
24   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25   * See the License for the specific language governing permissions and
26   * limitations under the License.
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 }