<commit_before>/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.jsp;

import org.opencms.ade.configuration.CmsADEConfigData;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.collectors.I_CmsCollectorPostCreateHandler;
import org.opencms.flex.CmsFlexController;
import org.opencms.jsp.util.CmsJspContentAccessValueWrapper;
import org.opencms.jsp.util.CmsJspStandardContextBean;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsRequestUtil;
import org.opencms.util.CmsUUID;
import org.opencms.workplace.editors.directedit.CmsAdvancedDirectEditProvider;
import org.opencms.workplace.editors.directedit.CmsDirectEditMode;
import org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider;
import org.opencms.xml.containerpage.CmsContainerElementBean;
import org.opencms.xml.containerpage.CmsFormatterConfiguration;
import org.opencms.xml.containerpage.I_CmsFormatterBean;
import org.opencms.xml.types.CmsXmlDisplayFormatterValue;
import org.opencms.xml.types.I_CmsXmlContentValue;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.logging.Log;

/**
 * The 'display' tag can be used to display a single resource using a formatter. It also allows to activate direct editing.<p>
 */
public class CmsJspTagDisplay extends BodyTagSupport implements I_CmsJspTagParamParent {

    /** The log object for this class. */
    private static final Log LOG = CmsLog.getLog(CmsJspTagDisplay.class);

    /** The serial version id. */
    private static final long serialVersionUID = 2285680951218629093L;

    /** Flag, indicating if the create option should be displayed. */
    private boolean m_canCreate;

    /** Flag, indicating if the delete option should be displayed. */
    private boolean m_canDelete;

    /** The tag attribute's value, specifying the path to the (sub)sitemap where new content should be created. */
    private String m_creationSiteMap;

    /** The display formatter ids. */
    private Map<String, CmsUUID> m_displayFormatterIds;

    /** The display formatter paths. */
    private Map<String, String> m_displayFormatterPaths;

    /** The editable flag. */
    private boolean m_editable;

    /** The settings parameter map. */
    private Map<String, String> m_parameterMap;

    /** The pass settings flag. */
    private boolean m_passSettings;

    /** The fully qualified class name of the post create handler to use. */
    private String m_postCreateHandler;

    /** The site path to the resource to display. */
    private String m_value;

    /**
     * Constructor.<p>
     */
    public CmsJspTagDisplay() {
        m_parameterMap = new HashMap<String, String>();
        m_displayFormatterPaths = new HashMap<String, String>();
        m_displayFormatterIds = new HashMap<String, CmsUUID>();
    }

    /**
     * Includes the formatter rendering the given element.<p>
     *
     * @param element the element
     * @param formatter the formatter configuration bean
     * @param editable if editable
     * @param canCreate if new resources may be created
     * @param canDelete if the resource may be deleted
     * @param creationSiteMap the create location sub site
     * @param postCreateHandler the post create handler
     * @param context the page context
     * @param request the request
     * @param response the response
     */
    public static void displayAction(
        CmsContainerElementBean element,
        I_CmsFormatterBean formatter,
        boolean editable,
        boolean canCreate,
        boolean canDelete,
        String creationSiteMap,
        String postCreateHandler,
        PageContext context,
        ServletRequest request,
        ServletResponse response) {

        if (CmsFlexController.isCmsRequest(request)) {
            // this will always be true if the page is called through OpenCms
            CmsObject cms = CmsFlexController.getCmsObject(request);
            Locale locale = cms.getRequestContext().getLocale();
            boolean isOnline = cms.getRequestContext().getCurrentProject().isOnlineProject();
            CmsJspStandardContextBean contextBean = CmsJspStandardContextBean.getInstance(request);
            CmsContainerElementBean parentElement = contextBean.getElement();

            try {
                if (formatter != null) {
                    element.initResource(cms);
                    element.initSettings(cms, formatter);
                    boolean openedEditable = false;
                    if (editable && contextBean.getIsEditMode()) {
                        if (CmsJspTagEditable.getDirectEditProvider(context) == null) {
                            I_CmsDirectEditProvider eb = new CmsAdvancedDirectEditProvider();
                            eb.init(cms, CmsDirectEditMode.TRUE, element.getSitePath());
                            request.setAttribute(I_CmsDirectEditProvider.ATTRIBUTE_DIRECT_EDIT_PROVIDER, eb);
                        }
                        openedEditable = CmsJspTagEdit.insertDirectEditStart(
                            cms,
                            context,
                            element.getResource(),
                            canCreate,
                            canDelete,
                            null,
                            creationSiteMap,
                            postCreateHandler);
                    }
                    contextBean.setElement(element);
                    try {
                        CmsJspTagInclude.includeTagAction(
                            context,
                            cms.getRequestContext().removeSiteRoot(formatter.getJspRootPath()),
                            null,
                            locale,
                            false,
                            isOnline,
                            null,
                            CmsRequestUtil.getAtrributeMap(request),
                            request,
                            response);
                    } catch (JspException e) {
                        LOG.error(e.getLocalizedMessage(), e);
                    }
                    if (openedEditable) {
                        CmsJspTagEdit.insertDirectEditEnd(context);
                    }
                }
            } catch (CmsException e) {
                LOG.error(e.getLocalizedMessage(), e);
            }
            contextBean.setElement(parentElement);
        }

    }

