org.apache.bval.jsr.resolver.DefaultTraversableResolver.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.bval.jsr.resolver.DefaultTraversableResolver.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with this
 * work for additional information regarding copyright ownership. The ASF
 * licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.bval.jsr.resolver;

import org.apache.bval.util.reflection.Reflection;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.weaver.privilizer.Privilizing;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;

import javax.validation.Path;
import javax.validation.TraversableResolver;

import java.lang.annotation.ElementType;
import java.util.logging.Level;
import java.util.logging.Logger;

/** @see javax.validation.TraversableResolver */
@Privilizing(@CallTo(Reflection.class))
public class DefaultTraversableResolver implements TraversableResolver, CachingRelevant {
    private static final Logger log = Logger.getLogger(DefaultTraversableResolver.class.getName());
    private static final boolean LOG_FINEST = log.isLoggable(Level.FINEST);

    /** Class to load to check whether JPA 2 is on the classpath. */
    private static final String PERSISTENCE_UTIL_CLASSNAME = "javax.persistence.PersistenceUtil";

    /** Class to instantiate in case JPA 2 is on the classpath. */
    private static final String JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME = "org.apache.bval.jsr.resolver.JPATraversableResolver";

    private TraversableResolver jpaTR;

    /**
     * Create a new DefaultTraversableResolver instance.
     */
    public DefaultTraversableResolver() {
        initJpa();
    }

    /**
     * {@inheritDoc}
     */
    public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
            Path pathToTraversableObject, ElementType elementType) {
        return jpaTR == null || jpaTR.isReachable(traversableObject, traversableProperty, rootBeanType,
                pathToTraversableObject, elementType);
    }

    /**
     * {@inheritDoc}
     */
    public boolean isCascadable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType,
            Path pathToTraversableObject, ElementType elementType) {
        return jpaTR == null || jpaTR.isCascadable(traversableObject, traversableProperty, rootBeanType,
                pathToTraversableObject, elementType);
    }

    /** Tries to load detect and load JPA. */
    @SuppressWarnings("unchecked")
    private void initJpa() {
        final ClassLoader classLoader = Reflection.getClassLoader(DefaultTraversableResolver.class);
        try {
            Reflection.getClass(classLoader, PERSISTENCE_UTIL_CLASSNAME);
            if (LOG_FINEST) {
                log.log(Level.FINEST, String.format("Found %s on classpath.", PERSISTENCE_UTIL_CLASSNAME));
            }
        } catch (final Exception e) {
            log.log(Level.FINEST,
                    String.format("Cannot find %s on classpath. All properties will per default be traversable.",
                            PERSISTENCE_UTIL_CLASSNAME));
            return;
        }

        try {
            Class<? extends TraversableResolver> jpaAwareResolverClass = (Class<? extends TraversableResolver>) ClassUtils
                    .getClass(classLoader, JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME, true);
            jpaTR = jpaAwareResolverClass.newInstance();
            if (LOG_FINEST) {
                log.log(Level.FINEST,
                        String.format("Instantiated an instance of %s.", JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME));
            }
        } catch (final Exception e) {
            log.log(Level.WARNING, String.format(
                    "Unable to load or instantiate JPA aware resolver %s. All properties will per default be traversable.",
                    JPA_AWARE_TRAVERSABLE_RESOLVER_CLASSNAME), e);
        }
    }

    /**
     * {@inheritDoc}
     */
    public boolean needsCaching() {
        return jpaTR != null && CachingTraversableResolver.needsCaching(jpaTR);
    }
}