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.aggregated;
8
9 import java.lang.invoke.MethodHandles;
10 import java.lang.reflect.TypeVariable;
11 import java.util.Set;
12
13 import javax.validation.metadata.GroupConversionDescriptor;
14
15 import org.hibernate.validator.internal.engine.valueextraction.AnnotatedObject;
16 import org.hibernate.validator.internal.engine.valueextraction.ValueExtractorManager;
17 import org.hibernate.validator.internal.util.logging.Log;
18 import org.hibernate.validator.internal.util.logging.LoggerFactory;
19
20 /**
21  * A simplified view of the cascading validation metadata for an element that does not contain any container element
22  * cascading.
23  * <p>
24  * Note that the element might be a container but doesn't have any cascading metadata on the container elements.
25  *
26  * @author Guillaume Smet
27  * @author Marko Bekhta
28  */

29 public class NonContainerCascadingMetaData implements CascadingMetaData {
30
31     private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
32
33     private static final NonContainerCascadingMetaData NON_CASCADING = new NonContainerCascadingMetaData( false,
34             GroupConversionHelper.EMPTY );
35
36     private static final NonContainerCascadingMetaData CASCADING_WITHOUT_GROUP_CONVERSIONS = new NonContainerCascadingMetaData( true,
37             GroupConversionHelper.EMPTY );
38
39     /**
40      * If this type parameter is marked for cascading.
41      */

42     private final boolean cascading;
43
44     /**
45      * The group conversions defined for this type parameter.
46      */

47     private GroupConversionHelper groupConversionHelper;
48
49     public static NonContainerCascadingMetaData of(CascadingMetaDataBuilder cascadingMetaDataBuilder, Object context) {
50         if ( !cascadingMetaDataBuilder.isCascading() ) {
51             return NON_CASCADING;
52         }
53         else if ( cascadingMetaDataBuilder.getGroupConversions().isEmpty() ) {
54             return CASCADING_WITHOUT_GROUP_CONVERSIONS;
55         }
56         else {
57             return new NonContainerCascadingMetaData( cascadingMetaDataBuilder );
58         }
59     }
60
61     private NonContainerCascadingMetaData(CascadingMetaDataBuilder cascadingMetaDataBuilder) {
62         this(
63                 cascadingMetaDataBuilder.isCascading(),
64                 GroupConversionHelper.of( cascadingMetaDataBuilder.getGroupConversions() )
65         );
66     }
67
68     private NonContainerCascadingMetaData(boolean cascading, GroupConversionHelper groupConversionHelper) {
69         this.cascading = cascading;
70         this.groupConversionHelper = groupConversionHelper;
71     }
72
73     @Override
74     public TypeVariable<?> getTypeParameter() {
75         return AnnotatedObject.INSTANCE;
76     }
77
78     @Override
79     public boolean isCascading() {
80         return cascading;
81     }
82
83     @Override
84     public boolean isMarkedForCascadingOnAnnotatedObjectOrContainerElements() {
85         return cascading;
86     }
87
88     @Override
89     public Class<?> convertGroup(Class<?> originalGroup) {
90         return groupConversionHelper.convertGroup( originalGroup );
91     }
92
93     @Override
94     public Set<GroupConversionDescriptor> getGroupConversionDescriptors() {
95         return groupConversionHelper.asDescriptors();
96     }
97
98     @Override
99     public boolean isContainer() {
100         return false;
101     }
102
103     @Override
104     public CascadingMetaData addRuntimeContainerSupport(ValueExtractorManager valueExtractorManager, Class<?> valueClass) {
105         // do nothing, we are sure it is not a container
106         return this;
107     }
108
109     @Override
110     @SuppressWarnings("unchecked")
111     public <T extends CascadingMetaData> T as(Class<T> clazz) {
112         if ( clazz.isAssignableFrom( getClass() ) ) {
113             return (T) this;
114         }
115
116         throw LOG.getUnableToCastException( this, clazz );
117     }
118
119     @Override
120     public String toString() {
121         StringBuilder sb = new StringBuilder();
122         sb.append( getClass().getSimpleName() );
123         sb.append( " [" );
124         sb.append( "cascading=" ).append( cascading ).append( ", " );
125         sb.append( "groupConversions=" ).append( groupConversionHelper ).append( ", " );
126         sb.append( "]" );
127         return sb.toString();
128     }
129 }
130