1 /*
2  * Hibernate Validator, declare and validate application constraints
3  *
4  * License: Apache License, Version 2.0
5  * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
6  */

7 package org.hibernate.validator.internal.metadata.raw;
8
9 import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet;
10
11 import java.lang.reflect.Type;
12 import java.util.Collections;
13 import java.util.HashSet;
14 import java.util.Set;
15
16 import org.hibernate.validator.internal.metadata.aggregated.CascadingMetaDataBuilder;
17 import org.hibernate.validator.internal.metadata.core.MetaConstraint;
18 import org.hibernate.validator.internal.properties.Callable;
19
20 /**
21  * Contains constraint-related meta-data for one method parameter.
22  *
23  * @author Gunnar Morling
24  * @author Guillaume Smet
25  */

26 public class ConstrainedParameter extends AbstractConstrainedElement {
27
28     private final Callable callable;
29     private final Type type;
30     private final int index;
31
32     public ConstrainedParameter(ConfigurationSource source,
33                                 Callable callable,
34                                 Type type,
35                                 int index) {
36         this(
37                 source,
38                 callable,
39                 type,
40                 index,
41                 Collections.<MetaConstraint<?>>emptySet(),
42                 Collections.<MetaConstraint<?>>emptySet(),
43                 CascadingMetaDataBuilder.nonCascading()
44         );
45     }
46
47     /**
48      * Creates a new parameter meta data object.
49      *
50      * @param source The source of meta data.
51      * @param callable The executable of the represented method parameter.
52      * @param type the parameter type
53      * @param index the index of the parameter
54      * @param constraints The constraints of the represented method parameter, if
55      * any.
56      * @param typeArgumentConstraints Type arguments constraints, if any.
57      * @param cascadingMetaDataBuilder The cascaded validation metadata for this element and its container elements.
58      */

59     public ConstrainedParameter(ConfigurationSource source,
60                                 Callable callable,
61                                 Type type,
62                                 int index,
63                                 Set<MetaConstraint<?>> constraints,
64                                 Set<MetaConstraint<?>> typeArgumentConstraints,
65                                 CascadingMetaDataBuilder cascadingMetaDataBuilder) {
66         super(
67                 source,
68                 ConstrainedElementKind.PARAMETER,
69                 constraints,
70                 typeArgumentConstraints,
71                 cascadingMetaDataBuilder
72         );
73
74         this.callable = callable;
75         this.type = type;
76         this.index = index;
77     }
78
79     public Type getType() {
80         return type;
81     }
82
83     public Callable getCallable() {
84         return callable;
85     }
86
87     public int getIndex() {
88         return index;
89     }
90
91     /**
92      * Creates a new constrained parameter object by merging this and the given
93      * other parameter.
94      *
95      * @param other The parameter to merge.
96      *
97      * @return A merged parameter.
98      */

99     public ConstrainedParameter merge(ConstrainedParameter other) {
100         ConfigurationSource mergedSource = ConfigurationSource.max( source, other.source );
101
102         Set<MetaConstraint<?>> mergedConstraints = newHashSet( constraints );
103         mergedConstraints.addAll( other.constraints );
104
105         Set<MetaConstraint<?>> mergedTypeArgumentConstraints = new HashSet<>( typeArgumentConstraints );
106         mergedTypeArgumentConstraints.addAll( other.typeArgumentConstraints );
107
108         CascadingMetaDataBuilder mergedCascadingMetaData = cascadingMetaDataBuilder.merge( other.cascadingMetaDataBuilder );
109
110         return new ConstrainedParameter(
111                 mergedSource,
112                 callable,
113                 type,
114                 index,
115                 mergedConstraints,
116                 mergedTypeArgumentConstraints,
117                 mergedCascadingMetaData
118         );
119     }
120
121     @Override
122     public String toString() {
123         //display short annotation type names
124         StringBuilder sb = new StringBuilder();
125
126         for ( MetaConstraint<?> oneConstraint : getConstraints() ) {
127             sb.append( oneConstraint.getDescriptor().getAnnotation().annotationType().getSimpleName() );
128             sb.append( ", " );
129         }
130
131         String constraintsAsString = sb.length() > 0 ? sb.substring( 0, sb.length() - 2 ) : sb.toString();
132
133         return "ParameterMetaData [callable=" + callable + ", index=" + index + "], constraints=["
134                 + constraintsAsString + "]";
135     }
136
137     @Override
138     public int hashCode() {
139         final int prime = 31;
140         int result = super.hashCode();
141         result = prime * result + index;
142         result = prime * result + callable.hashCode();
143         return result;
144     }
145
146     @Override
147     public boolean equals(Object obj) {
148         if ( this == obj ) {
149             return true;
150         }
151         if ( !super.equals( obj ) ) {
152             return false;
153         }
154         if ( getClass() != obj.getClass() ) {
155             return false;
156         }
157         ConstrainedParameter other = (ConstrainedParameter) obj;
158         if ( index != other.index ) {
159             return false;
160         }
161         else if ( !callable.equals( other.callable ) ) {
162             return false;
163         }
164         return true;
165     }
166 }
167