    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}