@Override
    public int doEndTag() throws JspException {

        ServletRequest req = pageContext.getRequest();
        // This will always be true if the page is called through OpenCms
        if (CmsFlexController.isCmsRequest(req)) {

            try {
                CmsFlexController controller = CmsFlexController.getController(req);
                CmsObject cms = controller.getCmsObject();
                String requestUri = cms.getRequestContext().getUri();
                Locale locale = cms.getRequestContext().getLocale();
                CmsJspStandardContextBean standardContext = CmsJspStandardContextBean.getInstance(req);
                standardContext.initPage();
                m_editableRequest = standardContext.getIsEditMode();
                m_parentElement = standardContext.getElement();
                m_parentContainer = standardContext.getContainer();
                m_hasModelGroupAncestor = m_editableRequest ? hasModelGroupAncestor(standardContext) : false;
                CmsContainerPageBean containerPage = standardContext.getPage();
                CmsResource detailContent = standardContext.getDetailContent();
                CmsResource detailFunctionPage = standardContext.getDetailFunctionPage();
                // get the container
                CmsContainerBean container = null;
                boolean detailOnly = m_detailOnly || ((m_parentContainer != null) && m_parentContainer.isDetailOnly());
                if (detailOnly) {
                    if (detailContent == null) {
                        // this is no detail page, so the detail only container will not be rendered at all
                        resetState();
                        return EVAL_PAGE;
                    } else {
                        String pageRootPath = cms.getRequestContext().addSiteRoot(cms.getRequestContext().getUri());
                        CmsContainerPageBean detailOnlyPage = CmsDetailOnlyContainerUtil.getDetailOnlyPage(
                            cms,
                            req,
                            pageRootPath);
                        if (detailOnlyPage != null) {
                            container = detailOnlyPage.getContainers().get(getName());
                        }
                    }
                } else if (containerPage != null) {
                    container = containerPage.getContainers().get(getName());
                }
                // get the maximal number of elements
                int maxElements = getMaxElements(requestUri);
                if (container == null) {
                    container = new CmsContainerBean(
                        getName(),
                        getType(),
                        m_parentElement != null ? m_parentElement.getInstanceId() : null,
                        (m_parentContainer == null) || (m_detailOnly && !m_parentContainer.isDetailOnly()),
                        maxElements,
                        Collections.<CmsContainerElementBean> emptyList());
                } else if ((m_parentElement != null)
                    && !m_detailOnly //ignore parent information for detail only containers to render content on different detail pages.
                    && !m_parentElement.getInstanceId().equals(container.getParentInstanceId())) {
                    // the container parent instance id does not match the parent element instance id, skip rendering to avoid recursion
                    LOG.error(
                        new CmsIllegalStateException(
                            Messages.get().container(
                                Messages.ERR_INVALID_CONTAINER_PARENT_2,
                                getName(),
                                m_parentElement.getInstanceId())));
                    resetState();
                    return EVAL_PAGE;
                }
                // set the parameter
                container.setParam(getParam());
                // set the detail only flag
                container.setDetailOnly(detailOnly);
                boolean isUsedAsDetailView = false;
                if (m_detailView && ((detailContent != null) || (detailFunctionPage != null))) {
                    isUsedAsDetailView = true;
                }
                // create tag for container
                String tagName = CmsStringUtil.isEmptyOrWhitespaceOnly(getTag()) ? DEFAULT_TAG_NAME : getTag();
                pageContext.getOut().print(
                    getTagOpen(
                        tagName,
                        getName(),
                        getTagClass(),
                        isNested(),
                        !m_editableRequest,
                        m_editableRequest ? getContainerData(cms, maxElements, isUsedAsDetailView, detailOnly) : null));

                standardContext.setContainer(container);
                // validate the type
                if (!getType().equals(container.getType())) {
                    container.setType(getType());
                    LOG.warn(
                        new CmsIllegalStateException(
                            Messages.get().container(
                                Messages.LOG_WRONG_CONTAINER_TYPE_4,
                                new Object[] {requestUri, locale, getName(), getType()})));
                }

                // update the cache
                container.setMaxElements(maxElements);
                container.setWidth("" + getContainerWidth());
                List<CmsContainerElementBean> allElements = new ArrayList<CmsContainerElementBean>();
                CmsContainerElementBean detailElement = null;
                if (isUsedAsDetailView) {
                    if (detailContent != null) {
                        detailElement = generateDetailViewElement(req, cms, detailContent, container);
                    } else {
                        detailElement = getDetailFunctionElement(cms, detailFunctionPage, req);
                    }
                }
                if (detailElement != null) {
                    allElements.add(detailElement);
                } else {
                    allElements.addAll(container.getElements());
                }
                // iterate over elements to render
                int numRenderedElements = 0;
                boolean first = true;
                for (CmsContainerElementBean elementBean : allElements) {
                    // in case of rendering a detail container on a detail page,
                    // the first element may be used to provide settings for the detail content
                    // this element will not be rendered, in case the detail page is not actually used to render detail content
                    boolean skipDetailTemplateElement = false;
                    try {
                        skipDetailTemplateElement = first
                            && !m_editableRequest
                            && m_detailView
                            && (detailElement == null)
                            && OpenCms.getADEManager().isDetailPage(cms, standardContext.getPageResource())
                            && OpenCms.getADEManager().getDetailPages(cms, elementBean.getTypeName()).contains(
                                CmsResource.getFolderPath(standardContext.getPageResource().getRootPath()));
                    } catch (Exception e) {
                        LOG.error(e.getLocalizedMessage(), e);
                    }
                    first = false;
                    if (!skipDetailTemplateElement) {
                        try {
                            boolean rendered = renderContainerElement(
                                (HttpServletRequest)req,
                                cms,
                                standardContext,
                                elementBean,
                                locale,
                                numRenderedElements >= maxElements);
                            if (rendered) {
                                numRenderedElements += 1;
                            }
                        } catch (Exception e) {
                            if (LOG.isErrorEnabled()) {
                                LOG.error(e.getLocalizedMessage(), e);
                            }
                        }
                    }
                }
                if ((numRenderedElements == 0) && (m_bodyContent != null) && CmsJspTagEditable.isEditableRequest(req)) {
                    // the container is empty, print the evaluated body content
                    pageContext.getOut().print(m_bodyContent);
                }
                // close tag for container
                pageContext.getOut().print(getTagClose(tagName));
            } catch (Exception ex) {
                if (LOG.isErrorEnabled()) {
                    LOG.error(Messages.get().getBundle().key(Messages.ERR_PROCESS_TAG_1, "container"), ex);
                }
                throw new javax.servlet.jsp.JspException(ex);
            }
        }

        resetState();
        return super.doEndTag();
    }
