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.ui.apps.resourcetypes;
029
030import org.opencms.configuration.CmsConfigurationException;
031import org.opencms.file.CmsObject;
032import org.opencms.file.types.CmsResourceTypeXmlContent;
033import org.opencms.file.types.I_CmsResourceType;
034import org.opencms.main.CmsException;
035import org.opencms.main.CmsLog;
036import org.opencms.main.OpenCms;
037import org.opencms.module.CmsModule;
038import org.opencms.ui.A_CmsUI;
039import org.opencms.ui.CmsVaadinUtils;
040import org.opencms.ui.FontOpenCms;
041import org.opencms.ui.apps.Messages;
042import org.opencms.ui.components.CmsBasicDialog;
043import org.opencms.ui.components.CmsResourceInfo;
044import org.opencms.ui.components.fileselect.CmsPathSelectField;
045import org.opencms.util.CmsStringUtil;
046import org.opencms.workplace.explorer.CmsExplorerTypeSettings;
047import org.opencms.workplace.explorer.CmsResourceUtil;
048
049import java.util.ArrayList;
050import java.util.Arrays;
051import java.util.List;
052
053import org.apache.commons.logging.Log;
054
055import com.google.common.collect.Lists;
056import com.vaadin.ui.Button;
057import com.vaadin.ui.Window;
058import com.vaadin.v7.data.Property.ValueChangeEvent;
059import com.vaadin.v7.data.Property.ValueChangeListener;
060import com.vaadin.v7.data.Validator;
061import com.vaadin.v7.shared.ui.label.ContentMode;
062import com.vaadin.v7.ui.CheckBox;
063import com.vaadin.v7.ui.Label;
064import com.vaadin.v7.ui.OptionGroup;
065import com.vaadin.v7.ui.TextField;
066
067/**
068 * Class for the edit resource type dialog.<p>
069 */
070@SuppressWarnings("deprecation")
071public class CmsEditResourceTypeDialog extends CmsBasicDialog {
072
073    /**
074     * Validator for the title field.<p>
075     */
076
077    class IDValidator implements Validator {
078
079        /**vaadin serial id.*/
080        private static final long serialVersionUID = 7878441125879949490L;
081
082        /**
083         * @see com.vaadin.v7.data.Validator#validate(java.lang.Object)
084         */
085        public void validate(Object value) throws InvalidValueException {
086
087            if (((String)value).isEmpty()) {
088                throw new InvalidValueException(
089                    CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_ID_0));
090            }
091            try {
092                int id = Integer.parseInt((String)value);
093
094                if (id == m_type.getTypeId()) {
095                    return;
096                }
097
098                if (!CmsResourceTypeApp.isResourceTypeIdFree(id)) {
099                    throw new InvalidValueException(
100                        CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_ID_0));
101                }
102            } catch (NumberFormatException e) {
103                throw new InvalidValueException(
104                    CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_ID_0));
105            }
106
107        }
108
109    }
110
111    /**
112     * Validator for the title field.<p>
113     */
114    class NameValidator implements Validator {
115
116        /**vaadin serial id.*/
117        private static final long serialVersionUID = 7878441125879949490L;
118
119        /**
120         * @see com.vaadin.data.Validator#validate(java.lang.Object)
121         */
122        public void validate(Object value) throws InvalidValueException {
123
124            if (((String)value).isEmpty()) {
125                throw new InvalidValueException(
126                    CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_NAME_0));
127            }
128            if (m_type.getTypeName().equals(value)) {
129                return;
130            }
131            if (!CmsResourceTypeApp.isResourceTypeNameFree((String)value)) {
132                throw new InvalidValueException(
133                    CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_NAME_0));
134            }
135        }
136    }
137
138    /**
139     * Validator for the title field.<p>
140     */
141    class ResourceValidator implements Validator {
142
143        /**vaadin serial id.*/
144        private static final long serialVersionUID = 7878441125879949490L;
145
146        /**
147         * @see com.vaadin.v7.data.Validator#validate(java.lang.Object)
148         */
149        public void validate(Object value) throws InvalidValueException {
150
151            if ((value == null) || ((String)value).isEmpty()) {
152                throw new InvalidValueException(
153                    CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_RESORUCE_0));
154            }
155
156            String resource = (String)value;
157            if (!m_cms.existsResource(resource)) {
158                throw new InvalidValueException(
159                    CmsVaadinUtils.getMessageText(Messages.GUI_RESOURCETYPE_EDIT_INVALID_RESORUCE_0));
160            }
161
162        }
163
164    }
165
166    /** Vaadin serial id.*/
167    private static final long serialVersionUID = -5966214615311043554L;
168
169    /**constant. */
170    private static final String ICON_MODE_CSS = "css";
171
172    /**constant. */
173    private static final String ICON_MODE_FILE = "file";
174
175    /** Logger instance for this class. */
176    private static final Log LOG = CmsLog.getLog(CmsEditResourceTypeDialog.class);
177
178    /** Vaadin vomponent.*/
179    private OptionGroup m_iconMode;
180
181    /** Vaadin vomponent.*/
182    private TextField m_smallIconCSS;
183
184    /** Vaadin vomponent.*/
185    private TextField m_bigIconCSS;
186
187    /** Vaadin vomponent.*/
188    private TextField m_smallIconFile;
189
190    /** Vaadin vomponent.*/
191    private TextField m_bigIconFile;
192
193    /** Resource type.*/
194    protected I_CmsResourceType m_type;
195
196    /** Vaadin vomponent.*/
197    private Label m_warningIcon;
198
199    /** Vaadin vomponent.*/
200    private Button m_ok;
201
202    /** Vaadin vomponent.*/
203    private CheckBox m_confirm;
204
205    /** Vaadin vomponent.*/
206    private Button m_cancel;
207
208    /** Vaadin vomponent.*/
209    private TextField m_typeShortName;
210
211    /** Vaadin vomponent.*/
212    private TextField m_typeName;
213
214    /** Vaadin vomponent.*/
215    private TextField m_typeDescription;
216
217    /** Vaadin vomponent.*/
218    private TextField m_typeTitle;
219
220    /** Vaadin vomponent.*/
221    private TextField m_typeID;
222
223    /** Vaadin vomponent.*/
224    private CmsPathSelectField m_schema;
225
226    /** A root CmsObject.*/
227    private CmsObject m_cms;
228
229    /**
230     * Public constructor.<p>
231     *
232     * @param window Window
233     * @param app app
234     * @param resourceType type to be edited.
235     */
236    public CmsEditResourceTypeDialog(Window window, CmsResourceTypeApp app, I_CmsResourceType resourceType) {
237
238        m_type = resourceType;
239        try {
240            m_cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
241        } catch (CmsException e1) {
242            m_cms = A_CmsUI.getCmsObject();
243        }
244        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
245        m_warningIcon.setContentMode(ContentMode.HTML);
246        m_warningIcon.setValue(FontOpenCms.WARNING.getHtml());
247        if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_type.getModuleName())) {
248            CmsModule module = OpenCms.getModuleManager().getModule(m_type.getModuleName());
249            CmsExplorerTypeSettings dummy = OpenCms.getWorkplaceManager().getExplorerTypeSetting(m_type.getTypeName());
250            for (CmsExplorerTypeSettings settings : module.getExplorerTypes()) {
251                if (dummy.equals(settings)) {
252                    CmsResourceInfo resInfo = new CmsResourceInfo(
253                        CmsVaadinUtils.getMessageText(settings.getKey()),
254                        m_type.getTypeName(),
255                        CmsResourceUtil.getBigIconResource(settings, null));
256                    displayResourceInfoDirectly(Arrays.asList(resInfo));
257                }
258            }
259        } else {
260            m_confirm.setEnabled(false);
261        }
262
263        m_ok.addClickListener(e -> submit(window, app));
264        m_cancel.addClickListener(e -> window.close());
265        setFields();
266        setVisibilityOfIconFields();
267
268        m_typeShortName.addValidator(new NameValidator());
269        m_typeID.addValidator(new IDValidator());
270
271        m_ok.setEnabled(false);
272        m_confirm.addValueChangeListener(e -> m_ok.setEnabled(m_confirm.getValue().booleanValue()));
273        m_typeShortName.setValue(m_type.getTypeName());
274        m_typeID.setValue(String.valueOf(m_type.getTypeId()));
275        if (m_type instanceof CmsResourceTypeXmlContent) {
276            CmsResourceTypeXmlContent typeXML = (CmsResourceTypeXmlContent)m_type;
277            if (CmsStringUtil.isEmptyOrWhitespaceOnly(typeXML.getSchema())) {
278                m_schema.setVisible(false);
279            } else {
280                m_schema.setValue(typeXML.getSchema());
281                m_schema.addValidator(new ResourceValidator());
282            }
283        } else {
284            m_schema.setVisible(false);
285        }
286
287        m_iconMode.addValueChangeListener(new ValueChangeListener() {
288
289            private static final long serialVersionUID = -4165180367864561412L;
290
291            public void valueChange(ValueChangeEvent event) {
292
293                setVisibilityOfIconFields();
294            }
295
296        });
297
298    }
299
300    /**
301     * Sets the visibility of the icon fields.<p>
302     */
303    protected void setVisibilityOfIconFields() {
304
305        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_type.getModuleName())) {
306            m_iconMode.setVisible(false);
307            m_smallIconCSS.setVisible(false);
308            m_smallIconFile.setVisible(false);
309            m_bigIconCSS.setVisible(false);
310            m_bigIconFile.setVisible(false);
311            return;
312        }
313
314        if (ICON_MODE_CSS.equals(m_iconMode.getValue())) {
315            m_smallIconCSS.setVisible(true);
316            m_bigIconCSS.setVisible(true);
317            m_smallIconFile.setVisible(false);
318            m_bigIconFile.setVisible(false);
319            return;
320        }
321        if (ICON_MODE_FILE.equals(m_iconMode.getValue())) {
322            m_smallIconCSS.setVisible(false);
323            m_bigIconCSS.setVisible(false);
324            m_smallIconFile.setVisible(true);
325            m_bigIconFile.setVisible(true);
326            return;
327        }
328        m_smallIconCSS.setVisible(false);
329        m_bigIconCSS.setVisible(false);
330        m_smallIconFile.setVisible(false);
331        m_bigIconFile.setVisible(false);
332    }
333
334    /**
335     * Submit changes.<p>
336     *
337     * @param window Window
338     * @param app app
339     */
340    protected void submit(Window window, CmsResourceTypeApp app) {
341
342        if (isValid()) {
343            CmsModule module = OpenCms.getModuleManager().getModule(m_type.getModuleName()).clone();
344            if (isKeepTypeCase()) {
345                saveResourceType(module);
346            } else {
347                try {
348                    changeIdNameOrSchema(module);
349                } catch (CmsConfigurationException e) {
350                    LOG.error("Unable to change resource type.", e);
351                }
352            }
353
354            try {
355                OpenCms.getModuleManager().updateModule(m_cms, module);
356                OpenCms.getResourceManager().initialize(m_cms);
357                OpenCms.getWorkplaceManager().addExplorerTypeSettings(module);
358                // re-initialize the workplace
359                OpenCms.getWorkplaceManager().initialize(m_cms);
360            } catch (CmsException e) {
361                LOG.error("Unable to save resource type", e);
362            }
363
364            window.close();
365            app.reload();
366        }
367
368    }
369
370    /**
371     * Change Id, name or schema (all require to delete old type and create new one).<p>
372     *
373     * @param module Module
374     * @throws CmsConfigurationException exception
375     */
376    private void changeIdNameOrSchema(CmsModule module) throws CmsConfigurationException {
377
378        //Remove m_type from current module (= delete type)
379        List<CmsExplorerTypeSettings> typeSettings = Lists.newArrayList(module.getExplorerTypes());
380        List<CmsExplorerTypeSettings> newTypeSettings = new ArrayList<CmsExplorerTypeSettings>();
381        for (CmsExplorerTypeSettings setting : typeSettings) {
382            if (!setting.getName().equals(m_type.getTypeName())) {
383                newTypeSettings.add(setting);
384            }
385        }
386        OpenCms.getWorkplaceManager().removeExplorerTypeSettings(module);
387
388        List<I_CmsResourceType> types = new ArrayList<I_CmsResourceType>(module.getResourceTypes());
389
390        types.remove(m_type);
391
392        //Create new type
393        CmsResourceTypeXmlContent type = new CmsResourceTypeXmlContent();
394        type.addConfigurationParameter(CmsResourceTypeXmlContent.CONFIGURATION_SCHEMA, m_schema.getValue());
395        type.setAdditionalModuleResourceType(true);
396        type.setModuleName(module.getName());
397        type.initConfiguration(
398            m_typeShortName.getValue(),
399            m_typeID.getValue(),
400            CmsResourceTypeXmlContent.class.getName());
401        types.add(type);
402
403        module.setResourceTypes(types);
404
405        // create the matching explorer type
406        CmsExplorerTypeSettings setting = new CmsExplorerTypeSettings();
407        setting.setTypeAttributes(
408            m_typeShortName.getValue(),
409            m_typeName.getValue(), //ToDo nicename
410            null,
411            null,
412            CmsNewResourceTypeDialog.ICON_SMALL_DEFAULT,
413            CmsNewResourceTypeDialog.ICON_BIG_DEFAULT,
414            CmsResourceTypeXmlContent.getStaticTypeName(),
415            null,
416            "false",
417            null,
418            null);
419        setting.setAutoSetNavigation("false");
420        setting.setAutoSetTitle("false");
421        setting.setNewResourceOrder("10");
422        setting.setAddititionalModuleExplorerType(true);
423
424        setting.setBigIcon(
425            ICON_MODE_CSS.equals(m_iconMode.getValue())
426            ? null
427            : CmsStringUtil.isEmptyOrWhitespaceOnly(m_bigIconFile.getValue()) ? null : m_bigIconFile.getValue());
428        setting.setIcon(
429            ICON_MODE_CSS.equals(m_iconMode.getValue())
430            ? null
431            : CmsStringUtil.isEmptyOrWhitespaceOnly(m_smallIconFile.getValue()) ? null : m_smallIconFile.getValue());
432        setting.setBigIconStyle(
433            ICON_MODE_CSS.equals(m_iconMode.getValue())
434            ? CmsStringUtil.isEmptyOrWhitespaceOnly(m_bigIconCSS.getValue()) ? null : m_bigIconCSS.getValue()
435            : null);
436        setting.setSmallIconStyle(
437            ICON_MODE_CSS.equals(m_iconMode.getValue())
438            ? CmsStringUtil.isEmptyOrWhitespaceOnly(m_smallIconCSS.getValue()) ? null : m_smallIconCSS.getValue()
439            : null);
440        setting.setKey(m_typeName.getValue());
441        setting.setTitleKey(m_typeTitle.getValue());
442        setting.setInfo(m_typeDescription.getValue());
443
444        newTypeSettings.add(setting);
445        module.setExplorerTypes(newTypeSettings);
446
447        OpenCms.getWorkplaceManager().addExplorerTypeSettings(module);
448
449    }
450
451    private boolean isKeepTypeCase() {
452
453        boolean res = ((Integer.parseInt(m_typeID.getValue())) == m_type.getTypeId()); //same id
454
455        res = res && m_typeShortName.getValue().equals(m_type.getTypeName()); //same name
456
457        if (m_type instanceof CmsResourceTypeXmlContent) {
458
459            res = res && ((CmsResourceTypeXmlContent)m_type).getSchema().equals(m_schema.getValue()); //same schema
460        }
461
462        return res;
463
464    }
465
466    private boolean isValid() {
467
468        return m_schema.isValid() && m_typeID.isValid() && m_typeShortName.isValid();
469    }
470
471    private void saveResourceType(CmsModule module) {
472
473        List<CmsExplorerTypeSettings> typeSettings = Lists.newArrayList(
474            OpenCms.getModuleManager().getModule(m_type.getModuleName()).getExplorerTypes());
475        for (CmsExplorerTypeSettings setting : typeSettings) {
476            if (!setting.getName().equals(m_type.getTypeName())) {
477                continue;
478            }
479            setting.setBigIcon(
480                ICON_MODE_CSS.equals(m_iconMode.getValue())
481                ? null
482                : CmsStringUtil.isEmptyOrWhitespaceOnly(m_bigIconFile.getValue()) ? null : m_bigIconFile.getValue());
483            setting.setIcon(
484                ICON_MODE_CSS.equals(m_iconMode.getValue())
485                ? null
486                : CmsStringUtil.isEmptyOrWhitespaceOnly(m_smallIconFile.getValue())
487                ? null
488                : m_smallIconFile.getValue());
489            setting.setBigIconStyle(
490                ICON_MODE_CSS.equals(m_iconMode.getValue())
491                ? CmsStringUtil.isEmptyOrWhitespaceOnly(m_bigIconCSS.getValue()) ? null : m_bigIconCSS.getValue()
492                : null);
493            setting.setSmallIconStyle(
494                ICON_MODE_CSS.equals(m_iconMode.getValue())
495                ? CmsStringUtil.isEmptyOrWhitespaceOnly(m_smallIconCSS.getValue()) ? null : m_smallIconCSS.getValue()
496                : null);
497            setting.setKey(m_typeName.getValue());
498            setting.setTitleKey(m_typeTitle.getValue());
499            setting.setInfo(m_typeDescription.getValue());
500            break;
501        }
502        module.setExplorerTypes(typeSettings);
503        OpenCms.getWorkplaceManager().addExplorerTypeSettings(module);
504    }
505
506    private void setFields() {
507
508        if (CmsStringUtil.isEmptyOrWhitespaceOnly(m_type.getModuleName())) {
509            return;
510        }
511
512        List<CmsExplorerTypeSettings> typeSettings = Lists.newArrayList(
513            OpenCms.getModuleManager().getModule(m_type.getModuleName()).getExplorerTypes());
514        for (CmsExplorerTypeSettings setting : typeSettings) {
515            if (!setting.getName().equals(m_type.getTypeName())) {
516                continue;
517            }
518            boolean cssIconStyle = setting.getBigIcon() == null;
519
520            if (cssIconStyle) {
521                m_iconMode.setValue(ICON_MODE_CSS);
522                if (setting.getBigIconStyle() == null) {
523                    m_smallIconCSS.setValue("");
524                    m_bigIconCSS.setValue("");
525                } else {
526                    m_smallIconCSS.setValue(setting.getSmallIconStyle());
527                    m_bigIconCSS.setValue(setting.getBigIconStyle());
528                }
529            } else {
530                m_iconMode.setValue(ICON_MODE_FILE);
531                m_smallIconFile.setValue(setting.getIcon());
532                m_bigIconFile.setValue(setting.getBigIcon());
533            }
534            m_typeName.setValue(setting.getKey());
535            m_typeTitle.setValue(setting.getTitleKey());
536            m_typeDescription.setValue(setting.getInfo());
537            break;
538        }
539    }
540
541}