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