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 GmbH & Co. KG, 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;
029
030import org.opencms.file.CmsObject;
031import org.opencms.flex.CmsFlexController;
032import org.opencms.i18n.CmsEncoder;
033import org.opencms.i18n.CmsLocaleManager;
034import org.opencms.i18n.CmsMessageContainer;
035import org.opencms.i18n.CmsMessages;
036import org.opencms.main.CmsLog;
037import org.opencms.main.OpenCms;
038import org.opencms.util.CmsMacroResolver;
039import org.opencms.util.CmsStringUtil;
040import org.opencms.xml.CmsXmlUtils;
041import org.opencms.xml.I_CmsXmlDocument;
042
043import java.io.IOException;
044import java.util.Locale;
045
046import javax.servlet.jsp.JspException;
047import javax.servlet.jsp.JspTagException;
048import javax.servlet.jsp.PageContext;
049import javax.servlet.jsp.tagext.Tag;
050import javax.servlet.jsp.tagext.TagSupport;
051
052import org.apache.commons.logging.Log;
053
054/**
055 * Used to access and display XML content item information from the VFS.<p>
056 *
057 * @since 6.0.0
058 */
059public class CmsJspTagContentShow extends TagSupport {
060
061    /** The log object for this class. */
062    private static final Log LOG = CmsLog.getLog(CmsJspTagContentShow.class);
063
064    /** Serial version UID required for safe serialization. */
065    private static final long serialVersionUID = -6776067180965738432L;
066
067    /** Name of the content node element to show. */
068    private String m_element;
069
070    /** Indicates if HTML should be escaped. */
071    private boolean m_escapeHtml;
072
073    /** Locale of the content node element to show. */
074    private Locale m_locale;
075
076    /**
077     * Internal action method to show an element from a XML content document.<p>
078     *
079     * @param container the content container to read the XML content from
080     * @param context the current JSP page context
081     * @param element the node name of the element to show
082     * @param locale the locale of the element to show
083     * @param escape if the result html should be escaped or not
084     *
085     * @return the value of the selected content element
086     */
087    public static String contentShowTagAction(
088        I_CmsXmlContentContainer container,
089        PageContext context,
090        String element,
091        Locale locale,
092        boolean escape) {
093
094        // get the current users OpenCms context
095        CmsObject cms = CmsFlexController.getCmsObject(context.getRequest());
096
097        // get loaded content from content container
098        I_CmsXmlDocument xmlContent = container.getXmlDocument();
099
100        if (CmsStringUtil.isEmpty(element)) {
101            element = container.getXmlDocumentElement();
102        } else {
103            element = CmsXmlUtils.concatXpath(container.getXmlDocumentElement(), element);
104        }
105
106        String content;
107        if (CmsMacroResolver.isMacro(element)) {
108            // this is a macro, initialize a macro resolver
109            String resourcename = CmsJspTagResourceLoad.getResourceName(cms, container);
110            CmsMacroResolver resolver = CmsMacroResolver.newInstance().setCmsObject(cms).setJspPageContext(
111                context).setResourceName(resourcename).setKeepEmptyMacros(true);
112            // resolve the macro
113            content = resolver.resolveMacros(element);
114        } else if (xmlContent == null) {
115            // no XML content- no output
116            content = null;
117        } else {
118
119            // determine the locale to display
120            if (locale == null) {
121                // no locale was set, use default from parent tag (usually "contentload")
122                locale = container.getXmlDocumentLocale();
123            }
124            // now get the content element value to display
125
126            if (xmlContent.hasValue(element, locale)) {
127                try {
128                    // read the element from the content
129                    content = xmlContent.getStringValue(cms, element, locale);
130                } catch (Exception e) {
131                    LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_CONTENT_SHOW_1, element), e);
132                    content = null;
133                }
134            } else {
135                content = null;
136            }
137
138            // make sure that no null String is returned
139            if (content == null) {
140                content = CmsMessages.formatUnknownKey(element);
141            }
142            if (escape) {
143                // HTML escape the value
144                content = CmsEncoder.escapeHtml(content);
145            }
146        }
147
148        return content;
149    }
150
151    /**
152     * @see javax.servlet.jsp.tagext.Tag#doEndTag()
153     */
154    @Override
155    public int doEndTag() {
156
157        if (OpenCms.getSystemInfo().getServletContainerSettings().isReleaseTagsAfterEnd()) {
158            // need to release manually, JSP container may not call release as required (happens with Tomcat)
159            release();
160        }
161        return EVAL_PAGE;
162    }
163
164    /**
165     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
166     */
167    @Override
168    public int doStartTag() throws JspException {
169
170        // get a reference to the parent "content container" class
171        Tag ancestor = findAncestorWithClass(this, I_CmsXmlContentContainer.class);
172        if (ancestor == null) {
173            CmsMessageContainer errMsgContainer = Messages.get().container(
174                Messages.ERR_PARENTLESS_TAG_1,
175                "contentshow");
176            String msg = Messages.getLocalizedMessage(errMsgContainer, pageContext);
177            throw new JspTagException(msg);
178        }
179        I_CmsXmlContentContainer contentContainer = (I_CmsXmlContentContainer)ancestor;
180
181        // now get the content element value to display
182        String content = contentShowTagAction(contentContainer, pageContext, getElement(), m_locale, m_escapeHtml);
183
184        try {
185            if (content != null) {
186                pageContext.getOut().print(content);
187            }
188        } catch (IOException e) {
189            if (LOG.isErrorEnabled()) {
190                LOG.error(Messages.get().getBundle().key(Messages.LOG_ERR_JSP_BEAN_0), e);
191            }
192            throw new JspException(e);
193        }
194
195        return SKIP_BODY;
196    }
197
198    /**
199     * Returns the name of the content node element to show.<p>
200     *
201     * @return the name of the content node element to show
202     */
203    public String getElement() {
204
205        return (m_element != null) ? m_element : "";
206    }
207
208    /**
209     * Returns the locale.<p>
210     *
211     * @return the locale
212     */
213    public String getLocale() {
214
215        return (m_locale != null) ? m_locale.toString() : "";
216    }
217
218    /**
219     * @see javax.servlet.jsp.tagext.Tag#release()
220     */
221    @Override
222    public void release() {
223
224        m_element = null;
225        m_locale = null;
226        super.release();
227    }
228
229    /**
230     * Sets the name of the content node element to show.<p>
231     *
232     * @param element the name of the content node element to show
233     */
234    public void setElement(String element) {
235
236        m_element = element;
237    }
238
239    /**
240     * Set the escape html flag.<p>
241     *
242     * @param value should be <code>"true"</code> or <code>"false"</code> (all values other then <code>"true"</code> are
243     * considered to be false)
244     */
245    public void setEscapeHtml(String value) {
246
247        if (value != null) {
248            m_escapeHtml = Boolean.valueOf(value.trim()).booleanValue();
249        } else {
250            m_escapeHtml = false;
251        }
252    }
253
254    /**
255     * Sets the locale.<p>
256     *
257     * @param locale the locale to set
258     */
259    public void setLocale(String locale) {
260
261        if (CmsStringUtil.isEmpty(locale)) {
262            m_locale = null;
263        } else {
264            m_locale = CmsLocaleManager.getLocale(locale);
265        }
266    }
267}