/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software GmbH, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.jsp;
import org.opencms.file.CmsResource;
import org.opencms.i18n.CmsMessageContainer;
import org.opencms.xml.CmsXmlUtils;
import org.opencms.xml.I_CmsXmlDocument;
import java.util.List;
import java.util.Locale;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
/**
* Used to loop through the element values of an XML content item.<p>
*
* @since 6.0.0
*/
public class CmsJspTagContentLoop extends TagSupport implements I_CmsXmlContentContainer {
/** Serial version UID required for safe serialization. */
private static final long serialVersionUID = 8832749526732064836L;
/** Reference to the parent 'contentload' tag. */
private transient I_CmsXmlContentContainer m_container;
/** Reference to the looped content element. */
private transient I_CmsXmlDocument m_content;
/** Name of the current element (including the index). */
private String m_currentElement;
/** Name of the content node element to show. */
private String m_element;
/** Indicates if this is the first content iteration loop. */
private boolean m_firstLoop;
/** Index of the content node element to show. */
private int m_index = -1;
/** Reference to the currently selected locale. */
private Locale m_locale;
/**
* Empty constructor, required for JSP tags.<p>
*/
public CmsJspTagContentLoop() {
super();
}
/**
* Constructor used when using <code>contentloop</code> from scriptlet code.<p>
*
* @param container the parent content container that provides the content element to loop
* @param element the element to loop in the content
*/
public CmsJspTagContentLoop(I_CmsXmlContentContainer container, String element) {
m_element = element;
init(container);
}
/**
* @see javax.servlet.jsp.tagext.TagSupport#doAfterBody()
*/
@Override
public int doAfterBody() {
if (hasMoreResources()) {
// one more element with the same name is available, loop again
return EVAL_BODY_AGAIN;
}
// no more elements with this name available, finish the loop
return SKIP_BODY;
}
/**
* @see javax.servlet.jsp.tagext.Tag#doEndTag()
*/
@Override
public int doEndTag() {
release();
return EVAL_PAGE;
}
/**
* @see javax.servlet.jsp.tagext.Tag#doStartTag()
*/
@Override
public int doStartTag() throws JspException {
// get a reference to the parent "content container" class
Tag ancestor = findAncestorWithClass(this, I_CmsXmlContentContainer.class);
if (ancestor == null) {
CmsMessageContainer errMsgContainer = Messages.get().container(Messages.ERR_PARENTLESS_TAG_1, "contentloop");
String msg = Messages.getLocalizedMessage(errMsgContainer, pageContext);
throw new JspTagException(msg);
}
I_CmsXmlContentContainer container = (I_CmsXmlContentContainer)ancestor;
// initialize the content
init(container);
if (hasMoreResources()) {
// selected element is available at last once in content
return EVAL_BODY_INCLUDE;
} else {
// no value available for the selected element name, so we skip the whole body
return SKIP_BODY;
}
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getCollectorName()
*/
public String getCollectorName() {
return m_container.getCollectorName();
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getCollectorParam()
*/
public String getCollectorParam() {
return m_container.getCollectorParam();
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getCollectorResult()
*/
public List<CmsResource> getCollectorResult() {
return m_container.getCollectorResult();
}
/**
* Returns the name of the content node element to show.<p>
*
* @return the name of the content node element to show
*/
public String getElement() {
return (m_element != null) ? m_element : "";
}
/**
* @see org.opencms.jsp.I_CmsResourceContainer#getResource()
*/
public CmsResource getResource() {
return m_content.getFile();
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getResourceName()
*/
public String getResourceName() {
return m_container.getResourceName();
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getXmlDocument()
*/
public I_CmsXmlDocument getXmlDocument() {
return m_content;
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getXmlDocumentElement()
*/
public String getXmlDocumentElement() {
return m_currentElement;
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#getXmlDocumentLocale()
*/
public Locale getXmlDocumentLocale() {
return m_locale;
}
/**
* @see org.opencms.jsp.I_CmsResourceContainer#hasMoreContent()
*/
@Deprecated
public boolean hasMoreContent() {
return hasMoreResources();
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#hasMoreResources()
*/
public boolean hasMoreResources() {
if (m_firstLoop) {
m_firstLoop = false;
} else {
m_index++;
}
if (m_content.hasValue(m_element, m_locale, m_index)) {
m_currentElement = CmsXmlUtils.createXpath(m_element, m_index + 1);
// one more element with the same name is available, loop again
return true;
} else {
// no more elements with this name available, finish the loop
return false;
}
}
/**
* @see org.opencms.jsp.I_CmsXmlContentContainer#isPreloader()
*/
public boolean isPreloader() {
return m_container.isPreloader();
}
/**
* @see javax.servlet.jsp.tagext.Tag#release()
*/
@Override
public void release() {
m_element = null;
m_currentElement = null;
m_content = null;
m_locale = null;
m_container = null;
m_index = 0;
super.release();
}
/**
* Sets the name of the content node element to show.<p>
*
* @param element the name of the content node element to show
*/
public void setElement(String element) {
m_element = element;
}
/**
* Initializes this content loop tag.<p>
*
* @param container the parent content container that provides the content element to loop
*/
protected void init(I_CmsXmlContentContainer container) {
m_container = container;
// append to parent element name (required for nested schemas)
m_element = CmsXmlUtils.concatXpath(m_container.getXmlDocumentElement(), m_element);
// get loaded content from parent <contentload> tag
m_content = m_container.getXmlDocument();
m_locale = m_container.getXmlDocumentLocale();
m_index = 0;
m_currentElement = null;
// the next loop is the first loop
m_firstLoop = true;
}
}