View Javadoc

1   /**
2    * Copyright (c) 2008-2012, http://www.snakeyaml.org
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 org.yaml.snakeyaml.introspector;
17  
18  import java.lang.reflect.Array;
19  import java.lang.reflect.GenericArrayType;
20  import java.lang.reflect.ParameterizedType;
21  import java.lang.reflect.Type;
22  
23  abstract public class GenericProperty extends Property {
24  
25      private Type genType;
26  
27      public GenericProperty(String name, Class<?> aClass, Type aType) {
28          super(name, aClass);
29          genType = aType;
30          actualClassesChecked = aType == null;
31      }
32  
33      private boolean actualClassesChecked;
34      private Class<?>[] actualClasses;
35  
36      public Class<?>[] getActualTypeArguments() { // should we synchronize here ?
37          if (!actualClassesChecked) {
38              if (genType instanceof ParameterizedType) {
39                  ParameterizedType parameterizedType = (ParameterizedType) genType;
40                  Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
41                  if (actualTypeArguments.length > 0) {
42                      actualClasses = new Class<?>[actualTypeArguments.length];
43                      for (int i = 0; i < actualTypeArguments.length; i++) {
44                          if (actualTypeArguments[i] instanceof Class<?>) {
45                              actualClasses[i] = (Class<?>) actualTypeArguments[i];
46                          } else if (actualTypeArguments[i] instanceof ParameterizedType) {
47                              actualClasses[i] = (Class<?>) ((ParameterizedType) actualTypeArguments[i])
48                                      .getRawType();
49                          } else if (actualTypeArguments[i] instanceof GenericArrayType) {
50                              Type componentType = ((GenericArrayType) actualTypeArguments[i])
51                                      .getGenericComponentType();
52                              if (componentType instanceof Class<?>) {
53                                  actualClasses[i] = Array.newInstance((Class<?>) componentType, 0)
54                                          .getClass();
55                              } else {
56                                  actualClasses = null;
57                                  break;
58                              }
59                          } else {
60                              actualClasses = null;
61                              break;
62                          }
63                      }
64                  }
65              } else if (genType instanceof GenericArrayType) {
66                  Type componentType = ((GenericArrayType) genType).getGenericComponentType();
67                  if (componentType instanceof Class<?>) {
68                      actualClasses = new Class<?>[] { (Class<?>) componentType };
69                  }
70              } else if (genType instanceof Class<?>) {// XXX this check is only
71                                                       // required for IcedTea6
72                  Class<?> classType = (Class<?>) genType;
73                  if (classType.isArray()) {
74                      actualClasses = new Class<?>[1];
75                      actualClasses[0] = getType().getComponentType();
76                  }
77              }
78              actualClassesChecked = true;
79          }
80          return actualClasses;
81      }
82  }