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