com.stehno.sjdbcx.support.SqlResolver.java Source code

Java tutorial

Introduction

Here is the source code for com.stehno.sjdbcx.support.SqlResolver.java

Source

/*
 * Copyright (c) 2013 Christopher J. Stehno
 *
 * Licensed 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 com.stehno.sjdbcx.support;

import com.stehno.sjdbcx.annotation.JdbcRepository;
import com.stehno.sjdbcx.annotation.ResolveMethod;
import com.stehno.sjdbcx.annotation.Sql;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * Used to resolve the SQL string from the annotation content or from the specified (or default) properties file.
 */
public class SqlResolver {

    private static final Logger log = LoggerFactory.getLogger(SqlResolver.class);
    private static final String PROP_FILE = "%s.sql.properties";

    /**
     * Uses the Sql and JdbcRepository annotations to resolve the SQL string to be used.
     *
     * @param prototype the repository prototype class
     * @param method the method to resolve SQL for
     * @return the String of SQL
     */
    public String resolve(final Class prototype, final Method method) {
        final JdbcRepository jdbcAnno = AnnotationUtils.findAnnotation(prototype, JdbcRepository.class);
        final Sql sqlAnno = AnnotationUtils.getAnnotation(method, Sql.class);

        if (shouldLookupSql(jdbcAnno, sqlAnno)) {
            final String sqlKey = StringUtils.hasLength(sqlAnno.value()) ? sqlAnno.value()
                    : method.getName().toLowerCase();
            final Resource resource = determineResolverResource(prototype, jdbcAnno);

            final String sql = resolve(resource).getProperty(sqlKey);

            log.debug("Resolved SQL ({}) for repository ({}) from resource ({}) property ({})", sql, prototype,
                    resource, sqlKey);

            return sql;

        } else {
            return sqlAnno.value();
        }
    }

    private Resource determineResolverResource(final Class clazz, final JdbcRepository jdbcAnno) {
        final String resourceStr = jdbcAnno != null ? jdbcAnno.value() : null;
        final String fileName = clazz.getSimpleName().toLowerCase();
        final String resourcePath = StringUtils.isEmpty(resourceStr) ? String.format(PROP_FILE, fileName)
                : resourceStr;
        final ClassPathResource resource = new ClassPathResource("/" + resourcePath);

        log.debug("Resolving SQL for ({}) from resource ({})", clazz, resource);

        return resource;
    }

    private boolean shouldLookupSql(final JdbcRepository jdbcAnno, final Sql sqlAnno) {
        ResolveMethod resolveMethod = sqlAnno.resolve();
        if (resolveMethod == ResolveMethod.DEFAULT) {
            if (jdbcAnno != null) {
                resolveMethod = jdbcAnno.defaultResolve() == ResolveMethod.DEFAULT ? ResolveMethod.LOOKUP
                        : jdbcAnno.defaultResolve();
            } else {
                resolveMethod = ResolveMethod.LOOKUP;
            }
        }

        return resolveMethod == ResolveMethod.LOOKUP;
    }

    private Properties resolve(final Resource resource) {
        // FIXME: properties files need to be cached once loaded.

        final Properties properties = new Properties();

        try (final InputStream input = resource.getInputStream()) {
            properties.load(input);
        } catch (IOException e) {
            log.error("Unable to load property resource ({}): {}", resource, e.getMessage(), e);
        }

        log.trace("Loaded properties file ({}): {}", resource, properties);

        return properties;
    }
}