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, 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.file.CmsResourceFilter;
032import org.opencms.flex.CmsFlexController;
033import org.opencms.gwt.shared.CmsGwtConstants;
034import org.opencms.gwt.shared.I_CmsAutoBeanFactory;
035import org.opencms.gwt.shared.I_CmsListAddMetadata;
036import org.opencms.i18n.CmsEncoder;
037import org.opencms.jsp.search.config.parser.simplesearch.CmsConfigurationBean;
038import org.opencms.jsp.util.CmsJspStandardContextBean;
039import org.opencms.main.CmsException;
040import org.opencms.main.CmsLog;
041import org.opencms.util.CmsStringUtil;
042
043import java.io.IOException;
044import java.util.ArrayList;
045import java.util.Arrays;
046import java.util.Collection;
047import java.util.List;
048import java.util.stream.Collectors;
049
050import javax.servlet.jsp.JspException;
051import javax.servlet.jsp.PageContext;
052import javax.servlet.jsp.tagext.SimpleTagSupport;
053
054import org.apache.commons.logging.Log;
055
056import com.google.web.bindery.autobean.shared.AutoBean;
057import com.google.web.bindery.autobean.shared.AutoBeanCodex;
058import com.google.web.bindery.autobean.vm.AutoBeanFactorySource;
059
060/**
061 * Generates a special HTML element which enables the 'create list element' dialog for a set of types when used in a formatter.
062 */
063public class CmsJspTagEnableListAdd extends SimpleTagSupport {
064
065    /** The log object for this class. */
066    private static final Log LOG = CmsLog.getLog(CmsJspTagEnableListAdd.class);
067
068    /** The post-create handler. */
069    private String m_postCreateHandler;
070
071    /** The resource type names. */
072    private List<String> m_types = new ArrayList<>();
073
074    /** The upload folder. */
075    private String m_uploadFolder;
076
077    /**
078     * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
079     */
080    @Override
081    public void doTag() throws IOException {
082
083        // in practice, the JSP context will always be a page context
084        PageContext pageContext = (PageContext)getJspContext();
085        CmsFlexController controller = CmsFlexController.getController(pageContext.getRequest());
086        CmsObject cms = controller.getCmsObject();
087        CmsJspStandardContextBean standardContext = CmsJspStandardContextBean.getInstance(pageContext.getRequest());
088        // the list add information is only used by the page editor
089        if (standardContext.getIsEditMode()) {
090            // use autobean factory to create the necessary JSON
091            I_CmsAutoBeanFactory beanFactory = AutoBeanFactorySource.create(I_CmsAutoBeanFactory.class);
092            AutoBean<I_CmsListAddMetadata> bean = beanFactory.createListAddMetadata();
093            bean.as().setTypes(m_types);
094            bean.as().setPostCreateHandler(m_postCreateHandler);
095            if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_uploadFolder) && !"none".equals(m_uploadFolder)) {
096                try {
097                    // don't bother with enabling uploads if the upload folder doesn't exist
098                    cms.readResource(m_uploadFolder, CmsResourceFilter.IGNORE_EXPIRATION);
099                    bean.as().setUploadFolder(m_uploadFolder);
100                } catch (CmsException e) {
101                    LOG.warn(e.getLocalizedMessage(), e);
102                }
103            }
104            String jsonData = AutoBeanCodex.encode(bean).getPayload();
105            StringBuilder buffer = new StringBuilder();
106            buffer.append("<div style='display: none !important;' " + CmsGwtConstants.ATTR_DATA_LISTADD + "='");
107            buffer.append(CmsEncoder.escapeXml(jsonData));
108            buffer.append("'></div>");
109            pageContext.getOut().println(buffer.toString());
110        }
111    }
112
113    /**
114     * Sets the post-create handler to use after creating new elements.
115     *
116     * @param postCreateHandler the post-create handler
117     */
118    public void setPostCreateHandler(String postCreateHandler) {
119
120        m_postCreateHandler = postCreateHandler;
121    }
122
123    /**
124     * Sets the types to offer to create.
125     *
126     * @param typesObj either a string containing type names separated by commas, or a collection of objects whose toString() methods return resource type names.
127     *
128     * @throws JspException if something goes wrong
129     */
130    public void setTypes(Object typesObj) throws JspException {
131
132        if (typesObj instanceof String) {
133            String[] tokens = ((String)typesObj).split(",");
134            setTypes(Arrays.asList(tokens));
135        } else if (typesObj instanceof Collection) {
136            Collection<?> types = (Collection<?>)typesObj;
137            // list elements may be value wrappers - convert to string
138            // list elements may be display type strings - convert to resource type names
139            m_types = types.stream().map(
140                type -> CmsConfigurationBean.getResourceTypeForDisplayType("" + type).trim()).distinct().collect(
141                    Collectors.toList());
142        } else {
143            throw new JspException("Invalid type for types attribute of enable-list-add tag: " + typesObj);
144        }
145    }
146
147    /**
148     * Sets the upload folder.
149     *
150     * @param uploadFolder the upload folder
151     */
152    public void setUploadFolder(String uploadFolder) {
153
154        m_uploadFolder = uploadFolder;
155    }
156
157}