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