/*
 * Copyright 2002-2008 the original author or authors.
 *
 * 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 org.springframework.samples.petclinic.config;

import javax.sql.DataSource;

import org.springframework.config.java.annotation.Bean;
import org.springframework.config.java.annotation.Configuration;
import org.springframework.config.java.annotation.ExternalBean;
import org.springframework.config.java.annotation.Import;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.samples.petclinic.Clinic;
import org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic;
import org.springframework.transaction.PlatformTransactionManager;

/**
 * Application context definition for JDBC-based Petclinic. This configuration is an
 * alternative to {@link JpaPetclinicApplicationConfig}. See web.xml to see how
 * it is bootstrapped at webapp startup time.
 * 
 * <h3>Understanding the annotations</h3>
 * 
 * {@code @Import} behaves similarly to Spring XML's {@literal <import/>}
 * element.  In this case, in pulls in all {@code @Bean} definitions from
 * {@link PetclinicApplicationConfig} and {@link EmbeddedDataSourceConfig}.
 * These two configuration classes are broken up for modularity purposes:
 * {@code JpaPetclinicApplicationConfig} needs a {@code DataSource} object,
 * but it does not need to be concerned with how or where that object is configured.
 * See {@link EmbeddedDataSourceConfig} for further details.  Note that the
 * {@code @ExternalBean} {@link #dataSource()} will be overriden by the framework
 * at runtime to return the {@code DataSource} object provided by
 * {@link EmbeddedDataSourceConfig}.
 * <p/>
 * 
 * {@code @PropertiesValueSource} ensures that properties from db/jdbc.properties
 * will be read in and made available for resolution via {@code @ExternalValue} methods
 * and/or fields.
 * 
 * @see PetclinicApplicationConfig
 * @see JpaPetclinicApplicationConfig
 * @see EmbeddedDataSourceConfig
 * @see src/main/webapp/WEB-INF/web.xml
 * @see WEB-INF/web.xml for use in conjunction with {@link ContextLoaderListener}
 *
 * @author Chris Beams
 */
@Configuration
@Import({PetclinicApplicationConfig.class, EmbeddedDataSourceConfig.class})
public abstract class JdbcPetclinicApplicationConfig {

    /** Provided by {@link EmbeddedDataSourceConfig#dataSource()} */
    abstract @ExternalBean DataSource dataSource();

    /**
     * PetClinic's central data access object using Spring's SimpleJdbcTemplate
     * 
     * @see SimpleJdbcClinic#init(DataSource)
     */
    public @Bean Clinic clinic() {
        return new SimpleJdbcClinic();
    }

    /**
     * Transaction manager for a single JDBC DataSource (alternative to JTA)
     */
    public @Bean PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

}
