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.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.i18n.CmsMessages;
033import org.opencms.util.CmsMacroResolver;
034import org.opencms.util.CmsStringUtil;
035import org.opencms.workplace.CmsDialog;
036import org.opencms.xml.content.I_CmsXmlContentHandler.DisplayType;
037import org.opencms.xml.types.A_CmsXmlContentValue;
038
039import java.util.ArrayList;
040import java.util.Collections;
041import java.util.Iterator;
042import java.util.List;
043import java.util.Locale;
044
045/**
046 * Base class for select widgets.<p>
047 *
048 * @since 6.0.0
049 *
050 * @see org.opencms.widgets.CmsSelectWidgetOption
051 */
052public abstract class A_CmsSelectWidget extends A_CmsWidget implements I_CmsADEWidget {
053
054    /** Configuration parameter to set the height from the select widget in pixel. */
055    public static final String CONFIGURATION_HEIGHT = "height";
056
057    /** The select widget height in pixel. */
058    private String m_height;
059
060    /** The possible options for the select box. */
061    private List<CmsSelectWidgetOption> m_selectOptions;
062
063    /**
064     * Creates a new select widget.<p>
065     */
066    public A_CmsSelectWidget() {
067
068        // empty constructor is required for class registration
069        super();
070    }
071
072    /**
073     * Creates a select widget with the select options specified in the given configuration List.<p>
074     *
075     * The list elements must be of type <code>{@link CmsSelectWidgetOption}</code>.<p>
076     *
077     * @param configuration the configuration (possible options) for the select widget
078     *
079     * @see CmsSelectWidgetOption
080     */
081    public A_CmsSelectWidget(List<CmsSelectWidgetOption> configuration) {
082
083        super();
084        m_selectOptions = configuration;
085    }
086
087    /**
088     * Creates a select widget with the select options specified in the given configuration String.<p>
089     *
090     * Please see <code>{@link CmsSelectWidgetOption}</code> for a description of the syntax
091     * of the configuration String.<p>
092     *
093     * @param configuration the configuration (possible options) for the select widget
094     *
095     * @see CmsSelectWidgetOption
096     */
097    public A_CmsSelectWidget(String configuration) {
098
099        super(configuration);
100    }
101
102    /**
103     * Adds a new select option to this widget.<p>
104     *
105     * @param option the select option to add
106     */
107    public void addSelectOption(CmsSelectWidgetOption option) {
108
109        if (m_selectOptions == null) {
110            m_selectOptions = new ArrayList<CmsSelectWidgetOption>();
111        }
112        m_selectOptions.add(option);
113    }
114
115    /**
116     * @see org.opencms.widgets.A_CmsWidget#getConfiguration()
117     */
118    @Override
119    public String getConfiguration() {
120
121        if (super.getConfiguration() != null) {
122            return super.getConfiguration();
123        }
124        return CmsSelectWidgetOption.createConfigurationString(m_selectOptions);
125    }
126
127    /**
128     * @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)
129     */
130    public String getConfiguration(
131        CmsObject cms,
132        A_CmsXmlContentValue schemaType,
133        CmsMessages messages,
134        CmsResource resource,
135        Locale contentLocale) {
136
137        CmsDummyWidgetDialog widgetDialog = new CmsDummyWidgetDialog(messages.getLocale(), messages);
138        widgetDialog.setResource(resource);
139        List<CmsSelectWidgetOption> options = parseSelectOptions(cms, widgetDialog, schemaType);
140        String result = optionsToConfigurationString(options);
141        return result;
142    }
143
144    /**
145     * Returns a list of CSS resources required by the widget.<p>
146     *
147     * @param cms the current OpenCms context
148     *
149     * @return the required CSS resource links
150     */
151    public List<String> getCssResourceLinks(CmsObject cms) {
152
153        return null;
154    }
155
156    /**
157     * @see org.opencms.widgets.I_CmsADEWidget#getDefaultDisplayType()
158     */
159    public DisplayType getDefaultDisplayType() {
160
161        return DisplayType.singleline;
162    }
163
164    /**
165     * Returns the java script initialization call.<p>
166     *
167     * @return the java script initialization call
168     */
169    public String getInitCall() {
170
171        return null;
172    }
173
174    /**
175     * Returns a list of java script resources required by the widget.<p>
176     *
177     * @param cms the current OpenCms context
178     *
179     * @return the required java script resource links
180     */
181    public List<String> getJavaScriptResourceLinks(CmsObject cms) {
182
183        return null;
184    }
185
186    /**
187     * @see org.opencms.widgets.I_CmsADEWidget#getWidgetName()
188     */
189    public String getWidgetName() {
190
191        return A_CmsSelectWidget.class.getName();
192    }
193
194    /**
195     * Returns if this is an internal widget.<p>
196     * Only widgets belonging to the OpenCms core should be marked as internal.<p>
197     *
198     * @return <code>true</code> if this is an internal widget
199     */
200    public boolean isInternal() {
201
202        return false;
203    }
204
205    /**
206     * @see org.opencms.widgets.A_CmsWidget#setConfiguration(java.lang.String)
207     */
208    @Override
209    public void setConfiguration(String configuration) {
210
211        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(configuration)) {
212            int heightIndex = configuration.indexOf(CONFIGURATION_HEIGHT);
213            if (heightIndex != -1) {
214                // the height is set
215                String height = configuration.substring(heightIndex + CONFIGURATION_HEIGHT.length() + 1);
216                if (height.indexOf('|') != -1) {
217                    // cut eventual following configuration values
218                    height = height.substring(0, height.indexOf('|'));
219                }
220                m_height = height;
221            }
222        }
223        super.setConfiguration(configuration);
224    }
225
226    /**
227     * Gets the configured select widget height.<p>
228     *
229     * @return the configured select widget height
230     */
231    protected String getHeight() {
232
233        return m_height;
234    }
235
236    /**
237     * Gets the resource path for the given dialog.<p>
238     * @param cms TODO
239     * @param dialog the dialog
240     *
241     * @return the resource path
242     */
243    protected String getResourcePath(CmsObject cms, I_CmsWidgetDialog dialog) {
244
245        String result = null;
246        if (dialog instanceof CmsDummyWidgetDialog) {
247            result = ((CmsDummyWidgetDialog)dialog).getResource().getRootPath();
248        } else if (dialog instanceof CmsDialog) {
249            result = ((CmsDialog)dialog).getParamResource();
250            if (result != null) {
251                result = cms.getRequestContext().addSiteRoot(result);
252            }
253        }
254        return result;
255    }
256
257    /**
258     * Returns the currently selected value of the select widget.<p>
259     *
260     * If a value is found in the given parameter, this is used. Otherwise
261     * the default value of the select options are used. If there is neither a parameter value
262     * nor a default value, <code>null</code> is returned.<p>
263     *
264     * @param cms the current users OpenCms context
265     * @param param the widget parameter of this dialog
266     *
267     * @return the currently selected value of the select widget
268     */
269    protected String getSelectedValue(CmsObject cms, I_CmsWidgetParameter param) {
270
271        String paramValue = param.getStringValue(cms);
272        if (CmsStringUtil.isEmpty(paramValue)) {
273            CmsSelectWidgetOption option = CmsSelectWidgetOption.getDefaultOption(m_selectOptions);
274            if (option != null) {
275                paramValue = option.getValue();
276            }
277        }
278        return paramValue;
279    }
280
281    /**
282     * Returns the currently selected values of the select widget.<p>
283     *
284     * If a value is found in the given parameter, this is used. Otherwise
285     * the default value of the select options are used. If there is neither a parameter value
286     * nor a default value, <code>null</code> is used.<p>
287     *
288     * @param cms the current users OpenCms context
289     * @param param the widget parameter of this dialog
290     *
291     * @return a list of the currently selected values of the select widget
292     */
293    protected List<String> getSelectedValues(CmsObject cms, I_CmsWidgetParameter param) {
294
295        List<String> values = new ArrayList<String>();
296        String paramValue = param.getStringValue(cms);
297        if (CmsStringUtil.isEmpty(paramValue)) {
298            Iterator<CmsSelectWidgetOption> itOptions = CmsSelectWidgetOption.getDefaultOptions(
299                m_selectOptions).iterator();
300            while (itOptions.hasNext()) {
301                CmsSelectWidgetOption option = itOptions.next();
302                values.add(option.getValue());
303            }
304        } else {
305            values.addAll(CmsStringUtil.splitAsList(paramValue, ',', true));
306        }
307        return values;
308    }
309
310    /**
311     * Returns the list of configured select options.<p>
312     *
313     * The list elements are of type <code>{@link CmsSelectWidgetOption}</code>.<p>
314     *
315     * @return the list of select options
316     */
317    protected List<CmsSelectWidgetOption> getSelectOptions() {
318
319        return m_selectOptions;
320    }
321
322    /**
323     * Returns the list of configured select options, parsing the configuration String if required.<p>
324     *
325     * The list elements are of type <code>{@link CmsSelectWidgetOption}</code>.
326     * The configuration String is parsed only once and then stored internally.<p>
327     *
328     * @param cms the current users OpenCms context
329     * @param widgetDialog the dialog of this widget
330     * @param param the widget parameter of this dialog
331     *
332     * @return the list of select options
333     *
334     * @see CmsSelectWidgetOption
335     */
336    protected List<CmsSelectWidgetOption> parseSelectOptions(
337        CmsObject cms,
338        I_CmsWidgetDialog widgetDialog,
339        I_CmsWidgetParameter param) {
340
341        if (m_selectOptions == null) {
342            String configuration = getConfiguration();
343            if (configuration == null) {
344                // workaround: use the default value to parse the options
345                configuration = param.getDefault(cms);
346            }
347            configuration = CmsMacroResolver.resolveMacros(configuration, cms, widgetDialog.getMessages());
348            m_selectOptions = CmsSelectWidgetOption.parseOptions(configuration);
349            if (m_selectOptions == Collections.EMPTY_LIST) {
350                m_selectOptions = new ArrayList<CmsSelectWidgetOption>();
351            }
352        }
353        return m_selectOptions;
354    }
355
356    /**
357     * Sets the list of configured select options.<p>
358     *
359     * The list elements must be of type <code>{@link CmsSelectWidgetOption}</code>.<p>
360     *
361     * @param selectOptions the list of select options to set
362     */
363    protected void setSelectOptions(List<CmsSelectWidgetOption> selectOptions) {
364
365        m_selectOptions = new ArrayList<CmsSelectWidgetOption>();
366        m_selectOptions.addAll(selectOptions);
367    }
368
369    /**
370     * Converts a list of select widget options to the configuration string as expected on the client side of the widget.
371     * @param options the options to convert
372     * @return the configuration String as expected on the client side of the widget.
373     *
374     * @deprecated use {@link CmsSelectWidgetOption#createConfigurationString(List)}.
375     */
376    @Deprecated
377    String optionsToConfigurationString(final List<CmsSelectWidgetOption> options) {
378
379        return CmsSelectWidgetOption.createConfigurationString(options);
380    }
381
382}