View Javadoc

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