    001// Copyright 2007, 2008, 2012 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.renderers;
    016
    017import org.apache.tapestry5.MarkupWriter;
    018import org.apache.tapestry5.SymbolConstants;
    019import org.apache.tapestry5.commons.util.CollectionFactory;
    020import org.apache.tapestry5.http.TapestryHttpSymbolConstants;
    021import org.apache.tapestry5.http.services.Context;
    022import org.apache.tapestry5.http.services.Request;
    023import org.apache.tapestry5.internal.services.PageSource;
    024import org.apache.tapestry5.internal.structure.Page;
    025import org.apache.tapestry5.ioc.annotations.Primary;
    026import org.apache.tapestry5.ioc.annotations.Symbol;
    027import org.apache.tapestry5.ioc.internal.util.InternalUtils;
    028import org.apache.tapestry5.services.ComponentClassResolver;
    029import org.apache.tapestry5.services.ObjectRenderer;
    030import org.apache.tapestry5.services.pageload.PageClassLoaderContext;
    031import org.apache.tapestry5.services.pageload.PageClassLoaderContextManager;
    032
    033import java.util.ArrayList;
    034import java.util.Collections;
    035import java.util.Comparator;
    036import java.util.List;
    037import java.util.stream.Collectors;
    038
    039public class RequestRenderer implements ObjectRenderer<Request>
    040{
    041    private final Context context;
    042
    043    private final String contextPath;
    044
    045    private final ObjectRenderer masterObjectRenderer;
    046
    047    private final boolean productionMode;
    048
    049    private final PageClassLoaderContextManager pageClassLoaderContextManager;
    050
    051    private final PageSource pageSource;
    052
    053    private final ComponentClassResolver componentClassResolver;
    054
    055    public RequestRenderer(
    056            @Primary ObjectRenderer masterObjectRenderer,
    057            Context context,
    058            @Symbol(TapestryHttpSymbolConstants.CONTEXT_PATH) String contextPath,
    059            @Symbol(SymbolConstants.PRODUCTION_MODE) boolean productionMode,
    060            PageClassLoaderContextManager pageClassLoaderContextManager,
    061            PageSource pageSource,
    062            ComponentClassResolver componentClassResolver)
    063    {
    064        this.masterObjectRenderer = masterObjectRenderer;
    065        this.context = context;
    066        this.contextPath = contextPath;
    067        this.productionMode = productionMode;
    068        this.pageClassLoaderContextManager = pageClassLoaderContextManager;
    069        this.pageSource = pageSource;
    070        this.componentClassResolver = componentClassResolver;
    071    }
    072
    073    public void render(Request request, MarkupWriter writer)
    074    {
    075        coreProperties(request, writer);
    076        parameters(request, writer);
    077        headers(request, writer);
    078        attributes(request, writer);
    079        context(writer);
    080
    081//        pageClassloaderContext(writer);
    082//        pages(writer);
    083    }
    084
    085    private void coreProperties(Request request, MarkupWriter writer)
    086    {
    087        writer.element("dl", "class", "dl-horizontal");
    088
    089        dt(writer, "Context Path");
    090
    091        writer.element("dd");
    092
    093        if (contextPath.equals(""))
    094        {
    095            writer.element("em");
    096            writer.write("none (deployed as root)");
    097            writer.end();
    098        } else
    099        {
    100            writer.write(contextPath);
    101        }
    102
    103        writer.end(); // dd
    104
    105        dt(writer, "Path", request.getPath());
    106
    107        dt(writer, "Locale", request.getLocale().toString());
    108
    109        dt(writer, "Server Name", request.getServerName());
    110
    111
    112        List<String> flags = CollectionFactory.newList();
    113        if (request.isSecure())
    114        {
    115            flags.add("secure");
    116        }
    117
    118        if (request.isXHR())
    119        {
    120            flags.add("XHR");
    121        }
    122
    123        if (request.isRequestedSessionIdValid())
    124        {
    125            flags.add("requested session id valid");
    126        }
    127
    128        if (request.isSessionInvalidated())
    129        {
    130            flags.add("session invalidated");
    131        }
    132
    133        if (!flags.isEmpty())
    134        {
    135            dt(writer, "Flags", InternalUtils.join(flags));
    136        }
    137
    138        dt(writer, "Ports (local/server)",
    139                String.format("%d / %d", request.getLocalPort(), request.getServerPort()));
    140
    141        dt(writer, "Method", request.getMethod());
    142
    143        writer.end();
    144    }
    145
    146    private void context(MarkupWriter writer)
    147    {
    148        List<String> attributeNames = context.getAttributeNames();
    149
    150        if (attributeNames.isEmpty()) return;
    151
    152        section(writer, "Context Attributes");
    153
    154        writer.element("dl");
    155
    156        for (String name : attributeNames)
    157        {
    158            dt(writer, name);
    159
    160            writer.element("dd");
    161
    162            masterObjectRenderer.render(context.getAttribute(name), writer);
    163
    164            writer.end(); // dd
    165        }
    166
    167        writer.end(); // dl
    168    }
    169
    170    private void parameters(Request request, MarkupWriter writer)
    171    {
    172        List<String> parameterNames = request.getParameterNames();
    173
    174        if (parameterNames.isEmpty())
    175            return;
    176
    177        section(writer, "Query Parameters");
    178
    179        writer.element("dl");
    180
    181        for (String name : parameterNames)
    182        {
    183            String[] values = request.getParameters(name);
    184
    185            dt(writer, name);
    186
    187            writer.element("dd");
    188
    189            if (values.length > 1)
    190            {
    191                writer.element("ul");
    192
    193                for (String value : values)
    194                {
    195                    writer.element("li");
    196                    writer.write(value);
    197                    writer.end();
    198                }
    199
    200                writer.end(); // ul
    201            } else
    202            {
    203                writer.write(values[0]);
    204            }
    205
    206            writer.end(); // dd
    207        }
    208
    209        writer.end(); // dl
    210    }
    211
    212    private void dt(MarkupWriter writer, String name, String value)
    213    {
    214        if (value != null)
    215        {
    216            dt(writer, name);
    217            dd(writer, value);
    218        }
    219    }
    220
    221    private void dt(MarkupWriter writer, String name)
    222    {
    223        writer.element("dt");
    224        writer.write(name);
    225        writer.end();
    226    }
    227
    228    private void dd(MarkupWriter writer, String name)
    229    {
    230        writer.element("dd");
    231        writer.write(name);
    232        writer.end();
    233    }
    234
    235    private void section(MarkupWriter writer, String name)
    236    {
    237        writer.element("h3");
    238        writer.write(name);
    239        writer.end();
    240    }
    241
    242    private void headers(Request request, MarkupWriter writer)
    243    {
    244        section(writer, "Headers");
    245
    246        writer.element("dl", "class", "dl-horizontal");
    247
    248        for (String name : request.getHeaderNames())
    249        {
    250            dt(writer, name, request.getHeader(name));
    251        }
    252
    253        writer.end(); // dl
    254
    255    }
    256
    257    private void attributes(Request request, MarkupWriter writer)
    258    {
    259        List<String> attributeNames = request.getAttributeNames();
    260
    261        if (attributeNames.isEmpty())
    262        {
    263            return;
    264        }
    265
    266        section(writer, "Attributes");
    267
    268        writer.element("dl");
    269
    270        for (String name : attributeNames)
    271        {
    272            dt(writer, name, String.valueOf(request.getAttribute(name)));
    273        }
    274
    275        writer.end(); // dl
    276    }
    277
    278//    private void pageClassloaderContext(MarkupWriter writer)
    279//    {
    280//        if (!productionMode)
    281//        {
    282//            section(writer, "Page Classloader Context");
    283//            writer.element("ul");
    284//            render(pageClassLoaderContextManager.getRoot(), writer);
    285//            writer.end(); // ul
    286//        }
    287//    }
    288//
    289//    private void render(PageClassloaderContext context, MarkupWriter writer)
    290//    {
    291//        if (context != null)
    292//        {
    293//
    294//            writer.element("li");
    295//
    296//            writer.element("p");
    297//            writer.element("em");
    298//            writer.write(context.getName());
    299//            writer.write(", ");
    300//            writer.write(context.getClassLoader().toString());
    301//            writer.end(); // em
    302//            writer.end(); // p
    303//
    304//            writer.element("p");
    305//            writer.write(context.getClassNames().stream().collect(Collectors.joining(", ")));
    306//            writer.end(); // p
    307//
    308//            if (!context.getChildren().isEmpty())
    309//            {
    310//                writer.element("ul");
    311//                for (PageClassloaderContext child : context.getChildren())
    312//                {
    313//                    render(child, writer);
    314//                }
    315//                writer.end(); // ul
    316//            }
    317//            writer.end(); // li
    318//
    319//        }
    320//
    321//    }
    322//
    323//    private void pages(MarkupWriter writer)
    324//    {
    325//        if (!productionMode)
    326//        {
    327//            section(writer, "Pages");
    328//            writer.element("table", "class", "table table-condensed table-hover table-striped exception-report-threads");
    329//            writer.element("thead");
    330//
    331//            writer.element("td");
    332//            writer.write("Name");
    333//            writer.end(); //td Name
    334//
    335//            writer.element("td");
    336//            writer.write("Context");
    337//            writer.end(); //td Context
    338//
    339//            writer.end(); // thead
    340//
    341//            writer.element("tbody");
    342//
    343//            List<Page> pages = new ArrayList<>(pageSource.getAllPages());
    344//            Collections.sort(pages, Comparator.comparing(Page::getName));
    345//
    346//            for (Page page : pages) {
    347//                writer.element("tr");
    348//                writer.element("td");
    349//                writer.write(page.getName());
    350//                writer.end(); // td
    351//                writer.element("td");
    352//                writer.write(pageClassLoaderContextManager.getRoot().findByClassName(componentClassResolver.getClassName(page.getName())).toString());
    353//                writer.end(); // td
    354//                writer.end(); // tr
    355//            }
    356//
    357//            writer.end(); // tbody
    358//
    359//            writer.end(); // table
    360//        }
    361//    }
    362
    363}