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.file.CmsProject;
031import org.opencms.file.CmsResource;
032import org.opencms.gwt.CmsCoreService;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
036import org.opencms.ui.A_CmsUI;
037import org.opencms.ui.CmsVaadinUtils;
038import org.opencms.ui.I_CmsDialogContext;
039import org.opencms.ui.apps.CmsFileExplorerConfiguration;
040import org.opencms.ui.apps.CmsPageEditorConfiguration;
041import org.opencms.ui.apps.I_CmsHasAppLaunchCommand;
042import org.opencms.ui.apps.I_CmsWorkplaceAppConfiguration;
043import org.opencms.ui.apps.Messages;
044import org.opencms.ui.components.CmsBasicDialog;
045import org.opencms.ui.components.CmsExtendedSiteSelector;
046import org.opencms.ui.components.CmsExtendedSiteSelector.SiteSelectorOption;
047import org.opencms.ui.components.CmsOkCancelActionHandler;
048import org.opencms.util.CmsUUID;
049
050import java.util.Collections;
051
052import org.apache.commons.logging.Log;
053
054import com.vaadin.server.Page;
055import com.vaadin.ui.Button;
056import com.vaadin.ui.Button.ClickEvent;
057import com.vaadin.ui.Button.ClickListener;
058import com.vaadin.ui.FormLayout;
059import com.vaadin.ui.UI;
060import com.vaadin.v7.data.util.IndexedContainer;
061import com.vaadin.v7.shared.ui.combobox.FilteringMode;
062import com.vaadin.v7.ui.ComboBox;
063
064/**
065 * The project select dialog.<p>
066 */
067public class CmsProjectSelectDialog extends CmsBasicDialog {
068
069    /** Logger instance for this class. */
070    static final Log LOG = CmsLog.getLog(CmsProjectSelectDialog.class);
071
072    /** The project name property. */
073    private static final String CAPTION_PROPERTY = "caption";
074
075    /** The serial version id. */
076    private static final long serialVersionUID = 4455901453008760434L;
077
078    /** The cancel button. */
079    private Button m_cancelButton;
080
081    /** The dialog context. */
082    private I_CmsDialogContext m_context;
083
084    /** The project select. */
085    private ComboBox m_projectComboBox;
086
087    /** The site select. */
088    private CmsExtendedSiteSelector m_siteComboBox;
089
090    /**
091     * Constructor.<p>
092     *
093     * @param context the dialog context
094     */
095    public CmsProjectSelectDialog(I_CmsDialogContext context) {
096
097        m_context = context;
098        setContent(initForm());
099        m_cancelButton = createButtonCancel();
100        m_cancelButton.addClickListener(new ClickListener() {
101
102            private static final long serialVersionUID = 1L;
103
104            public void buttonClick(ClickEvent event) {
105
106                cancel();
107            }
108        });
109        addButton(m_cancelButton);
110
111        setActionHandler(new CmsOkCancelActionHandler() {
112
113            private static final long serialVersionUID = 1L;
114
115            @Override
116            protected void cancel() {
117
118                CmsProjectSelectDialog.this.cancel();
119            }
120
121            @Override
122            protected void ok() {
123
124                submit();
125            }
126        });
127    }
128
129    /**
130     * Static method for actually changing the site/project.
131     *
132     * @param context the dialog context
133     * @param projectId the project id (possibly null)
134     * @param siteOption the option from the site selector
135     */
136    public static void changeSiteOrProject(
137        I_CmsDialogContext context,
138        CmsUUID projectId,
139        SiteSelectorOption siteOption) {
140
141        String siteRoot = null;
142        try {
143            CmsProject project = null;
144            if (projectId != null) {
145                project = context.getCms().readProject(projectId);
146                if (!context.getCms().getRequestContext().getCurrentProject().equals(project)) {
147                    A_CmsUI.get().changeProject(project);
148                } else {
149                    project = null;
150                }
151            }
152            if (siteOption != null) {
153
154                siteRoot = siteOption.getSite();
155                if (!context.getCms().getRequestContext().getSiteRoot().equals(siteRoot)) {
156                    A_CmsUI.get().changeSite(siteRoot);
157                } else if (siteOption.getPath() == null) {
158                    siteRoot = null;
159                }
160            }
161            if ((siteRoot != null) && CmsFileExplorerConfiguration.APP_ID.equals(context.getAppId())) {
162                if (siteOption.getPath() != null) {
163                    CmsResource defaultFile = null;
164                    try {
165                        defaultFile = A_CmsUI.getCmsObject().readDefaultFile(siteOption.getPath());
166                    } catch (Exception e) {
167                        // ignore
168                    }
169                    if (defaultFile != null) {
170                        Page.getCurrent().setLocation(
171                            OpenCms.getLinkManager().substituteLinkForUnknownTarget(
172                                A_CmsUI.getCmsObject(),
173                                siteOption.getPath()));
174                        return;
175                    } else {
176                        Page.getCurrent().open(
177                            CmsCoreService.getFileExplorerLink(A_CmsUI.getCmsObject(), siteOption.getSite())
178                                + siteOption.getPath(),
179                            "_top");
180                    }
181                } else {
182                    I_CmsWorkplaceAppConfiguration editorConf = OpenCms.getWorkplaceAppManager().getAppConfiguration(
183                        CmsPageEditorConfiguration.APP_ID);
184                    if (editorConf.getVisibility(context.getCms()).isActive()) {
185                        ((I_CmsHasAppLaunchCommand)editorConf).getAppLaunchCommand().run();
186                        return;
187                    }
188                }
189            }
190            context.finish(project, siteRoot);
191        } catch (CmsException e) {
192            context.error(e);
193        }
194    }
195
196    /**
197     * Cancels the dialog action.<p>
198     */
199    void cancel() {
200
201        m_context.finish(Collections.<CmsUUID> emptyList());
202    }
203
204    /**
205     * Submits the dialog action.<p>
206     */
207    void submit() {
208
209        I_CmsDialogContext context = m_context;
210        CmsUUID projectId = (CmsUUID)m_projectComboBox.getValue();
211        SiteSelectorOption option = m_siteComboBox.getValue();
212        changeSiteOrProject(context, projectId, option);
213    }
214
215    /**
216     * Initializes the form component.<p>
217     *
218     * @return the form component
219     */
220    private FormLayout initForm() {
221
222        FormLayout form = new FormLayout();
223        form.setWidth("100%");
224
225        m_siteComboBox = prepareSiteSelector(org.opencms.workplace.Messages.GUI_LABEL_SITE_0);
226
227        m_siteComboBox.selectSite(m_context.getCms().getRequestContext().getSiteRoot());
228        form.addComponent(m_siteComboBox);
229
230        m_siteComboBox.addValueChangeListener(evt -> submit());
231        IndexedContainer projects = CmsVaadinUtils.getProjectsContainer(m_context.getCms(), CAPTION_PROPERTY);
232        m_projectComboBox = prepareComboBox(projects, org.opencms.workplace.Messages.GUI_LABEL_PROJECT_0);
233        CmsUUID currentProjectId = m_context.getCms().getRequestContext().getCurrentProject().getUuid();
234        if (projects.containsId(currentProjectId)) {
235            m_projectComboBox.select(currentProjectId);
236        } else {
237            try {
238                CmsUUID ouProject = OpenCms.getOrgUnitManager().readOrganizationalUnit(
239                    m_context.getCms(),
240                    m_context.getCms().getRequestContext().getOuFqn()).getProjectId();
241                if (projects.containsId(ouProject)) {
242                    m_projectComboBox.select(ouProject);
243                }
244            } catch (CmsException e) {
245                LOG.error("Error while reading current OU.", e);
246            }
247        }
248
249        form.addComponent(m_projectComboBox);
250        m_projectComboBox.addValueChangeListener(evt -> submit());
251        return form;
252    }
253
254    /**
255     * Prepares a combo box.<p>
256     *
257     * @param container the indexed item container
258     * @param captionKey the caption message key
259     *
260     * @return the combo box
261     */
262    private ComboBox prepareComboBox(IndexedContainer container, String captionKey) {
263
264        ComboBox result = new ComboBox(CmsVaadinUtils.getWpMessagesForCurrentLocale().key(captionKey), container);
265        result.setTextInputAllowed(true);
266        result.setNullSelectionAllowed(false);
267        result.setWidth("100%");
268        result.setInputPrompt(
269            Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_CLICK_TO_EDIT_0));
270        result.setItemCaptionPropertyId(CAPTION_PROPERTY);
271        result.setFilteringMode(FilteringMode.CONTAINS);
272        return result;
273    }
274
275    /**
276     * Prepares a combo box.<p>
277     *
278     * @param captionKey the caption message key
279     *
280     * @return the combo box
281     */
282    private CmsExtendedSiteSelector prepareSiteSelector(String captionKey) {
283
284        CmsExtendedSiteSelector result = new CmsExtendedSiteSelector();
285        boolean isExplorer = CmsFileExplorerConfiguration.APP_ID.equals(m_context.getAppId());
286        result.initOptions(m_context.getCms(), isExplorer);
287        result.setPageLength(CmsExtendedSiteSelector.LONG_PAGE_LENGTH);
288        result.setCaption(CmsVaadinUtils.getWpMessagesForCurrentLocale().key(captionKey));
289        result.setWidth("100%");
290        result.setPlaceholder(
291            Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_CLICK_TO_EDIT_0));
292        return result;
293    }
294}