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.engine.resolver;
8
9 import java.lang.annotation.ElementType;
10 import java.lang.invoke.MethodHandles;
11
12 import javax.persistence.Persistence;
13 import javax.validation.Path;
14 import javax.validation.TraversableResolver;
15
16 import org.hibernate.validator.internal.util.logging.Log;
17 import org.hibernate.validator.internal.util.logging.LoggerFactory;
18
19 /**
20  * An implementation of {@code TraversableResolver} which is aware of JPA 2 and utilizes {@code PersistenceUtil} to
21  * query the reachability of a property.
22  * This resolver will be automatically enabled if JPA 2 is on the classpath and the default {@code TraversableResolver} is
23  * used.
24  * <p>
25  * This class needs to be public as it's instantiated via a privileged action that is not in this package.
26  *
27  * @author Hardy Ferentschik
28  * @author Emmanuel Bernard
29  */

30 public class JPATraversableResolver implements TraversableResolver {
31
32     private static final Log LOG = LoggerFactory.make( MethodHandles.lookup() );
33
34     @Override
35     public final boolean isReachable(Object traversableObject,
36                                      Path.Node traversableProperty,
37                                      Class<?> rootBeanType,
38                                      Path pathToTraversableObject,
39                                      ElementType elementType) {
40         if ( LOG.isTraceEnabled() ) {
41             LOG.tracef(
42                     "Calling isReachable on object %s with node name %s.",
43                     traversableObject,
44                     traversableProperty.getName()
45             );
46         }
47
48         if ( traversableObject == null ) {
49             return true;
50         }
51
52         return Persistence.getPersistenceUtil().isLoaded( traversableObject, traversableProperty.getName() );
53     }
54
55     @Override
56     public final boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType, Path pathToTraversableObject, ElementType elementType) {
57         return true;
58     }
59 }
60