Package org.ajax4jsf.application

Source Code of org.ajax4jsf.application.DebugOutputMaker

/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/

package org.ajax4jsf.application;

import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.PhaseId;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.ajax4jsf.Messages;
import org.ajax4jsf.resource.InternetResource;
import org.ajax4jsf.resource.InternetResourceBuilder;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;


/**
* @author asmirnov@exadel.com (latest modification by $Author: alexsmirnov $)
* @version $Revision: 1.1.2.1 $ $Date: 2007/01/09 18:57:11 $
*
*/
public class DebugOutputMaker {
    private final static String LT = "<";
    private final static String GT = ">";
  // Attributes that should not be printed
  static public final HashSet IGNORE_ATTRIBUTES;

  static {
    IGNORE_ATTRIBUTES = new HashSet();
    IGNORE_ATTRIBUTES.add("attributes");
    IGNORE_ATTRIBUTES.add("children");
    IGNORE_ATTRIBUTES.add("childCount");
    IGNORE_ATTRIBUTES.add("class");
    IGNORE_ATTRIBUTES.add("facets");
    IGNORE_ATTRIBUTES.add("facetsAndChildren");
    IGNORE_ATTRIBUTES.add("parent");
    IGNORE_ATTRIBUTES.add("actionListeners");
    IGNORE_ATTRIBUTES.add("valueChangeListeners");
    IGNORE_ATTRIBUTES.add("validators");
    IGNORE_ATTRIBUTES.add("rowData");
    IGNORE_ATTRIBUTES.add("javax.faces.webapp.COMPONENT_IDS");
    IGNORE_ATTRIBUTES.add("javax.faces.webapp.FACET_NAMES");
    IGNORE_ATTRIBUTES.add("javax.faces.webapp.CURRENT_VIEW_ROOT");
  }
 
  private static final String LOGFILE_PARAM = "org.ajax4jsf.LOGFILE";

  /**
   * Output error state for lifecycle.
   *
   * @param context
   * @param phase
   *            TODO
   * @param error
   * @throws IOException
   */
  public void writeErrorMessage(FacesContext context, Throwable e, String phase)
      throws FacesException {
    if (null == context) {
      throw new FacesException(Messages.getMessage(Messages.FACES_CONTEXT_NOT_CREATED), e);
    }
    ExternalContext externalContext = context
    .getExternalContext();
    if (null == externalContext) {
      throw new FacesException(Messages.getMessage(Messages.FACES_CONTEXT_HAS_NOT_EXTERNAL), e);
    }
    // debug for http servlet environment, portlets needs other debugger
    HttpServletResponse response;
    HttpServletRequest request;
    try {
      response = (HttpServletResponse) externalContext
          .getResponse();
      request = (HttpServletRequest) externalContext.getRequest();
      response.setContentType("text/html;charset=UTF-8");
      // set internal server error status
      response.setStatus(500);
    } catch (Exception er) {
      throw new FacesException(Messages.getMessage(Messages.FACES_CONTEXT_HAS_NOT_RESPONSE), e);
    }
    PrintWriter out;
    try {
      out = response.getWriter();
    } catch (IOException e1) {
      throw new FacesException(e1.getMessage(), e);
    }
    UIViewRoot viewRoot = context.getViewRoot();
    String viewId;
    if (null != viewRoot) {
      viewId = viewRoot.getViewId();
    } else {
      viewId = request.getRequestURL().toString();
    }
    // output html prolog
    out.println("<html><head><title>" +
        Messages.getMessage(Messages.ERROR_ON_PAGE, viewId) +
        "</title></head><body>");
    // write script
    writeScriptAndStyle(out);
    // Header
    PhaseId facesPhase = (PhaseId) context.getExternalContext().getRequestMap().get(DebugLifecycle.PHASE_ID_PARAM);
   
    String errorMessage =
      (facesPhase == null)
          ? Messages.getMessage(Messages.LIFECYCLE_ERROR, viewId, phase)
          : Messages.getMessage(Messages.LIFECYCLE_ERROR_AT_PHASE, new Object[]{viewId, phase, facesPhase.toString()});
    out.println("<h1 >");
    out.println(errorMessage);
    out.println("</h1>");
    response.setHeader("Ajax-Error-Message", errorMessage+",\n caused by "+e.getClass().getName()+", with message: "+e.getMessage());
    // Output exceptions
    writeExceptionStack(e, out);
    // Output view tree :
    if (null != viewRoot) {
      writeComponentsTree(context, out);
    } else {
      out.print("<h2 class=' a4j_debug'> " +
          Messages.getMessage(Messages.COMPONENT_TREE_NOT_CREATED) +
          " </h2>");
    }
    // Out scope variables
    writeContextVariables(context, out);
    // Write log output iframe :
    writeLog(context, out);
    // out html tail
    out.println("</body></html>");
    out.flush();
    out.close();
  }
  /**
   * @param e
   * @param out
   */
  public void writeExceptionStack(Throwable e, PrintWriter out) {
    out.println("<h2 class=\"a4j_debug\">Exceptions: </h2>");
    Throwable error = e;
    int errorId = 0;
    String caused = "exception ";
    while (null != error) {
      out.print("<h3 onclick=\"toggle('exception" + errorId + "')\"  class='exception a4j_debug'>");
      writeToggleMark(out,"exception" + errorId);         
      out.print( caused + error.getClass().getName() + " : "
          + error.getMessage() + "</h3>");
      out.println("<div id='exception" + errorId
          + "' style='display: none;' class='exception'><p>Exception stack :</p><pre>");
      StackTraceElement[] stackTrace = error.getStackTrace();
      for (int i = 0; i < stackTrace.length; i++) {
        out.print("  at " + stackTrace[i].getClassName());
        out.print("." + stackTrace[i].getMethodName());
        out.println(" in " + stackTrace[i].getFileName() + " line "
            + stackTrace[i].getLineNumber());
      }
      // error.printStackTrace(out);
      out.println("</pre></div>");
      error = error.getCause();
      caused = "caused by ";
      errorId++;
    }
  }
 
