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.widgets;
029
030import org.opencms.ade.configuration.CmsADEConfigData;
031import org.opencms.ade.configuration.CmsResourceTypeConfig;
032import org.opencms.ade.galleries.shared.CmsGalleryTabConfiguration;
033import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants;
034import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryMode;
035import org.opencms.file.CmsObject;
036import org.opencms.file.CmsResource;
037import org.opencms.file.types.CmsResourceTypeBinary;
038import org.opencms.file.types.CmsResourceTypeImage;
039import org.opencms.file.types.CmsResourceTypePlain;
040import org.opencms.file.types.CmsResourceTypeXmlContainerPage;
041import org.opencms.i18n.CmsMessages;
042import org.opencms.json.JSONException;
043import org.opencms.json.JSONObject;
044import org.opencms.loader.CmsLoaderException;
045import org.opencms.main.CmsLog;
046import org.opencms.main.OpenCms;
047import org.opencms.util.CmsMacroResolver;
048import org.opencms.util.CmsStringUtil;
049import org.opencms.workplace.CmsWorkplace;
050import org.opencms.xml.content.I_CmsXmlContentHandler.DisplayType;
051import org.opencms.xml.types.A_CmsXmlContentValue;
052
053import java.util.Arrays;
054import java.util.List;
055import java.util.Locale;
056import java.util.Set;
057
058import org.apache.commons.collections.Factory;
059import org.apache.commons.logging.Log;
060
061import com.google.common.base.Objects;
062
063/**
064 * Provides a OpenCms VFS file selection widget, for use on a widget dialog.<p>
065 *
066 * @since 6.0.0
067 */
068public class CmsVfsFileWidget extends A_CmsWidget implements I_CmsADEWidget {
069
070    /** Macro resolver factory to get the default searchable types. */
071    protected class SearchTypesFactory implements Factory {
072
073        /** The CMS context. */
074        private CmsObject m_cms;
075
076        /** The resource. */
077        private CmsResource m_resource;
078
079        /**
080         * Constructor.<p>
081         *
082         * @param cms the CMS context
083         * @param resource the resource
084         */
085        public SearchTypesFactory(CmsObject cms, CmsResource resource) {
086
087            m_cms = cms;
088            m_resource = resource;
089        }
090
091        /**
092         * @see org.apache.commons.collections.Factory#create()
093         */
094        public Object create() {
095
096            return getDefaultSearchTypes(m_cms, m_resource);
097        }
098    }
099
100    /** Configuration parameter to set the flag to include files in popup resource tree. */
101    public static final String CONFIGURATION_EXCLUDEFILES = "excludefiles";
102
103    /** Configuration parameter to restrict the widget to gallery selection only. */
104    public static final String CONFIGURATION_GALLERYSELECT = "galleryselect";
105
106    /** Configuration parameter to set the flag to show the site selector in popup resource tree. */
107    public static final String CONFIGURATION_HIDESITESELECTOR = "hidesiteselector";
108
109    /** Configuration parameter to set the flag to include files in popup resource tree. */
110    public static final String CONFIGURATION_INCLUDEFILES = "includefiles";
111
112    /** Configuration parameter to prevent the project awareness flag in the popup resource tree. */
113    public static final String CONFIGURATION_NOTPROJECTAWARE = "notprojectaware";
114
115    /** Configuration parameter to set the project awareness flag in the popup resource tree. */
116    public static final String CONFIGURATION_PROJECTAWARE = "projectaware";
117
118    /** Configuration parameter to set search types of the gallery widget. */
119    public static final String CONFIGURATION_SEARCHTYPES = "searchtypes";
120
121    /** Configuration parameter to set the selectable types of the gallery widget. */
122    public static final String CONFIGURATION_SELECTABLETYPES = "selectabletypes";
123
124    /** Configuration parameter to set the flag to show the site selector in popup resource tree. */
125    public static final String CONFIGURATION_SHOWSITESELECTOR = "showsiteselector";
126
127    /** Configuration parameter to set start folder. */
128    public static final String CONFIGURATION_STARTFOLDER = "startfolder";
129
130    /** Configuration parameter to set start site of the popup resource tree. */
131    public static final String CONFIGURATION_STARTSITE = "startsite";
132
133    /** The default search types macro name. */
134    public static final String DEFAULT_SEARCH_TYPES_MACRO = "defaultSearchTypes";
135
136    /** The logger instance for this class. */
137    private static final Log LOG = CmsLog.getLog(CmsVfsFileWidget.class);
138
139    /** Flag which, when set, restricts the user to select only galleries or folders. */
140    private boolean m_gallerySelect;
141
142    /** Flag to determine if files should be shown in popup window. */
143    private boolean m_includeFiles;
144
145    /** Flag to determine project awareness, ie. if resources outside of the current project should be displayed as normal. */
146    private boolean m_projectAware;
147
148    /** The type shown in the gallery types tab. */
149    private String m_searchTypes;
150
151    /** The types that may be selected through the gallery widget. */
152    private String m_selectableTypes;
153
154    /** Flag to determine if the site selector should be shown in popup window. */
155    private boolean m_showSiteSelector;
156
157    /** The start folder. */
158    private String m_startFolder;
159
160    /** The start site used in the popup window. */
161    private String m_startSite;
162
163    /**
164     * Creates a new vfs file widget.<p>
165     */
166    public CmsVfsFileWidget() {
167
168        // empty constructor is required for class registration
169        this("");
170    }
171
172    /**
173     * Creates a new vfs file widget with the parameters to configure the popup tree window behavior.<p>
174     *
175     * @param showSiteSelector true if the site selector should be shown in the popup window
176     * @param startSite the start site root for the popup window
177     */
178    public CmsVfsFileWidget(boolean showSiteSelector, String startSite) {
179
180        this(showSiteSelector, startSite, true);
181    }
182
183    /**
184     * Creates a new vfs file widget with the parameters to configure the popup tree window behavior.<p>
185     *
186     * @param showSiteSelector true if the site selector should be shown in the popup window
187     * @param startSite the start site root for the popup window
188     * @param includeFiles true if files should be shown in the popup window
189     */
190    public CmsVfsFileWidget(boolean showSiteSelector, String startSite, boolean includeFiles) {
191
192        this(showSiteSelector, startSite, includeFiles, true);
193    }
194
195    /**
196     * Creates a new vfs file widget with the parameters to configure the popup tree window behavior.<p>
197     *
198     * @param showSiteSelector true if the site selector should be shown in the popup window
199     * @param startSite the start site root for the popup window
200     * @param includeFiles <code>true</code> if files should be shown in the popup window
201     * @param projectAware <code>true</code> if resources outside of the current project should be displayed as normal
202     */
203    public CmsVfsFileWidget(boolean showSiteSelector, String startSite, boolean includeFiles, boolean projectAware) {
204
205        m_showSiteSelector = showSiteSelector;
206        m_startSite = startSite;
207        m_includeFiles = includeFiles;
208        m_projectAware = projectAware;
209    }
210
211    /**
212     * Creates a new vfs file widget with the given configuration.<p>
213     *
214     * @param configuration the configuration to use
215     */
216    public CmsVfsFileWidget(String configuration) {
217
218        super(configuration);
219    }
220
221    /**
222     * Returns a comma separated list of the default search type names.<p>
223     *
224     * @param cms the CMS context
225     * @param resource the edited resource
226     *
227     * @return a comma separated list of the default search type names
228     */
229    public static String getDefaultSearchTypes(CmsObject cms, CmsResource resource) {
230
231        StringBuffer result = new StringBuffer();
232        String referenceSitePath = cms.getSitePath(resource);
233        String configPath;
234        if (resource == null) {
235            // not sure if this can ever happen?
236            configPath = cms.addSiteRoot(cms.getRequestContext().getUri());
237        } else {
238            configPath = resource.getRootPath();
239        }
240        CmsADEConfigData config = OpenCms.getADEManager().lookupConfiguration(cms, configPath);
241        Set<String> detailPageTypes = OpenCms.getADEManager().getDetailPageTypes(cms);
242        for (CmsResourceTypeConfig typeConfig : config.getResourceTypes()) {
243            String typeName = typeConfig.getTypeName();
244            if (!detailPageTypes.contains(typeName)) {
245                continue;
246            }
247            if (typeConfig.checkViewable(cms, referenceSitePath)) {
248                result.append(typeName).append(",");
249            }
250        }
251        result.append(CmsResourceTypeXmlContainerPage.getStaticTypeName()).append(",");
252        result.append(CmsResourceTypeBinary.getStaticTypeName()).append(",");
253        result.append(CmsResourceTypeImage.getStaticTypeName()).append(",");
254        result.append(CmsResourceTypePlain.getStaticTypeName());
255        return result.toString();
256    }
257
258    /**
259     * @see org.opencms.widgets.A_CmsWidget#getConfiguration()
260     */
261    @Override
262    public String getConfiguration() {
263
264        StringBuffer result = new StringBuffer(8);
265
266        // append site selector flag to configuration
267        if (m_showSiteSelector) {
268            result.append(CONFIGURATION_SHOWSITESELECTOR);
269        } else {
270            result.append(CONFIGURATION_HIDESITESELECTOR);
271        }
272
273        // append start site to configuration
274        if (m_startSite != null) {
275            result.append("|");
276            result.append(CONFIGURATION_STARTSITE);
277            result.append("=");
278            result.append(m_startSite);
279        }
280
281        // append flag for including files
282        result.append("|");
283        if (m_includeFiles) {
284            result.append(CONFIGURATION_INCLUDEFILES);
285        } else {
286            result.append(CONFIGURATION_EXCLUDEFILES);
287        }
288
289        if (m_gallerySelect) {
290            result.append("|");
291            result.append(CONFIGURATION_GALLERYSELECT);
292        }
293
294        // append flag for project awareness
295        result.append("|");
296        if (m_projectAware) {
297            result.append(CONFIGURATION_PROJECTAWARE);
298        } else {
299            result.append(CONFIGURATION_NOTPROJECTAWARE);
300        }
301        if (m_searchTypes != null) {
302            result.append("|");
303            result.append(CONFIGURATION_SEARCHTYPES);
304            result.append("=");
305            result.append(m_searchTypes);
306        }
307        if (m_selectableTypes != null) {
308            result.append("|");
309            result.append(CONFIGURATION_SELECTABLETYPES);
310            result.append("=");
311            result.append(m_selectableTypes);
312        }
313        return result.toString();
314    }
315
316    /**
317     * @see org.opencms.widgets.I_CmsADEWidget#getConfiguration(org.opencms.file.CmsObject, org.opencms.xml.types.A_CmsXmlContentValue, org.opencms.i18n.CmsMessages, org.opencms.file.CmsResource, java.util.Locale)
318     */
319    public String getConfiguration(
320        CmsObject cms,
321        A_CmsXmlContentValue schemaType,
322        CmsMessages messages,
323        CmsResource resource,
324        Locale contentLocale) {
325
326        JSONObject config = getJsonConfig(cms, schemaType, messages, resource, contentLocale);
327        return config.toString();
328    }
329
330    /**
331     * @see org.opencms.widgets.I_CmsADEWidget#getCssResourceLinks(org.opencms.file.CmsObject)
332     */
333    public List<String> getCssResourceLinks(CmsObject cms) {
334
335        return null;
336    }
337
338    /**
339     * @see org.opencms.widgets.I_CmsADEWidget#getDefaultDisplayType()
340     */
341    public DisplayType getDefaultDisplayType() {
342
343        return DisplayType.wide;
344    }
345
346    /**
347     * @see org.opencms.widgets.I_CmsWidget#getDialogIncludes(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
348     */
349    @Override
350    public String getDialogIncludes(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
351
352        StringBuffer result = new StringBuffer(16);
353        result.append(getJSIncludeFile(CmsWorkplace.getSkinUri() + "commons/tree.js"));
354        result.append("\n");
355        result.append(getJSIncludeFile(CmsWorkplace.getSkinUri() + "components/widgets/fileselector.js"));
356        return result.toString();
357    }
358
359    /**
360     * @see org.opencms.widgets.I_CmsWidget#getDialogInitCall(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
361     */
362    @Override
363    public String getDialogInitCall(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
364
365        return "\tinitVfsFileSelector();\n";
366    }
367
368    /**
369     * @see org.opencms.widgets.I_CmsWidget#getDialogInitMethod(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog)
370     */
371    @Override
372    public String getDialogInitMethod(CmsObject cms, I_CmsWidgetDialog widgetDialog) {
373
374        StringBuffer result = new StringBuffer(16);
375        result.append("function initVfsFileSelector() {\n");
376        //initialize tree javascript, does parts of <code>CmsTree.initTree(CmsObject, encoding, skinuri);</code>
377        result.append("\tinitResources(\"");
378        result.append(OpenCms.getWorkplaceManager().getEncoding());
379        result.append("\", \"");
380        result.append(CmsWorkplace.VFS_PATH_WORKPLACE);
381        result.append("\", \"");
382        result.append(CmsWorkplace.getSkinUri());
383        result.append("\", \"");
384        result.append(OpenCms.getSystemInfo().getOpenCmsContext());
385        result.append("\");\n");
386        result.append("}\n");
387        return result.toString();
388    }
389
390    /**
391     * @see org.opencms.widgets.I_CmsWidget#getDialogWidget(org.opencms.file.CmsObject, org.opencms.widgets.I_CmsWidgetDialog, org.opencms.widgets.I_CmsWidgetParameter)
392     */
393    public String getDialogWidget(CmsObject cms, I_CmsWidgetDialog widgetDialog, I_CmsWidgetParameter param) {
394
395        String id = param.getId();
396        StringBuffer result = new StringBuffer(128);
397
398        result.append("<td class=\"xmlTd\">");
399        result.append(
400            "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" class=\"maxwidth\"><tr><td style=\"width: 100%;\">");
401        result.append("<input style=\"width: 99%;\" class=\"xmlInput");
402        if (param.hasError()) {
403            result.append(" xmlInputError");
404        }
405        result.append("\" value=\"");
406        result.append(param.getStringValue(cms));
407        result.append("\" name=\"");
408        result.append(id);
409        result.append("\" id=\"");
410        result.append(id);
411        result.append("\"></td>");
412        result.append(widgetDialog.dialogHorizontalSpacer(10));
413        result.append(
414            "<td><table class=\"editorbuttonbackground\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>");
415
416        StringBuffer buttonJs = new StringBuffer(8);
417        buttonJs.append("javascript:openTreeWin('EDITOR',  '");
418        buttonJs.append(id);
419        buttonJs.append("', document, ");
420        buttonJs.append(m_showSiteSelector);
421        buttonJs.append(", '");
422        if (m_startSite != null) {
423            buttonJs.append(m_startSite);
424        } else {
425            buttonJs.append(cms.getRequestContext().getSiteRoot());
426        }
427        buttonJs.append("', ");
428        // include files
429        buttonJs.append(m_includeFiles);
430        // project awareness
431        buttonJs.append(", ");
432        buttonJs.append(m_projectAware);
433        buttonJs.append(");return false;");
434
435        result.append(
436            widgetDialog.button(
437                buttonJs.toString(),
438                null,
439                "folder",
440                org.opencms.workplace.Messages.GUI_DIALOG_BUTTON_SEARCH_0,
441                widgetDialog.getButtonStyle()));
442        result.append("</tr></table>");
443        result.append("</td></tr></table>");
444
445        result.append("</td>");
446
447        return result.toString();
448    }
449
450    /**
451     * @see org.opencms.widgets.I_CmsADEWidget#getInitCall()
452     */
453    public String getInitCall() {
454
455        return null;
456    }
457
458    /**
459     * @see org.opencms.widgets.I_CmsADEWidget#getJavaScriptResourceLinks(org.opencms.file.CmsObject)
460     */
461    public List<String> getJavaScriptResourceLinks(CmsObject cms) {
462
463        return null;
464    }
465
466    /**
467     * Returns the start site root shown by the widget when first displayed.<p>
468     *
469     * If <code>null</code> is returned, the dialog will display the current site of
470     * the current user.<p>
471     *
472     * @return the start site root shown by the widget when first displayed
473     */
474    public String getStartSite() {
475
476        return m_startSite;
477    }
478
479    /**
480     * @see org.opencms.widgets.I_CmsADEWidget#getWidgetName()
481     */
482    public String getWidgetName() {
483
484        return CmsVfsFileWidget.class.getName();
485    }
486
487    /**
488     * @see org.opencms.widgets.I_CmsADEWidget#isInternal()
489     */
490    public boolean isInternal() {
491
492        return true;
493    }
494
495    /**
496     * Returns <code>true</code> if the site selector is shown.<p>
497     *
498     * The default is <code>true</code>.<p>
499     *
500     * @return <code>true</code> if the site selector is shown
501     */
502    public boolean isShowingSiteSelector() {
503
504        return m_showSiteSelector;
505    }
506
507    /**
508     * @see org.opencms.widgets.I_CmsWidget#newInstance()
509     */
510    public I_CmsWidget newInstance() {
511
512        return new CmsVfsFileWidget(getConfiguration());
513    }
514
515    /**
516     * @see org.opencms.widgets.A_CmsWidget#setConfiguration(java.lang.String)
517     */
518    @Override
519    public void setConfiguration(String configuration) {
520
521        m_showSiteSelector = true;
522        m_includeFiles = true;
523        m_projectAware = true;
524
525        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration)) {
526            if (configuration.contains(CONFIGURATION_HIDESITESELECTOR)) {
527                // site selector should be hidden
528                m_showSiteSelector = false;
529            }
530            int siteIndex = configuration.indexOf(CONFIGURATION_STARTSITE);
531            if (siteIndex != -1) {
532                // start site is given
533                String site = configuration.substring(siteIndex + CONFIGURATION_STARTSITE.length() + 1);
534                if (site.indexOf('|') != -1) {
535                    // cut eventual following configuration values
536                    site = site.substring(0, site.indexOf('|'));
537                }
538                m_startSite = site;
539            }
540            if (configuration.contains(CONFIGURATION_EXCLUDEFILES)) {
541                // files should not be included
542                m_includeFiles = false;
543            }
544            if (configuration.contains(CONFIGURATION_GALLERYSELECT)) {
545                m_gallerySelect = true;
546            }
547
548            if (configuration.contains(CONFIGURATION_NOTPROJECTAWARE)) {
549                // resources outside of the current project should not be disabled
550                m_projectAware = false;
551            }
552            int searchTypesIndex = configuration.indexOf(CONFIGURATION_SEARCHTYPES);
553            if (searchTypesIndex != -1) {
554                String searchTypes = configuration.substring(searchTypesIndex + CONFIGURATION_SEARCHTYPES.length() + 1);
555                if (searchTypes.contains("|")) {
556                    m_searchTypes = searchTypes.substring(0, searchTypes.indexOf("|"));
557                } else {
558                    m_searchTypes = searchTypes;
559                }
560            }
561            int selectableTypesIndex = configuration.indexOf(CONFIGURATION_SELECTABLETYPES);
562            if (selectableTypesIndex != -1) {
563                String selectableTypes = configuration.substring(
564                    selectableTypesIndex + CONFIGURATION_SELECTABLETYPES.length() + 1);
565                if (selectableTypes.contains("|")) {
566                    m_selectableTypes = selectableTypes.substring(0, selectableTypes.indexOf("|"));
567                } else {
568                    m_selectableTypes = selectableTypes;
569                }
570            }
571            int startFolderIndex = configuration.indexOf(CONFIGURATION_STARTFOLDER);
572            if (startFolderIndex != -1) {
573                String startFolder = configuration.substring(startFolderIndex + CONFIGURATION_STARTFOLDER.length() + 1);
574                if (startFolder.contains("|")) {
575                    m_startFolder = startFolder.substring(0, startFolder.indexOf("|"));
576                } else {
577                    m_startFolder = startFolder;
578                }
579            }
580        }
581        super.setConfiguration(configuration);
582    }
583
584    /**
585     * Gets the JSON configuration.<p>
586     *
587     * @param cms the current CMS context
588     * @param schemaType the schema type
589     * @param messages the messages
590     * @param resource the content resource
591     * @param contentLocale the content locale
592     *
593     * @return the JSON configuration object
594     */
595    protected JSONObject getJsonConfig(
596        CmsObject cms,
597        A_CmsXmlContentValue schemaType,
598        CmsMessages messages,
599        CmsResource resource,
600        Locale contentLocale) {
601
602        JSONObject config = new JSONObject();
603        try {
604            config.put(I_CmsGalleryProviderConstants.CONFIG_START_SITE, m_startSite);
605
606            config.put(I_CmsGalleryProviderConstants.CONFIG_SHOW_SITE_SELECTOR, m_showSiteSelector);
607            config.put(I_CmsGalleryProviderConstants.CONFIG_REFERENCE_PATH, cms.getSitePath(resource));
608            config.put(I_CmsGalleryProviderConstants.CONFIG_LOCALE, contentLocale.toString());
609            config.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_MODE, GalleryMode.widget.name());
610            config.put(I_CmsGalleryProviderConstants.CONFIG_GALLERY_STORAGE_PREFIX, "linkselect");
611            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_selectableTypes)) {
612                config.put(I_CmsGalleryProviderConstants.CONFIG_RESOURCE_TYPES, m_selectableTypes.trim());
613            }
614            String tabConfig = null;
615            m_includeFiles = m_includeFiles
616                && (CmsStringUtil.isEmptyOrWhitespaceOnly(m_selectableTypes)
617                    || !isOnlyFolders(m_selectableTypes.trim()));
618            if (m_includeFiles) {
619                tabConfig = CmsGalleryTabConfiguration.TC_SELECT_ALL;
620                if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_selectableTypes)
621                    && !Arrays.asList(m_selectableTypes.split("[, ]+")).contains(
622                        CmsResourceTypeXmlContainerPage.getStaticTypeName())) {
623                    tabConfig = CmsGalleryTabConfiguration.TC_SELECT_ALL_NO_SITEMAP;
624                }
625            } else {
626                tabConfig = CmsGalleryTabConfiguration.TC_FOLDERS;
627            }
628            config.put(I_CmsGalleryProviderConstants.CONFIG_TAB_CONFIG, tabConfig);
629            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_searchTypes)) {
630                CmsMacroResolver resolver = CmsMacroResolver.newInstance();
631                resolver.addDynamicMacro(DEFAULT_SEARCH_TYPES_MACRO, new SearchTypesFactory(cms, resource));
632                String searchTypes = resolver.resolveMacros(m_searchTypes.trim());
633                config.put(I_CmsGalleryProviderConstants.CONFIG_SEARCH_TYPES, searchTypes);
634            } else if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_selectableTypes)) {
635                config.put(I_CmsGalleryProviderConstants.CONFIG_SEARCH_TYPES, getDefaultSearchTypes(cms, resource));
636            }
637            if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_startFolder)) {
638                config.put(I_CmsGalleryProviderConstants.CONFIG_START_FOLDER, m_startFolder);
639            }
640            String treeToken = ""
641                + Objects.hashCode(m_startSite, cms.getRequestContext().getSiteRoot(), "" + m_selectableTypes);
642            config.put(I_CmsGalleryProviderConstants.CONFIG_TREE_TOKEN, treeToken);
643
644            if (m_gallerySelect) {
645                config.put(I_CmsGalleryProviderConstants.CONFIG_GALLERIES_SELECTABLE, "true");
646                config.put(I_CmsGalleryProviderConstants.CONFIG_RESULTS_SELECTABLE, "false");
647                config.put(I_CmsGalleryProviderConstants.CONFIG_TAB_CONFIG, CmsGalleryTabConfiguration.TC_GALLERIES);
648            }
649
650        } catch (JSONException e) {
651            LOG.error(e.getLocalizedMessage(), e);
652        }
653        return config;
654    }
655
656    /**
657     * Computes the tree token, which is used to decide which preloaded tree, if any, to load for the VFS/sitemap tabs.<p>
658     *
659     * @param cms the current CMS context
660     * @param value the content value
661     * @param resource the content resource
662     * @param contentLocale the content locale
663     *
664     * @return the tree token
665     */
666    protected String getTreeToken(
667        CmsObject cms,
668        A_CmsXmlContentValue value,
669        CmsResource resource,
670        Locale contentLocale) {
671
672        return cms.getRequestContext().getSiteRoot();
673    }
674
675    /**
676     * Checks whether the given type list contains only folder types.<p>
677     *
678     * @param types the type list
679     *
680     * @return <code>true</code> if the given type list contains only folder types
681     */
682    private boolean isOnlyFolders(String types) {
683
684        boolean result = true;
685        for (String type : types.split("[, ]+")) {
686            try {
687                if (!OpenCms.getResourceManager().getResourceType(type).isFolder()) {
688                    result = false;
689                    break;
690                }
691            } catch (CmsLoaderException e) {
692                // ignore
693            }
694        }
695        return result;
696    }
697}