1
7 package org.hibernate.validator.internal.metadata.aggregated;
8
9 import java.lang.reflect.Type;
10 import java.util.List;
11 import java.util.Set;
12
13 import javax.validation.ElementKind;
14 import javax.validation.metadata.ParameterDescriptor;
15
16 import org.hibernate.validator.internal.engine.ConstraintCreationContext;
17 import org.hibernate.validator.internal.engine.path.PathImpl;
18 import org.hibernate.validator.internal.metadata.core.MetaConstraint;
19 import org.hibernate.validator.internal.metadata.descriptor.ParameterDescriptorImpl;
20 import org.hibernate.validator.internal.metadata.facets.Cascadable;
21 import org.hibernate.validator.internal.metadata.location.ConstraintLocation.ConstraintLocationKind;
22 import org.hibernate.validator.internal.metadata.raw.ConstrainedElement;
23 import org.hibernate.validator.internal.metadata.raw.ConstrainedElement.ConstrainedElementKind;
24 import org.hibernate.validator.internal.metadata.raw.ConstrainedParameter;
25 import org.hibernate.validator.internal.properties.Callable;
26 import org.hibernate.validator.internal.util.ExecutableParameterNameProvider;
27
28
35 public class ParameterMetaData extends AbstractConstraintMetaData implements Cascadable {
36
37 private final int index;
38 private final CascadingMetaData cascadingMetaData;
39
40 private ParameterMetaData(int index,
41 String name,
42 Type type,
43 Set<MetaConstraint<?>> constraints,
44 Set<MetaConstraint<?>> containerElementsConstraints,
45 CascadingMetaData cascadingMetaData) {
46 super(
47 name,
48 type,
49 constraints,
50 containerElementsConstraints,
51 cascadingMetaData.isMarkedForCascadingOnAnnotatedObjectOrContainerElements(),
52 !constraints.isEmpty() || !containerElementsConstraints.isEmpty() || cascadingMetaData.isMarkedForCascadingOnAnnotatedObjectOrContainerElements()
53 );
54
55 this.index = index;
56
57 this.cascadingMetaData = cascadingMetaData;
58 }
59
60 public int getIndex() {
61 return index;
62 }
63
64 @Override
65 public ConstraintLocationKind getConstraintLocationKind() {
66 return ConstraintLocationKind.PARAMETER;
67 }
68
69 @Override
70 public ParameterDescriptor asDescriptor(boolean defaultGroupSequenceRedefined, List<Class<?>> defaultGroupSequence) {
71 return new ParameterDescriptorImpl(
72 getType(),
73 index,
74 getName(),
75 asDescriptors( getDirectConstraints() ),
76 asContainerElementTypeDescriptors( getContainerElementsConstraints(), cascadingMetaData, defaultGroupSequenceRedefined, defaultGroupSequence ),
77 cascadingMetaData.isCascading(),
78 defaultGroupSequenceRedefined,
79 defaultGroupSequence,
80 cascadingMetaData.getGroupConversionDescriptors()
81 );
82 }
83
84 @Override
85 public Object getValue(Object parent) {
86 return ( (Object[]) parent )[getIndex()];
87 }
88
89 @Override
90 public Type getCascadableType() {
91 return getType();
92 }
93
94 @Override
95 public void appendTo(PathImpl path) {
96 path.addParameterNode( getName(), getIndex() );
97 }
98
99 @Override
100 public CascadingMetaData getCascadingMetaData() {
101 return cascadingMetaData;
102 }
103
104 @Override
105 public ElementKind getKind() {
106 return ElementKind.PARAMETER;
107 }
108
109 public static class Builder extends MetaDataBuilder {
110 private final ExecutableParameterNameProvider parameterNameProvider;
111 private final Type parameterType;
112 private final int parameterIndex;
113 private Callable callableForNameRetrieval;
114 private CascadingMetaDataBuilder cascadingMetaDataBuilder;
115
116 public Builder(Class<?> beanClass,
117 ConstrainedParameter constrainedParameter,
118 ConstraintCreationContext constraintCreationContext,
119 ExecutableParameterNameProvider parameterNameProvider) {
120 super( beanClass, constraintCreationContext );
121
122 this.parameterNameProvider = parameterNameProvider;
123 this.parameterType = constrainedParameter.getType();
124 this.parameterIndex = constrainedParameter.getIndex();
125
126 add( constrainedParameter );
127 }
128
129 @Override
130 public boolean accepts(ConstrainedElement constrainedElement) {
131 if ( constrainedElement.getKind() != ConstrainedElementKind.PARAMETER ) {
132 return false;
133 }
134
135 return ( (ConstrainedParameter) constrainedElement ).getIndex() == parameterIndex;
136 }
137
138 @Override
139 public void add(ConstrainedElement constrainedElement) {
140 super.add( constrainedElement );
141
142 ConstrainedParameter newConstrainedParameter = (ConstrainedParameter) constrainedElement;
143
144 if ( cascadingMetaDataBuilder == null ) {
145 cascadingMetaDataBuilder = newConstrainedParameter.getCascadingMetaDataBuilder();
146 }
147 else {
148 cascadingMetaDataBuilder = cascadingMetaDataBuilder.merge( newConstrainedParameter.getCascadingMetaDataBuilder() );
149 }
150
151
152
153
154
155 if ( callableForNameRetrieval == null ||
156 newConstrainedParameter.getCallable().getDeclaringClass().isAssignableFrom( callableForNameRetrieval.getDeclaringClass() ) ) {
157 callableForNameRetrieval = newConstrainedParameter.getCallable();
158 }
159 }
160
161 @Override
162 public ParameterMetaData build() {
163 return new ParameterMetaData(
164 parameterIndex,
165 callableForNameRetrieval.getParameterName( parameterNameProvider, parameterIndex ),
166 parameterType,
167 adaptOriginsAndImplicitGroups( getDirectConstraints() ),
168 adaptOriginsAndImplicitGroups( getContainerElementConstraints() ),
169 cascadingMetaDataBuilder.build( constraintCreationContext.getValueExtractorManager(), callableForNameRetrieval )
170 );
171 }
172 }
173 }
174