  /**
   * @param context
   * @param out
   */
  public void writeContextVariables(FacesContext context, PrintWriter out) {
    out.print("<h2  class=\"a4j_debug\" onclick=\"toggle('variables')\">");
    writeToggleMark(out,"variables");
    out.println("Faces variables: </h2><div id='variables' style='display: none;'  class='variables a4j_debug'>");
    writeVariables(out,context);
    out.println("</div>");
  }

  /**
   * @param context
   * @param out
   */
  public void writeComponentsTree(FacesContext context, PrintWriter out) {
    out
        .print("<h2 class=\"a4j_debug\" onclick=\"toggle('tree')\">");
    writeToggleMark(out,"tree");
    out.println("Component tree: </h2><div id='tree' style='display: none;'  class='tree a4j_debug'><dl>");
    writeComponent(context, out, context.getViewRoot(), null);
    out.println("</dl></div>");
  }
 
  public void writeScriptAndStyle(PrintWriter out) {
    writeScript(out);
    writeStyleSheet(out);
  }

  /**
   * @param context
   * @param out
   * @throws FacesException
   */
  public void writeLog(FacesContext context, PrintWriter out) throws FacesException {
    String logname = context.getExternalContext().getInitParameter(LOGFILE_PARAM);
    if (null != logname) {
      InternetResource logResource = InternetResourceBuilder.getInstance().createResource(this,logname);
      out.print("<h2 onclick=\"toggle('log')\" class=\"a4j_debug\">");
      writeToggleMark(out, "log");
      out
          .println("Faces log: </h2><div id='log' style='display: none;'  class='log a4j_debug'>");
      out.print("<iframe name='log' class='log' src='"+logResource.getUri(context,null)+"'><a href='src='"+logResource.getUri(context,null)+"'>Faces log file </a> </iframe>");
      out.println("</div>");
    }
  }

  public void writeToggleMark(PrintWriter out,String id) {
    out.print("<span style=\"display:none;\" id=\""+id+"_expanded\" >-&nbsp;</span>");
    out.print("<span style=\"display:inline;\" id=\""+id+"_collapsed\" >+</span>&nbsp;");
  }


