001 package org.apache.commons.ognl.internal.entry; 002 003 /* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022 /* 023 * $Id: GenericMethodParameterTypeFactory.java 1194956 2011-10-29 18:02:14Z mcucchiara $ 024 */ 025 026 import org.apache.commons.ognl.internal.CacheException; 027 028 import java.lang.reflect.Array; 029 import java.lang.reflect.GenericArrayType; 030 import java.lang.reflect.ParameterizedType; 031 import java.lang.reflect.Type; 032 import java.lang.reflect.TypeVariable; 033 034 public class GenericMethodParameterTypeFactory 035 implements CacheEntryFactory<GenericMethodParameterTypeCacheEntry, Class<?>[]> 036 { 037 public Class<?>[] create( GenericMethodParameterTypeCacheEntry entry ) 038 throws CacheException 039 { 040 Class<?>[] types; 041 042 ParameterizedType param = (ParameterizedType) entry.type.getGenericSuperclass(); 043 Type[] genTypes = entry.method.getGenericParameterTypes(); 044 TypeVariable<?>[] declaredTypes = entry.method.getDeclaringClass().getTypeParameters(); 045 046 types = new Class[genTypes.length]; 047 048 for ( int i = 0; i < genTypes.length; i++ ) 049 { 050 TypeVariable<?> paramType = null; 051 052 if ( TypeVariable.class.isInstance( genTypes[i] ) ) 053 { 054 paramType = (TypeVariable<?>) genTypes[i]; 055 } 056 else if ( GenericArrayType.class.isInstance( genTypes[i] ) ) 057 { 058 paramType = (TypeVariable<?>) ( (GenericArrayType) genTypes[i] ).getGenericComponentType(); 059 } 060 else if ( ParameterizedType.class.isInstance( genTypes[i] ) ) 061 { 062 types[i] = (Class<?>) ( (ParameterizedType) genTypes[i] ).getRawType(); 063 continue; 064 } 065 else if ( Class.class.isInstance( genTypes[i] ) ) 066 { 067 types[i] = (Class<?>) genTypes[i]; 068 continue; 069 } 070 071 Class<?> resolved = resolveType( param, paramType, declaredTypes ); 072 073 if ( resolved != null ) 074 { 075 if ( GenericArrayType.class.isInstance( genTypes[i] ) ) 076 { 077 resolved = Array.newInstance( resolved, 0 ).getClass(); 078 } 079 080 types[i] = resolved; 081 continue; 082 } 083 types[i] = entry.method.getParameterTypes()[i]; 084 } 085 086 return types; 087 } 088 089 private Class<?> resolveType( ParameterizedType param, TypeVariable<?> var, TypeVariable<?>[] declaredTypes ) 090 { 091 if ( param.getActualTypeArguments().length < 1 ) 092 { 093 return null; 094 } 095 096 for ( int i = 0; i < declaredTypes.length; i++ ) 097 { 098 if ( !TypeVariable.class.isInstance( param.getActualTypeArguments()[i] ) 099 && declaredTypes[i].getName().equals( var.getName() ) ) 100 { 101 return (Class<?>) param.getActualTypeArguments()[i]; 102 } 103 } 104 105 return null; 106 } 107 }