org.opencms.jsp.util.CmsJspStandardContextBean.java Source code

Java tutorial

Introduction

Here is the source code for org.opencms.jsp.util.CmsJspStandardContextBean.java

Source

/*
 * 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, 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.util;

import org.opencms.ade.configuration.CmsADEConfigData;
import org.opencms.ade.configuration.CmsFunctionReference;
import org.opencms.ade.detailpage.CmsDetailPageInfo;
import org.opencms.ade.detailpage.CmsDetailPageResourceHandler;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsRequestContext;
import org.opencms.file.CmsResource;
import org.opencms.flex.CmsFlexController;
import org.opencms.jsp.CmsJspBean;
import org.opencms.jsp.Messages;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.CmsRuntimeException;
import org.opencms.main.OpenCms;
import org.opencms.util.CmsUUID;
import org.opencms.xml.containerpage.CmsContainerBean;
import org.opencms.xml.containerpage.CmsContainerElementBean;
import org.opencms.xml.containerpage.CmsContainerPageBean;
import org.opencms.xml.containerpage.CmsDynamicFunctionBean;
import org.opencms.xml.containerpage.CmsDynamicFunctionParser;
import org.opencms.xml.content.CmsXmlContent;

import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.ServletRequest;

import org.apache.commons.logging.Log;

import com.google.common.base.Function;
import com.google.common.collect.MapMaker;

/**
 * Allows convenient access to the most important OpenCms functions on a JSP page,
 * indented to be used from a JSP with the JSTL or EL.<p>
 * 
 * This bean is available by default in the context of an OpenCms managed JSP.<p> 
 * 
 * @since 8.0
 */
public final class CmsJspStandardContextBean {

    /** The attribute name of the cms object.*/
    public static final String ATTRIBUTE_CMS_OBJECT = "__cmsObject";

    /** The attribute name of the standard JSP context bean. */
    public static final String ATTRIBUTE_NAME = "cms";

    /** The logger instance for this class. */
    protected static final Log LOG = CmsLog.getLog(CmsJspStandardContextBean.class);

    /** OpenCms user context. */
    protected CmsObject m_cms;

    /** The container the currently rendered element is part of. */
    private CmsContainerBean m_container;

    /** The current detail content resource if available. */
    private CmsResource m_detailContentResource;

    /** Flag to indicate if element was just edited. */
    private boolean m_edited;

    /** The currently rendered element. */
    private CmsContainerElementBean m_element;

    /** Cached object for the EL 'function' accessor. */
    private Object m_function;

    /** The currently displayed container page. */
    private CmsContainerPageBean m_page;

    /** The VFS content access bean. */
    private CmsJspVfsAccessBean m_vfsBean;

    /**
     * Creates an empty instance.<p>
     */
    private CmsJspStandardContextBean() {

        // NOOP
    }

    /**
     * Creates a new standard JSP context bean.
     * 
     * @param req the current servlet request
     */
    private CmsJspStandardContextBean(ServletRequest req) {

        CmsFlexController controller = CmsFlexController.getController(req);
        CmsObject cms;
        if (controller != null) {
            cms = controller.getCmsObject();
        } else {
            cms = (CmsObject) req.getAttribute(ATTRIBUTE_CMS_OBJECT);
        }
        if (cms == null) {
            // cms object unavailable - this request was not initialized properly
            throw new CmsRuntimeException(
                    Messages.get().container(Messages.ERR_MISSING_CMS_CONTROLLER_1, CmsJspBean.class.getName()));
        }
        updateCmsObject(cms);

        m_detailContentResource = CmsDetailPageResourceHandler.getDetailResource(req);
    }

    /**
     * Creates a new instance of the standard JSP context bean.<p>
     * 
     * To prevent multiple creations of the bean during a request, the OpenCms request context 
     * attributes are used to cache the created VFS access utility bean.<p>
     * 
     * @param req the current servlet request
     * 
     * @return a new instance of the standard JSP context bean
     */
    public static CmsJspStandardContextBean getInstance(ServletRequest req) {

        Object attribute = req.getAttribute(ATTRIBUTE_NAME);
        CmsJspStandardContextBean result;
        if ((attribute != null) && (attribute instanceof CmsJspStandardContextBean)) {
            result = (CmsJspStandardContextBean) attribute;
        } else {
            result = new CmsJspStandardContextBean(req);
            req.setAttribute(ATTRIBUTE_NAME, result);
        }
        return result;
    }

    /**
     * Returns a copy of this JSP context bean.<p>
     * 
     * @return a copy of this JSP context bean
     */
    public CmsJspStandardContextBean createCopy() {

        CmsJspStandardContextBean result = new CmsJspStandardContextBean();
        result.m_container = getContainer();
        if (getDetailContent() != null) {
            result.m_detailContentResource = getDetailContent().getCopy();
        }
        result.m_element = getElement();
        result.m_page = getPage();
        return result;
    }

