1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.bedstead.harrier;
18 
19 import org.junit.runners.model.FrameworkMethod;
20 
21 import java.lang.annotation.Annotation;
22 import java.lang.reflect.Method;
23 import java.lang.reflect.Type;
24 import java.util.List;
25 import java.util.Objects;
26 
27 /**
28  * A {@link FrameworkMethod} which forwards calls to a wrapped {@link FrameworkMethod} except
29  * that it injects a parameter and adds the parameter to the name.
30  */
31 public final class FrameworkMethodWithParameter extends FrameworkMethod {
32     private final FrameworkMethod mWrappedFrameworkMethod;
33     private final Object mInjectedParam;
34 
FrameworkMethodWithParameter(FrameworkMethod frameworkMethod, Object injectedParam)35     public FrameworkMethodWithParameter(FrameworkMethod frameworkMethod, Object injectedParam) {
36         super(frameworkMethod.getMethod());
37         mWrappedFrameworkMethod = frameworkMethod;
38         mInjectedParam = injectedParam;
39     }
40 
41     @Override
isStatic()42     public boolean isStatic() {
43         if (mWrappedFrameworkMethod == null) {
44             return super.isStatic();
45         }
46         return mWrappedFrameworkMethod.isStatic();
47     }
48 
49     @Override
isPublic()50     public boolean isPublic() {
51         if (mWrappedFrameworkMethod == null) {
52             return super.isPublic();
53         }
54         return mWrappedFrameworkMethod.isPublic();
55     }
56 
57     @Override
getMethod()58     public Method getMethod() {
59         return mWrappedFrameworkMethod.getMethod();
60     }
61 
62     @Override
invokeExplosively(Object target, Object... params)63     public Object invokeExplosively(Object target, Object... params) throws Throwable {
64         Object[] allParams = params;
65         if (mInjectedParam != null) {
66             allParams = new Object[1 + params.length];
67             allParams[0] = mInjectedParam;
68             System.arraycopy(params, 0, allParams, 1, params.length);
69         }
70 
71         return mWrappedFrameworkMethod.invokeExplosively(target, allParams);
72     }
73 
74     @Override
getName()75     public String getName() {
76         if (mInjectedParam != null) {
77             return mWrappedFrameworkMethod.getName() + "[" + mInjectedParam + "]";
78         }
79         return mWrappedFrameworkMethod.getName();
80     }
81 
82     @Override
validatePublicVoidNoArg(boolean isStatic, List<Throwable> errors)83     public void validatePublicVoidNoArg(boolean isStatic, List<Throwable> errors) {
84         mWrappedFrameworkMethod.validatePublicVoidNoArg(isStatic, errors);
85     }
86 
87     @Override
validatePublicVoid(boolean isStatic, List<Throwable> errors)88     public void validatePublicVoid(boolean isStatic, List<Throwable> errors) {
89         mWrappedFrameworkMethod.validatePublicVoid(isStatic, errors);
90     }
91 
92     @Override
getReturnType()93     public Class<?> getReturnType() {
94         return mWrappedFrameworkMethod.getReturnType();
95     }
96 
97     @Override
getType()98     public Class<?> getType() {
99         return mWrappedFrameworkMethod.getType();
100     }
101 
102     @Override
getDeclaringClass()103     public Class<?> getDeclaringClass() {
104         return mWrappedFrameworkMethod.getDeclaringClass();
105     }
106 
107     @Override
validateNoTypeParametersOnArgs(List<Throwable> errors)108     public void validateNoTypeParametersOnArgs(List<Throwable> errors) {
109         mWrappedFrameworkMethod.validateNoTypeParametersOnArgs(errors);
110     }
111 
112     @Override
isShadowedBy(FrameworkMethod other)113     public boolean isShadowedBy(FrameworkMethod other) {
114         return mWrappedFrameworkMethod.isShadowedBy(other);
115     }
116 
117     @Override
equals(Object obj)118     public boolean equals(Object obj) {
119         if (obj == this) {
120             return true;
121         }
122 
123         if (obj instanceof FrameworkMethodWithParameter) {
124             FrameworkMethodWithParameter other = (FrameworkMethodWithParameter) obj;
125             return Objects.equals(mWrappedFrameworkMethod, other.mWrappedFrameworkMethod)
126                     && Objects.equals(mInjectedParam, other.mInjectedParam);
127         }
128 
129         return false;
130     }
131 
132     @Override
hashCode()133     public int hashCode() {
134         return Objects.hash(mWrappedFrameworkMethod, mInjectedParam);
135     }
136 
137     @Override
producesType(Type type)138     public boolean producesType(Type type) {
139         return mWrappedFrameworkMethod.producesType(type);
140     }
141 
142     @Override
getAnnotations()143     public Annotation[] getAnnotations() {
144         return mWrappedFrameworkMethod.getAnnotations();
145     }
146 
147     @Override
getAnnotation(Class<T> annotationType)148     public <T extends Annotation> T getAnnotation(Class<T> annotationType) {
149         return mWrappedFrameworkMethod.getAnnotation(annotationType);
150     }
151 }
152