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}