  /**
   * Out component with properties and it's facets and childrens
   * @param context TODO
   * @param out
   * @param viewRoot
   */
  private void writeComponent(FacesContext context, PrintWriter out,
      UIComponent component, String facetName) {
    String clientId = "_tree:"+component.getClientId(context);
    out.println("<dt onclick=\"toggle('"+clientId+"')\" class='tree'>");
    writeToggleMark(out,clientId);
    // out component name
    if (null != facetName) {
      out.print("Facet:'" + facetName + "' ");
    }
    out.println("<code>" + component.getClass().getName() + "</code> Id:["+component.getId()+"]");
    out.println("</dt>");
    out.println("<dd id='"+clientId+"' style='display:none;'   class='tree' ><ul   class='tree'>");
    // out bean properties
    try {
      PropertyDescriptor propertyDescriptors[] = PropertyUtils.getPropertyDescriptors(component);
      for (int i = 0; i < propertyDescriptors.length; i++) {
        if (PropertyUtils.isReadable(component,propertyDescriptors[i].getName())) {
          String name = propertyDescriptors[i].getName();
          ValueBinding vb = component.getValueBinding(name);
          if (vb != null) {
            writeAttribute(out, name, vb.getExpressionString());
          } else {
            if (!IGNORE_ATTRIBUTES.contains(name)) {
              try {
                String value = BeanUtils.getProperty(component,name);
                writeAttribute(out, name, value);
              } catch (Exception e) {
                writeAttribute(out, name, null);
              }
            }
          }
        }
      }
    } catch (Exception e) {
      // Do nothing - we in error page.
    }

    // out bindings
    // out attributes map
    for (Iterator it = component.getAttributes().entrySet().iterator(); it
        .hasNext();) {
      Map.Entry entry = (Map.Entry) it.next();
      writeAttribute(out, (String) entry.getKey(), entry.getValue());
    }
    // out listeners
    out.println("</ul></dd>");
    if (component.getFacetsAndChildren().hasNext()) {
      out.println("<dd class='tree_childs'><dl class='tree_childs'>");
      // out childs of this component
      // facets
      for (Iterator facetEntry = component.getFacets().entrySet()
          .iterator(); facetEntry.hasNext();) {
        Map.Entry entry = (Map.Entry) facetEntry.next();
        writeComponent(context, out,
            (UIComponent) entry.getValue(), (String) entry.getKey());
      }
      // childs components
      for (Iterator childIter = component.getChildren().iterator(); childIter
          .hasNext();) {
        UIComponent child = (UIComponent) childIter.next();
        writeComponent(context, out, child, null);
      }
      out.println("</dl></dd>");
    }

  }

  private void writeAttribute(PrintWriter out, String name, Object value) {
    if (IGNORE_ATTRIBUTES.contains(name))
      return;
    if (name.startsWith("javax.faces.webapp.UIComponentTag.")) {
      name = name
          .substring("javax.faces.webapp.UIComponentTag.".length());
    }
    out.print("<li>");
    out.print(name);
    out.print("=\"");
    if (value != null) {
      if (value instanceof UIComponent) {
        out.print("[id:");
        out.print(((UIComponent) value).getId());
        out.print(']');
      } else if (value instanceof MethodBinding) {
        out.print(((MethodBinding) value).getExpressionString());
      } else if (value instanceof ValueBinding) {
        out.print(((ValueBinding) value).getExpressionString());
      } else {
        out.print(value.toString());
      }
    } else {
      out.print("NULL");
    }
    out.println("\"</li>");
  }

    private  void writeVariables(PrintWriter out, FacesContext faces)  {
        ExternalContext ctx = faces.getExternalContext();
        writeVariables(out, ctx.getRequestParameterMap(), "Request Parameters");
        writeVariables(out, ctx.getRequestMap(), "Request Attributes");
        if (ctx.getSession(false) != null) {
            writeVariables(out, ctx.getSessionMap(), "Session Attributes");
        }
        writeVariables(out, ctx.getApplicationMap(), "Application Attributes");
    }
   
