View Javadoc
1   package org.apache.maven.surefire.common.junit4;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.lang.annotation.Annotation;
23  import java.lang.reflect.InvocationTargetException;
24  import java.lang.reflect.Method;
25  
26  import org.apache.maven.surefire.util.SurefireReflectionException;
27  import org.junit.Ignore;
28  import org.junit.runner.Description;
29  import org.junit.runner.Request;
30  
31  import static org.apache.maven.surefire.util.ReflectionUtils.tryGetMethod;
32  import static org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray;
33  
34  /**
35   * JUnit4 reflection helper
36   *
37   */
38  public final class JUnit4Reflector
39  {
40      private static final Class[] PARAMS = { Class.class };
41  
42      private static final Class[] IGNORE_PARAMS = { Ignore.class };
43  
44      private static final Class[] PARAMS_WITH_ANNOTATIONS = { String.class, Annotation[].class };
45  
46      private JUnit4Reflector()
47      {
48          throw new IllegalStateException( "not instantiable constructor" );
49      }
50  
51      public static Ignore getAnnotatedIgnore( Description d )
52      {
53          Method getAnnotation = tryGetMethod( d.getClass(), "getAnnotation", PARAMS );
54          return getAnnotation == null ? null : (Ignore) invokeMethodWithArray( d, getAnnotation, IGNORE_PARAMS );
55      }
56  
57      public static String getAnnotatedIgnoreValue( Description description )
58      {
59          final Ignore ignore = getAnnotatedIgnore( description );
60          return ignore != null ? ignore.value() : null;
61      }
62  
63      public static Request createRequest( Class<?>... classes )
64      {
65          try
66          {
67              return (Request) Request.class.getDeclaredMethod( "classes", Class[].class )// Since of JUnit 4.5
68                  .invoke( null, new Object[]{ classes } );
69          }
70          catch ( NoSuchMethodException e )
71          {
72              return Request.classes( null, classes ); // Since of JUnit 4.0
73          }
74          catch ( InvocationTargetException e )
75          {
76              throw new SurefireReflectionException( e.getCause() );
77          }
78          catch ( IllegalAccessException e )
79          {
80              // probably JUnit 5.x
81              throw new SurefireReflectionException( e );
82          }
83      }
84  
85      public static Description createDescription( String description )
86      {
87          try
88          {
89              return Description.createSuiteDescription( description );
90          }
91          catch ( NoSuchMethodError e )
92          {
93              Method method = tryGetMethod( Description.class, "createSuiteDescription", PARAMS_WITH_ANNOTATIONS );
94              // may throw exception probably with JUnit 5.x
95              return (Description) invokeMethodWithArray( null, method, description, new Annotation[0] );
96          }
97      }
98  
99      public static Description createDescription( String description, Annotation... annotations )
100     {
101         Method method = tryGetMethod( Description.class, "createSuiteDescription", PARAMS_WITH_ANNOTATIONS );
102         return method == null
103             ? Description.createSuiteDescription( description )
104             : (Description) invokeMethodWithArray( null, method, description, annotations );
105     }
106 
107     public static Ignore createIgnored( String value )
108     {
109         return new IgnoredWithUserError( value );
110     }
111 
112     private static class IgnoredWithUserError
113         implements Annotation, Ignore
114     {
115         private final String value;
116 
117         public IgnoredWithUserError( String value )
118         {
119             this.value = value;
120         }
121 
122         public IgnoredWithUserError()
123         {
124             this( "" );
125         }
126 
127         public String value()
128         {
129             return value;
130         }
131 
132         public Class<? extends Annotation> annotationType()
133         {
134             return Ignore.class;
135         }
136 
137         @Override
138         public int hashCode()
139         {
140             return value == null ? 0 : value.hashCode();
141         }
142 
143         @Override
144         public boolean equals( Object obj )
145         {
146             return obj instanceof Annotation && obj instanceof Ignore && equalValue( ( Ignore ) obj );
147         }
148 
149         @Override
150         public String toString()
151         {
152             return String.format( "%s(%s)", Ignore.class, value );
153         }
154 
155         private boolean equalValue( Ignore ignore )
156         {
157             if ( ignore == null )
158             {
159                 return false;
160             }
161             else
162             {
163                 String val = ignore.value();
164                 return val == null ? value == null : val.equals( value );
165             }
166         }
167     }
168 }