001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.jsp.util;
029
030import org.opencms.ade.configuration.CmsADEConfigData;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsResource;
033import org.opencms.file.CmsResourceFilter;
034import org.opencms.flex.CmsFlexController;
035import org.opencms.jsp.CmsJspTagContainer;
036import org.opencms.main.CmsLog;
037import org.opencms.main.OpenCms;
038import org.opencms.xml.containerpage.CmsContainerBean;
039import org.opencms.xml.containerpage.CmsContainerElementBean;
040import org.opencms.xml.containerpage.CmsContainerPageBean;
041import org.opencms.xml.containerpage.I_CmsFormatterBean;
042
043import java.util.Locale;
044import java.util.Map;
045
046import org.apache.commons.logging.Log;
047
048/**
049 * Wrapper for using container pages in JSPs.
050 */
051public class CmsJspContainerPageWrapper {
052
053    /** Logger instance for this class. */
054    private static final Log LOG = CmsLog.getLog(CmsJspContainerPageWrapper.class);
055
056    /** The wrapped container page bean. */
057    private CmsContainerPageBean m_page;
058
059    /**
060     * Creates a new instance.
061     *
062     * @param page the container page to wrap
063     */
064    public CmsJspContainerPageWrapper(CmsContainerPageBean page) {
065
066        m_page = page;
067
068    }
069
070    /**
071     * Renders the element in the container with the given name or name prefix.
072     * @param context the context bean
073     * @param name the container name or name prefix
074     * @return the rendered HTML
075     */
076    public String renderContainer(CmsJspStandardContextBean context, String name) {
077
078        CmsContainerBean container = findContainer(name);
079        if (container == null) {
080            return null;
081        }
082        return render(context, container);
083    }
084
085    /**
086     * Helper method for locating a container with the given name or name prefix.
087     * @param name the name or name prefix
088     * @return the container, or null if none were found
089     */
090    private CmsContainerBean findContainer(String name) {
091
092        CmsContainerBean result = m_page.getContainers().get(name);
093        if (result == null) {
094            for (Map.Entry<String, CmsContainerBean> entry : m_page.getContainers().entrySet()) {
095                if (entry.getKey().endsWith("-" + name)) {
096                    result = entry.getValue();
097                    break;
098                }
099            }
100        }
101        return result;
102    }
103
104    /**
105     * Renders the elements from the given container as HTML and returns it.
106     *
107     * @param context the context bean
108     * @param container the container whose elements should be rendered
109     * @return the HTML of the container elements, without a surrounding element
110     */
111    private String render(CmsJspStandardContextBean context, CmsContainerBean container) {
112
113        CmsFlexController controller = CmsFlexController.getController(context.getRequest());
114        CmsObject m_cms = context.getCmsObject();
115        CmsContainerBean oldContainer = context.getContainer();
116        CmsContainerElementBean oldElement = context.getElement();
117        CmsContainerPageBean oldPage = context.getPage();
118        boolean oldForceDisableEdit = context.isForceDisableEditMode();
119        Locale locale = m_cms.getRequestContext().getLocale();
120        context.getRequest();
121        try {
122            context.setContainer(container);
123            context.setPage(m_page);
124            // The forceDisableEditMode flag may be incorrectly cached in the standard
125            // context bean copies stored in flex cache entries, but it doesn't matter since edit mode is never
126            // active in the Online project anyway
127            context.setForceDisableEditMode(true);
128
129            int containerWidth = -1;
130            try {
131                containerWidth = Integer.parseInt(container.getWidth());
132            } catch (Exception e) {
133                LOG.debug(e.getLocalizedMessage(), e);
134            }
135            CmsADEConfigData adeConfig = context.getSitemapConfigInternal();
136            StringBuilder buffer = new StringBuilder();
137            for (CmsContainerElementBean element : container.getElements()) {
138
139                try {
140                    element.initResource(m_cms);
141                    I_CmsFormatterBean formatterBean = CmsJspTagContainer.ensureValidFormatterSettings(
142                        m_cms,
143                        element,
144                        adeConfig,
145                        container.getName(),
146                        container.getType(),
147                        containerWidth);
148                    element.initSettings(m_cms, adeConfig, formatterBean, locale, controller.getCurrentRequest(), null);
149                    context.setElement(element);
150                    CmsResource formatterRes = m_cms.readResource(
151                        formatterBean.getJspStructureId(),
152                        CmsResourceFilter.IGNORE_EXPIRATION);
153                    byte[] formatterOutput = OpenCms.getResourceManager().getLoader(formatterRes).dump(
154                        m_cms,
155                        formatterRes,
156                        null,
157                        locale,
158                        controller.getCurrentRequest(),
159                        controller.getCurrentResponse());
160                    String encoding = controller.getCurrentResponse().getEncoding();
161                    String formatterOutputStr = new String(formatterOutput, encoding);
162                    buffer.append(formatterOutputStr);
163                } catch (Exception e) {
164                    LOG.error(e.getLocalizedMessage(), e);
165                }
166            }
167            String resultHtml = buffer.toString();
168            return resultHtml;
169        } finally {
170            context.setPage(oldPage);
171            context.setContainer(oldContainer);
172            context.setElement(oldElement);
173            context.setForceDisableEditMode(oldForceDisableEdit);
174        }
175
176    }
177
178}