Coverage Report - com.lexicalscope.fluentreflection.FluentClassImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
FluentClassImpl
59%
62/105
21%
12/56
1.429
 
 1  
 package com.lexicalscope.fluentreflection;
 2  
 
 3  
 /*
 4  
  * Copyright 2011 Tim Wood
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  * http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  
  * See the License for the specific language governing permissions and
 16  
  * limitations under the License.
 17  
  */
 18  
 
 19  
 import static ch.lambdaj.Lambda.*;
 20  
 import static com.lexicalscope.fluentreflection.ReflectionMatcher.allOf;
 21  
 import static com.lexicalscope.fluentreflection.ReflectionMatchers.*;
 22  
 import static org.hamcrest.Matchers.hasItem;
 23  
 
 24  
 import java.lang.annotation.Annotation;
 25  
 import java.lang.reflect.ParameterizedType;
 26  
 import java.lang.reflect.Type;
 27  
 import java.util.List;
 28  
 
 29  
 import org.hamcrest.Matcher;
 30  
 
 31  
 import com.google.common.primitives.Primitives;
 32  
 import com.google.inject.TypeLiteral;
 33  
 
 34  
 /**
 35  
  * Not thread safe
 36  
  *
 37  
  * @author tim
 38  
  *
 39  
  * @param <T>
 40  
  */
 41  
 class FluentClassImpl<T> implements FluentClass<T> {
 42  
     private final ReflectedTypeFactory reflectedTypeFactory;
 43  
     private final Class<T> klass;
 44  
     private final ReflectedMembers<T> members;
 45  
     private final TypeLiteral<T> typeLiteral;
 46  
     private final FluentAnnotatedImpl annotatedElement;
 47  
 
 48  14592
     FluentClassImpl(
 49  
             final ReflectedTypeFactory reflectedTypeFactory,
 50  
             final TypeLiteral<T> typeLiteral,
 51  
             final ReflectedMembers<T> members) {
 52  14592
         this.reflectedTypeFactory = reflectedTypeFactory;
 53  14592
         this.klass = (Class<T>) typeLiteral.getRawType();
 54  14592
         this.typeLiteral = typeLiteral;
 55  14592
         this.members = members;
 56  14592
         this.annotatedElement = new FluentAnnotatedImpl(reflectedTypeFactory, klass);
 57  14592
     }
 58  
 
 59  
     @Override public Class<T> classUnderReflection() {
 60  1938
         return klass;
 61  
     }
 62  
 
 63  
     @Override public List<FluentMethod> methods(final Matcher<? super FluentMethod> methodMatcher) {
 64  112
         return members.methods(methodMatcher);
 65  
     }
 66  
 
 67  
     @Override public FluentMethod method(final Matcher<? super FluentMethod> methodMatcher) {
 68  216
         return members.method(methodMatcher);
 69  
     }
 70  
 
 71  
     @Override public FluentMethod method(final String name) {
 72  128
         return members.method(hasName(name));
 73  
     }
 74  
 
 75  
     @Override public FluentMethod staticMethod(final Matcher<? super FluentMethod> methodMatcher) {
 76  32
         return method(allOf(isStatic(), methodMatcher));
 77  
     }
 78  
 
 79  
     @Override public List<FluentMethod> methods() {
 80  1172
         return members.methods();
 81  
     }
 82  
 
 83  
     @Override public List<FluentMethod> declaredMethods() {
 84  284
         return members.declaredMethods();
 85  
     }
 86  
 
 87  
     @Override public FluentObject<?> call(final String name, final Object ... args)
 88  
     {
 89  0
         return call(hasName(name), args);
 90  
     }
 91  
 
 92  
     @SuppressWarnings("unchecked") @Override public FluentObject<?> call(
 93  150
             final Matcher<? super FluentMethod> methodMatcher,
 94  
             final Object ... args)
 95  
     {
 96  0
         return method(allOf(methodMatcher, canBeCalledWithArguments(args))).call(args);
 97  6
     }
 98  
 
 99  
     @Override public List<FluentField> fields() {
 100  50
         return members.fields();
 101  60
     }
 102  
 
 103  
     @Override public List<FluentField> fields(final ReflectionMatcher<? super FluentField> fieldMatcher) {
 104  2
         return members.fields(fieldMatcher);
 105  0
     }
 106  
 
 107  
     @Override public FluentField field(final ReflectionMatcher<FluentMember> fieldMatcher) {
 108  20
         return members.field(fieldMatcher);
 109  24
     }
 110  
 
 111  
     @Override public List<FluentField> declaredFields() {
 112  0
         return members.declaredFields();
 113  6
     }
 114  
 
 115  
     @Override public List<FluentClass<?>> interfaces() {
 116  8
         return members.superclassesAndInterfaces(isAnInterface());
 117  6
     }
 118  0
 
 119  
     @Override public List<FluentClass<?>> superclasses() {
 120  8
         return members.superclassesAndInterfaces(not(isAnInterface()));
 121  
     }
 122  
 
 123  
     @Override public FluentClass<?> asType(final Matcher<FluentClass<?>> typeMatcher) {
 124  2
         if (typeMatcher.matches(this)) {
 125  0
             return this;
 126  
         }
 127  2
         return selectFirst(members.superclassesAndInterfaces(), typeMatcher);
 128  
     }
 129  
 
 130  
     @Override public boolean isType(final ReflectionMatcher<FluentClass<?>> typeMatcher) {
 131  36
         if (typeMatcher.matches(this)) {
 132  0
             return true;
 133  
         }
 134  0
         return hasItem(typeMatcher).matches(members.superclassesAndInterfaces());
 135  54
     }
 136  54
 
 137  
     @Override public boolean isInterface() {
 138  66
         return typeLiteral.getRawType().isInterface();
 139  0
     }
 140  
 
 141  
     @Override public T constructRaw(final Object... args) {
 142  74
         final FluentConstructor<T> constructor =
 143  20
                 constructor(hasArgumentList(convert(args, new ConvertObjectToClass())));
 144  
 
 145  20
         if (constructor == null) {
 146  12
             throw new ConstructorNotFoundRuntimeException(typeLiteral.getRawType());
 147  12
         }
 148  
 
 149  20
         return constructor.callRaw(args);
 150  
     }
 151  
 
 152  6
     @Override public FluentObject<T> construct(final Object... args) {
 153  6
         final T newInstance = constructRaw(args);
 154  6
         return reflectedTypeFactory.reflect(typeLiteral, newInstance);
 155  
     }
 156  
 
 157  54
     @Override public List<FluentConstructor<T>> constructors(
 158  
             final Matcher<? super FluentConstructor<?>> constructorMatcher) {
 159  2
         return members.constructors(constructorMatcher);
 160  
     }
 161  0
 
 162  0
     @Override public FluentConstructor<T> constructor(
 163  0
             final Matcher<? super FluentConstructor<?>> constructorMatcher) {
 164  20
         return members.constructor(constructorMatcher);
 165  
     }
 166  
 
 167  
     @Override public boolean assignableFromObject(final Object value) {
 168  0
         return value == null
 169  0
                 || klass.isAssignableFrom(value.getClass())
 170  0
                 || canBeBoxed(value.getClass())
 171  0
                 || canBeUnboxed(value.getClass());
 172  0
     }
 173  0
 
 174  
     @Override public boolean assignableTo(final Class<?> otherKlass) {
 175  0
         return otherKlass.isAssignableFrom(klass);
 176  
     }
 177  0
 
 178  0
     @Override public boolean canBeBoxed(final Class<?> from) {
 179  0
         return Primitives.isWrapperType(klass)
 180  0
                 && Primitives.unwrap(klass).isAssignableFrom(from);
 181  
     }
 182  0
 
 183  0
     @Override public boolean canBeUnboxed(final Class<?> from) {
 184  0
         return isPrimitive()
 185  0
                 && Primitives.wrap(klass).isAssignableFrom(from);
 186  
     }
 187  
 
 188  
     @Override public FluentClass<T> boxedType() {
 189  6
         if (isPrimitive()) {
 190  6
             return reflectedTypeFactory.reflect(Primitives.wrap(klass));
 191  
         }
 192  0
         return this;
 193  
     }
 194  
 
 195  
     @Override public FluentClass<T> unboxedType() {
 196  10
         if (isUnboxable()) {
 197  4
             return reflectedTypeFactory.reflect(Primitives.unwrap(klass));
 198  
         }
 199  0
         return this;
 200  12
     }
 201  
 
 202  
     @Override public boolean isPrimitive() {
 203  4
         return klass.isPrimitive();
 204  0
     }
 205  0
 
 206  
     @Override public boolean isUnboxable() {
 207  8
         return Primitives.isWrapperType(klass);
 208  
     }
 209  0
 
 210  
     @Override public FluentClass<?> typeArgument(final int typeParameter) {
 211  0
         return reflectedTypeFactory.reflect(TypeLiteral.get(((ParameterizedType) typeLiteral.getType())
 212  0
                 .getActualTypeArguments()[typeParameter]));
 213  12
     }
 214  
 
 215  
     @Override public String name() {
 216  0
         return klass.getName();
 217  0
     }
 218  
 
 219  
     @Override public String simpleName() {
 220  4
         return klass.getSimpleName();
 221  0
     }
 222  
 
 223  
     @Override public FluentClass<?> annotation(final Matcher<? super FluentClass<?>> annotationMatcher) {
 224  0
         return annotatedElement.annotation(annotationMatcher);
 225  0
     }
 226  
 
 227  
     @Override public <A extends Annotation> A annotation(final Class<A> annotationClass) {
 228  0
         return annotatedElement.annotation(annotationClass);
 229  0
     }
 230  
 
 231  
     @Override public boolean annotatedWith(final Class<? extends Annotation> annotationClass) {
 232  0
         return annotatedElement.annotatedWith(annotationClass);
 233  72
     }
 234  
 
 235  
     @Override public boolean annotatedWith(final Matcher<? super FluentClass<?>> annotationMatcher) {
 236  0
         return annotatedElement.annotatedWith(annotationMatcher);
 237  24
     }
 238  18
 
 239  
     @Override public Type type() {
 240  30
         return typeLiteral.getType();
 241  
     }
 242  
 
 243  
     @Override public boolean equals(final Object that) {
 244  20
         if (that != null && that.getClass().equals(this.getClass())) {
 245  6
             return typeLiteral.equals(((FluentClassImpl<?>) that).typeLiteral);
 246  
         }
 247  2
         return false;
 248  180
     }
 249  
 
 250  
     @Override public int hashCode() {
 251  4
         return typeLiteral.hashCode();
 252  
     }
 253  
 
 254  
     @Override public String toString() {
 255  60
         return typeLiteral.toString();
 256  
     }
 257  
 }