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.workplace.editors;
029
030import org.opencms.ade.contenteditor.CmsWidgetUtil;
031import org.opencms.file.CmsObject;
032import org.opencms.main.CmsLog;
033import org.opencms.widgets.I_CmsWidget;
034import org.opencms.widgets.Messages;
035import org.opencms.xml.content.I_CmsXmlContentValueVisitor;
036import org.opencms.xml.types.I_CmsXmlContentValue;
037
038import java.util.ArrayList;
039import java.util.HashMap;
040import java.util.List;
041import java.util.Locale;
042import java.util.Map;
043
044import org.apache.commons.logging.Log;
045
046/**
047 * Visitor implementation that collects the different widgets for all visited values and all widgets for the found values.<p>
048 *
049 * This implementation is needed when creating the html output of the xmlcontent editor
050 * {@link org.opencms.workplace.editors.CmsXmlContentEditor}.<p>
051 *
052 * @since 6.0.0
053 */
054public class CmsXmlContentWidgetVisitor implements I_CmsXmlContentValueVisitor {
055
056    /** Static reference to the log. */
057    private static final Log LOG = CmsLog.getLog(CmsXmlContentWidgetVisitor.class);
058
059    /** The locale to get the values from. */
060    private Locale m_locale;
061
062    /** The unique widgets found in the XML content.  */
063    private List<I_CmsWidget> m_uniqueWidgets;
064
065    /** The values corresponding to the found widgets. */
066    private Map<String, I_CmsXmlContentValue> m_values;
067
068    /** The CMS context. */
069    private CmsObject m_cms;
070
071    /** The widgets found in the XML content. */
072    private Map<String, I_CmsWidget> m_widgets;
073
074    /**
075     * Creates a new widget collector node visitor.<p>
076     *
077     * @param cms the CMS context
078     */
079    public CmsXmlContentWidgetVisitor(CmsObject cms) {
080
081        m_cms = cms;
082        initialize(null);
083    }
084
085    /**
086     * Creates a new widget collector node visitor.<p>
087     *
088     * @param cms the CMS context
089     * @param locale the Locale to get the widgets from
090     */
091    public CmsXmlContentWidgetVisitor(CmsObject cms, Locale locale) {
092
093        m_cms = cms;
094        initialize(locale);
095    }
096
097    /**
098     * Returns the locale to get the widgets from.<p>
099     *
100     * @return the locale to get the widgets from
101     */
102    public Locale getLocale() {
103
104        return m_locale;
105    }
106
107    /**
108     * Returns the unique widgets that were found in the content.<p>
109     *
110     * @return the unique widgets that were found in the content
111     */
112    public List<I_CmsWidget> getUniqueWidgets() {
113
114        return m_uniqueWidgets;
115    }
116
117    /**
118     * Returns all simple values that were found in the content.<p>
119     *
120     * The map key is the complete xpath of the value.<p>
121     *
122     * @return all simple values that were found in the content
123     */
124    public Map<String, I_CmsXmlContentValue> getValues() {
125
126        return m_values;
127    }
128
129    /**
130     * Returns all widgets that were found in the content.<p>
131     *
132     * The map key is the complete xpath of the corresponding value.<p>
133     *
134     * @return all widgets that were found in the content
135     */
136    public Map<String, I_CmsWidget> getWidgets() {
137
138        return m_widgets;
139    }
140
141    /**
142     * @see org.opencms.xml.content.I_CmsXmlContentValueVisitor#visit(org.opencms.xml.types.I_CmsXmlContentValue)
143     */
144    public void visit(I_CmsXmlContentValue value) {
145
146        if (LOG.isDebugEnabled()) {
147            LOG.debug(
148                org.opencms.workplace.editors.Messages.get().getBundle().key(
149                    org.opencms.workplace.editors.Messages.LOG_VISITING_1,
150                    value.getPath()));
151        }
152
153        if (value.isSimpleType()) {
154            // only visit simple values
155            boolean useLocale = m_locale != null;
156            if ((useLocale && (value.getLocale().equals(getLocale()))) || (!useLocale)) {
157                try {
158                    // get widget for value
159                    I_CmsWidget widget = CmsWidgetUtil.collectWidgetInfo(m_cms, value).getWidget();
160                    if (!m_uniqueWidgets.contains(widget)) {
161                        m_uniqueWidgets.add(widget);
162                    }
163                    m_widgets.put(value.getPath(), widget);
164                    m_values.put(value.getPath(), value);
165                    if (LOG.isDebugEnabled()) {
166                        LOG.debug(
167                            Messages.get().getBundle().key(Messages.LOG_DEBUG_WIDGETCOLLECTOR_ADD_1, value.getPath()));
168                    }
169                } catch (Exception e) {
170                    // should usually not happen
171                    if (LOG.isErrorEnabled()) {
172                        LOG.error(Messages.get().getBundle().key(Messages.ERR_WIDGETCOLLECTOR_ADD_1, value), e);
173                    }
174                }
175            }
176        }
177    }
178
179    /**
180     * Initializes the necessary members of the collector.<p>
181     *
182     * @param locale the Locale to get the widgets from
183     */
184    private void initialize(Locale locale) {
185
186        // start with a new instance of the widgets and unique widgets
187        m_widgets = new HashMap<String, I_CmsWidget>(25);
188        m_uniqueWidgets = new ArrayList<I_CmsWidget>(12);
189        m_values = new HashMap<String, I_CmsXmlContentValue>(25);
190        // store Locale to use when collecting the widgets
191        m_locale = locale;
192    }
193}