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.setup.ui;
029
030import org.opencms.ui.A_CmsUI;
031import org.opencms.ui.CmsVaadinUtils;
032import org.opencms.ui.FontOpenCms;
033import org.opencms.ui.components.CmsBasicDialog;
034import org.opencms.ui.components.CmsCopyToClipboardButton;
035import org.opencms.ui.components.OpenCmsTheme;
036import org.opencms.util.CmsUUID;
037
038import org.apache.commons.lang3.exception.ExceptionUtils;
039
040import com.vaadin.ui.Button;
041import com.vaadin.ui.Button.ClickEvent;
042import com.vaadin.ui.Button.ClickListener;
043import com.vaadin.ui.CssLayout;
044import com.vaadin.ui.Window;
045import com.vaadin.ui.Window.CloseEvent;
046import com.vaadin.ui.Window.CloseListener;
047import com.vaadin.v7.shared.ui.label.ContentMode;
048import com.vaadin.v7.ui.Label;
049
050/**
051 * Dialog used to display error stack traces in the workplace.<p>
052 */
053public class CmsSetupErrorDialog extends CmsBasicDialog {
054
055    /** Serial version id. */
056    private static final long serialVersionUID = 1L;
057
058    /** The select text button. */
059    private CmsCopyToClipboardButton m_copyText;
060
061    /** The details component. */
062    private CssLayout m_details;
063
064    /** The toggle details button. */
065    private Button m_detailsButton;
066
067    /** Label to display. */
068    private Label m_errorLabel;
069
070    /** Error message label. */
071    private Label m_errorMessage;
072
073    /** Hidden stack trace element. */
074    private Label m_hiddenStack;
075
076    /** Warning icon. */
077    private Label m_icon;
078
079    /** The OK button. */
080    private Button m_okButton;
081
082    /** The dialog context. */
083    private Runnable m_onClose;
084
085    /** The dialog window. */
086    private Window m_window;
087
088    /**
089     * Creates a new instance.<p>
090     *
091     * @param message the error message
092     * @param t the error to be displayed
093     * @param onClose executed on close
094     * @param window the dialog window if available
095     */
096    public CmsSetupErrorDialog(String message, String details, Runnable onClose, final Window window) {
097
098        m_onClose = onClose;
099        m_window = window;
100        CmsVaadinUtils.readAndLocalizeDesign(this, null, null);
101        m_icon.setContentMode(ContentMode.HTML);
102        m_icon.setValue(FontOpenCms.ERROR.getHtml());
103        m_errorLabel.setContentMode(ContentMode.PREFORMATTED);
104        final String labelId = "label" + new CmsUUID().toString();
105
106        m_hiddenStack.setId(labelId);
107        m_hiddenStack.setValue(details);
108        m_errorLabel.setValue(details);
109        m_errorLabel.addStyleName(OpenCmsTheme.FULL_WIDTH_PADDING);
110        m_errorMessage.setContentMode(ContentMode.HTML);
111        m_errorMessage.setValue(message);
112
113        m_copyText.setSelector("#" + labelId);
114        m_details.setVisible(false);
115
116        m_okButton.addClickListener(new ClickListener() {
117
118            private static final long serialVersionUID = 1L;
119
120            public void buttonClick(ClickEvent event) {
121
122                onClose();
123            }
124        });
125        m_detailsButton.addClickListener(new ClickListener() {
126
127            private static final long serialVersionUID = 1L;
128
129            public void buttonClick(ClickEvent event) {
130
131                toggleDetails();
132            }
133        });
134        if (m_window != null) {
135            m_window.addCloseListener(new CloseListener() {
136
137                private static final long serialVersionUID = 1L;
138
139                public void windowClose(CloseEvent e) {
140
141                    onClose();
142                }
143            });
144        }
145
146    }
147
148    /**
149     * Shows error dialog, manually supplying details instead of getting them from an exception stack trace.
150     *
151     * @param message the error message
152     * @param details the details
153     */
154    public static void showErrorDialog(String message, String details) {
155
156        Window window = prepareWindow(DialogWidth.wide);
157        window.setCaption("Error");
158        window.setContent(new CmsSetupErrorDialog(message, details, null, window));
159        A_CmsUI.get().addWindow(window);
160
161    }
162
163    /**
164     * Shows the error dialog.<p>
165     *
166     * @param message the error message
167     * @param t the error to be displayed
168     */
169    public static void showErrorDialog(String message, Throwable t) {
170
171        showErrorDialog(message, t, null);
172    }
173
174    /**
175     * Shows the error dialog.<p>
176     *
177     * @param message the error message
178     * @param t the error to be displayed
179     * @param onClose executed on close
180     */
181    public static void showErrorDialog(String message, Throwable t, Runnable onClose) {
182
183        Window window = prepareWindow(DialogWidth.wide);
184        window.setCaption("Error");
185        window.setContent(
186            new CmsSetupErrorDialog(message, message + "\n\n" + ExceptionUtils.getStackTrace(t), onClose, window));
187        A_CmsUI.get().addWindow(window);
188    }
189
190    /**
191     * Shows the error dialog.<p>
192     *
193     * @param t the error to be displayed
194     */
195    public static void showErrorDialog(Throwable t) {
196
197        showErrorDialog(t.getLocalizedMessage(), t, null);
198    }
199
200    /**
201     * Shows the error dialog.<p>
202     *
203     * @param t the error to be displayed
204     * @param onClose executed on close
205     */
206    public static void showErrorDialog(Throwable t, Runnable onClose) {
207
208        showErrorDialog(t.getLocalizedMessage(), t, onClose);
209    }
210
211    /**
212     * Called on dialog close.<p>
213     */
214    void onClose() {
215
216        if (m_onClose != null) {
217            m_onClose.run();
218        }
219        if (m_window != null) {
220            m_window.close();
221        }
222    }
223
224    /**
225     * Toggles the details visibility.<p>
226     */
227    void toggleDetails() {
228
229        m_details.setVisible(!m_details.isVisible());
230        if (m_window != null) {
231            m_window.center();
232        }
233    }
234
235}