    /**
     * Includes the formatter rendering the given element.<p>
     *
     * @param element the element
     * @param formatter the formatter configuration bean
     * @param context the page context
     * @param request the request
     * @param response the response
     */
    public static void displayAction(
        CmsContainerElementBean element,
        I_CmsFormatterBean formatter,
        PageContext context,
        ServletRequest request,
        ServletResponse response) {

        displayAction(element, formatter, false, false, false, null, null, context, request, response);
    }

    /**
     * Includes the formatter rendering the given element.<p>
     *
     * @param elementResource the element resource
     * @param formatter the formatter configuration bean
     * @param settings the element settings
     * @param editable if editable
     * @param canCreate if new resources may be created
     * @param canDelete if the resource may be deleted
     * @param creationSiteMap the create location sub site
     * @param postCreateHandler the post create handler
     * @param context the page context
     * @param request the request
     * @param response the response
     */
    public static void displayAction(
        CmsResource elementResource,
        I_CmsFormatterBean formatter,
        Map<String, String> settings,
        boolean editable,
        boolean canCreate,
        boolean canDelete,
        String creationSiteMap,
        String postCreateHandler,
        PageContext context,
        ServletRequest request,
        ServletResponse response) {

        CmsContainerElementBean element = new CmsContainerElementBean(
            elementResource.getStructureId(),
            formatter.getJspStructureId(),
            settings,
            false);
        displayAction(
            element,
            formatter,
            editable,
            canCreate,
            canDelete,
            creationSiteMap,
            postCreateHandler,
            context,
            request,
            response);
    }

    /**
     * Adds a display formatter.<p>
     *
     * @param type the resource type
     * @param path the path to the formatter configuration file.<p>
     */
    public void addDisplayFormatter(String type, String path) {

        m_displayFormatterPaths.put(type, path);
    }

    /**
     * @see org.opencms.jsp.I_CmsJspTagParamParent#addParameter(java.lang.String, java.lang.String)
     */
    public void addParameter(String name, String value) {

        // No null values allowed in parameters
        if ((name == null) || (value == null)) {
            return;
        }

        m_parameterMap.put(name, value);
    }

