Import atomix/{storage,utils}
[controller.git] / third-party / atomix / utils / src / main / java / io / atomix / utils / Generics.java
1 /*
2  * Copyright 2018-present Open Networking Foundation
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 package io.atomix.utils;
17
18 import java.lang.reflect.ParameterizedType;
19 import java.lang.reflect.Type;
20
21 /**
22  * Generics utility.
23  */
24 public class Generics {
25
26   /**
27    * Returns the generic type at the given position for the given class.
28    *
29    * @param instance the implementing instance
30    * @param clazz    the generic class
31    * @param position the generic position
32    * @return the generic type at the given position
33    */
34   public static Type getGenericClassType(Object instance, Class<?> clazz, int position) {
35     Class<?> type = instance.getClass();
36     while (type != Object.class) {
37       if (type.getGenericSuperclass() instanceof ParameterizedType) {
38         ParameterizedType genericSuperclass = (ParameterizedType) type.getGenericSuperclass();
39         if (genericSuperclass.getRawType() == clazz) {
40           return genericSuperclass.getActualTypeArguments()[position];
41         } else {
42           type = type.getSuperclass();
43         }
44       } else {
45         type = type.getSuperclass();
46       }
47     }
48     return null;
49   }
50
51   /**
52    * Returns the generic type at the given position for the given interface.
53    *
54    * @param instance the implementing instance
55    * @param iface    the generic interface
56    * @param position the generic position
57    * @return the generic type at the given position
58    */
59   public static Type getGenericInterfaceType(Object instance, Class<?> iface, int position) {
60     Class<?> type = instance.getClass();
61     while (type != Object.class) {
62       for (Type genericType : type.getGenericInterfaces()) {
63         if (genericType instanceof ParameterizedType) {
64           ParameterizedType parameterizedType = (ParameterizedType) genericType;
65           if (parameterizedType.getRawType() == iface) {
66             return parameterizedType.getActualTypeArguments()[position];
67           }
68         }
69       }
70       type = type.getSuperclass();
71     }
72     return null;
73   }
74
75   private Generics() {
76   }
77 }