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.ade.sitemap.client.edit;
029
030import org.opencms.ade.sitemap.client.Messages;
031import org.opencms.gwt.client.property.A_CmsPropertyEditor;
032import org.opencms.gwt.client.property.I_CmsPropertyEditorHandler;
033import org.opencms.gwt.client.ui.input.I_CmsFormWidget;
034import org.opencms.gwt.client.ui.input.I_CmsHasGhostValue;
035import org.opencms.gwt.client.ui.input.form.CmsBasicFormField;
036import org.opencms.gwt.client.ui.input.form.CmsInfoBoxFormFieldPanel;
037import org.opencms.gwt.shared.property.CmsClientProperty;
038import org.opencms.gwt.shared.property.CmsPathValue;
039import org.opencms.util.CmsStringUtil;
040import org.opencms.xml.content.CmsXmlContentProperty;
041
042import java.util.ArrayList;
043import java.util.Collections;
044import java.util.List;
045import java.util.Map;
046
047import com.google.gwt.user.client.ui.Widget;
048
049/**
050 * Sitemap entry editor class for the navigation mode.<p>
051 *
052 * @since 8.0.0
053 */
054public class CmsNavModePropertyEditor extends A_CmsPropertyEditor {
055
056    /**
057    * Creates a new instance.<p>
058    *
059    * @param propertyConfig the property configuration
060    * @param handler the entry editor handler
061    */
062    public CmsNavModePropertyEditor(
063        Map<String, CmsXmlContentProperty> propertyConfig,
064        I_CmsPropertyEditorHandler handler) {
065
066        super(propertyConfig, handler);
067    }
068
069    /**
070     * @see org.opencms.gwt.client.property.A_CmsPropertyEditor#buildFields()
071     */
072    @Override
073    public void buildFields() {
074
075        Map<String, CmsClientProperty> ownProps = m_handler.getOwnProperties();
076        Map<String, CmsClientProperty> defaultFileProps = m_handler.getDefaultFileProperties();
077        String entryId = m_handler.getId().toString();
078        String defaultFileId = toStringOrNull(m_handler.getDefaultFileId());
079        List<String> keys = new ArrayList<String>(m_propertyConfig.keySet());
080        moveToTop(keys, CmsClientProperty.PROPERTY_NAVTEXT);
081        moveToTop(keys, CmsClientProperty.PROPERTY_DESCRIPTION);
082        moveToTop(keys, CmsClientProperty.PROPERTY_TITLE);
083        for (String propName : keys) {
084            buildSimpleField(entryId, defaultFileId, ownProps, defaultFileProps, propName);
085        }
086    }
087
088    /**
089     * @see org.opencms.gwt.client.property.A_CmsPropertyEditor#setupFieldContainer()
090     */
091    @Override
092    protected void setupFieldContainer() {
093
094        m_form.setWidget(new CmsInfoBoxFormFieldPanel(m_handler.getPageInfo()));
095    }
096
097    /**
098     * Builds a single form field.<p>
099     *
100
101     * @param entryId the entry id
102     * @param defaultFileId the default file id
103     * @param ownProps the entry's own properties
104     * @param defaultFileProps the default file properties
105     * @param propName the property name
106     */
107    private void buildSimpleField(
108        String entryId,
109        String defaultFileId,
110        Map<String, CmsClientProperty> ownProps,
111        Map<String, CmsClientProperty> defaultFileProps,
112        String propName) {
113
114        CmsXmlContentProperty propDef = m_propertyConfig.get(propName);
115        CmsClientProperty fileProp = defaultFileProps == null ? null : defaultFileProps.get(propName);
116        CmsClientProperty ownProp = ownProps.get(propName);
117        CmsPathValue pathValue;
118        if ((fileProp != null) && !CmsClientProperty.isPropertyEmpty(fileProp)) {
119            pathValue = fileProp.getPathValue().prepend(defaultFileId + "/" + propName);
120        } else if (!CmsClientProperty.isPropertyEmpty(ownProp)) {
121            pathValue = ownProp.getPathValue().prepend(entryId + "/" + propName);
122        } else {
123            String targetId = null;
124            if (propDef.isPreferFolder() || (m_handler.getDefaultFileId() == null)) {
125                targetId = entryId;
126            } else {
127                targetId = m_handler.getDefaultFileId().toString();
128            }
129            pathValue = new CmsPathValue("", targetId + "/" + propName + "/" + CmsClientProperty.PATH_STRUCTURE_VALUE);
130        }
131        boolean alwaysAllowEmpty = !propName.equals(CmsClientProperty.PROPERTY_NAVTEXT);
132        //CHECK: should we really generally allow empty fields other than NavText to be empty?
133
134        CmsBasicFormField field = CmsBasicFormField.createField(
135            propDef,
136            pathValue.getPath(),
137            this,
138            Collections.<String, String> emptyMap(),
139            alwaysAllowEmpty);
140        CmsClientProperty inheritedProperty = m_handler.getInheritedProperty(propName);
141        String inherited = (inheritedProperty == null) ? null : inheritedProperty.getEffectiveValue();
142        if (inheritedProperty != null) {
143            String message = Messages.get().key(
144                Messages.GUI_PROPERTY_ORIGIN_2,
145                inheritedProperty.getOrigin(),
146                inherited);
147            ((Widget)field.getWidget()).setTitle(message);
148        }
149        I_CmsFormWidget w = field.getWidget();
150        // model binding not necessary here
151        String initialValue = pathValue.getValue();
152
153        boolean ghost = CmsStringUtil.isEmptyOrWhitespaceOnly(pathValue.getValue());
154        if (w instanceof I_CmsHasGhostValue) {
155            ((I_CmsHasGhostValue)w).setGhostValue(inherited, ghost);
156            if (ghost) {
157                initialValue = null;
158            }
159        }
160        if (ghost && (inheritedProperty != null)) {
161            String message = org.opencms.gwt.client.Messages.get().key(
162                org.opencms.gwt.client.Messages.GUI_ORIGIN_INHERITED_1,
163                inheritedProperty.getOrigin());
164            field.getLayoutData().put("info", message);
165        }
166        m_form.addField(m_form.getWidget().getDefaultGroup(), field, initialValue);
167    }
168
169    /**
170     * Moves the given property name to the top of the keys if present.<p>
171     *
172     * @param keys the list of keys
173     * @param propertyName the property name to move
174     */
175    private void moveToTop(List<String> keys, String propertyName) {
176
177        if (keys.contains(propertyName)) {
178            keys.remove(propertyName);
179            keys.add(0, propertyName);
180        }
181    }
182
183    /**
184     * Helper method which converts an object to a string and returns null if it is null.<p>
185     *
186     * @param obj the object for which to return the string
187     *
188     * @return the string representation or null
189     */
190    private String toStringOrNull(Object obj) {
191
192        return obj == null ? null : obj.toString();
193    }
194
195}