001    /*
002     * $Id: DescriptionUtils.java,v 1.1 2012/04/20 18:57:54 oboehm Exp $
003     *
004     * Copyright (c) 2012 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     * 
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     * 
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     * 
018     * (c)reated 19.04.2012 by oliver (ob@oasd.de)
019     */
020    
021    package patterntesting.runtime.junit.internal;
022    
023    import java.lang.annotation.Annotation;
024    import java.util.regex.*;
025    
026    import org.junit.runner.Description;
027    import org.slf4j.*;
028    
029    import patterntesting.annotation.check.runtime.MayReturnNull;
030    
031    /**
032     * This class provides some utiltis for the Description class for older
033     * versions of JUnit 4. In newer versions we have some more methods to use
034     * but because we want to support also JUnit 4.4 we provide the missing
035     * methods here.
036     * 
037     * @author oliver
038     * @since 1.2.20 (19.04.2012)
039     */
040    public class DescriptionUtils {
041        
042        private static final Logger log = LoggerFactory.getLogger(DescriptionUtils.class);
043        private static final Pattern METHOD_NAME_PATTTERN = Pattern.compile("(.*)\\((.*)\\)");
044        
045        /** Utility class - no need to instantiate it. */
046        private DescriptionUtils() {}
047        
048        /**
049         * Here we extract the test class from the given descripiton.
050         * In JUnit 4.4 we don't have the Description does not have a method
051         * getTestClass(). We cannot provide our own "Description44" subclass of
052         * it because it is not designed for subclassing (no public constructor).
053         * Se we (re)implement the missing features for the SmokeFilter here.
054         *
055         * @param description the description
056         * @return the test class from
057         * @since 1.2.20
058         */
059        @MayReturnNull
060        public static Class<?> getTestClassOf(final Description description) {
061            String name = description.toString();
062            Matcher matcher = Pattern.compile("(.*)\\((.*)\\)").matcher(name);
063            if (matcher.matches()) {
064                name = matcher.group(2);
065            }
066            if (name == null)
067                return null;
068            try {
069                return Class.forName(name);
070            } catch (ClassNotFoundException e) {
071                log.debug("Cannot get test class from description \"{}\"", description);
072                return null;
073            }
074        }
075        
076        /**
077         * Gets the method name the given description. This method is needed for
078         * JUnit 4.5 and older. In JUnit 4.6 and newer there is a getMethodName()
079         * available in the {@link Description} class.
080         *
081         * @param description the description
082         * @return the method name of
083         */
084        @MayReturnNull
085        public static String getMethodNameOf(final Description description) {
086            Matcher matcher = METHOD_NAME_PATTTERN.matcher(description.getDisplayName());
087            if (matcher.matches()) {
088                return matcher.group(1);
089            }
090            return null;
091        }
092    
093        /**
094         * Creates the test description.
095         *
096         * @param description the description
097         * @param annotations the annotations
098         * @return the description
099         */
100        public static Description createTestDescription(final Description description,
101                final Annotation[] annotations) {
102            return Description.createTestDescription(getTestClassOf(description),
103                    description.getDisplayName(), annotations);
104        }
105    
106    }
107