    /**
     * Returns a caching hash specific to the element, it's properties and the current container width.<p>
     * 
     * @return the caching hash
     */
    public String elementCachingHash() {

        if ((m_element != null) && (m_container != null)) {
            return m_element.editorHash() + "w:" + m_container.getWidth() + "cName:" + m_container.getName()
                    + "cType:" + m_container.getType();
        }
        return "";
    }

    /**
     * Returns the container the currently rendered element is part of.<p>
     * 
     * @return the currently the currently rendered element is part of
     */
    public CmsContainerBean getContainer() {

        return m_container;
    }

    /**
     * Returns the current detail content, or <code>null</code> if no detail content is requested.<p>
     * 
     * @return the current detail content, or <code>null</code> if no detail content is requested.<p>
     */
    public CmsResource getDetailContent() {

        return m_detailContentResource;
    }

    /**
     * Returns the structure id of the current detail content, or <code>null</code> if no detail content is requested.<p>
     * 
     * @return the structure id of the current detail content, or <code>null</code> if no detail content is requested.<p>
     */
    public CmsUUID getDetailContentId() {

        return m_detailContentResource == null ? null : m_detailContentResource.getStructureId();
    }

    /**
     * Returns the detail content site path. Returns <code>null</code> if not available.<p>
     * 
     * @return the detail content site path
     */
    public String getDetailContentSitePath() {

        return ((m_cms == null) || (m_detailContentResource == null)) ? null
                : m_cms.getSitePath(m_detailContentResource);
    }

    /**    
     * Returns the currently rendered element.<p>
     * 
     * @return the currently rendered element
     */
    public CmsContainerElementBean getElement() {

        return m_element;
    }

    /**
     * Returns a map which allows access to dynamic function beans using the JSP EL.<p>
     * 
     * When given a key, the returned map will look up the corresponding dynamic function in the module configuration.<p>
     * 
     * @return  a map which allows access to dynamic function beans
     */
    public Object getFunction() {

        if (m_function != null) {
            return m_function;
        }
        MapMaker mm = new MapMaker();
        m_function = mm.makeComputingMap(new Function<String, Object>() {

            public Object apply(String key) {

                try {
                    CmsDynamicFunctionBean dynamicFunction = readDynamicFunctionBean(key);
                    CmsDynamicFunctionBeanWrapper wrapper = new CmsDynamicFunctionBeanWrapper(m_cms,
                            dynamicFunction);
                    return wrapper;

                } catch (CmsException e) {
                    return new CmsDynamicFunctionBeanWrapper(m_cms, null);
                }
            }
        });
        return m_function;

    }

    /**
     * Returns a lazy map which computes the detail page link as a value when given the name of a (named) dynamic function
     * as a key.<p>
     * 
     * @return a lazy map for computing function detail page links  
     */
    public Map<String, String> getFunctionDetail() {

        MapMaker mm = new MapMaker();
        return mm.makeComputingMap(new Function<String, String>() {

            public String apply(String key) {

                String detailType = CmsDetailPageInfo.FUNCTION_PREFIX + key;
                CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(m_cms,
                        m_cms.addSiteRoot(m_cms.getRequestContext().getUri()));
                List<CmsDetailPageInfo> detailPages = config.getDetailPagesForType(detailType);
                if ((detailPages == null) || (detailPages.size() == 0)) {
                    return "";
                }
                CmsDetailPageInfo mainDetailPage = detailPages.get(0);
                CmsUUID id = mainDetailPage.getId();
                CmsResource detailRes;
                try {
                    detailRes = m_cms.readResource(id);
                    return OpenCms.getLinkManager().substituteLink(m_cms, detailRes);
                } catch (CmsException e) {
                    LOG.warn(e.getLocalizedMessage(), e);
                    return "";
                }
            }
        });
    }

    /**
     * Returns a lazy map which creates a wrapper object for a dynamic function format when given an XML content
     * as a key.<p>
     * 
     * @return a lazy map for accessing function formats for a content 
     */
    public Map<CmsJspContentAccessBean, CmsDynamicFunctionFormatWrapper> getFunctionFormatFromContent() {

        MapMaker mm = new MapMaker();
        return mm.makeComputingMap(new Function<CmsJspContentAccessBean, CmsDynamicFunctionFormatWrapper>() {

            public CmsDynamicFunctionFormatWrapper apply(CmsJspContentAccessBean contentAccess) {

                CmsXmlContent content = (CmsXmlContent) (contentAccess.getRawContent());
                CmsDynamicFunctionParser parser = new CmsDynamicFunctionParser();
                CmsDynamicFunctionBean functionBean = null;
                try {
                    functionBean = parser.parseFunctionBean(m_cms, content);
                } catch (CmsException e) {
                    return new CmsDynamicFunctionFormatWrapper(m_cms, null);
                }
                String type = getContainer().getType();
                String width = getContainer().getWidth();
                int widthNum = -1;
                try {
                    widthNum = Integer.parseInt(width);
                } catch (NumberFormatException e) {
                    // NOOP 
                }
                CmsDynamicFunctionBean.Format format = functionBean.getFormatForContainer(m_cms, type, widthNum);
                CmsDynamicFunctionFormatWrapper wrapper = new CmsDynamicFunctionFormatWrapper(m_cms, format);
                return wrapper;
            }
        });

    }