@ Override public int doEndTag ( ) throws JspException { ServletRequest req = pageContext . getRequest ( ) ; if ( CmsFlexController . isCmsRequest ( req ) ) { try { CmsFlexController controller = CmsFlexController . getController ( req ) ; CmsObject cms = controller . getCmsObject ( ) ; String requestUri = cms . getRequestContext ( ) . getUri ( ) ; Locale locale = cms . getRequestContext ( ) . getLocale ( ) ; CmsJspStandardContextBean standardContext = CmsJspStandardContextBean . getInstance ( req ) ; standardContext . initPage ( ) ; m_editableRequest = standardContext . getIsEditMode ( ) ; m_parentElement = standardContext . getElement ( ) ; m_parentContainer = standardContext . getContainer ( ) ; m_hasModelGroupAncestor = m_editableRequest ? hasModelGroupAncestor ( standardContext ) : false ; CmsContainerPageBean containerPage = standardContext . getPage ( ) ; CmsResource detailContent = standardContext . getDetailContent ( ) ; CmsResource detailFunctionPage = standardContext . getDetailFunctionPage ( ) ; CmsContainerBean container = null ; boolean detailOnly = m_detailOnly || ( ( m_parentContainer != null ) && m_parentContainer . isDetailOnly ( ) ) ; if ( detailOnly ) { if ( detailContent == null ) { resetState ( ) ; return EVAL_PAGE ; } else { String pageRootPath = cms . getRequestContext ( ) . addSiteRoot ( cms . getRequestContext ( ) . getUri ( ) ) ; CmsContainerPageBean detailOnlyPage = CmsDetailOnlyContainerUtil . getDetailOnlyPage ( cms , req , pageRootPath ) ; if ( detailOnlyPage != null ) { container = detailOnlyPage . getContainers ( ) . get ( getName ( ) ) ; } } } else if ( containerPage != null ) { container = containerPage . getContainers ( ) . get ( getName ( ) ) ; } int maxElements = getMaxElements ( requestUri ) ; if ( container == null ) { container = new CmsContainerBean ( getName ( ) , getType ( ) , m_parentElement != null ? m_parentElement . getInstanceId ( ) : null , ( m_parentContainer == null ) || ( m_detailOnly && ! m_parentContainer . isDetailOnly ( ) ) , maxElements , Collections . < CmsContainerElementBean > emptyList ( ) ) ; } else if ( ( m_parentElement != null ) && ! m_detailOnly && ! m_parentElement . getInstanceId ( ) . equals ( container . getParentInstanceId ( ) ) ) { LOG . error ( new CmsIllegalStateException ( Messages . get ( ) . container ( Messages . ERR_INVALID_CONTAINER_PARENT_2 , getName ( ) , m_parentElement . getInstanceId ( ) ) ) ) ; resetState ( ) ; return EVAL_PAGE ; } container . setParam ( getParam ( ) ) ; container . setDetailOnly ( detailOnly ) ; boolean isUsedAsDetailView = false ; if ( m_detailView && ( ( detailContent != null ) || ( detailFunctionPage != null ) ) ) { isUsedAsDetailView = true ; } String tagName = CmsStringUtil . isEmptyOrWhitespaceOnly ( getTag ( ) ) ? DEFAULT_TAG_NAME : getTag ( ) ; pageContext . getOut ( ) . print ( getTagOpen ( tagName , getName ( ) , getTagClass ( ) , isNested ( ) , ! m_editableRequest , m_editableRequest ? getContainerData ( cms , maxElements , isUsedAsDetailView , detailOnly ) : null ) ) ; standardContext . setContainer ( container ) ; if ( ! getType ( ) . equals ( container . getType ( ) ) ) { container . setType ( getType ( ) ) ; LOG . warn ( new CmsIllegalStateException ( Messages . get ( ) . container ( Messages . LOG_WRONG_CONTAINER_TYPE_4 , new Object [ ] { requestUri , locale , getName ( ) , getType ( ) } ) ) ) ; } container . setMaxElements ( maxElements ) ; container . setWidth ( "" + getContainerWidth ( ) ) ; List < CmsContainerElementBean > allElements = new ArrayList < CmsContainerElementBean > ( ) ; CmsContainerElementBean detailElement = null ; if ( isUsedAsDetailView ) { if ( detailContent != null ) { detailElement = generateDetailViewElement ( req , cms , detailContent , container ) ; } else { detailElement = getDetailFunctionElement ( cms , detailFunctionPage , req ) ; } } if ( detailElement != null ) { allElements . add ( detailElement ) ; } else { allElements . addAll ( container . getElements ( ) ) ; } int numRenderedElements = 0 ; boolean first = true ; for ( CmsContainerElementBean elementBean : allElements ) { boolean skipDetailTemplateElement = false ; try { skipDetailTemplateElement = first && ! m_editableRequest && m_detailView && ( detailElement == null ) && OpenCms . getADEManager ( ) . isDetailPage ( cms , standardContext . getPageResource ( ) ) && OpenCms . getADEManager ( ) . getDetailPages ( cms , elementBean . getTypeName ( ) ) . contains ( CmsResource . getFolderPath ( standardContext . getPageResource ( ) . getRootPath ( ) ) ) ; } catch ( Exception e ) { LOG . error ( e . getLocalizedMessage ( ) , e ) ; } first = false ; if ( ! skipDetailTemplateElement ) { try { boolean rendered = renderContainerElement ( ( HttpServletRequest ) req , cms , standardContext , elementBean , locale , numRenderedElements >= maxElements ) ; if ( rendered ) { numRenderedElements += 1 ; } } catch ( Exception e ) { if ( LOG . isErrorEnabled ( ) ) { LOG . error ( e . getLocalizedMessage ( ) , e ) ; } } } } if ( ( numRenderedElements == 0 ) && ( m_bodyContent != null ) && CmsJspTagEditable . isEditableRequest ( req ) ) { pageContext . getOut ( ) . print ( m_bodyContent ) ; } pageContext . getOut ( ) . print ( getTagClose ( tagName ) ) ; } catch ( Exception ex ) { if ( LOG . isErrorEnabled ( ) ) { LOG . error ( Messages . get ( ) . getBundle ( ) . key ( Messages . ERR_PROCESS_TAG_1 , "container" ) , ex ) ; } throw new javax . servlet . jsp . JspException ( ex ) ; } } resetState ( ) ; return super . doEndTag ( ) ; }
@see javax.servlet.jsp.tagext.TagSupport#doEndTag()