001/*
002 * Copyright 2002-2015 the original author or authors.
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 *      https://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 */
016
017package org.springframework.test.context.support;
018
019import java.util.LinkedHashSet;
020import java.util.Set;
021
022import org.apache.commons.logging.Log;
023import org.apache.commons.logging.LogFactory;
024
025import org.springframework.test.context.ActiveProfiles;
026import org.springframework.test.context.ActiveProfilesResolver;
027import org.springframework.test.util.MetaAnnotationUtils.AnnotationDescriptor;
028import org.springframework.util.Assert;
029import org.springframework.util.StringUtils;
030
031import static org.springframework.test.util.MetaAnnotationUtils.*;
032
033/**
034 * Default implementation of the {@link ActiveProfilesResolver} strategy that
035 * resolves <em>active bean definition profiles</em> based solely on profiles
036 * configured declaratively via {@link ActiveProfiles#profiles} or
037 * {@link ActiveProfiles#value}.
038 *
039 * @author Sam Brannen
040 * @since 4.1
041 * @see ActiveProfiles
042 * @see ActiveProfilesResolver
043 */
044public class DefaultActiveProfilesResolver implements ActiveProfilesResolver {
045
046        private static final Log logger = LogFactory.getLog(DefaultActiveProfilesResolver.class);
047
048
049        /**
050         * Resolve the <em>bean definition profiles</em> for the given {@linkplain
051         * Class test class} based on profiles configured declaratively via
052         * {@link ActiveProfiles#profiles} or {@link ActiveProfiles#value}.
053         * @param testClass the test class for which the profiles should be resolved;
054         * never {@code null}
055         * @return the list of bean definition profiles to use when loading the
056         * {@code ApplicationContext}; never {@code null}
057         */
058        @Override
059        public String[] resolve(Class<?> testClass) {
060                Assert.notNull(testClass, "Class must not be null");
061
062                final Set<String> activeProfiles = new LinkedHashSet<String>();
063
064                Class<ActiveProfiles> annotationType = ActiveProfiles.class;
065                AnnotationDescriptor<ActiveProfiles> descriptor = findAnnotationDescriptor(testClass, annotationType);
066
067                if (descriptor == null) {
068                        if (logger.isDebugEnabled()) {
069                                logger.debug(String.format(
070                                        "Could not find an 'annotation declaring class' for annotation type [%s] and class [%s]",
071                                        annotationType.getName(), testClass.getName()));
072                        }
073                }
074                else {
075                        Class<?> declaringClass = descriptor.getDeclaringClass();
076                        ActiveProfiles annotation = descriptor.synthesizeAnnotation();
077
078                        if (logger.isTraceEnabled()) {
079                                logger.trace(String.format("Retrieved @ActiveProfiles [%s] for declaring class [%s].", annotation,
080                                        declaringClass.getName()));
081                        }
082
083                        for (String profile : annotation.profiles()) {
084                                if (StringUtils.hasText(profile)) {
085                                        activeProfiles.add(profile.trim());
086                                }
087                        }
088                }
089
090                return StringUtils.toStringArray(activeProfiles);
091        }
092
093}