001/*
002 * Copyright 2011 Atteo.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.atteo.moonshine.tests;
017
018import javax.sql.DataSource;
019
020import org.aopalliance.intercept.MethodInterceptor;
021import org.aopalliance.intercept.MethodInvocation;
022import org.atteo.moonshine.liquibase.LiquibaseFacade;
023
024import com.google.common.base.Strings;
025import com.google.inject.ConfigurationException;
026import com.google.inject.Inject;
027import com.google.inject.Injector;
028import com.google.inject.Key;
029import com.google.inject.name.Names;
030
031public class FixtureInterceptor implements MethodInterceptor {
032    @Inject
033    private Injector injector;
034
035    @Override
036    public Object invoke(final MethodInvocation invocation) throws Throwable {
037        final Fixture annotation = invocation.getMethod().getAnnotation(Fixture.class);
038        String fixtureName = annotation.value();
039        String databaseName = annotation.database();
040
041        DataSource dataSource;
042        try {
043            if (Strings.isNullOrEmpty(databaseName)) {
044                dataSource = injector.getInstance(DataSource.class);
045            } else {
046                dataSource = injector.getInstance(Key.get(DataSource.class, Names.named(databaseName)));
047            }
048        } catch (ConfigurationException e) {
049            throw new RuntimeException("Cannot find database for annotation " + annotation, e);
050        }
051
052        if (!fixtureName.startsWith("/")) {
053            fixtureName = "/" + invocation.getMethod().getDeclaringClass().getPackage().getName()
054                    .replace('.', '/')
055                    + "/" + fixtureName;
056        }
057
058        LiquibaseFacade liquibase = new LiquibaseFacade(dataSource);
059        liquibase.migrate(fixtureName);
060        Object o = null;
061        try {
062            o = invocation.proceed();
063        } finally {
064            liquibase.rollbackLastUpdate(fixtureName);
065        }
066        return o;
067    }
068}