    /**
     * @see javax.servlet.jsp.tagext.BodyTagSupport#doEndTag()
     */
    @Override
    public int doEndTag() {

        ServletRequest request = pageContext.getRequest();
        ServletResponse response = pageContext.getResponse();
        if (CmsFlexController.isCmsRequest(request)) {
            // this will always be true if the page is called through OpenCms
            CmsObject cms = CmsFlexController.getCmsObject(request);
            try {
                CmsResource res = cms.readResource(m_value);
                boolean isOnline = cms.getRequestContext().getCurrentProject().isOnlineProject();
                I_CmsFormatterBean formatter = getFormatterForType(cms, res, isOnline);
                displayAction(
                    res,
                    formatter,
                    m_parameterMap,
                    m_editable,
                    m_canCreate,
                    m_canDelete,
                    m_creationSiteMap,
                    m_postCreateHandler,
                    pageContext,<commit_msg>Fixing issue where expired resources where not rendered in edit mode.<commit_after>/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package org.opencms.jsp;

import org.opencms.ade.configuration.CmsADEConfigData;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.collectors.I_CmsCollectorPostCreateHandler;
import org.opencms.flex.CmsFlexController;
import org.opencms.jsp.util.CmsJspContentAccessValueWrapper;
import org.opencms.jsp.util.CmsJspStandardContextBean;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsRequestUtil;
import org.opencms.util.CmsUUID;
import org.opencms.workplace.editors.directedit.CmsAdvancedDirectEditProvider;
import org.opencms.workplace.editors.directedit.CmsDirectEditMode;
import org.opencms.workplace.editors.directedit.I_CmsDirectEditProvider;
import org.opencms.xml.containerpage.CmsContainerElementBean;
import org.opencms.xml.containerpage.CmsFormatterConfiguration;
import org.opencms.xml.containerpage.I_CmsFormatterBean;
import org.opencms.xml.types.CmsXmlDisplayFormatterValue;
import org.opencms.xml.types.I_CmsXmlContentValue;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.logging.Log;

/**
 * The 'display' tag can be used to display a single resource using a formatter. It also allows to activate direct editing.<p>
 */
public class CmsJspTagDisplay extends BodyTagSupport implements I_CmsJspTagParamParent {

    /** The log object for this class. */
    private static final Log LOG = CmsLog.getLog(CmsJspTagDisplay.class);

    /** The serial version id. */
    private static final long serialVersionUID = 2285680951218629093L;

    /** Flag, indicating if the create option should be displayed. */
    private boolean m_canCreate;

    /** Flag, indicating if the delete option should be displayed. */
    private boolean m_canDelete;

    /** The tag attribute's value, specifying the path to the (sub)sitemap where new content should be created. */
    private String m_creationSiteMap;

    /** The display formatter ids. */
    private Map<String, CmsUUID> m_displayFormatterIds;

    /** The display formatter paths. */
    private Map<String, String> m_displayFormatterPaths;

    /** The editable flag. */
    private boolean m_editable;

    /** The settings parameter map. */
    private Map<String, String> m_parameterMap;

    /** The pass settings flag. */
    private boolean m_passSettings;

    /** The fully qualified class name of the post create handler to use. */
    private String m_postCreateHandler;

    /** The site path to the resource to display. */
    private String m_value;

    /**
     * Constructor.<p>
     */
    public CmsJspTagDisplay() {
        m_parameterMap = new HashMap<String, String>();
        m_displayFormatterPaths = new HashMap<String, String>();
        m_displayFormatterIds = new HashMap<String, CmsUUID>();
    }

    /**
     * Includes the formatter rendering the given element.<p>
     *
     * @param element the element
     * @param formatter the formatter configuration bean
     * @param editable if editable
     * @param canCreate if new resources may be created
     * @param canDelete if the resource may be deleted
     * @param creationSiteMap the create location sub site
     * @param postCreateHandler the post create handler
     * @param context the page context
     * @param request the request
     * @param response the response
     */
    public static void displayAction(
        CmsContainerElementBean element,
        I_CmsFormatterBean formatter,
        boolean editable,
        boolean canCreate,
        boolean canDelete,
        String creationSiteMap,
        String postCreateHandler,
        PageContext context,
        ServletRequest request,
        ServletResponse response) {

        if (CmsFlexController.isCmsRequest(request)) {
            // this will always be true if the page is called through OpenCms
            CmsObject cms = CmsFlexController.getCmsObject(request);
            Locale locale = cms.getRequestContext().getLocale();
            boolean isOnline = cms.getRequestContext().getCurrentProject().isOnlineProject();
            CmsJspStandardContextBean contextBean = CmsJspStandardContextBean.getInstance(request);
            CmsContainerElementBean parentElement = contextBean.getElement();

            try {
                if (formatter != null) {
                    element.initResource(cms);
                    element.initSettings(cms, formatter);
                    boolean openedEditable = false;
                    if (editable && contextBean.getIsEditMode()) {
                        if (CmsJspTagEditable.getDirectEditProvider(context) == null) {
                            I_CmsDirectEditProvider eb = new CmsAdvancedDirectEditProvider();
                            eb.init(cms, CmsDirectEditMode.TRUE, element.getSitePath());
                            request.setAttribute(I_CmsDirectEditProvider.ATTRIBUTE_DIRECT_EDIT_PROVIDER, eb);
                        }
                        openedEditable = CmsJspTagEdit.insertDirectEditStart(
                            cms,
                            context,
                            element.getResource(),
                            canCreate,
                            canDelete,
                            null,
                            creationSiteMap,
                            postCreateHandler);
                    }
                    contextBean.setElement(element);
                    try {
                        CmsJspTagInclude.includeTagAction(
                            context,
                            cms.getRequestContext().removeSiteRoot(formatter.getJspRootPath()),
                            null,
                            locale,
                            false,
                            isOnline,
                            null,
                            CmsRequestUtil.getAtrributeMap(request),
                            request,
                            response);
                    } catch (JspException e) {
                        LOG.error(e.getLocalizedMessage(), e);
                    }
                    if (openedEditable) {
                        CmsJspTagEdit.insertDirectEditEnd(context);
                    }
                }
            } catch (CmsException e) {
                LOG.error(e.getLocalizedMessage(), e);
            }
            contextBean.setElement(parentElement);
        }

    }

    /**
     * Includes the formatter rendering the given element.<p>
     *
     * @param element the element
     * @param formatter the formatter configuration bean
     * @param context the page context
     * @param request the request
     * @param response the response
     */
    public static void displayAction(
        CmsContainerElementBean element,
        I_CmsFormatterBean formatter,
        PageContext context,
        ServletRequest request,
        ServletResponse response) {

        displayAction(element, formatter, false, false, false, null, null, context, request, response);
    }

    /**
     * Includes the formatter rendering the given element.<p>
     *
     * @param elementResource the element resource
     * @param formatter the formatter configuration bean
     * @param settings the element settings
     * @param editable if editable
     * @param canCreate if new resources may be created
     * @param canDelete if the resource may be deleted
     * @param creationSiteMap the create location sub site
     * @param postCreateHandler the post create handler
     * @param context the page context
     * @param request the request
     * @param response the response
     */
    public static void displayAction(
        CmsResource elementResource,
        I_CmsFormatterBean formatter,
        Map<String, String> settings,
        boolean editable,
        boolean canCreate,
        boolean canDelete,
        String creationSiteMap,
        String postCreateHandler,
        PageContext context,
        ServletRequest request,
        ServletResponse response) {

        CmsContainerElementBean element = new CmsContainerElementBean(
            elementResource.getStructureId(),
            formatter.getJspStructureId(),
            settings,
            false);
        displayAction(
            element,
            formatter,
            editable,
            canCreate,
            canDelete,
            creationSiteMap,
            postCreateHandler,
            context,
            request,
            response);
    }

    /**
     * Adds a display formatter.<p>
     *
     * @param type the resource type
     * @param path the path to the formatter configuration file.<p>
     */
    public void addDisplayFormatter(String type, String path) {

        m_displayFormatterPaths.put(type, path);
    }

    /**
     * @see org.opencms.jsp.I_CmsJspTagParamParent#addParameter(java.lang.String, java.lang.String)
     */
    public void addParameter(String name, String value) {

        // No null values allowed in parameters
        if ((name == null) || (value == null)) {
            return;
        }

        m_parameterMap.put(name, value);
    }

    /**
     * @see javax.servlet.jsp.tagext.BodyTagSupport#doEndTag()
     */
    @Override
    public int doEndTag() {

        ServletRequest request = pageContext.getRequest();
        ServletResponse response = pageContext.getResponse();
        if (CmsFlexController.isCmsRequest(request)) {
            // this will always be true if the page is called through OpenCms
            CmsObject cms = CmsFlexController.getCmsObject(request);
            try {
                boolean isOnline = cms.getRequestContext().getCurrentProject().isOnlineProject();
                CmsResource res = isOnline
                ? cms.readResource(m_value)
                : cms.readResource(m_value, CmsResourceFilter.IGNORE_EXPIRATION);
                I_CmsFormatterBean formatter = getFormatterForType(cms, res, isOnline);
                displayAction(
                    res,
                    formatter,
                    m_parameterMap,
                    m_editable,
                    m_canCreate,
                    m_canDelete,
                    m_creationSiteMap,
                    m_postCreateHandler,
                    pageContext,
{'fraction_non_alphanumeric': 0.07283439354480639, 'fraction_numerical': 0.00298851556162746, 'mean_word_length': 2.18867410835829, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7475127', 'n_tokens_mistral': 6052, 'n_tokens_neox': 5832, 'n_words': 1690}