    private  void writeVariables(PrintWriter out, Map vars, String caption)  {
        out.print("<table><caption>");
        out.print(caption);
        out.println("</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) {
                    out.println("<tr><td>");
                    out.println(key.replaceAll("<", LT).replaceAll(">", GT));
                    out.println("</td><td><span class='value'>");
                    Object value = entry.getValue();
                    out.println(value.toString().replaceAll("<", LT).replaceAll(">", GT));
                    out.println("</span>");
                try {
                  PropertyDescriptor propertyDescriptors[] = PropertyUtils.getPropertyDescriptors(value);
                  if (propertyDescriptors.length>0) {
                      out.print("<div class='properties'><ul class=\'properties\'>");
              for (int i = 0; i < propertyDescriptors.length; i++) {
                String beanPropertyName = propertyDescriptors[i].getName();
                if (PropertyUtils.isReadable(value,beanPropertyName
                    )) {
                        out.print("<li class=\'properties\'>");
                        out.print(beanPropertyName+" = "+BeanUtils.getProperty(value,beanPropertyName));
                        out.print("</li>");

                }
              }
                    out.print("</ul></div>");
            }
                } catch (Exception e) {
            // TODO: log exception
          }

                    out.println("</td></tr>");
                    written = true;
                }
            }
        }
        if (!written) {
            out.println("<tr><td colspan=\"2\"><em>None</em></td></tr>");
        }
        out.println("</tbody></table>");
    }
  /**
   * @param out
   */
  private void writeScript(PrintWriter out) {
    out
        .println("<script type='text/javascript' language='javascript'>\n"
            + "function toggle(id) {\n"
            + "var style = document.getElementById(id).style;\n"
            + "if ('block' == style.display) {\n"
            + "style.display = 'none';\n"
            + "document.getElementById(id+'_collapsed').style.display = 'inline';\n"
            + "document.getElementById(id+'_expanded').style.display = 'none';\n"
            + "} else {\n"
            + "style.display = 'block';\n"
            + "document.getElementById(id+'_collapsed').style.display = 'none';\n"
            + "document.getElementById(id+'_expanded').style.display = 'inline';\n"
            + "}\n" + "}\n\n" +

            "</script>");
  }

  /**
   * @param out
   */
  private void writeStyleSheet(PrintWriter out) {
    out
        .println("<style type=\'text/css\' >\n" +
            "div.a4j_debug, .a4j_debug span, .a4j_debug td, .a4j_debug th, .a4j_debug caption { font-family: Verdana, Arial, Sans-Serif; }\n" +
            ".a4j_debug li{\n" +
            "   list-style-position : inside;\n" +
            "}\n" +
            "\n" +
            ".a4j_debug li, .a4j_debug pre { padding: 0; margin: 0;  font-size : 12px;}\n" +
            ".a4j_debug ul { padding: 0 0 10 0; margin: 0;  font-size : 12px;}\n" +
            ".a4j_debug h1 { color: #fff; background-color : #a00; font-size : 17px; padding : 7px 10px 10px 10px}\n" +
            "h2.a4j_debug , h2.a4j_debug  span { color: #a00;  font-size : 17px; padding : 0px 0px 0px 10px;}\n" +
            "h2.a4j_debug  a { text-decoration: none; color: #a00; }\n" +
            ".exception { color: #000;  font-size : 14px; padding : 0px 0px 0px 10px;}\n" +
            ".grayBox { padding: 8px; margin: 10px 0; border: 1px solid #CCC; background-color: #f9f9f9;   font-size : 12px; }\n" +
            "#error { color: #900; font-weight: bold; font-size: medium; }\n" +
            "#trace, #tree, #vars { display: none; }\n" +
            ".a4j_debug code { font-size: medium;   font-size : 14px;}\n" +
            "#tree dl { color: #666; }\n" +
            "#tree dd {   font-size : 12px;}\n" +
            "#tree dt { border: 1px solid #DDD; padding: 2px 4px 4px 4px; border-left: 2px solid #a00; font-family: \"Courier New\", Courier, mono; font-size: small;   font-size : 12px; margin-top: 2px; margin-bottom: 2px;}\n" +
            ".uicText { color: #999;  }\n" +
            ".a4j_debug table { border: 1px solid #CCC; border-collapse: collapse; border-spacing: 0px; width: 100%; text-align: left; }\n" +
            ".a4j_debug td { border: 1px solid #CCC;    font-size : 12px; vertical-align : top}\n" +
            ".a4j_debug thead tr th { padding: 2px; color: #030; background-color: #F9F9F9;   font-size : 12px;}\n" +
            ".a4j_debug tbody tr td { padding: 10px 6px; }\n" +
            ".a4j_debug table caption { text-align: left; padding: 20 0 5 0; font-size : 12px; font-weight : bold;}\n" +
            ".value {font-size : 12px; font-weight : bold;}\n" +
            "div.log { width: 100%; height: 400px;}\n" +
            "iframe.log { width: 99%; height: 99%; border: 1px solid #CCC;}\n" +
            "</style>");
  }

}
TOP

Related Classes of org.ajax4jsf.application.DebugOutputMaker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.