    001    // Copyright 2008, 2010, 2011 The Apache Software Foundation
    002    //
    003    // Licensed under the Apache License, Version 2.0 (the "License");
    004    // you may not use this file except in compliance with the License.
    005    // You may obtain a copy of the License at
    006    //
    007    // http://www.apache.org/licenses/LICENSE-2.0
    008    //
    009    // Unless required by applicable law or agreed to in writing, software
    010    // distributed under the License is distributed on an "AS IS" BASIS,
    011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    012    // See the License for the specific language governing permissions and
    013    // limitations under the License.
    014
    015    package org.apache.tapestry5.internal.services;
    016
    017    import org.apache.tapestry5.internal.plastic.PlasticInternalUtils;
    018    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
    019    import org.apache.tapestry5.ioc.services.PlasticProxyFactory;
    020    import org.apache.tapestry5.ioc.services.TypeCoercer;
    021    import org.apache.tapestry5.services.ComponentLayer;
    022    import org.apache.tapestry5.services.InvalidationListener;
    023
    024    import java.util.Map;
    025
    026    public class ComponentClassCacheImpl implements ComponentClassCache, InvalidationListener
    027    {
    028        private final Map<String, Class> cache = CollectionFactory.newConcurrentMap();
    029
    030        private final PlasticProxyFactory plasticFactory;
    031
    032        private final TypeCoercer typeCoercer;
    033
    034        public ComponentClassCacheImpl(@ComponentLayer
    035        PlasticProxyFactory plasticFactory, TypeCoercer typeCoercer)
    036        {
    037            this.plasticFactory = plasticFactory;
    038            this.typeCoercer = typeCoercer;
    039        }
    040
    041        public void objectWasInvalidated()
    042        {
    043            cache.clear();
    044        }
    045
    046        @SuppressWarnings("unchecked")
    047        public Object defaultValueForType(String className)
    048        {
    049            Class clazz = forName(className);
    050
    051            if (!clazz.isPrimitive())
    052                return null;
    053
    054            // Remembering that 0 coerces to boolean false, this covers all the primitive
    055            // types (boolean, int, short, etc.)
    056            return typeCoercer.coerce(0, clazz);
    057        }
    058
    059        public Class forName(String className)
    060        {
    061            Class result = cache.get(className);
    062
    063            if (result == null)
    064            {
    065                result = lookupClassForType(className);
    066
    067                cache.put(className, result);
    068            }
    069
    070            return result;
    071        }
    072
    073        private Class lookupClassForType(String className)
    074        {
    075            ClassLoader componentLoader = plasticFactory.getClassLoader();
    076            try
    077            {
    078                return PlasticInternalUtils.toClass(componentLoader, className);
    079            }
    080            catch (ClassNotFoundException ex)
    081            {
    082                throw new RuntimeException(ex);
    083            }
    084        }
    085    }