/*
* Copyright 2000-2016 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.server;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
/**
* Base class for component error messages.
*
* This class is used on the server side to construct the error messages to send
* to the client.
*
* @since 7.0
*/
public abstract class AbstractErrorMessage implements ErrorMessage {
public enum ContentMode {
/**
* Content mode, where the error contains only plain text.
*/
TEXT,
/**
* Content mode, where the error contains preformatted text.
*/
PREFORMATTED,
/**
* Content mode, where the error contains HTML.
*
*/
HTML,
}
/**
* Content mode.
*/
private ContentMode mode = ContentMode.TEXT;
/**
* Message in content mode.
*/
private String message;
/**
* Error level.
*/
private ErrorLevel level = ErrorLevel.ERROR;
private final List<ErrorMessage> causes = new ArrayList<>();
protected AbstractErrorMessage(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
protected void setMessage(String message) {
this.message = message;
}
/* Documented in interface */
@Override
public ErrorLevel getErrorLevel() {
return level;
}
public void setErrorLevel(ErrorLevel level) {
this.level = level;
}
protected ContentMode getMode() {
return mode;
}
protected void setMode(ContentMode mode) {
this.mode = mode;
}
protected List<ErrorMessage> getCauses() {
return causes;
}
public void addCause(ErrorMessage cause) {
causes.add(cause);
}
@Override
public String getFormattedHtmlMessage() {
String result = null;
switch (getMode()) {
case TEXT:
result = VaadinServlet.safeEscapeForHtml(getMessage());
break;
case PREFORMATTED:
result = "<pre>" + VaadinServlet.safeEscapeForHtml(getMessage())
+ "</pre>";
break;
case HTML:
result = getMessage();
break;
}
// if no message, combine the messages of all children
if (null == result && null != getCauses() && getCauses().size() > 0) {
StringBuilder sb = new StringBuilder();
for (ErrorMessage cause : getCauses()) {
String childMessage = cause.getFormattedHtmlMessage();
if (null != childMessage && !childMessage.isEmpty()) {
sb.append("<div>");
sb.append(childMessage);
sb.append("</div>\n");
}
}
if (sb.length() > 0) {
result = sb.toString();
}
}
// still no message? use an empty string for backwards compatibility
if (null == result) {
result = "";
}
return result;
}
public static ErrorMessage getErrorMessageForException(Throwable t) {
if (null == t) {
return null;
} else if (t instanceof ErrorMessage) {
// legacy case for custom error messages
return (ErrorMessage) t;
} else if (t instanceof ErrorMessageProducer) {
return ((ErrorMessageProducer) t).getErrorMessage();
} else {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return new SystemError(sw.toString());
}
}
/* Documented in superclass */
@Override
public String toString() {
return getMessage();
}
}