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.error; 029 030import org.opencms.file.CmsObject; 031import org.opencms.flex.CmsFlexController; 032import org.opencms.jsp.util.Messages; 033import org.opencms.main.CmsLog; 034import org.opencms.main.CmsMultiException; 035import org.opencms.main.I_CmsThrowable; 036import org.opencms.main.OpenCms; 037import org.opencms.ui.A_CmsUI; 038import org.opencms.ui.CmsVaadinUtils; 039import org.opencms.ui.apps.CmsLegacyApp; 040import org.opencms.ui.components.CmsErrorDialog; 041import org.opencms.ui.shared.CmsVaadinConstants; 042import org.opencms.util.CmsFileUtil; 043import org.opencms.util.CmsMacroResolver; 044import org.opencms.util.CmsStringUtil; 045 046import javax.servlet.http.HttpServletRequest; 047 048import org.apache.commons.logging.Log; 049 050import com.vaadin.annotations.Theme; 051import com.vaadin.server.VaadinRequest; 052import com.vaadin.server.WrappedSession; 053import com.vaadin.shared.Version; 054import com.vaadin.ui.JavaScript; 055 056/** 057 * Displays the error page.<p> 058 */ 059@Theme("opencms") 060public class CmsErrorUI extends A_CmsUI { 061 062 /** The serial version id. */ 063 private static final long serialVersionUID = -7274300240145879438L; 064 065 /** Logger instance for this class. */ 066 private static final Log LOG = CmsLog.getLog(CmsErrorUI.class); 067 068 /** The throwable session attribute name. */ 069 private static final String THROWABLE = "THROWABLE"; 070 071 /** The path session attribute name. */ 072 private static final String PATH = "PATH"; 073 074 /** The error page path fragment. */ 075 public static final String ERROR_PAGE_PATH_FRAQUMENT = "errorpage/"; 076 077 /** The path to the requested page. */ 078 @SuppressWarnings("unused") 079 private String m_requestedPage; 080 081 /** The displayed exception. */ 082 private Throwable m_throwable; 083 084 /** 085 * Returns the error bootstrap page HTML.<p> 086 * 087 * @param cms the cms context 088 * @param throwable the throwable 089 * @param request the current request 090 * 091 * @return the error bootstrap page HTML 092 */ 093 public static String getBootstrapPage(CmsObject cms, Throwable throwable, HttpServletRequest request) { 094 095 try { 096 setErrorAttributes(cms, throwable, request); 097 098 byte[] pageBytes = CmsFileUtil.readFully( 099 Thread.currentThread().getContextClassLoader().getResourceAsStream( 100 "org/opencms/ui/error/error-page.html")); 101 String page = new String(pageBytes, "UTF-8"); 102 CmsMacroResolver resolver = new CmsMacroResolver(); 103 String context = OpenCms.getSystemInfo().getContextPath(); 104 String vaadinDir = CmsStringUtil.joinPaths(context, "VAADIN/"); 105 String vaadinVersion = Version.getFullVersion(); 106 String vaadinServlet = CmsStringUtil.joinPaths(context, "workplace/", ERROR_PAGE_PATH_FRAQUMENT); 107 String vaadinBootstrap = CmsStringUtil.joinPaths(context, "VAADIN/vaadinBootstrap.js"); 108 109 resolver.addMacro("loadingHtml", CmsVaadinConstants.LOADING_INDICATOR_HTML); 110 resolver.addMacro("vaadinDir", vaadinDir); 111 resolver.addMacro("vaadinVersion", vaadinVersion); 112 resolver.addMacro("vaadinServlet", vaadinServlet); 113 resolver.addMacro("vaadinBootstrap", vaadinBootstrap); 114 resolver.addMacro("title", "Error page"); 115 116 page = resolver.resolveMacros(page); 117 return page; 118 } catch (Exception e) { 119 LOG.error("Failed to display error page.", e); 120 return "<!--Error-->"; 121 } 122 } 123 124 /** 125 * Sets the error attributes to the current session.<p> 126 * 127 * @param cms the cms context 128 * @param throwable the throwable 129 * @param request the current request 130 */ 131 private static void setErrorAttributes(CmsObject cms, Throwable throwable, HttpServletRequest request) { 132 133 String errorUri = CmsFlexController.getThrowableResourceUri(request); 134 if (errorUri == null) { 135 errorUri = cms.getRequestContext().getUri(); 136 } 137 138 // try to get the exception root cause 139 Throwable cause = CmsFlexController.getThrowable(request); 140 if (cause == null) { 141 cause = throwable; 142 } 143 144 request.getSession().setAttribute(THROWABLE, cause); 145 request.getSession().setAttribute(PATH, errorUri); 146 } 147 148 /** 149 * @see com.vaadin.ui.UI#init(com.vaadin.server.VaadinRequest) 150 */ 151 @Override 152 protected void init(VaadinRequest request) { 153 154 readErrorAttributes(); 155 CmsErrorDialog.showErrorDialog(getErrorMessage(m_throwable), m_throwable, new Runnable() { 156 157 public void run() { 158 159 JavaScript.eval( 160 "if (window.parent && window.parent." 161 + CmsLegacyApp.VAR_IS_LEGACY_APP 162 + ") window.parent.location.reload();"); 163 } 164 }); 165 } 166 167 /** 168 * Returns the error message to be displayed.<p> 169 * 170 * @param throwable the throwable 171 * 172 * @return the error message to be displayed 173 */ 174 private String getErrorMessage(Throwable throwable) { 175 176 StringBuffer result = new StringBuffer(512); 177 178 result.append( 179 CmsVaadinUtils.getMessageText(org.opencms.ui.components.Messages.GUI_ERROR_DIALOG_MESSAGE_0)).append( 180 "<br />"); 181 182 // if a localized message is already set as a parameter, append it. 183 result.append(getMessage(throwable)); 184 185 return result.toString(); 186 } 187 188 /** 189 * Returns the localized Message, if the argument is a CmsException, or 190 * the message otherwise.<p> 191 * 192 * @param t the Throwable to get the message from 193 * 194 * @return returns the localized Message, if the argument is a CmsException, or 195 * the message otherwise 196 */ 197 private String getMessage(Throwable t) { 198 199 if ((t instanceof I_CmsThrowable) && (((I_CmsThrowable)t).getMessageContainer() != null)) { 200 StringBuffer result = new StringBuffer(256); 201 if (t instanceof CmsMultiException) { 202 CmsMultiException exc = (CmsMultiException)t; 203 String message = exc.getMessage(getLocale()); 204 if (CmsStringUtil.isNotEmpty(message)) { 205 result.append(message); 206 result.append("<br />"); 207 } 208 209 } 210 211 I_CmsThrowable cmsThrowable = (I_CmsThrowable)t; 212 result.append(cmsThrowable.getLocalizedMessage(getLocale())); 213 return result.toString(); 214 } else { 215 String message = t.getMessage(); 216 if (CmsStringUtil.isEmptyOrWhitespaceOnly(message)) { 217 // no error message found (e.g. for NPE), provide default message text 218 message = CmsVaadinUtils.getMessageText(Messages.GUI_ERROR_UNKNOWN_0); 219 } 220 return message; 221 } 222 } 223 224 /** 225 * Reads the error attributes from current session.<p> 226 */ 227 private void readErrorAttributes() { 228 229 WrappedSession session = getSession().getSession(); 230 m_requestedPage = (String)session.getAttribute(PATH); 231 m_throwable = (Throwable)session.getAttribute(THROWABLE); 232 233 // remove the attributes after read to keep the session clean 234 session.removeAttribute(THROWABLE); 235 session.removeAttribute(PATH); 236 } 237}