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