    /**
     * Returns the current locale.<p>
     * 
     * @return the current locale
     */
    public Locale getLocale() {

        return getRequestContext().getLocale();
    }

    /**
     * Returns the currently displayed container page.<p>
     * 
     * @return the currently displayed container page
     */
    public CmsContainerPageBean getPage() {

        return m_page;
    }

    /**
     * Returns the request context.<p>
     * 
     * @return the request context
     */
    public CmsRequestContext getRequestContext() {

        return m_cms.getRequestContext();
    }

    /**
     * Returns the subsite path for the currently requested URI.<p>
     * 
     * @return the subsite path
     */
    public String getSubSitePath() {

        return m_cms.getRequestContext().removeSiteRoot(
                OpenCms.getADEManager().getSubSiteRoot(m_cms, m_cms.getRequestContext().getRootUri()));
    }

    /**
     * Returns an initialized VFS access bean.<p>
     * 
     * @return an initialized VFS access bean
     */
    public CmsJspVfsAccessBean getVfs() {

        if (m_vfsBean == null) {
            // create a new VVFS access bean
            m_vfsBean = CmsJspVfsAccessBean.create(m_cms);
        }
        return m_vfsBean;
    }

    /**
     * Returns the workplace locale from the current user's settings.<p>
     * 
     * @return returns the workplace locale from the current user's settings
     */
    public Locale getWorkplaceLocale() {

        return OpenCms.getWorkplaceManager().getWorkplaceLocale(m_cms);
    }

    /**
     * Checks whether a detail page is available for the container element.<p>
     * 
     * @return true if there is a detail page for the container element
     */
    public boolean isDetailPageAvailable() {

        if (m_cms == null) {
            return false;
        }
        CmsContainerElementBean element = getElement();
        if (element == null) {
            return false;
        }
        if (element.isInMemoryOnly()) {
            return false;
        }
        CmsResource res = element.getResource();
        if (res == null) {
            return false;
        }
        try {
            String detailPage = OpenCms.getADEManager().getDetailPageFinder().getDetailPage(m_cms,
                    res.getRootPath(), m_cms.getRequestContext().getUri());
            return detailPage != null;
        } catch (CmsException e) {
            LOG.warn(e.getLocalizedMessage(), e);
            return false;
        }
    }

    /**
     * Returns <code>true</code> if this is a request to a detail resource, <code>false</code> otherwise.<p>
     * 
     * Same as to check if {@link #getDetailContent()} is <code>null</code>.<p>
     * 
     * @return <code>true</code> if this is a request to a detail resource, <code>false</code> otherwise
     */
    public boolean isDetailRequest() {

        return m_detailContentResource != null;
    }

    /**
     * Returns the flag to indicate if in drag and drop mode.<p>
     *
     * @return <code>true</code> if in drag and drop mode
     */
    public boolean isEdited() {

        return m_edited;
    }

    /**
     * Sets the container the currently rendered element is part of.<p>
     *
     * @param container the container the currently rendered element is part of
     */
    public void setContainer(CmsContainerBean container) {

        m_container = container;
    }

    /**
     * Sets the flag to indicate if in drag and drop mode.<p>
     *
     * @param edited <code>true</code> if in drag and drop mode
     */
    public void setEdited(boolean edited) {

        m_edited = edited;
    }

    /**
     * Sets the currently rendered element.<p>
     *
     * @param element the currently rendered element to set
     */
    public void setElement(CmsContainerElementBean element) {

        m_element = element;
    }

    /**
     * Sets the currently displayed container page.<p>
     *
     * @param page the currently displayed container page to set
     */
    public void setPage(CmsContainerPageBean page) {

        m_page = page;
    }

    /** 
     * Updates the internally stored OpenCms user context.<p>
     * 
     * @param cms the new OpenCms user context
     */
    public void updateCmsObject(CmsObject cms) {

        try {
            m_cms = OpenCms.initCmsObject(cms);
        } catch (CmsException e) {
            // should not happen
            m_cms = cms;
        }
    }

    /**
     * Reads a dynamic function bean, given its name in the module configuration.<p>
     * 
     * @param configuredName the name of the dynamic function in the module configuration  
     * @return the dynamic function bean for the dynamic function configured under that name 
     * 
     * @throws CmsException if something goes wrong 
     */
    protected CmsDynamicFunctionBean readDynamicFunctionBean(String configuredName) throws CmsException {

        CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(m_cms,
                m_cms.addSiteRoot(m_cms.getRequestContext().getUri()));
        CmsFunctionReference functionRef = config.getFunctionReference(configuredName);
        if (functionRef == null) {
            return null;
        }
        CmsDynamicFunctionParser parser = new CmsDynamicFunctionParser();
        CmsResource functionResource = m_cms.readResource(functionRef.getStructureId());
        CmsDynamicFunctionBean result = parser.parseFunctionBean(m_cms, functionResource);
        return result;
    }

}