001    package org.apache.commons.ognl.internal;
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: ClassCacheHandler.java 1203584 2011-11-18 10:54:19Z mcucchiara $
024     */
025    public class ClassCacheHandler
026    {
027    
028        private ClassCacheHandler()
029        {
030        }
031    
032        public static <T> T getHandler( Class<?> forClass, ClassCache<T> handlers )
033            throws CacheException
034        {
035            T answer;
036    
037            synchronized ( handlers )
038            {
039                answer = handlers.get( forClass );
040                if ( answer == null )
041                {
042                    Class<?> keyFound;
043    
044                    if ( forClass.isArray() )
045                    {
046                        answer = handlers.get( Object[].class );
047                        keyFound = null;
048                    }
049                    else
050                    {
051                        keyFound = forClass;
052                        outer:
053                        for ( Class<?> clazz = forClass; clazz != null; clazz = clazz.getSuperclass() )
054                        {
055                            answer = handlers.get( clazz );
056                            if ( answer == null )
057                            {
058                                Class<?>[] interfaces = clazz.getInterfaces();
059                                for ( Class<?> iface : interfaces )
060                                {
061                                    answer = handlers.get( iface );
062                                    if ( answer == null )
063                                    {
064                                        /* Try super-interfaces */
065                                        answer = getHandler( iface, handlers );
066                                    }
067                                    if ( answer != null )
068                                    {
069                                        keyFound = iface;
070                                        break outer;
071                                    }
072                                }
073                            }
074                            else
075                            {
076                                keyFound = clazz;
077                                break;
078                            }
079                        }
080                    }
081                    if ( answer != null )
082                    {
083                        if ( keyFound != forClass )
084                        {
085                            handlers.put( forClass, answer );
086                        }
087                    }
088                }
089            }
090            return answer;
091    
092        }
093    }