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.dialogs;
029
030import org.opencms.ade.configuration.CmsADEManager;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsProject;
033import org.opencms.file.CmsResource;
034import org.opencms.main.OpenCms;
035import org.opencms.ui.A_CmsUI;
036import org.opencms.ui.I_CmsDialogContext;
037import org.opencms.ui.apps.CmsQuickLaunchLocationCache;
038import org.opencms.ui.components.CmsBasicDialog;
039import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
040import org.opencms.ui.components.CmsErrorDialog;
041import org.opencms.ui.shared.rpc.I_CmsEmbeddedDialogClientRPC;
042import org.opencms.util.CmsStringUtil;
043import org.opencms.util.CmsUUID;
044
045import java.util.Collection;
046import java.util.Collections;
047import java.util.List;
048import java.util.regex.Pattern;
049
050import com.vaadin.server.AbstractExtension;
051import com.vaadin.ui.Component;
052import com.vaadin.ui.UI;
053import com.vaadin.ui.Window;
054import com.vaadin.ui.Window.CloseEvent;
055import com.vaadin.ui.Window.CloseListener;
056
057/**
058 * Context for dialogs embedded into plain GWT modules.<p>
059 */
060public class CmsEmbeddedDialogContext extends AbstractExtension implements I_CmsDialogContext {
061
062    /** Pattern to check if a given server link starts with with a protocol string. */
063    private static Pattern PROTOCOL_PATTERN = Pattern.compile("^http.?://.*");
064
065    /** The serial version id. */
066    private static final long serialVersionUID = -7446784547935775629L;
067
068    /** The app id. */
069    private String m_appId;
070
071    /** The context type. */
072    private ContextType m_contextType;
073
074    /** Keeps the dialog frame on window close. */
075    private boolean m_keepFrameOnClose;
076
077    /** The list of resources. */
078    private List<CmsResource> m_resources;
079
080    /** The window used to display the dialog. */
081    private Window m_window;
082
083    /**
084     * Constructor.<p>
085     *
086     * @param appId the app id
087     * @param contextType the context type
088     * @param resources the resources
089     */
090    public CmsEmbeddedDialogContext(String appId, ContextType contextType, List<CmsResource> resources) {
091
092        extend(UI.getCurrent());
093        m_appId = appId;
094        m_contextType = contextType;
095        m_resources = resources != null ? resources : Collections.<CmsResource> emptyList();
096    }
097
098    /**
099     * Closes the dialog window.<p>
100     *
101     * @param keepFrame <code>true</code> to keep the embedded iFrame.<p>
102     */
103    public void closeWindow(boolean keepFrame) {
104
105        if (m_window != null) {
106            m_keepFrameOnClose = keepFrame;
107            m_window.close();
108            m_window = null;
109        }
110    }
111
112    /**
113     * @see org.opencms.ui.I_CmsDialogContext#error(java.lang.Throwable)
114     */
115    public void error(Throwable error) {
116
117        closeWindow(true);
118        CmsErrorDialog.showErrorDialog(error, new Runnable() {
119
120            public void run() {
121
122                removeDialogFrame();
123            }
124        });
125    }
126
127    /**
128     * @see org.opencms.ui.I_CmsDialogContext#finish(org.opencms.file.CmsProject, java.lang.String)
129     */
130    public void finish(CmsProject project, String siteRoot) {
131
132        if ((project != null) || (siteRoot != null)) {
133            String sitePath = null;
134            if (siteRoot != null) {
135                CmsQuickLaunchLocationCache locationCache = CmsQuickLaunchLocationCache.getLocationCache(
136                    A_CmsUI.get().getHttpSession());
137                sitePath = locationCache.getPageEditorLocation(siteRoot);
138                if (sitePath == null) {
139                    sitePath = locationCache.getFileExplorerLocation(siteRoot);
140                    if (sitePath != null) {
141                        int index = sitePath.indexOf("/" + CmsADEManager.CONTENT_FOLDER_NAME);
142                        if (index >= 0) {
143                            sitePath = sitePath.substring(0, index);
144                        }
145                    }
146                }
147            } else if ((m_resources != null) && !m_resources.isEmpty()) {
148                sitePath = A_CmsUI.getCmsObject().getSitePath(m_resources.get(0));
149            }
150            if (CmsStringUtil.isEmptyOrWhitespaceOnly(sitePath)) {
151                sitePath = "/";
152            }
153            String serverLink = OpenCms.getLinkManager().getServerLink(getCms(), sitePath);
154            if (!PROTOCOL_PATTERN.matcher(serverLink).matches()) {
155                serverLink = "http://" + serverLink;
156            }
157
158            getClientRPC().finishForProjectOrSiteChange(sitePath, serverLink);
159        } else {
160            finish(null);
161        }
162    }
163
164    /**
165     * @see org.opencms.ui.I_CmsDialogContext#finish(java.util.Collection)
166     */
167    public void finish(Collection<CmsUUID> result) {
168
169        closeWindow(true);
170        String resources = "";
171        if (result != null) {
172            for (CmsUUID id : result) {
173                resources += id.toString() + ";";
174            }
175        }
176        getClientRPC().finish(resources);
177    }
178
179    /**
180     * @see org.opencms.ui.I_CmsDialogContext#focus(org.opencms.util.CmsUUID)
181     */
182    public void focus(CmsUUID structureId) {
183
184        // does not apply
185    }
186
187    /**
188     * @see org.opencms.ui.I_CmsDialogContext#getAllStructureIdsInView()
189     */
190    public List<CmsUUID> getAllStructureIdsInView() {
191
192        return Collections.emptyList();
193    }
194
195    /**
196     * @see org.opencms.ui.I_CmsDialogContext#getAppId()
197     */
198    public String getAppId() {
199
200        return m_appId;
201    }
202
203    /**
204     * @see org.opencms.ui.I_CmsDialogContext#getCms()
205     */
206    public CmsObject getCms() {
207
208        return A_CmsUI.getCmsObject();
209    }
210
211    /**
212     * @see org.opencms.ui.I_CmsDialogContext#getContextType()
213     */
214    public ContextType getContextType() {
215
216        return m_contextType;
217    }
218
219    /**
220     * @see org.opencms.ui.I_CmsDialogContext#getResources()
221     */
222    public List<CmsResource> getResources() {
223
224        return m_resources;
225    }
226
227    /**
228     * Leaves page by navigating to given URI.
229     *
230     * @param uri the URI to navigate to
231     */
232    public void leavePage(String uri) {
233
234        getClientRPC().leavePage(uri);
235    }
236
237    /**
238     * @see org.opencms.ui.I_CmsDialogContext#navigateTo(java.lang.String)
239     */
240    public void navigateTo(String appId) {
241
242        String targetUri = OpenCms.getSystemInfo().getWorkplaceContext() + "#!" + appId;
243        getClientRPC().leavePage(targetUri);
244    }
245
246    /**
247     * @see org.opencms.ui.I_CmsDialogContext#onViewChange()
248     */
249    public void onViewChange() {
250
251        if (m_window != null) {
252            m_window.center();
253        }
254    }
255
256    /**
257     * @see org.opencms.ui.I_CmsDialogContext#reload()
258     */
259    public void reload() {
260
261        closeWindow(true);
262        reloadParent();
263    }
264
265    /**
266     * Sets the principal.<p>
267     *
268     * @param principalName the principal name
269     */
270    public void setPrincipal(String principalName) {
271
272        getClientRPC().setPrincipal(principalName);
273    }
274
275    /**
276     * @see org.opencms.ui.I_CmsDialogContext#setWindow(com.vaadin.ui.Window)
277     */
278    public void setWindow(Window window) {
279
280        m_window = window;
281        m_window.addCloseListener(new CloseListener() {
282
283            private static final long serialVersionUID = 1L;
284
285            public void windowClose(CloseEvent e) {
286
287                handleWindowClose();
288            }
289        });
290    }
291
292    /**
293     * @see org.opencms.ui.I_CmsDialogContext#start(java.lang.String, com.vaadin.ui.Component)
294     */
295    public void start(String title, Component dialog) {
296
297        start(title, dialog, DialogWidth.narrow);
298    }
299
300    /**
301     * @see org.opencms.ui.I_CmsDialogContext#start(java.lang.String, com.vaadin.ui.Component, org.opencms.ui.components.CmsBasicDialog.DialogWidth)
302     */
303    public void start(String title, Component dialog, DialogWidth width) {
304
305        if (dialog != null) {
306            m_keepFrameOnClose = false;
307            m_window = CmsBasicDialog.prepareWindow(width);
308            m_window.setCaption(title);
309            m_window.setContent(dialog);
310            UI.getCurrent().addWindow(m_window);
311            m_window.addCloseListener(new CloseListener() {
312
313                private static final long serialVersionUID = 1L;
314
315                public void windowClose(CloseEvent e) {
316
317                    handleWindowClose();
318                }
319            });
320            if (dialog instanceof CmsBasicDialog) {
321                ((CmsBasicDialog)dialog).initActionHandler(m_window);
322            }
323        }
324    }
325
326    /**
327     * @see org.opencms.ui.I_CmsDialogContext#updateUserInfo()
328     */
329    public void updateUserInfo() {
330
331        getClientRPC().reloadParent();
332    }
333
334    /**
335     * Returns the client RPC.<p>
336     *
337     * @return the client RPC
338     */
339    protected I_CmsEmbeddedDialogClientRPC getClientRPC() {
340
341        return getRpcProxy(I_CmsEmbeddedDialogClientRPC.class);
342    }
343
344    /**
345     * Handles the window close event.<p>
346     */
347    void handleWindowClose() {
348
349        if (!m_keepFrameOnClose) {
350            removeDialogFrame();
351        }
352    }
353
354    /**
355     * Removes the dialog iFrame.<p>
356     */
357    void removeDialogFrame() {
358
359        getClientRPC().finish(null);
360    }
361
362    /**
363     * Reloads the parent window.<p>
364     */
365    private void reloadParent() {
366
367        getClientRPC().reloadParent();
368    }
369}