/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
// www.projectforge.org
//
// Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////
package org.projectforge.web.wicket;
import javax.servlet.ServletException;
import org.apache.commons.lang.StringUtils;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.protocol.http.PageExpiredException;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.projectforge.access.AccessException;
import org.projectforge.common.ExceptionHelper;
import org.projectforge.core.Configuration;
import org.projectforge.core.ConfigurationParam;
import org.projectforge.core.InternalErrorException;
import org.projectforge.core.ProjectForgeException;
import org.projectforge.core.SendFeedback;
import org.projectforge.core.UserException;
import org.projectforge.user.PFUserContext;
/**
* Standard error page should be shown in production mode.
*
* @author Kai Reinhard (k.reinhard@micromata.de)
*
*/
public class ErrorPage extends AbstractSecuredPage
{
private static final long serialVersionUID = -637809894879133209L;
private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(ErrorPage.class);
public static final String ONLY4NAMESPACE = "org.projectforge";
private String title;
String errorMessage, messageNumber;
@SpringBean(name = "sendFeedback")
private SendFeedback sendFeedback;
private final ErrorForm form;
private boolean showFeedback;
/**
* Get internationalized message inclusive the message params if exists.
* @param securedPage Needed for localization.
* @param exception
* @param doLog If true, then a log entry with level INFO will be produced.
* @return
*/
public static String getExceptionMessage(final AbstractSecuredBasePage securedPage, final ProjectForgeException exception,
final boolean doLog)
{
// Feedbackpanel!
if (exception instanceof UserException) {
final UserException ex = (UserException) exception;
if (doLog == true) {
log.info(ex.toString() + ExceptionHelper.getFilteredStackTrace(ex, ONLY4NAMESPACE));
}
return securedPage.translateParams(ex.getI18nKey(), ex.getMsgParams(), ex.getParams());
} else if (exception instanceof InternalErrorException) {
final InternalErrorException ex = (InternalErrorException) exception;
if (doLog == true) {
log.info(ex.toString() + ExceptionHelper.getFilteredStackTrace(ex, ONLY4NAMESPACE));
}
return securedPage.translateParams(ex.getI18nKey(), ex.getMsgParams(), ex.getParams());
} else if (exception instanceof AccessException) {
final AccessException ex = (AccessException) exception;
if (doLog == true) {
log.info(ex.toString() + ExceptionHelper.getFilteredStackTrace(ex, ONLY4NAMESPACE));
}
if (ex.getParams() != null) {
return securedPage.getLocalizedMessage(ex.getI18nKey(), ex.getParams());
} else {
return securedPage.translateParams(ex.getI18nKey(), ex.getMessageArgs(), ex.getParams());
}
}
throw new UnsupportedOperationException("For developer: Please add unknown ProjectForgeException here!", exception);
}
public ErrorPage()
{
this(null);
}
public ErrorPage(final Throwable throwable)
{
super(null);
errorMessage = getString("errorpage.unknownError");
messageNumber = null;
Throwable rootCause = null;
showFeedback = true;
if (throwable != null) {
rootCause = ExceptionHelper.getRootCause(throwable);
if (rootCause instanceof ProjectForgeException) {
errorMessage = getExceptionMessage(this, (ProjectForgeException) rootCause, true);
} else if (throwable instanceof ServletException) {
messageNumber = String.valueOf(System.currentTimeMillis());
log.error("Message #" + messageNumber + ": " + throwable.getMessage(), throwable);
if (rootCause != null) {
log.error("Message #" + messageNumber + " rootCause: " + rootCause.getMessage(), rootCause);
}
errorMessage = getLocalizedMessage(UserException.I18N_KEY_PLEASE_CONTACT_DEVELOPER_TEAM, messageNumber);
} else if (throwable instanceof PageExpiredException) {
log.info("Page expired (session time out).");
showFeedback = false;
errorMessage = getString("message.wicket.pageExpired");
title = getString("message.title");
} else {
messageNumber = String.valueOf(System.currentTimeMillis());
log.error("Message #" + messageNumber + ": " + throwable.getMessage(), throwable);
errorMessage = getLocalizedMessage(UserException.I18N_KEY_PLEASE_CONTACT_DEVELOPER_TEAM, messageNumber);
}
}
form = new ErrorForm(this);
final String receiver = Configuration.getInstance().getStringValue(ConfigurationParam.FEEDBACK_E_MAIL);
form.data.setReceiver(receiver);
form.data.setMessageNumber(messageNumber);
form.data.setMessage(throwable != null ? throwable.getMessage() : "");
form.data.setStackTrace(throwable != null ? ExceptionHelper.printStackTrace(throwable) : "");
form.data.setSender(PFUserContext.getUser().getFullname());
final String subject = "ProjectForge-Error #" + form.data.getMessageNumber() + " from " + form.data.getSender();
form.data.setSubject(subject);
if (rootCause != null) {
form.data.setRootCause(rootCause.getMessage());
form.data.setRootCauseStackTrace(ExceptionHelper.printStackTrace(rootCause));
}
final boolean visible = showFeedback == true && messageNumber != null && StringUtils.isNotBlank(receiver);
body.add(form);
if (visible == true) {
form.init();
}
form.setVisible(visible);
final Label errorMessageLabel = new Label("errorMessage", errorMessage);
body.add(errorMessageLabel.setVisible(errorMessage != null));
final FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
feedbackPanel.setOutputMarkupId(true);
body.add(feedbackPanel);
}
void cancel()
{
setResponsePage(WicketUtils.getDefaultPage());
}
void sendFeedback()
{
log.info("Send feedback.");
boolean result = false;
try {
result = sendFeedback.send(form.data);
} catch (final Throwable ex) {
log.error(ex.getMessage(), ex);
result = false;
}
final MessagePage messagePage = new MessagePage(new PageParameters());
if (result == true) {
messagePage.setMessage(getString("feedback.mailSendSuccessful"));
} else {
messagePage.setMessage(getString("mail.error.exception"));
messagePage.setWarning(true);
}
setResponsePage(messagePage);
}
@Override
protected String getTitle()
{
return title != null ? title : getString("errorpage.title");
}
/**
* @see org.apache.wicket.Component#isVersioned()
*/
@Override
public boolean isVersioned()
{
return false;
}
/**
* @see org.apache.wicket.Page#isErrorPage()
*/
@Override
public boolean isErrorPage()
{
return true;
}
}