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 }