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  02111R-1307  USA
026 */
027
028package org.opencms.jsp;
029
030import org.opencms.i18n.CmsMessageContainer;
031import org.opencms.main.CmsLog;
032import org.opencms.main.OpenCms;
033import org.opencms.util.CmsMacroResolver;
034import org.opencms.util.CmsStringUtil;
035import org.opencms.util.I_CmsMacroResolver;
036
037import java.io.IOException;
038import java.util.Arrays;
039import java.util.Collections;
040import java.util.List;
041
042import javax.servlet.jsp.JspException;
043import javax.servlet.jsp.JspTagException;
044import javax.servlet.jsp.tagext.Tag;
045
046import org.apache.commons.logging.Log;
047
048/**
049 * Used to access and display XML content item information from the VFS.<p>
050 *
051 * @since 6.0.0
052 */
053public class CmsJspTagContentInfo extends CmsJspScopedVarBodyTagSuport implements I_CmsMacroResolver {
054
055    /** The keys of the supported content info values. */
056    private static final String[] KEYS = {
057        "resultSize",
058        "resultIndex",
059        "pageCount",
060        "pageIndex",
061        "pageSize",
062        "pageNavStartIndex",
063        "pageNavEndIndex",
064        "pageNavLength"};
065
066    /** The keys of the supported content info values as a list. */
067    private static final List<String> KEYS_LIST = Collections.unmodifiableList(Arrays.asList(KEYS));
068
069    /** The log object for this class. */
070    private static final Log LOG = CmsLog.getLog(CmsJspTagContentInfo.class);
071
072    /** Serial version UID required for safe serialization. */
073    private static final long serialVersionUID = -1955531050687258685L;
074
075    /** The name of the content info's value that should be printed out. */
076    private String m_value;
077
078    /**
079     * @see javax.servlet.jsp.tagext.Tag#doEndTag()
080     */
081    @Override
082    public int doEndTag() {
083
084        if (OpenCms.getSystemInfo().getServletContainerSettings().isReleaseTagsAfterEnd()) {
085            // need to release manually, JSP container may not call release as required (happens with Tomcat)
086            release();
087        }
088        return EVAL_PAGE;
089    }
090
091    /**
092     * @see javax.servlet.jsp.tagext.Tag#doStartTag()
093     */
094    @Override
095    public int doStartTag() throws JspException {
096
097        // get a reference to the parent "content container" class
098        Tag ancestor = findAncestorWithClass(this, I_CmsResourceContainer.class);
099        if (ancestor == null) {
100            // build a container
101            CmsMessageContainer container = Messages.get().container(Messages.ERR_PARENTLESS_TAG_1, "contentinfo");
102            String msg = Messages.getLocalizedMessage(container, pageContext);
103            throw new JspTagException(msg);
104        }
105
106        I_CmsResourceContainer contentContainer = (I_CmsResourceContainer)ancestor;
107
108        String tagContent = "";
109
110        if (isScopeVarSet()) {
111            if (contentContainer instanceof CmsJspTagContentLoad) {
112                storeContentInfoBean((CmsJspTagContentLoad)contentContainer);
113            } else if (contentContainer instanceof CmsJspTagResourceLoad) {
114                storeContentInfoBean((CmsJspTagResourceLoad)contentContainer);
115            }
116        }
117
118        if (CmsStringUtil.isNotEmpty(m_value)) {
119            // value is provided - resolve macros
120            tagContent = resolveMacros(m_value);
121        }
122
123        try {
124            pageContext.getOut().print(tagContent);
125        } catch (IOException e) {
126            CmsMessageContainer message = Messages.get().container(Messages.ERR_PROCESS_TAG_1, "contentinfo");
127            LOG.error(message.key(), e);
128            throw new JspException(message.key(pageContext.getRequest().getLocale()));
129        }
130
131        return SKIP_BODY;
132    }
133
134    /**
135     * @see org.opencms.util.I_CmsMacroResolver#getMacroValue(java.lang.String)
136     */
137    public String getMacroValue(String macro) {
138
139        int dotIndex = macro.indexOf('.');
140        String beanName = null;
141
142        if ((dotIndex > 1) && (dotIndex < (macro.length() - 1))) {
143            beanName = macro.substring(0, dotIndex);
144        } else {
145            return null;
146        }
147
148        String variableName = macro.substring(dotIndex + 1, macro.length());
149
150        if (CmsStringUtil.isEmpty(beanName) || CmsStringUtil.isEmpty(variableName)) {
151            return null;
152        }
153
154        // extract bean from page context
155        CmsContentInfoBean bean;
156        int scope = pageContext.getAttributesScope(beanName);
157        try {
158            bean = (CmsContentInfoBean)pageContext.getAttribute(beanName, scope);
159        } catch (ClassCastException e) {
160            // attribute exists but is not of required class
161            return null;
162        }
163
164        if (bean == null) {
165            return null;
166        }
167
168        switch (KEYS_LIST.indexOf(variableName)) {
169            case 0:
170                // "resultSize"
171                return Integer.toString(bean.getResultSize());
172            case 1:
173                // "resultIndex"
174                return Integer.toString(bean.getResultIndex());
175            case 2:
176                // "pageCount"
177                return Integer.toString(bean.getPageCount());
178            case 3:
179                // "pageIndex"
180                return Integer.toString(bean.getPageIndex());
181            case 4:
182                // "pageSize"
183                return Integer.toString(bean.getPageSize());
184            case 5:
185                // pageNavStartIndex
186                return Integer.toString(bean.getPageNavStartIndex());
187            case 6:
188                // pageNavEndIndex
189                return Integer.toString(bean.getPageNavEndIndex());
190            case 7:
191                // pageNavLength
192                return Integer.toString(bean.getPageNavLength());
193            default:
194                // unknown value
195                return null;
196        }
197    }
198
199    /**
200     * Returns the name of the content info's value that should be printed out.<p>
201     *
202     * @return the name of the content info's value that should be printed out
203     */
204    public String getValue() {
205
206        return m_value;
207    }
208
209    /**
210     * @see org.opencms.util.I_CmsMacroResolver#isKeepEmptyMacros()
211     */
212    public boolean isKeepEmptyMacros() {
213
214        return true;
215    }
216
217    /**
218     * @see javax.servlet.jsp.tagext.Tag#release()
219     */
220    @Override
221    public void release() {
222
223        m_value = null;
224        super.release();
225    }
226
227    /**
228     * @see org.opencms.util.I_CmsMacroResolver#resolveMacros(java.lang.String)
229     */
230    public String resolveMacros(String input) {
231
232        return CmsMacroResolver.resolveMacros(input, this);
233    }
234
235    /**
236     * Sets the name of the content info's value that should be printed out.<p>
237     *
238     * @param value the name of the content info's value that should be printed out
239     */
240    public void setValue(String value) {
241
242        m_value = value;
243    }
244
245    /**
246     * Stores the container's content info bean in the page context.<p>
247     *
248     * @param container the parent container
249     */
250    protected void storeContentInfoBean(CmsJspTagResourceLoad container) {
251
252        CmsContentInfoBean contentInfoBean = container.getContentInfoBean();
253
254        contentInfoBean.setPageSize(container.getContentInfoBean().getPageSize());
255        contentInfoBean.setPageIndex(container.getContentInfoBean().getPageIndex());
256        contentInfoBean.setResultSize(container.getContentInfoBean().getResultSize());
257
258        storeAttribute(contentInfoBean);
259    }
260}