/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.webx.handler.component; import static com.alibaba.citrus.util.ClassUtil.*; import static com.alibaba.citrus.util.ExceptionUtil.*; import static com.alibaba.citrus.util.StringEscapeUtil.*; import static com.alibaba.citrus.util.StringUtil.*; import java.util.Iterator; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.alibaba.citrus.util.internal.webpagelite.PageComponent; import com.alibaba.citrus.util.internal.webpagelite.PageComponentRegistry; import com.alibaba.citrus.util.templatelite.Template; import com.alibaba.citrus.webx.handler.RequestHandlerContext; import com.alibaba.citrus.webx.handler.support.AbstractVisitor; /** * 用来显示异常信息的页面组件。 * * @author Michael Zhou */ public class ExceptionComponent extends PageComponent { public ExceptionComponent(PageComponentRegistry registry, String componentPath) { super(registry, componentPath); } public void visitTemplate(RequestHandlerContext context, Throwable exception) { getTemplate().accept(new ExceptionVisitor(context, exception)); } @SuppressWarnings("unused") private class ExceptionVisitor extends AbstractVisitor { private final List<Throwable> exceptions; private Throwable exception; private int exceptionId; private boolean defaultOpen; private StackTraceElement stackTraceElement; private String location; private boolean firstException = true; public ExceptionVisitor(RequestHandlerContext context, Throwable exception) { super(context, ExceptionComponent.this); this.exceptions = getCauses(exception); } public void visitException(Template exceptionTemplate) { for (Iterator<Throwable> i = exceptions.iterator(); i.hasNext(); ) { this.exception = i.next(); this.exceptionId++; this.defaultOpen = !i.hasNext(); exceptionTemplate.accept(this); this.firstException = false; } } public void visitExceptionId() { out().print(exceptionId); } public void visitShowHideHandleImage(String openImage, String closeImage) { visitComponentUrl(defaultOpen ? openImage : closeImage); } public void visitCausedBy(Template causedByTemplate) { if (!firstException) { causedByTemplate.accept(this); } } public void visitExceptionType() { out().append(exception.getClass().getCanonicalName()); } public void visitExceptionMessage() { if (isEmpty(exception.getMessage())) { out().append("No Message"); } else { out().append(escapeHtml(exception.getMessage())); } } public void visitStackTrace(Template stackTraceElementTemplate) { for (StackTraceElement element : exception.getStackTrace()) { this.stackTraceElement = element; this.location = locateClass(stackTraceElement.getClassName()); stackTraceElementTemplate.accept(this); } } public void visitStackTraceElement_Class() { out().append(stackTraceElement.getClassName()); } public void visitStackTraceElement_PackageName() { String className = stackTraceElement.getClassName(); int index = className.lastIndexOf("."); if (index > 0) { out().append(className.substring(0, index)); } else { out().append("(default package)"); } } public void visitStackTraceElement_SimpleClassName() { String className = stackTraceElement.getClassName(); out().append(className.substring(className.lastIndexOf(".") + 1)); } public void visitStackTraceElement_ClassLocation() { if (location != null) { out().append(location); } else { out().append("Could not locate class " + stackTraceElement.getClassName()); } } public void visitStackTraceElement_ClassLocationShort() { String shortLocation = null; if (location != null) { Matcher m = Pattern.compile("[^/]+/?$").matcher(location); if (m.find()) { shortLocation = m.group(); } } if (shortLocation != null) { out().append(shortLocation); } else { out().append("<unknown location>"); } } public void visitStackTraceElement_Method() { out().append(stackTraceElement.getMethodName()); } public void visitStackTraceElement_File() { out().append(stackTraceElement.getFileName()); } public void visitStackTraceElement_Line() { out().print(stackTraceElement.getLineNumber()); } } }