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.CmsFile;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsResource;
033import org.opencms.flex.CmsFlexController;
034import org.opencms.i18n.CmsLocaleManager;
035import org.opencms.jsp.util.CmsJspContentAccessBean;
036import org.opencms.main.CmsException;
037import org.opencms.main.CmsIllegalArgumentException;
038import org.opencms.main.CmsLog;
039import org.opencms.main.OpenCms;
040import org.opencms.util.CmsStringUtil;
041import org.opencms.xml.I_CmsXmlDocument;
042import org.opencms.xml.containerpage.CmsContainerElementBean;
043import org.opencms.xml.content.CmsXmlContentFactory;
044
045import java.util.Locale;
046
047import javax.servlet.jsp.JspException;
048import javax.servlet.jsp.PageContext;
049
050import org.apache.commons.logging.Log;
051
052/**
053 * Implementation of the <code>&lt;cms:formatter var="..." val="..." /&gt;</code> tag,
054 * used to access and display XML content item information in a formatter.<p>
055 *
056 * @since 8.0.0
057 */
058public class CmsJspTagFormatter extends CmsJspScopedVarBodyTagSuport {
059
060    /** The log object for this class. */
061    private static final Log LOG = CmsLog.getLog(CmsJspTagFormatter.class);
062
063    /** Serial version UID required for safe serialization. */
064    private static final long serialVersionUID = -8232834808735187624L;
065
066    /** The CmsObject for the current user. */
067    protected transient CmsObject m_cms;
068
069    /** The FlexController for the current request. */
070    protected CmsFlexController m_controller;
071
072    /** Reference to the last loaded resource element. */
073    protected transient CmsResource m_resource;
074
075    /** The current container element. */
076    private CmsContainerElementBean m_element;
077
078    /** Reference to the currently selected locale. */
079    private Locale m_locale;
080
081    /** Optional name for the attribute that provides direct access to the RDFA map. */
082    private String m_rdfa;
083
084    /** Optional name for the attribute that provides direct access to the content value map. */
085    private String m_value;
086
087    /**
088     * Empty constructor, required for JSP tags.<p>
089     */
090    public CmsJspTagFormatter() {
091
092        super();
093    }
094
095    /**
096     * Constructor used when using <code>formatter</code> from scriptlet code.<p>
097     *
098     * @param context the JSP page context
099     * @param locale the locale to use
100     *
101     * @throws JspException in case something goes wrong
102     */
103    public CmsJspTagFormatter(PageContext context, Locale locale)
104    throws JspException {
105
106        m_locale = locale;
107        setPageContext(context);
108        init();
109    }
110
111    /**
112     * @see javax.servlet.jsp.tagext.BodyTagSupport#doEndTag()
113     */
114    @Override
115    public int doEndTag() throws JspException {
116
117        release();
118        return super.doEndTag();
119    }
120
121    /**
122     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
123     */
124    @Override
125    public int doStartTag() throws JspException, CmsIllegalArgumentException {
126
127        // initialize the content load tag
128        init();
129        return EVAL_BODY_INCLUDE;
130    }
131
132    /**
133     * Returns the locale.<p>
134     *
135     * @return the locale
136     */
137    public String getLocale() {
138
139        return (m_locale != null) ? m_locale.toString() : "";
140    }
141
142    /**
143     * Returns the name for the optional attribute that provides direct access to the RDFA map.<p>
144     *
145     * @return the name for the optional attribute that provides direct access to the RDFA map
146     */
147    public String getRdfa() {
148
149        return m_rdfa;
150    }
151
152    /**
153     * Returns the name for the optional attribute that provides direct access to the content value map.<p>
154     *
155     * @return the name for the optional attribute that provides direct access to the content value map
156     */
157    public String getVal() {
158
159        return m_value;
160    }
161
162    /**
163     * @see javax.servlet.jsp.tagext.Tag#release()
164     */
165    @Override
166    public void release() {
167
168        m_locale = null;
169        m_cms = null;
170        m_resource = null;
171        m_controller = null;
172        super.release();
173    }
174
175    /**
176     * Sets the locale.<p>
177     *
178     * @param locale the locale to set
179     */
180    public void setLocale(String locale) {
181
182        if (CmsStringUtil.isEmpty(locale)) {
183            m_locale = null;
184        } else {
185            m_locale = CmsLocaleManager.getLocale(locale);
186        }
187    }
188
189    /**
190     * Sets the name for the optional attribute that provides direct access to the RDFA map.<p>
191     *
192     * @param rdfa the name for the optional attribute that provides direct access to the RDFA map
193     */
194    public void setRdfa(String rdfa) {
195
196        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(rdfa)) {
197            m_rdfa = rdfa.trim();
198        } else {
199            m_rdfa = rdfa;
200        }
201    }
202
203    /**
204     * Sets the name for the optional attribute that provides direct access to the content value map.<p>
205     *
206     * @param val the name for the optional attribute that provides direct access to the content value map
207     */
208    public void setVal(String val) {
209
210        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(val)) {
211            m_value = val.trim();
212        } else {
213            m_value = val;
214        }
215    }
216
217    /**
218     * Initializes this formatter tag.<p>
219     *
220     * @throws JspException in case something goes wrong
221     */
222    protected void init() throws JspException {
223
224        // initialize OpenCms access objects
225        m_controller = CmsFlexController.getController(pageContext.getRequest());
226        m_cms = m_controller.getCmsObject();
227
228        try {
229            // get the resource name from the selected container
230            m_element = OpenCms.getADEManager().getCurrentElement(pageContext.getRequest());
231            m_element.initResource(m_cms);
232            if (m_cms.getRequestContext().getCurrentProject().isOnlineProject()
233                && !m_element.isReleasedAndNotExpired()) {
234                throw new CmsException(
235                    Messages.get().container(
236                        Messages.ERR_RESOURCE_IS_NOT_RELEASE_OR_EXPIRED_1,
237                        m_element.getResource().getRootPath()));
238            }
239            if (m_locale == null) {
240                // no locale set, use locale from users request context
241                m_locale = m_cms.getRequestContext().getLocale();
242            }
243
244            // load content and store it
245            CmsJspContentAccessBean bean;
246            if ((m_element.isInMemoryOnly() || m_element.isTemporaryContent())
247                && (m_element.getResource() instanceof CmsFile)) {
248                I_CmsXmlDocument xmlContent = CmsXmlContentFactory.unmarshal(
249                    m_cms,
250                    m_element.getResource(),
251                    pageContext.getRequest());
252                bean = new CmsJspContentAccessBean(m_cms, m_locale, xmlContent);
253            } else {
254                bean = new CmsJspContentAccessBean(m_cms, m_locale, m_element.getResource());
255            }
256            storeAttribute(getVar(), bean);
257
258            if (m_value != null) {
259                // if the optional "val" parameter has been set, store the value map of the content in the page context scope
260                storeAttribute(getVal(), bean.getValue());
261            }
262
263            if (m_rdfa != null) {
264                // if the optional "rdfa" parameter has been set, store the rdfa map of the content in the page context scope
265                storeAttribute(getRdfa(), bean.getRdfa());
266            }
267
268        } catch (CmsException e) {
269            LOG.error(e.getLocalizedMessage(), e);
270            m_controller.setThrowable(e, m_cms.getRequestContext().getUri());
271            throw new JspException(e);
272        }
273    }
274}