001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (https://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: https://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: https://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.sitemap;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsProject;
032import org.opencms.file.CmsResource;
033import org.opencms.file.CmsResourceFilter;
034import org.opencms.gwt.shared.CmsGwtConstants;
035import org.opencms.main.CmsException;
036import org.opencms.main.CmsLog;
037import org.opencms.ui.A_CmsUI;
038import org.opencms.ui.CmsVaadinUtils;
039import org.opencms.ui.I_CmsDialogContext;
040import org.opencms.ui.Messages;
041import org.opencms.ui.apps.CmsSitemapEditorConfiguration;
042import org.opencms.ui.components.CmsBasicDialog;
043import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
044import org.opencms.ui.components.CmsErrorDialog;
045import org.opencms.ui.components.CmsExternalLayout;
046import org.opencms.ui.shared.rpc.I_CmsEmbeddedDialogClientRPC;
047import org.opencms.ui.shared.rpc.I_CmsSitemapClientRpc;
048import org.opencms.ui.shared.rpc.I_CmsSitemapServerRpc;
049import org.opencms.util.CmsStringUtil;
050import org.opencms.util.CmsUUID;
051
052import java.util.ArrayList;
053import java.util.Arrays;
054import java.util.Collections;
055import java.util.List;
056
057import org.apache.commons.logging.Log;
058
059import com.vaadin.server.AbstractExtension;
060import com.vaadin.ui.Component;
061import com.vaadin.ui.UI;
062import com.vaadin.ui.Window;
063import com.vaadin.ui.Window.CloseEvent;
064import com.vaadin.ui.Window.CloseListener;
065import com.vaadin.v7.ui.VerticalLayout;
066
067/**
068 * Extension used for the Vaadin dialogs in the sitemap editor.<p>
069 */
070public class CmsSitemapExtension extends AbstractExtension implements I_CmsSitemapServerRpc {
071
072    /**
073     * Dialog context for Vaadin dialogs in the sitemap editor.<p>
074     */
075    abstract class DialogContext implements I_CmsDialogContext {
076
077        /** The context type. */
078        private ContextType m_contextType;
079
080        /** The list of resources. */
081        private List<CmsResource> m_resources;
082
083        /** The window used to display the dialog. */
084        private Window m_window;
085
086        /**
087         * Constructor.<p>
088         *
089         * @param contextType the context type
090         * @param resources the resources
091         */
092        public DialogContext(ContextType contextType, List<CmsResource> resources) {
093
094            m_contextType = contextType;
095            m_resources = resources != null ? resources : Collections.<CmsResource> emptyList();
096        }
097
098        /**
099         * Closes the dialog window.<p>
100         */
101        public void closeWindow() {
102
103            if (m_window != null) {
104                m_window.close();
105                m_window = null;
106            }
107        }
108
109        /**
110         * @see org.opencms.ui.I_CmsDialogContext#error(java.lang.Throwable)
111         */
112        @SuppressWarnings("synthetic-access")
113        public void error(Throwable error) {
114
115            closeWindow();
116            LOG.error(error.getLocalizedMessage(), error);
117            CmsErrorDialog.showErrorDialog(error, new Runnable() {
118
119                public void run() {
120
121                    // empty
122                }
123            });
124        }
125
126        /**
127         * @see org.opencms.ui.I_CmsDialogContext#finish(org.opencms.file.CmsProject, java.lang.String)
128         */
129        public void finish(CmsProject project, String siteRoot) {
130
131            throw new RuntimeException("NOT INPLEMENTED");
132
133        }
134
135        /**
136         * @see org.opencms.ui.I_CmsDialogContext#focus(org.opencms.util.CmsUUID)
137         */
138        public void focus(CmsUUID structureId) {
139
140            // does not apply
141        }
142
143        /**
144         * @see org.opencms.ui.I_CmsDialogContext#getAllStructureIdsInView()
145         */
146        public List<CmsUUID> getAllStructureIdsInView() {
147
148            return Collections.emptyList();
149        }
150
151        /**
152         * @see org.opencms.ui.I_CmsDialogContext#getAppId()
153         */
154        public String getAppId() {
155
156            return CmsSitemapEditorConfiguration.APP_ID;
157        }
158
159        /**
160         * @see org.opencms.ui.I_CmsDialogContext#getCms()
161         */
162        public CmsObject getCms() {
163
164            return A_CmsUI.getCmsObject();
165        }
166
167        /**
168         * @see org.opencms.ui.I_CmsDialogContext#getContextType()
169         */
170        public ContextType getContextType() {
171
172            return m_contextType;
173        }
174
175        /**
176         * @see org.opencms.ui.I_CmsDialogContext#getResources()
177         */
178        public List<CmsResource> getResources() {
179
180            return m_resources;
181        }
182
183        /**
184         * @see org.opencms.ui.I_CmsDialogContext#navigateTo(java.lang.String)
185         */
186        public void navigateTo(String appId) {
187
188            throw new RuntimeException("NOT IMPLEMENTED");
189        }
190
191        /**
192         * @see org.opencms.ui.I_CmsDialogContext#onViewChange()
193         */
194        public void onViewChange() {
195
196            throw new RuntimeException("NOT IMPLEMENTED");
197        }
198
199        /**
200         * @see org.opencms.ui.I_CmsDialogContext#reload()
201         */
202        public void reload() {
203
204            throw new RuntimeException("NOT IMPLEMENTED");
205        }
206
207        /**
208         * @see org.opencms.ui.I_CmsDialogContext#setWindow(com.vaadin.ui.Window)
209         */
210        public void setWindow(Window window) {
211
212            m_window = window;
213        }
214
215        /**
216         * @see org.opencms.ui.I_CmsDialogContext#start(java.lang.String, com.vaadin.ui.Component)
217         */
218        public void start(String title, Component dialog) {
219
220            start(title, dialog, DialogWidth.narrow);
221        }
222
223        /**
224         * @see org.opencms.ui.I_CmsDialogContext#start(java.lang.String, com.vaadin.ui.Component, org.opencms.ui.components.CmsBasicDialog.DialogWidth)
225         */
226        public void start(String title, Component dialog, DialogWidth width) {
227
228            if (dialog != null) {
229                m_window = CmsBasicDialog.prepareWindow(width);
230                m_window.setCaption(title);
231                m_window.setContent(dialog);
232                UI.getCurrent().addWindow(m_window);
233                m_window.addCloseListener(new CloseListener() {
234
235                    private static final long serialVersionUID = 1L;
236
237                    public void windowClose(CloseEvent e) {
238
239                        handleWindowClose();
240                    }
241                });
242                if (dialog instanceof CmsBasicDialog) {
243                    ((CmsBasicDialog)dialog).initActionHandler(m_window);
244                }
245            }
246        }
247
248        /**
249         * @see org.opencms.ui.I_CmsDialogContext#updateUserInfo()
250         */
251        public void updateUserInfo() {
252
253            // not supported
254        }
255
256        /**
257         * Returns the client RPC.<p>
258         *
259         * @return the client RPC
260         */
261        @SuppressWarnings("synthetic-access")
262        protected I_CmsEmbeddedDialogClientRPC getClientRPC() {
263
264            return getRpcProxy(I_CmsEmbeddedDialogClientRPC.class);
265        }
266
267        /**
268         * Handles the window close event.<p>
269         */
270        void handleWindowClose() {
271
272            // empty
273        }
274
275    }
276
277    /** Log instance for this class. */
278    private static final Log LOG = CmsLog.getLog(CmsSitemapExtension.class);
279
280    /** Serial version id. */
281    private static final long serialVersionUID = 1L;
282
283    /** The container for the locale comparison view. */
284    private VerticalLayout m_localeCompareContainer;
285
286    /** The currently active sitemap tree controller. */
287    private CmsSitemapTreeController m_sitemapTreeController;
288
289    /** The UI instance. */
290    private CmsSitemapUI m_ui;
291
292    /**
293     * Creates a new instance.<p>
294     *
295     * @param ui the component to attach to
296     */
297    public CmsSitemapExtension(CmsSitemapUI ui) {
298
299        extend(ui);
300        m_ui = ui;
301        registerRpc(this, I_CmsSitemapServerRpc.class);
302    }
303
304    /**
305     * @see org.opencms.ui.shared.rpc.I_CmsSitemapServerRpc#handleChangedProperties(java.lang.String)
306     */
307    public void handleChangedProperties(String id) {
308
309        if (m_sitemapTreeController != null) {
310            m_sitemapTreeController.updateNodeForId(new CmsUUID(id));
311        }
312    }
313
314    /**
315     * @see org.opencms.ui.shared.rpc.I_CmsSitemapServerRpc#openPageCopyDialog(java.lang.String, java.lang.String)
316     */
317    public void openPageCopyDialog(final String callId, final String structureId) {
318
319        CmsObject cms = A_CmsUI.getCmsObject();
320        try {
321            CmsResource resource = cms.readResource(new CmsUUID(structureId), CmsResourceFilter.IGNORE_EXPIRATION);
322            DialogContext context = new DialogContext(null, Arrays.asList(resource)) {
323
324                @SuppressWarnings("synthetic-access")
325                public void finish(java.util.Collection<CmsUUID> result) {
326
327                    closeWindow();
328                    String response = result.isEmpty()
329                    ? ""
330                    : CmsStringUtil.listAsString(new ArrayList<Object>(result), "|");
331                    getRpcProxy(I_CmsSitemapClientRpc.class).finishPageCopyDialog(callId, response);
332                }
333            };
334            CmsCopyPageDialog dialog = new CmsCopyPageDialog(context);
335            String title = CmsVaadinUtils.getMessageText(Messages.GUI_COPYPAGE_DIALOG_TITLE_0);
336            context.start(title, dialog);
337        } catch (CmsException e) {
338            LOG.error(e.getLocalizedMessage(), e);
339            CmsErrorDialog.showErrorDialog(e);
340        }
341    }
342
343    /**
344     * Opens the property dialog for the locale comparison view.<p>
345     *
346     * @param sitemapEntryId the structure id for the sitemap entry to edit
347     * @param rootId the structure id of the current tree's root
348     */
349    public void openPropertyDialog(CmsUUID sitemapEntryId, CmsUUID rootId) {
350
351        getRpcProxy(I_CmsSitemapClientRpc.class).openPropertyDialog("" + sitemapEntryId, "" + rootId);
352    }
353
354    /**
355     * Sets the currently active sitemap tree controller.<p>
356     *
357     * @param controller the controller to set
358     */
359    public void setSitemapTreeController(CmsSitemapTreeController controller) {
360
361        m_sitemapTreeController = controller;
362    }
363
364    /**
365     * Shows an info header in the locale-header-container element.<p>
366     *
367     * @param title the title
368     * @param description the description
369     * @param path the path
370     * @param locale the locale
371     * @param iconClass the icon class
372     */
373    public void showInfoHeader(String title, String description, String path, String locale, String iconClass) {
374
375        getRpcProxy(I_CmsSitemapClientRpc.class).showInfoHeader(title, description, path, locale, iconClass);
376    }
377
378    /**
379     * @see org.opencms.ui.shared.rpc.I_CmsSitemapServerRpc#showLocaleComparison(java.lang.String)
380     */
381    public void showLocaleComparison(String id) {
382
383        if (m_localeCompareContainer == null) {
384            m_localeCompareContainer = new VerticalLayout();
385            CmsExternalLayout layout = new CmsExternalLayout(
386                CmsGwtConstants.ID_LOCALE_COMPARISON,
387                m_localeCompareContainer);
388            m_ui.getContent().addComponent(layout);
389        }
390        m_localeCompareContainer.removeAllComponents();
391        m_localeCompareContainer.addComponent(new CmsLocaleComparePanel(id));
392
393    }
394
395}