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  }