You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2008/08/28 02:50:09 UTC
svn commit: r689684 - in /myfaces/tomahawk/trunk/sandbox:
core/src/main/java/org/apache/myfaces/tomahawk/
core/src/main/java/org/apache/myfaces/tomahawk/util/
core12/src/main/java/org/apache/myfaces/tomahawk/
core12/src/main/java/org/apache/myfaces/tom...
Author: lu4242
Date: Wed Aug 27 17:50:09 2008
New Revision: 689684
URL: http://svn.apache.org/viewvc?rev=689684&view=rev
Log:
TOMAHAWK-1297 Redirect to a JSF page when Throwable exception or error occur
Added:
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java (with props)
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java (with props)
myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java (with props)
myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/
myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/
myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java (with props)
Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java?rev=689684&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java Wed Aug 27 17:50:09 2008
@@ -0,0 +1,617 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.myfaces.tomahawk.util;
+
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.lang.reflect.Method;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.el.MethodBinding;
+import javax.faces.el.ValueBinding;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class is the same as javax.faces.webapp._ErrorPageWriter,
+ * but is cloned here to allow ErrorRedirectJSFPageHandler to provide
+ * an alternative when no navigation rule for a specific exception is
+ * found.
+ *
+ * @author Jacob Hookom (ICLA with ASF filed)
+ */
+public class ErrorPageWriter {
+
+ private static final Log log = LogFactory.getLog(ErrorPageWriter.class);
+ private static final Class[] NO_ARGS = new Class[0];
+
+ private final static String TS = "<";
+
+ private static final String ERROR_TEMPLATE = "META-INF/rsc/myfaces-dev-error.xml";
+
+ private static final String ERROR_TEMPLATE_RESOURCE = "org.apache.myfaces.ERROR_TEMPLATE_RESOURCE";
+
+ private static String[] ERROR_PARTS;
+
+ private static final String DEBUG_TEMPLATE = "META-INF/rsc/myfaces-dev-debug.xml";
+
+ private static final String DEBUG_TEMPLATE_RESOURCE = "org.apache.myfaces.DEBUG_TEMPLATE_RESOURCE";
+
+ private static String[] DEBUG_PARTS;
+
+ public ErrorPageWriter() {
+ super();
+ }
+
+ private static String getErrorTemplate(FacesContext context)
+ {
+ String errorTemplate = context.getExternalContext().getInitParameter(ERROR_TEMPLATE_RESOURCE);
+ if (errorTemplate != null)
+ {
+ return errorTemplate;
+ }
+ return ERROR_TEMPLATE;
+ }
+
+ private static String getDebugTemplate(FacesContext context)
+ {
+ String debugTemplate = context.getExternalContext().getInitParameter(DEBUG_TEMPLATE_RESOURCE);
+ if (debugTemplate != null)
+ {
+ return debugTemplate;
+ }
+ return DEBUG_TEMPLATE;
+ }
+
+ private static void init(FacesContext context) throws IOException {
+ if (ERROR_PARTS == null) {
+ ERROR_PARTS = splitTemplate(getErrorTemplate(context));
+ }
+
+ if (DEBUG_PARTS == null) {
+ DEBUG_PARTS = splitTemplate(getDebugTemplate(context));
+ }
+ }
+
+ private static String[] splitTemplate(String rsc) throws IOException {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(rsc);
+ if (is == null) {
+ throw new FileNotFoundException(rsc);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buff = new byte[512];
+ int read;
+ while ((read = is.read(buff)) != -1) {
+ baos.write(buff, 0, read);
+ }
+ String str = baos.toString();
+ return str.split("@@");
+ }
+
+ static ArrayList getErrorId(Throwable e){
+ String message = e.getMessage();
+
+ if(message==null)
+ return null;
+
+ ArrayList list = new ArrayList();
+ Pattern pattern = Pattern.compile(".*?\\Q,Id:\\E\\s*(\\S+)\\s*\\].*?");
+ Matcher matcher = pattern.matcher(message);
+
+ while (matcher.find()){
+ list.add(matcher.group(1));
+ }
+ if (list.size()>0) return list;
+ return null;
+ }
+
+ public static void writeCause(Writer writer, Throwable ex) throws IOException {
+ String msg = ex.getMessage();
+ for(;;) {
+ Throwable t = getCause(ex);
+ if (t == null)
+ break;
+
+ ex = t;
+ if (ex.getMessage()!=null) msg = ex.getMessage();
+ }
+
+ if (msg != null) {
+ msg =ex.getClass().getName() + " - " + msg;
+ writer.write(msg.replaceAll("<", TS));
+ } else {
+ writer.write(ex.getClass().getName());
+ }
+ }
+
+ public static void debugHtml(Writer writer, FacesContext faces, Throwable e) throws IOException {
+ init(faces);
+ Date now = new Date();
+ for (int i = 0; i < ERROR_PARTS.length; i++) {
+ if ("message".equals(ERROR_PARTS[i])) {
+ String msg = e.getMessage();
+ if (msg != null) {
+ writer.write(msg.replaceAll("<", TS));
+ } else {
+ writer.write(e.getClass().getName());
+ }
+ } else if ("trace".equals(ERROR_PARTS[i])) {
+ writeException(writer, e);
+ } else if ("now".equals(ERROR_PARTS[i])) {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ } else if ("tree".equals(ERROR_PARTS[i])) {
+ if (faces.getViewRoot() != null) {
+ writeComponent(writer, faces.getViewRoot(), getErrorId(e));
+ }
+ } else if ("vars".equals(ERROR_PARTS[i])) {
+ writeVariables(writer, faces);
+ } else if ("cause".equals(ERROR_PARTS[i])) {
+ writeCause(writer, e);
+ } else {
+ writer.write(ERROR_PARTS[i]);
+ }
+ }
+ }
+
+ public static void debugHtml(Writer writer, FacesContext faces, List exceptionList) throws IOException
+ {
+ init(faces);
+ Date now = new Date();
+ for (int i = 0; i < ERROR_PARTS.length; i++)
+ {
+ if ("message".equals(ERROR_PARTS[i]))
+ {
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ String msg = e.getMessage();
+ if (msg != null)
+ {
+ writer.write(msg.replaceAll("<", TS));
+ }
+ else
+ {
+ writer.write(e.getClass().getName());
+ }
+ if (!(j+1==exceptionList.size()))
+ {
+ writer.write("<br>");
+ }
+ }
+ }
+ else if ("trace".equals(ERROR_PARTS[i]))
+ {
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ writeException(writer, e);
+ }
+ }
+ else if ("now".equals(ERROR_PARTS[i]))
+ {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ }
+ else if ("tree".equals(ERROR_PARTS[i]))
+ {
+ if (faces.getViewRoot() != null)
+ {
+ List highlightId = null;
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ if (highlightId == null)
+ {
+ highlightId = getErrorId(e);
+ }
+ else
+ {
+ highlightId.addAll(getErrorId(e));
+ }
+ }
+ writeComponent(writer, faces.getViewRoot(), highlightId);
+ }
+ }
+ else if ("vars".equals(ERROR_PARTS[i]))
+ {
+ writeVariables(writer, faces);
+ }
+ else if ("cause".equals(ERROR_PARTS[i]))
+ {
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ writeCause(writer, e);
+ if (!(j+1==exceptionList.size()))
+ {
+ writer.write("<br>");
+ }
+ }
+ }
+ else
+ {
+ writer.write(ERROR_PARTS[i]);
+ }
+ }
+ }
+
+ private static void writeException(Writer writer, Throwable e) throws IOException {
+ StringWriter str = new StringWriter(256);
+ PrintWriter pstr = new PrintWriter(str);
+ e.printStackTrace(pstr);
+ pstr.close();
+ writer.write(str.toString().replaceAll("<", TS));
+ }
+
+ public static void debugHtml(Writer writer, FacesContext faces) throws IOException {
+ init(faces);
+ Date now = new Date();
+ for (int i = 0; i < DEBUG_PARTS.length; i++) {
+ if ("message".equals(DEBUG_PARTS[i])) {
+ writer.write(faces.getViewRoot().getViewId());
+ } else if ("now".equals(DEBUG_PARTS[i])) {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ } else if ("tree".equals(DEBUG_PARTS[i])) {
+ writeComponent(writer, faces.getViewRoot(), null);
+ } else if ("vars".equals(DEBUG_PARTS[i])) {
+ writeVariables(writer, faces);
+ } else {
+ writer.write(DEBUG_PARTS[i]);
+ }
+ }
+ }
+
+ static void writeVariables(Writer writer, FacesContext faces) throws IOException {
+ ExternalContext ctx = faces.getExternalContext();
+ writeVariables(writer, ctx.getRequestParameterMap(), "Request Parameters");
+ writeVariables(writer, ctx.getRequestMap(), "Request Attributes");
+ if (ctx.getSession(false) != null) {
+ writeVariables(writer, ctx.getSessionMap(), "Session Attributes");
+ }
+ writeVariables(writer, ctx.getApplicationMap(), "Application Attributes");
+ }
+
+ private static void writeVariables(Writer writer, Map vars, String caption) throws IOException {
+ writer.write("<table><caption>");
+ writer.write(caption);
+ writer.write("</caption><thead><tr><th style=\"width: 10%; \">Name</th><th style=\"width: 90%; \">Value</th></tr></thead><tbody>");
+ boolean written = false;
+ if (!vars.isEmpty()) {
+ SortedMap map = new TreeMap(vars);
+ Map.Entry entry = null;
+ String key = null;
+ for (Iterator itr = map.entrySet().iterator(); itr.hasNext(); ) {
+ entry = (Map.Entry) itr.next();
+ key = entry.getKey().toString();
+ if (key.indexOf('.') == -1) {
+ writer.write("<tr><td>");
+ writer.write(key.replaceAll("<", TS));
+ writer.write("</td><td>");
+ writer.write(entry.getValue().toString().replaceAll("<", TS));
+ writer.write("</td></tr>");
+ written = true;
+ }
+ }
+ }
+ if (!written) {
+ writer.write("<tr><td colspan=\"2\"><em>None</em></td></tr>");
+ }
+ writer.write("</tbody></table>");
+ }
+
+ static void writeComponent(Writer writer, UIComponent c, List highlightId) throws IOException {
+ writer.write("<dl><dt");
+ if (isText(c)) {
+ writer.write(" class=\"uicText\"");
+ }
+ if (highlightId != null){
+ if ((highlightId.size() > 0) && (highlightId.get(0).equals(c.getId()))){
+ highlightId.remove(0);
+ if (highlightId.size()==0){
+ writer.write(" class=\"highlightComponent\"");
+ }
+ }
+ }
+ writer.write(">");
+
+ boolean hasChildren = c.getChildCount() > 0 || c.getFacets().size() > 0;
+
+ writeStart(writer, c, hasChildren);
+ writer.write("</dt>");
+ if (hasChildren) {
+ if (c.getFacets().size() > 0) {
+ Map.Entry entry;
+ for (Iterator itr = c.getFacets().entrySet().iterator(); itr.hasNext(); ) {
+ entry = (Map.Entry) itr.next();
+ writer.write("<dd class=\"uicFacet\">");
+ writer.write("<span>");
+ writer.write((String) entry.getKey());
+ writer.write("</span>");
+ writeComponent(writer, (UIComponent) entry.getValue(), highlightId);
+ writer.write("</dd>");
+ }
+ }
+ if (c.getChildCount() > 0) {
+ for (Iterator itr = c.getChildren().iterator(); itr.hasNext(); ) {
+ writer.write("<dd>");
+ writeComponent(writer, (UIComponent) itr.next(), highlightId);
+ writer.write("</dd>");
+ }
+ }
+ writer.write("<dt>");
+ writeEnd(writer, c);
+ writer.write("</dt>");
+ }
+ writer.write("</dl>");
+ }
+
+ private static void writeEnd(Writer writer, UIComponent c) throws IOException {
+ if (!isText(c)) {
+ writer.write(TS);
+ writer.write('/');
+ writer.write(getName(c));
+ writer.write('>');
+ }
+ }
+
+ private final static String[] IGNORE = new String[] { "parent", "rendererType" };
+
+ private static void writeAttributes(Writer writer, UIComponent c) {
+ try {
+ BeanInfo info = Introspector.getBeanInfo(c.getClass());
+ PropertyDescriptor[] pd = info.getPropertyDescriptors();
+ Method m = null;
+ Object v = null;
+ String str = null;
+ for (int i = 0; i < pd.length; i++) {
+ if (pd[i].getWriteMethod() != null && Arrays.binarySearch(IGNORE, pd[i].getName()) < 0) {
+ m = pd[i].getReadMethod();
+ try {
+ v = m.invoke(c, null);
+ if (v != null) {
+ if (v instanceof Collection || v instanceof Map || v instanceof Iterator) {
+ continue;
+ }
+ writer.write(" ");
+ writer.write(pd[i].getName());
+ writer.write("=\"");
+ if (v instanceof ValueBinding) {
+ str = ((ValueBinding) v).getExpressionString();
+ } else if (v instanceof MethodBinding) {
+ str = ((MethodBinding) v).getExpressionString();
+ } else {
+ ValueBinding vb = c.getValueBinding(pd[i].getName());
+ str = vb!=null?(vb.getExpressionString()+"="+v.toString()):v.toString();
+ }
+ writer.write(str.replaceAll("<", TS));
+ writer.write("\"");
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
+
+ ValueBinding binding = c.getValueBinding("binding");
+ if (binding != null) {
+ writer.write(" binding=\"");
+ writer.write(binding.getExpressionString().replaceAll("<", TS));
+ writer.write("\"");
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+
+ private static void writeStart(Writer writer, UIComponent c, boolean children) throws IOException {
+ if (isText(c)) {
+ String str = c.toString().trim();
+ writer.write(str.replaceAll("<", TS));
+ } else {
+ writer.write(TS);
+ writer.write(getName(c));
+ writeAttributes(writer, c);
+ if (children) {
+ writer.write('>');
+ } else {
+ writer.write("/>");
+ }
+ }
+ }
+
+ private static String getName(UIComponent c) {
+ String nm = c.getClass().getName();
+ return nm.substring(nm.lastIndexOf('.') + 1);
+ }
+
+ private static boolean isText(UIComponent c) {
+ return (c.getClass().getName().startsWith("com.sun.facelets.compiler"));
+ }
+
+ public static void handleException(FacesContext facesContext, Exception ex) throws ServletException, IOException
+ {
+ handleThrowable(facesContext, ex);
+ }
+
+ public static void handleThrowable(FacesContext facesContext, Throwable ex) throws ServletException, IOException {
+
+ prepareExceptionStack(ex);
+
+ Object response = facesContext.getExternalContext().getResponse();
+ if(response instanceof HttpServletResponse) {
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+ if (!httpResp.isCommitted()) {
+ httpResp.reset();
+ httpResp.setContentType("text/html; charset=UTF-8");
+ Writer writer = httpResp.getWriter();
+
+ debugHtml(writer, facesContext, ex);
+
+ log.error("An exception occurred", ex);
+ }
+ else {
+ throwException(ex);
+ }
+ }
+ else {
+ throwException(ex);
+ }
+ }
+
+ public static void handleExceptionList(FacesContext facesContext, List exceptionList) throws ServletException, IOException
+ {
+ for (int i = 0; i < exceptionList.size(); i++)
+ {
+ prepareExceptionStack( (Exception) exceptionList.get(i));
+ }
+
+ Object response = facesContext.getExternalContext().getResponse();
+ if(response instanceof HttpServletResponse)
+ {
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+ if (!httpResp.isCommitted())
+ {
+ httpResp.reset();
+ httpResp.setContentType("text/html; charset=UTF-8");
+ Writer writer = httpResp.getWriter();
+
+ debugHtml(writer, facesContext, exceptionList);
+
+ for (int i = 0; i < exceptionList.size(); i++)
+ {
+ log.error("An exception occurred", (Exception) exceptionList.get(i));
+ }
+ }
+ else
+ {
+ throwException((Exception)exceptionList.get(0));
+ }
+ }
+ else
+ {
+ throwException((Exception)exceptionList.get(0));
+ }
+ }
+
+ private static void prepareExceptionStack(Throwable ex) {
+
+ if(ex==null)
+ return;
+
+ //check for getRootCause and getCause-methods
+ if(!initCausePerReflection(ex,"getRootCause")) {
+ initCausePerReflection(ex,"getCause");
+ }
+
+ prepareExceptionStack(getCause(ex));
+ }
+
+ /**
+ * Get the cause of an exception, if available. Reflection must be used because
+ * JSF11 supports java1.3 but Throwable.getCause was added in java1.4.
+ */
+ private static Throwable getCause(Throwable ex) {
+ try {
+ Method causeGetter = ex.getClass().getMethod("getCause", NO_ARGS);
+ Throwable cause = (Throwable) causeGetter.invoke(ex, NO_ARGS);
+ return cause;
+ } catch (Exception e1) {
+ return null;
+ }
+ }
+
+ private static boolean initCausePerReflection(Throwable ex, String methodName) {
+ try {
+ Method causeGetter = ex.getClass().getMethod(methodName, NO_ARGS);
+ Throwable rootCause = (Throwable) causeGetter.invoke(ex, NO_ARGS);
+ return initCauseIfAvailable(ex,rootCause);
+ } catch (Exception e1) {
+ return false;
+ }
+ }
+
+ static void throwException(Throwable e) throws IOException, ServletException {
+
+ prepareExceptionStack(e);
+
+ if (e instanceof IOException)
+ {
+ throw (IOException)e;
+ }
+ else if (e instanceof ServletException)
+ {
+ throw (ServletException)e;
+ }
+ else
+ {
+ ServletException ex;
+
+ if (e.getMessage() != null) {
+ ex=new ServletException(e.getMessage(), e);
+ }
+ else {
+ ex=new ServletException(e);
+ }
+
+ initCauseIfAvailable(ex, e);
+
+ throw ex;
+ }
+ }
+
+ private static boolean initCauseIfAvailable(Throwable th, Throwable cause) {
+
+ if(cause == null)
+ return false;
+
+ try {
+ Method m = Throwable.class.getMethod("initCause",new Class[]{Throwable.class});
+ m.invoke(th,new Object[]{cause});
+ return true;
+ }
+ catch(Exception e) {
+ return false;
+ }
+ }
+}
+
Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java
------------------------------------------------------------------------------
svn:mergeinfo =
Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java?rev=689684&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java Wed Aug 27 17:50:09 2008
@@ -0,0 +1,370 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.myfaces.tomahawk.util;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.faces.FacesException;
+import javax.faces.FactoryFinder;
+import javax.faces.application.NavigationHandler;
+import javax.faces.context.FacesContext;
+import javax.faces.el.ValueBinding;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.webapp.FacesServlet;
+import javax.servlet.ServletException;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This handler redirect to a jsf page when an error occurs.
+ * <p>
+ * This class is set as a config-parameter org.apache.myfaces.ERROR_HANDLER
+ * available on myfaces core jsf. (This does not work with RI)
+ * </p>
+ * <p>
+ * The idea is extends myfaces error handling feature, making possible to redirect
+ * to a jsf page when an error occur, using navigation rules.
+ * </p>
+ * <p>
+ * If this handler is not able to handle the error, and alternate error handler
+ * could be set in the config-parameter org.apache.myfaces.ERROR_REDIRECT_ALTERNATE_HANDLER
+ * </p>
+ * <p>
+ * The info of the error in the jsf page can be found using:
+ * </p>
+ * <ul>
+ * <li>#{exceptionContext.cause} : Cause retrieved from the exception</li>
+ * <li>#{exceptionContext.stackTrace} : Stack trace of the exception</li>
+ * <li>#{exceptionContext.exception} : Exception handled by this page </li>
+ * <li>#{exceptionContext.tree} : Print the component tree of the page that cause the error</li>
+ * <li>#{exceptionContext.vars} : Enviroment variables from the request</li>
+ * </ul>
+ *
+ * @author Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class ErrorRedirectJSFPageHandler
+{
+ private static final Log log = LogFactory
+ .getLog(ErrorRedirectJSFPageHandler.class);
+
+ /**
+ * This param tells if ignore java.lang.* superclass names errors
+ * are found. In other words, all java.lang.* exceptions are simply
+ * skipped by this handler (so it could be thrown to an alternate handler
+ * or the jsp handler).
+ */
+ private static final String ERROR_HANDLING_IGNORE_BASE_ERROR_REDIRECT = "org.apache.myfaces.ERROR_HANDLING_IGNORE_BASE_ERROR_REDIRECT";
+
+ private static final String ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER = "org.apache.myfaces.ERROR_REDIRECT_ALTERNATE_HANDLER";
+
+ private static String getErrorRedirectAlternateHandler(FacesContext context)
+ {
+ String errorHandlerClass = context.getExternalContext().getInitParameter(ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER);
+ return errorHandlerClass;
+ }
+
+ private static boolean isIgnoreBaseErrorRedirect(FacesContext context)
+ {
+ return getBooleanValue(context.getExternalContext().getInitParameter(
+ ERROR_HANDLING_IGNORE_BASE_ERROR_REDIRECT), false);
+ }
+
+ private static boolean getBooleanValue(String initParameter,
+ boolean defaultVal)
+ {
+ if (initParameter == null || initParameter.trim().length() == 0)
+ return defaultVal;
+
+ return (initParameter.equalsIgnoreCase("on")
+ || initParameter.equals("1") || initParameter
+ .equalsIgnoreCase("true"));
+ }
+
+ public static void handleException(FacesContext facesContext, Exception e)
+ throws ServletException, IOException
+ {
+ boolean oldRenderResponse = facesContext.getRenderResponse();
+ ExceptionContext exceptionContext = new ExceptionContext(e,
+ facesContext.getViewRoot());
+
+ if (!handleCauseOrThrowable(facesContext, exceptionContext, e,
+ oldRenderResponse, isIgnoreBaseErrorRedirect(facesContext)))
+ {
+ //ErrorPageWriter.handleException(facesContext, ex);
+ String errorHandlerClass = getErrorRedirectAlternateHandler(facesContext);
+ if (errorHandlerClass == null)
+ {
+ //Redirect to another handler if it is available
+ try
+ {
+ Class clazz = Class.forName(errorHandlerClass);
+
+ Object errorHandler = clazz.newInstance();
+
+ Method m = clazz.getMethod("handleException", new Class[]{FacesContext.class,Exception.class});
+ m.invoke(errorHandler, new Object[]{facesContext, e});
+ }
+ catch(ClassNotFoundException ex)
+ {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " was not found. Fix your web.xml-parameter : "+ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ }
+ catch (IllegalAccessException ex)
+ {
+ throw new ServletException("Constructor of error-Handler : "
+ +errorHandlerClass+ " is not accessible. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ }
+ catch (InstantiationException ex)
+ {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " could not be instantiated. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ }
+ catch (NoSuchMethodException ex)
+ {
+ log.error("Error-Handler : "
+ +errorHandlerClass
+ + " did not have a method with name : handleException and parameters : javax.faces.context.FacesContext, java.lang.Exception. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ //Try to look if it is implemented more general method handleThrowable
+ handleThrowable(facesContext, ex);
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw new ServletException("Excecution of method handleException in Error-Handler : "
+ +errorHandlerClass
+ + " caused an exception. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ }
+ }
+ else
+ {
+ //throw exception because this redirect handler
+ //does not have any rule defined.
+ ErrorPageWriter.throwException(e);
+ }
+ }
+ }
+
+ public static void handleThrowable(FacesContext facesContext, Throwable e)
+ throws ServletException, IOException
+ {
+ boolean oldRenderResponse = facesContext.getRenderResponse();
+ ExceptionContext exceptionContext = new ExceptionContext(e,
+ facesContext.getViewRoot());
+
+ if (!handleCauseOrThrowable(facesContext, exceptionContext, e,
+ oldRenderResponse, isIgnoreBaseErrorRedirect(facesContext)))
+ {
+ //ErrorPageWriter.handleThrowable(facesContext, e);
+ String errorHandlerClass = getErrorRedirectAlternateHandler(facesContext);
+ if (errorHandlerClass == null)
+ {
+ try {
+ Class clazz = Class.forName(errorHandlerClass);
+
+ Object errorHandler = clazz.newInstance();
+
+ Method m = clazz.getMethod("handleThrowable", new Class[]{FacesContext.class,Throwable.class});
+ m.invoke(errorHandler, new Object[]{facesContext, e});
+ }
+ catch(ClassNotFoundException ex) {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " was not found. Fix your web.xml-parameter : "+ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (IllegalAccessException ex) {
+ throw new ServletException("Constructor of error-Handler : "
+ +errorHandlerClass
+ + " is not accessible. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (InstantiationException ex) {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " could not be instantiated. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (NoSuchMethodException ex) {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " did not have a method with name : handleException and parameters : javax.faces.context.FacesContext, java.lang.Exception. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (InvocationTargetException ex) {
+ throw new ServletException("Excecution of method handleException in Error-Handler : "
+ +errorHandlerClass
+ + " threw an exception. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ }
+ }
+ else
+ {
+ //throw exception because this redirect handler
+ //does not have any rule defined.
+ ErrorPageWriter.throwException(e);
+ }
+ }
+ }
+
+ public static void handleExceptionList(FacesContext facesContext,
+ List exceptionList) throws ServletException, IOException
+ {
+ boolean isHandleCauseOrThrowable = false;
+
+ //Try to check if some exception on the list have a applicable
+ //navigation rule.
+ for (Iterator it = exceptionList.iterator(); it.hasNext();)
+ {
+ Exception ex = (Exception) it.next();
+
+ boolean oldRenderResponse = facesContext.getRenderResponse();
+ ExceptionContext exceptionContext = new ExceptionContext(ex,
+ facesContext.getViewRoot());
+
+ isHandleCauseOrThrowable = handleCauseOrThrowable(facesContext,
+ exceptionContext, ex, oldRenderResponse,
+ isIgnoreBaseErrorRedirect(facesContext));
+
+ if (isHandleCauseOrThrowable)
+ break;
+ }
+
+ if (!isHandleCauseOrThrowable)
+ {
+ //If no navigation happened, handle as exception using
+ //the default ErrorPageWriter
+ //ErrorPageWriter.handleException(facesContext,
+ // (Exception) exceptionList.get(0));
+ String errorHandlerClass = getErrorRedirectAlternateHandler(facesContext);
+ if(errorHandlerClass != null) {
+ try {
+ Class clazz = Class.forName(errorHandlerClass);
+
+ Object errorHandler = clazz.newInstance();
+
+ Method m = clazz.getMethod("handleExceptionList", new Class[]{FacesContext.class,Exception.class});
+ m.invoke(errorHandler, new Object[]{facesContext, exceptionList});
+ }
+ catch(ClassNotFoundException ex) {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " was not found. Fix your web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (IllegalAccessException ex) {
+ throw new ServletException("Constructor of error-Handler : "
+ +errorHandlerClass
+ + " is not accessible. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (InstantiationException ex) {
+ throw new ServletException("Error-Handler : "
+ +errorHandlerClass
+ + " could not be instantiated. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ } catch (NoSuchMethodException ex) {
+ //Handle in the old way, since no custom method handleExceptionList found,
+ //throwing the first FacesException on the list.
+ throw (FacesException) exceptionList.get(0);
+ } catch (InvocationTargetException ex) {
+ throw new ServletException("Excecution of method handleException in Error-Handler : "
+ +errorHandlerClass
+ + " threw an exception. Error-Handler is specified in web.xml-parameter : "
+ +ERROR_REDIRECT_ALTERNATE_HANDLER_PARAMETER,ex);
+ }
+ }
+ else
+ {
+ ErrorPageWriter.throwException((Exception) exceptionList.get(0));
+ }
+ }
+ }
+
+ private static String getLifecycleId(FacesContext context)
+ {
+ String lifecycleId = context.getExternalContext().getInitParameter(
+ FacesServlet.LIFECYCLE_ID_ATTR);
+ return lifecycleId != null ? lifecycleId
+ : LifecycleFactory.DEFAULT_LIFECYCLE;
+ }
+
+ private static boolean handleCauseOrThrowable(FacesContext context,
+ ExceptionContext exceptionContext, Throwable th,
+ boolean oldRenderResponse, boolean ignoreBaseException)
+ {
+
+ boolean throwableHandled = false;
+ //First try to find the most inner child in the exception stack
+ if (th.getCause() != null)
+ {
+ throwableHandled = handleCauseOrThrowable(context,
+ exceptionContext, th.getCause(), oldRenderResponse,
+ ignoreBaseException);
+ }
+
+ if (throwableHandled == false)
+ {
+ Class thClass = th.getClass();
+ while (thClass != null)
+ {
+ // ignore java.lang.* superclass names
+ if (ignoreBaseException
+ && thClass.getName().startsWith("java.lang."))
+ {
+ return false;
+ }
+ log.info("Trying to redirect to jsf page:" + thClass.getName());
+ NavigationHandler nh = context.getApplication()
+ .getNavigationHandler();
+ nh.handleNavigation(context, null, thClass.getName());
+
+ //Check if the navigation happened.
+ //to call the render response phase
+ if (context.getRenderResponse())//navigationHappened(oldRenderResponse, oldViewId, context)
+ {
+ //exceptionHandlingContext.setExceptionHandled();
+ log.error("an error occurred : ", th);
+
+ ValueBinding vb = context.getApplication()
+ .createValueBinding("#{exceptionContext}");
+
+ vb.setValue(context, exceptionContext);
+
+ LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder
+ .getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+ Lifecycle _lifecycle = lifecycleFactory
+ .getLifecycle(getLifecycleId(context));
+ _lifecycle.render(context);
+
+ vb.setValue(context, null);
+
+ context.responseComplete();
+ return true;
+ }
+ thClass = thClass.getSuperclass();
+ }
+ }
+ return throwableHandled;
+ }
+}
Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ErrorRedirectJSFPageHandler.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java?rev=689684&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java Wed Aug 27 17:50:09 2008
@@ -0,0 +1,190 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.myfaces.tomahawk.util;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.text.DateFormat;
+import java.util.Date;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+
+/**
+ * The ExceptionContext class holds all information related to an error
+ * ocurred in a jsf environment, handled by a redirection using
+ * ErrorRedirectJSFPageHandler.
+ *
+ * @author Leonardo Uribe (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ */
+public class ExceptionContext
+{
+
+ private Throwable _exception;
+
+ private UIComponent _viewRoot;
+
+ private String _cause;
+
+ private String _tree;
+
+ private String _vars;
+
+ public ExceptionContext(Throwable _exception, UIComponent viewRoot)
+ {
+ super();
+ this._exception = _exception;
+ this._viewRoot = viewRoot;
+ }
+
+ public void setException(Throwable exception)
+ {
+ this._exception = exception;
+ }
+
+ public Throwable getException()
+ {
+ return _exception;
+ }
+
+ public String getCause()
+ {
+ if (_cause == null)
+ {
+ StringWriter writer = null;
+ try
+ {
+ writer = new StringWriter(256);
+ ErrorPageWriter.writeCause(writer, _exception);
+ }
+ catch (IOException e)
+ {
+ //do nothing
+ }
+ finally
+ {
+ try
+ {
+ if (writer != null)
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ //do nothing
+ }
+ }
+ _cause = writer.toString();
+ }
+ return _cause;
+ }
+
+ public String getStackTrace()
+ {
+ StringWriter str = new StringWriter(256);
+ PrintWriter pstr = new PrintWriter(str);
+ _exception.printStackTrace(pstr);
+ pstr.close();
+ return str.toString();
+ }
+
+ public String getNow()
+ {
+ Date now = new Date();
+ return DateFormat.getDateTimeInstance().format(now);
+ }
+
+ public UIComponent getViewRoot()
+ {
+ return _viewRoot;
+ }
+
+ public void setViewRoot(UIComponent viewRoot)
+ {
+ this._viewRoot = viewRoot;
+ }
+
+ public String getVars()
+ {
+ if (_vars == null)
+ {
+ StringWriter writer = null;
+ try
+ {
+ writer = new StringWriter(256);
+ ErrorPageWriter.writeVariables(writer, FacesContext.getCurrentInstance());
+ _vars = writer.toString();
+ }
+ catch (IOException e)
+ {
+ //do nothing
+ }
+ finally
+ {
+ try
+ {
+ if (writer != null)
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ //do nothing
+ }
+ }
+ }
+ return _vars;
+ }
+
+ public String getTree()
+ {
+ if (_tree == null)
+ {
+ if (_viewRoot != null)
+ {
+ StringWriter writer = null;
+ try
+ {
+ writer = new StringWriter(256);
+ ErrorPageWriter.writeComponent(writer, _viewRoot,
+ ErrorPageWriter.getErrorId(_exception));
+ _tree = writer.toString();
+ }
+ catch (IOException e)
+ {
+ //do nothing
+ }
+ finally
+ {
+ try
+ {
+ if (writer != null)
+ writer.close();
+ }
+ catch (IOException e)
+ {
+ //do nothing
+ }
+ }
+ }
+ }
+ return _tree;
+ }
+
+}
Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/tomahawk/trunk/sandbox/core/src/main/java/org/apache/myfaces/tomahawk/util/ExceptionContext.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Added: myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java?rev=689684&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java (added)
+++ myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java Wed Aug 27 17:50:09 2008
@@ -0,0 +1,578 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.myfaces.tomahawk.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.context.FacesContext;
+import javax.faces.context.ExternalContext;
+import javax.faces.component.UIComponent;
+import javax.el.Expression;
+import javax.el.ValueExpression;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.*;
+import java.lang.reflect.Method;
+import java.text.DateFormat;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * This class is the same as javax.faces.webapp._ErrorPageWriter,
+ * but is cloned here to allow ErrorRedirectJSFPageHandler to provide
+ * an alternative when no navigation rule for a specific exception is
+ * found.
+ *
+ * @author Jacob Hookom (ICLA with ASF filed)
+ */
+public class ErrorPageWriter {
+
+ private static final Log log = LogFactory.getLog(ErrorPageWriter.class);
+
+ private final static String TS = "<";
+
+ private static final String ERROR_TEMPLATE = "META-INF/rsc/myfaces-dev-error.xml";
+
+ private static final String ERROR_TEMPLATE_RESOURCE = "org.apache.myfaces.ERROR_TEMPLATE_RESOURCE";
+
+ private static String[] ERROR_PARTS;
+
+ private static final String DEBUG_TEMPLATE = "META-INF/rsc/myfaces-dev-debug.xml";
+
+ private static final String DEBUG_TEMPLATE_RESOURCE = "org.apache.myfaces.DEBUG_TEMPLATE_RESOURCE";
+
+ private static String[] DEBUG_PARTS;
+
+ public ErrorPageWriter() {
+ super();
+ }
+
+ private static String getErrorTemplate(FacesContext context)
+ {
+ String errorTemplate = context.getExternalContext().getInitParameter(ERROR_TEMPLATE_RESOURCE);
+ if (errorTemplate != null)
+ {
+ return errorTemplate;
+ }
+ return ERROR_TEMPLATE;
+ }
+
+ private static String getDebugTemplate(FacesContext context)
+ {
+ String debugTemplate = context.getExternalContext().getInitParameter(DEBUG_TEMPLATE_RESOURCE);
+ if (debugTemplate != null)
+ {
+ return debugTemplate;
+ }
+ return DEBUG_TEMPLATE;
+ }
+
+ private static void init(FacesContext context) throws IOException {
+ if (ERROR_PARTS == null) {
+ ERROR_PARTS = splitTemplate(getErrorTemplate(context));
+ }
+
+ if (DEBUG_PARTS == null) {
+ DEBUG_PARTS = splitTemplate(getDebugTemplate(context));
+ }
+ }
+
+ private static String[] splitTemplate(String rsc) throws IOException {
+ InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(rsc);
+ if (is == null) {
+ throw new FileNotFoundException(rsc);
+ }
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buff = new byte[512];
+ int read;
+ while ((read = is.read(buff)) != -1) {
+ baos.write(buff, 0, read);
+ }
+ String str = baos.toString();
+ return str.split("@@");
+ }
+
+ public static ArrayList getErrorId(Throwable e){
+ String message = e.getMessage();
+
+ if(message==null)
+ return null;
+
+ ArrayList list = new ArrayList();
+ Pattern pattern = Pattern.compile(".*?\\Q,Id:\\E\\s*(\\S+)\\s*\\].*?");
+ Matcher matcher = pattern.matcher(message);
+
+ while (matcher.find()){
+ list.add(matcher.group(1));
+ }
+ if (list.size()>0) return list;
+ return null;
+ }
+
+ public static void writeCause(Writer writer, Throwable ex) throws IOException {
+ String msg = ex.getMessage();
+ while (ex.getCause()!=null){
+ ex=ex.getCause();
+ if (ex.getMessage()!=null) msg = ex.getMessage();
+ }
+
+ if (msg != null) {
+ msg =ex.getClass().getName() + " - " + msg;
+ writer.write(msg.replaceAll("<", TS));
+ } else {
+ writer.write(ex.getClass().getName());
+ }
+ }
+
+ public static void debugHtml(Writer writer, FacesContext faces, Throwable e) throws IOException {
+ init(faces);
+ Date now = new Date();
+ for (int i = 0; i < ERROR_PARTS.length; i++) {
+ if ("message".equals(ERROR_PARTS[i])) {
+ String msg = e.getMessage();
+ if (msg != null) {
+ writer.write(msg.replaceAll("<", TS));
+ } else {
+ writer.write(e.getClass().getName());
+ }
+ } else if ("trace".equals(ERROR_PARTS[i])) {
+ writeException(writer, e);
+ } else if ("now".equals(ERROR_PARTS[i])) {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ } else if ("tree".equals(ERROR_PARTS[i])) {
+ if (faces.getViewRoot() != null) {
+ writeComponent(writer, faces.getViewRoot(), getErrorId(e));
+ }
+ } else if ("vars".equals(ERROR_PARTS[i])) {
+ writeVariables(writer, faces);
+ } else if ("cause".equals(ERROR_PARTS[i])) {
+ writeCause(writer, e);
+ } else {
+ writer.write(ERROR_PARTS[i]);
+ }
+ }
+ }
+
+ public static void debugHtml(Writer writer, FacesContext faces, List exceptionList) throws IOException
+ {
+ init(faces);
+ Date now = new Date();
+ for (int i = 0; i < ERROR_PARTS.length; i++)
+ {
+ if ("message".equals(ERROR_PARTS[i]))
+ {
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ String msg = e.getMessage();
+ if (msg != null)
+ {
+ writer.write(msg.replaceAll("<", TS));
+ }
+ else
+ {
+ writer.write(e.getClass().getName());
+ }
+ if (!(j+1==exceptionList.size()))
+ {
+ writer.write("<br>");
+ }
+ }
+ }
+ else if ("trace".equals(ERROR_PARTS[i]))
+ {
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ writeException(writer, e);
+ }
+ }
+ else if ("now".equals(ERROR_PARTS[i]))
+ {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ }
+ else if ("tree".equals(ERROR_PARTS[i]))
+ {
+ if (faces.getViewRoot() != null)
+ {
+ List highlightId = null;
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ if (highlightId == null)
+ {
+ highlightId = getErrorId(e);
+ }
+ else
+ {
+ highlightId.addAll(getErrorId(e));
+ }
+ }
+ writeComponent(writer, faces.getViewRoot(), highlightId);
+ }
+ }
+ else if ("vars".equals(ERROR_PARTS[i]))
+ {
+ writeVariables(writer, faces);
+ }
+ else if ("cause".equals(ERROR_PARTS[i]))
+ {
+ for (int j = 0; j < exceptionList.size(); j++)
+ {
+ Exception e = (Exception) exceptionList.get(j);
+ writeCause(writer, e);
+ if (!(j+1==exceptionList.size()))
+ {
+ writer.write("<br>");
+ }
+ }
+ }
+ else
+ {
+ writer.write(ERROR_PARTS[i]);
+ }
+ }
+ }
+
+ private static void writeException(Writer writer, Throwable e) throws IOException {
+ StringWriter str = new StringWriter(256);
+ PrintWriter pstr = new PrintWriter(str);
+ e.printStackTrace(pstr);
+ pstr.close();
+ writer.write(str.toString().replaceAll("<", TS));
+ }
+
+ public static void debugHtml(Writer writer, FacesContext faces) throws IOException {
+ init(faces);
+ Date now = new Date();
+ for (int i = 0; i < DEBUG_PARTS.length; i++) {
+ if ("message".equals(DEBUG_PARTS[i])) {
+ writer.write(faces.getViewRoot().getViewId());
+ } else if ("now".equals(DEBUG_PARTS[i])) {
+ writer.write(DateFormat.getDateTimeInstance().format(now));
+ } else if ("tree".equals(DEBUG_PARTS[i])) {
+ writeComponent(writer, faces.getViewRoot(), null);
+ } else if ("vars".equals(DEBUG_PARTS[i])) {
+ writeVariables(writer, faces);
+ } else {
+ writer.write(DEBUG_PARTS[i]);
+ }
+ }
+ }
+
+ public static void writeVariables(Writer writer, FacesContext faces) throws IOException {
+ ExternalContext ctx = faces.getExternalContext();
+ writeVariables(writer, ctx.getRequestParameterMap(), "Request Parameters");
+ writeVariables(writer, ctx.getRequestMap(), "Request Attributes");
+ if (ctx.getSession(false) != null) {
+ writeVariables(writer, ctx.getSessionMap(), "Session Attributes");
+ }
+ writeVariables(writer, ctx.getApplicationMap(), "Application Attributes");
+ }
+
+ private static void writeVariables(Writer writer, Map vars, String caption) throws IOException {
+ writer.write("<table><caption>");
+ writer.write(caption);
+ writer.write("</caption><thead><tr><th style=\"width: 10%; \">Name</th><th style=\"width: 90%; \">Value</th></tr></thead><tbody>");
+ boolean written = false;
+ if (!vars.isEmpty()) {
+ SortedMap map = new TreeMap(vars);
+ Map.Entry entry = null;
+ String key = null;
+ for (Iterator itr = map.entrySet().iterator(); itr.hasNext(); ) {
+ entry = (Map.Entry) itr.next();
+ key = entry.getKey().toString();
+ if (key.indexOf('.') == -1) {
+ writer.write("<tr><td>");
+ writer.write(key.replaceAll("<", TS));
+ writer.write("</td><td>");
+ writer.write(entry.getValue().toString().replaceAll("<", TS));
+ writer.write("</td></tr>");
+ written = true;
+ }
+ }
+ }
+ if (!written) {
+ writer.write("<tr><td colspan=\"2\"><em>None</em></td></tr>");
+ }
+ writer.write("</tbody></table>");
+ }
+
+ public static void writeComponent(Writer writer, UIComponent c, List highlightId) throws IOException {
+ writer.write("<dl><dt");
+ if (isText(c)) {
+ writer.write(" class=\"uicText\"");
+ }
+ if (highlightId != null){
+ if ((highlightId.size() > 0) && (highlightId.get(0).equals(c.getId()))){
+ highlightId.remove(0);
+ if (highlightId.size()==0){
+ writer.write(" class=\"highlightComponent\"");
+ }
+ }
+ }
+ writer.write(">");
+
+ boolean hasChildren = c.getChildCount() > 0 || c.getFacets().size() > 0;
+
+ writeStart(writer, c, hasChildren);
+ writer.write("</dt>");
+ if (hasChildren) {
+ if (c.getFacets().size() > 0) {
+ Map.Entry entry;
+ for (Iterator itr = c.getFacets().entrySet().iterator(); itr.hasNext(); ) {
+ entry = (Map.Entry) itr.next();
+ writer.write("<dd class=\"uicFacet\">");
+ writer.write("<span>");
+ writer.write((String) entry.getKey());
+ writer.write("</span>");
+ writeComponent(writer, (UIComponent) entry.getValue(), highlightId);
+ writer.write("</dd>");
+ }
+ }
+ if (c.getChildCount() > 0) {
+ for (Iterator itr = c.getChildren().iterator(); itr.hasNext(); ) {
+ writer.write("<dd>");
+ writeComponent(writer, (UIComponent) itr.next(), highlightId);
+ writer.write("</dd>");
+ }
+ }
+ writer.write("<dt>");
+ writeEnd(writer, c);
+ writer.write("</dt>");
+ }
+ writer.write("</dl>");
+ }
+
+ private static void writeEnd(Writer writer, UIComponent c) throws IOException {
+ if (!isText(c)) {
+ writer.write(TS);
+ writer.write('/');
+ writer.write(getName(c));
+ writer.write('>');
+ }
+ }
+
+ private final static String[] IGNORE = new String[] { "parent", "rendererType" };
+
+ private static void writeAttributes(Writer writer, UIComponent c) {
+ try {
+ BeanInfo info = Introspector.getBeanInfo(c.getClass());
+ PropertyDescriptor[] pd = info.getPropertyDescriptors();
+ Method m = null;
+ Object v = null;
+ String str = null;
+ for (int i = 0; i < pd.length; i++) {
+ if (pd[i].getWriteMethod() != null && Arrays.binarySearch(IGNORE, pd[i].getName()) < 0) {
+ m = pd[i].getReadMethod();
+ try {
+ v = m.invoke(c, null);
+ if (v != null) {
+ if (v instanceof Collection || v instanceof Map || v instanceof Iterator) {
+ continue;
+ }
+ writer.write(" ");
+ writer.write(pd[i].getName());
+ writer.write("=\"");
+ if (v instanceof Expression) {
+ str = ((Expression) v).getExpressionString();
+ }
+ writer.write(str.replaceAll("<", TS));
+ writer.write("\"");
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+ }
+
+ ValueExpression binding = c.getValueExpression("binding");
+ if (binding != null) {
+ writer.write(" binding=\"");
+ writer.write(binding.getExpressionString().replaceAll("<", TS));
+ writer.write("\"");
+ }
+ } catch (Exception e) {
+ // do nothing
+ }
+ }
+
+ private static void writeStart(Writer writer, UIComponent c, boolean children) throws IOException {
+ if (isText(c)) {
+ String str = c.toString().trim();
+ writer.write(str.replaceAll("<", TS));
+ } else {
+ writer.write(TS);
+ writer.write(getName(c));
+ writeAttributes(writer, c);
+ if (children) {
+ writer.write('>');
+ } else {
+ writer.write("/>");
+ }
+ }
+ }
+
+ private static String getName(UIComponent c) {
+ String nm = c.getClass().getName();
+ return nm.substring(nm.lastIndexOf('.') + 1);
+ }
+
+ private static boolean isText(UIComponent c) {
+ return (c.getClass().getName().startsWith("com.sun.facelets.compiler"));
+ }
+
+ public static void handleException(FacesContext facesContext, Exception ex) throws ServletException, IOException
+ {
+ handleThrowable(facesContext, ex);
+ }
+
+ public static void handleThrowable(FacesContext facesContext, Throwable ex) throws ServletException, IOException {
+
+ prepareExceptionStack(ex);
+
+ Object response = facesContext.getExternalContext().getResponse();
+ if(response instanceof HttpServletResponse) {
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+ if (!httpResp.isCommitted()) {
+ httpResp.reset();
+ httpResp.setContentType("text/html; charset=UTF-8");
+ Writer writer = httpResp.getWriter();
+
+ debugHtml(writer, facesContext, ex);
+
+ log.error("An exception occurred", ex);
+ }
+ else {
+ throwException(ex);
+ }
+ }
+ else {
+ throwException(ex);
+ }
+ }
+
+ public static void handleExceptionList(FacesContext facesContext, List exceptionList) throws ServletException, IOException
+ {
+ for (int i = 0; i < exceptionList.size(); i++)
+ {
+ prepareExceptionStack( (Exception) exceptionList.get(i));
+ }
+
+ Object response = facesContext.getExternalContext().getResponse();
+ if(response instanceof HttpServletResponse)
+ {
+ HttpServletResponse httpResp = (HttpServletResponse) response;
+ if (!httpResp.isCommitted())
+ {
+ httpResp.reset();
+ httpResp.setContentType("text/html; charset=UTF-8");
+ Writer writer = httpResp.getWriter();
+
+ debugHtml(writer, facesContext, exceptionList);
+
+ for (int i = 0; i < exceptionList.size(); i++)
+ {
+ log.error("An exception occurred", (Exception) exceptionList.get(i));
+ }
+ }
+ else
+ {
+ throwException((Exception)exceptionList.get(0));
+ }
+ }
+ else
+ {
+ throwException((Exception)exceptionList.get(0));
+ }
+ }
+
+ private static void prepareExceptionStack(Throwable ex) {
+
+ if(ex==null)
+ return;
+
+ //check for getRootCause and getCause-methods
+ if(!initCausePerReflection(ex,"getRootCause")) {
+ initCausePerReflection(ex,"getCause");
+ }
+
+ prepareExceptionStack(ex.getCause());
+ }
+
+ private static boolean initCausePerReflection(Throwable ex, String methodName) {
+ try {
+ Method causeGetter = ex.getClass().getMethod(methodName,new Class[]{});
+ Throwable rootCause = (Throwable) causeGetter.invoke(ex,new Class[]{});
+ return initCauseIfAvailable(ex,rootCause);
+ } catch (Exception e1) {
+ return false;
+ }
+ }
+
+ static void throwException(Throwable e) throws IOException, ServletException {
+
+ prepareExceptionStack(e);
+
+ if (e instanceof IOException)
+ {
+ throw (IOException)e;
+ }
+ else if (e instanceof ServletException)
+ {
+ throw (ServletException)e;
+ }
+ else
+ {
+ ServletException ex;
+
+ if (e.getMessage() != null) {
+ ex=new ServletException(e.getMessage(), e);
+ }
+ else {
+ ex=new ServletException(e);
+ }
+
+ initCauseIfAvailable(ex, e);
+
+ throw ex;
+ }
+ }
+
+ private static boolean initCauseIfAvailable(Throwable th, Throwable cause) {
+
+ if(cause == null)
+ return false;
+
+ try {
+ Method m = Throwable.class.getMethod("initCause",new Class[]{Throwable.class});
+ m.invoke(th,new Object[]{cause});
+ return true;
+ }
+ catch(Exception e) {
+ return false;
+ }
+ }
+}
+
Propchange: myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: myfaces/tomahawk/trunk/sandbox/core12/src/main/java/org/apache/myfaces/tomahawk/util/ErrorPageWriter.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL