View Javadoc

1   /*
2    * Copyright 2006-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sourceforge.domian.specification;
17  
18  
19  import java.lang.reflect.InvocationTargetException;
20  import java.lang.reflect.Method;
21  import java.util.Collection;
22  
23  import static java.lang.Boolean.FALSE;
24  import static net.sourceforge.domian.specification.AbstractSpecification.getNegatedSpecification;
25  
26  
27  /**
28   * A parameterized specification deals, as opposed to <i>value bound specifications</i>,
29   * also with <i>value context</i>. In this specification, this context is a class method.
30   * <p/>
31   * For candidate objects to be approved by a parameterized specifications, two things must be fulfilled:
32   * <ol>
33   * <li/>The candidate method must be successfully invoked
34   * <li/>The return value must then be approved by the provided {@link net.sourceforge.domian.specification.Specification}
35   * </ol>
36   * <p/>
37   *
38   * @author Eirik Torske
39   * @since 0.3
40   */
41  // TODO: rename to MethodSpecification?
42  final class MethodParameterizedSpecification<T, F> extends ParameterizedSpecification<T, F> {
43  
44      MethodParameterizedSpecification(final Class<T> declaringClass,
45                                       final Method method,
46                                       final Specification<F> accessibleObjectSpecification) {
47          this.type = declaringClass;
48          this.accessibleObject = method;
49          this.accessibleObjectSpecification = accessibleObjectSpecification;
50      }
51  
52      @Override
53      String getName() {
54          return ((Method) this.accessibleObject).getName();
55      }
56  
57      @Override
58      //@SuppressWarnings("unchecked")
59      public Boolean isSatisfiedBy(final T candidate) {
60          Method method = (Method) this.accessibleObject;
61          try {
62              //if (this.accessibleObjectSpecification instanceof CollectionSpecification) {
63                  /* @SuppressWarnings("unchecked") -> "I solemnly swear that this statement will not throw any ClassCastException!" -eirik torske-
64                  /* Such a type mismatch will be detected in the parent static factory method, and a java.lang.IllegalArgumentException will be thrown */
65              //    final Collection<F> candidateMethodReturnValue = (Collection<F>) method.invoke(candidate);
66              //    return ((CollectionSpecification<F>) this.accessibleObjectSpecification).isSatisfiedBy(candidateMethodReturnValue);
67              /*
68              } else if (this.accessibleObjectSpecification instanceof JointDenialSpecification) {
69  
70                  final Class<F> accessibleObjectSpecificationType = this.accessibleObjectSpecification.getType();
71                  final Object candidateMethodReturnValue = method.invoke(candidate);
72                  final Class candidateMethodReturnValueType = candidateMethodReturnValue.getClass();
73  
74                  final Specification invertedSpec = getNegatedSpecification((JointDenialSpecification) this.accessibleObjectSpecification);
75  
76                  return this.accessibleObjectSpecification.isSatisfiedBy((F) candidateMethodReturnValue);
77                  //return !invertedSpec.isSatisfiedBy(candidateMethodReturnValue);
78                */
79              //} else {
80                  //final Class<F> accessibleObjectSpecificationType = this.accessibleObjectSpecification.getType();
81                  //final Object candidateMethodReturnValue = method.invoke(candidate);
82                  //final Class candidateMethodReturnValueType = candidateMethodReturnValue.getClass();
83  
84                  return this.accessibleObjectSpecification.isSatisfiedBy((F) method.invoke(candidate));
85              //}
86  
87          } catch (ClassCastException e) {
88              // Keep until beta or something...
89              e.printStackTrace();
90  
91              return FALSE;
92  
93          } catch (IllegalAccessException e) {
94              // Keep until beta or something...
95              e.printStackTrace();
96  
97              throw new IllegalArgumentException(e);
98  
99          } catch (InvocationTargetException e) {
100             // Keep until beta or something...
101             e.printStackTrace();
102 
103             throw new IllegalArgumentException(e);
104         }
105     }
106 }