001    // Copyright 2008, 2009, 2010 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.structure;
016    
017    import java.util.Map;
018    
019    import org.apache.tapestry5.internal.services.ComponentClassCache;
020    import org.apache.tapestry5.internal.services.LinkSource;
021    import org.apache.tapestry5.internal.services.RequestPageCache;
022    import org.apache.tapestry5.ioc.LoggerSource;
023    import org.apache.tapestry5.ioc.OperationTracker;
024    import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
025    import org.apache.tapestry5.ioc.services.PerthreadManager;
026    import org.apache.tapestry5.ioc.services.TypeCoercer;
027    import org.apache.tapestry5.services.ComponentClassResolver;
028    import org.apache.tapestry5.services.ContextValueEncoder;
029    import org.apache.tapestry5.services.messages.ComponentMessagesSource;
030    import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
031    
032    public class ComponentPageElementResourcesSourceImpl implements ComponentPageElementResourcesSource
033    {
034        private final Map<ComponentResourceSelector, ComponentPageElementResources> cache = CollectionFactory
035                .newConcurrentMap();
036    
037        private final ComponentMessagesSource componentMessagesSource;
038    
039        private final TypeCoercer typeCoercer;
040    
041        private final ComponentClassCache componentClassCache;
042    
043        private final ContextValueEncoder contextValueEncoder;
044    
045        private final LinkSource linkSource;
046    
047        private final RequestPageCache requestPageCache;
048    
049        private final ComponentClassResolver componentClassResolver;
050    
051        private final LoggerSource loggerSource;
052    
053        private final OperationTracker tracker;
054    
055        private final PerthreadManager perThreadManager;
056    
057        public ComponentPageElementResourcesSourceImpl(ComponentMessagesSource componentMessagesSource,
058                TypeCoercer typeCoercer, ComponentClassCache componentClassCache, ContextValueEncoder contextValueEncoder,
059                LinkSource linkSource, RequestPageCache requestPageCache, ComponentClassResolver componentClassResolver,
060                LoggerSource loggerSource, OperationTracker tracker, PerthreadManager perThreadManager)
061        {
062            this.componentMessagesSource = componentMessagesSource;
063            this.typeCoercer = typeCoercer;
064            this.componentClassCache = componentClassCache;
065            this.contextValueEncoder = contextValueEncoder;
066            this.linkSource = linkSource;
067            this.requestPageCache = requestPageCache;
068            this.componentClassResolver = componentClassResolver;
069            this.loggerSource = loggerSource;
070            this.tracker = tracker;
071            this.perThreadManager = perThreadManager;
072        }
073    
074        public ComponentPageElementResources get(ComponentResourceSelector selector)
075        {
076            assert selector != null;
077    
078            ComponentPageElementResources result = cache.get(selector);
079    
080            if (result == null)
081            {
082                result = new ComponentPageElementResourcesImpl(selector, componentMessagesSource, typeCoercer,
083                        componentClassCache, contextValueEncoder, linkSource, requestPageCache, componentClassResolver,
084                        loggerSource, tracker, perThreadManager);
085    
086                // Small race condition here, where we may create two instances of the CPER for the same locale,
087                // but that's not worth worrying about.
088    
089                cache.put(selector, result);
090            }
091    
092            return result;
093        }
094    }