    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.ComponentResources;
    018import org.apache.tapestry5.commons.*;
    019import org.apache.tapestry5.commons.services.TypeCoercer;
    020import org.apache.tapestry5.commons.util.CommonsUtils;
    021import org.apache.tapestry5.http.Link;
    022import org.apache.tapestry5.http.services.Request;
    023import org.apache.tapestry5.http.services.RequestGlobals;
    024import org.apache.tapestry5.internal.services.ComponentClassCache;
    025import org.apache.tapestry5.internal.services.LinkSource;
    026import org.apache.tapestry5.internal.services.RequestPageCache;
    027import org.apache.tapestry5.ioc.IOOperation;
    028import org.apache.tapestry5.ioc.Invokable;
    029import org.apache.tapestry5.ioc.LoggerSource;
    030import org.apache.tapestry5.ioc.OperationTracker;
    031import org.apache.tapestry5.ioc.services.PerThreadValue;
    032import org.apache.tapestry5.ioc.services.PerthreadManager;
    033import org.apache.tapestry5.model.ComponentModel;
    034import org.apache.tapestry5.services.ComponentClassResolver;
    035import org.apache.tapestry5.services.ContextValueEncoder;
    036import org.apache.tapestry5.services.messages.ComponentMessagesSource;
    037import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
    038import org.slf4j.Logger;
    039
    040import java.io.IOException;
    041
    042public class ComponentPageElementResourcesImpl implements ComponentPageElementResources
    043{
    044    private final ComponentResourceSelector selector;
    045
    046    private final ComponentMessagesSource componentMessagesSource;
    047
    048    private final TypeCoercer typeCoercer;
    049
    050    private final ComponentClassCache componentClassCache;
    051
    052    private final ContextValueEncoder contextValueEncoder;
    053
    054    private final LinkSource linkSource;
    055
    056    private final RequestPageCache requestPageCache;
    057
    058    private final ComponentClassResolver componentClassResolver;
    059
    060    private final LoggerSource loggerSource;
    061
    062    private final OperationTracker tracker;
    063
    064    private final PerthreadManager perThreadManager;
    065
    066    private final boolean productionMode, componentTracingEnabled;
    067
    068    private final RequestGlobals requestGlobals;
    069
    070    public ComponentPageElementResourcesImpl(ComponentResourceSelector selector,
    071                                             ComponentMessagesSource componentMessagesSource, TypeCoercer typeCoercer,
    072                                             ComponentClassCache componentClassCache, ContextValueEncoder contextValueEncoder, LinkSource linkSource,
    073                                             RequestPageCache requestPageCache, ComponentClassResolver componentClassResolver,
    074                                             LoggerSource loggerSource, OperationTracker tracker, PerthreadManager perThreadManager, boolean productionMode, boolean componentTracingEnabled, RequestGlobals requestGlobals)
    075    {
    076        this.selector = selector;
    077        this.componentMessagesSource = componentMessagesSource;
    078        this.typeCoercer = typeCoercer;
    079        this.componentClassCache = componentClassCache;
    080        this.contextValueEncoder = contextValueEncoder;
    081        this.linkSource = linkSource;
    082        this.requestPageCache = requestPageCache;
    083        this.componentClassResolver = componentClassResolver;
    084        this.loggerSource = loggerSource;
    085        this.tracker = tracker;
    086        this.perThreadManager = perThreadManager;
    087        this.productionMode = productionMode;
    088        this.componentTracingEnabled = componentTracingEnabled;
    089        this.requestGlobals = requestGlobals;
    090    }
    091
    092    public ComponentResourceSelector getSelector()
    093    {
    094        return selector;
    095    }
    096
    097    public Messages getMessages(ComponentModel componentModel)
    098    {
    099        return componentMessagesSource.getMessages(componentModel, selector);
    100    }
    101
    102    public <S, T> T coerce(S input, Class<T> targetType)
    103    {
    104        return typeCoercer.coerce(input, targetType);
    105    }
    106
    107    public Class toClass(String className)
    108    {
    109        return componentClassCache.forName(className);
    110    }
    111
    112    public Link createComponentEventLink(ComponentResources resources, String eventType, boolean forForm,
    113                                         Object... context)
    114    {
    115        Page page = requestPageCache.get(resources.getPageName());
    116
    117        return linkSource.createComponentEventLink(page, resources.getNestedId(), eventType, forForm,
    118                defaulted(context));
    119    }
    120
    121    public Link createPageRenderLink(String pageName, boolean override, Object... context)
    122    {
    123        return linkSource.createPageRenderLink(pageName, override, defaulted(context));
    124    }
    125
    126    public Link createPageRenderLink(Class pageClass, boolean override, Object... context)
    127    {
    128        assert pageClass != null;
    129        String pageName = componentClassResolver.resolvePageClassNameToPageName(pageClass.getName());
    130
    131        return linkSource.createPageRenderLink(pageName, override, defaulted(context));
    132    }
    133
    134    public Logger getEventLogger(Logger componentLogger)
    135    {
    136        String name = "tapestry.events." + componentLogger.getName();
    137
    138        return loggerSource.getLogger(name);
    139    }
    140
    141    public String toClient(Object value)
    142    {
    143        return contextValueEncoder.toClient(value);
    144    }
    145
    146    public <T> T toValue(Class<T> requiredType, String clientValue)
    147    {
    148        return contextValueEncoder.toValue(requiredType, clientValue);
    149    }
    150
    151    private Object[] defaulted(Object[] context)
    152    {
    153        return context == null ? CommonsUtils.EMPTY_STRING_ARRAY : context;
    154    }
    155
    156    public <T> T invoke(String description, Invokable<T> operation)
    157    {
    158        return tracker.invoke(description, operation);
    159    }
    160
    161    public <T> T perform(String description, IOOperation<T> operation) throws IOException
    162    {
    163        return tracker.perform(description, operation);
    164    }
    165
    166    public void run(String description, Runnable operation)
    167    {
    168        tracker.run(description, operation);
    169    }
    170
    171    public <T> PerThreadValue<T> createPerThreadValue()
    172    {
    173        return perThreadManager.createValue();
    174    }
    175
    176    public boolean isRenderTracingEnabled()
    177    {
    178        if (productionMode)
    179        {
    180            return false;
    181        }
    182
    183        if (componentTracingEnabled)
    184        {
    185            return true;
    186        }
    187
    188        Request request = requestGlobals.getRequest();
    189
    190        if (request == null)
    191        {
    192            return false;
    193        }
    194
    195        return "true".equals(request.getParameter("t:component-trace"));
    196    }
    197
    198}