FileDocCategorySizeDatePackage
ShowViewStateServlet.javaAPI DocExample5994Tue Jun 08 11:26:42 BST 2004com.mycompany.jsf.servlets

ShowViewStateServlet

public class ShowViewStateServlet extends HttpServlet
This class is a servlet that produces a response showing the state captured by the CaptureStatePhaseListener, as a tree with links for opening and closing nodes.
author
Hans Bergsten, Gefion Software
version
1.0

Fields Summary
Constructors Summary
Methods Summary
public voiddoGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
If invoked without a "viewId" parameter, renders a response with links back to itself for all views available in the session scope variable "com.mycompany.debug". Otherwise, toggles the "expanded" flag for the node identified by the "nodeId" parameter (if any) and renders the view state tree by calling renderDocument().


	response.setContentType("text/html");
	PrintWriter out = response.getWriter();

	HttpSession session = request.getSession();
	Map debugMap = 	(Map) session.getAttribute("com.mycompany.debug");
	if (debugMap == null) {
	    response.sendError(HttpServletResponse.SC_BAD_REQUEST,
			       "No state available");
	    return;
	}
	
	String uri = request.getContextPath() + request.getServletPath();
	String viewId = request.getParameter("viewId");
	if (viewId == null) {
	    renderLinks(debugMap, out, uri);
	}
	else {
	    TreeNode root = (TreeNode) debugMap.get(viewId);
	    if (root == null) {
		response.sendError(HttpServletResponse.SC_BAD_REQUEST,
				   "No state for viewId parameter");
		return;
	    }

	    String path = request.getParameter("nodePath");
	    if (path != null) {
		toggleExpanded(path, root);
	    }

	    renderDocument(root, out, viewId, uri);
	}
    
private java.lang.Stringindent(int level)
Returns a blank String of the appropriate length for the indention level.

	StringBuffer sb = new StringBuffer();
	for (int i = 0; i < level; i++) {
	    sb.append("  ");
	}
	return sb.toString();
    
private voidrenderDocument(com.mycompany.jsf.model.TreeNode root, java.io.PrintWriter out, java.lang.String viewId, java.lang.String uri)
Renders the "html", "head" and "body" elements and calls the renderTreeNode() method to render the tree.

	out.println("<html>");
	out.println("  <head>");
	out.println("    <title>Info for view '" + viewId + "'</title>");
	out.println("  </head>");
	out.println("  <body bgcolor=\"white\">");
	renderTreeNode(root, out, viewId, uri, 2, "0", 0);
	out.println("  </body>");
	out.println("</html>");
    
private voidrenderLinks(java.util.Map debugMap, java.io.PrintWriter out, java.lang.String uri)
Renders a response with links for all views in the Map.

	out.println("<html>");
	out.println("  <head>");
	out.println("    <title>Debug info for views</title>");
	out.println("  </head>");
	out.println("  <body bgcolor=\"white\">");
	out.println("    Info for the following views is available:");
	out.println("    <ul>");

	Iterator i = debugMap.keySet().iterator();
	while (i.hasNext()) {
	    String viewId = (String) i.next();
	    out.println(indent(3) + "<li><a href=\"" + uri + 
			"?viewId=" + URLEncoder.encode(viewId) + 
			"\">" + viewId + "</a></li>");
	}
	
	out.println("  </body>");
	out.println("</html>");
    
private voidrenderTreeNode(com.mycompany.jsf.model.TreeNode node, java.io.PrintWriter out, java.lang.String viewId, java.lang.String uri, int level, java.lang.String parentNodeId, int childId)
Renders the node, as "name=value" if it's a leaf node or as a link for expanding or collapsing the node otherwise. If the node is expanded, calls itself recursively for all node children, rendering the children within a "blockquote" element.

	if (node.isLeafNode()) {
	    out.println(indent(level) + node.getName() + " = " +
			node.getValue() + "<br>");
	}
	else {
	    String nodeId = parentNodeId + ":" + childId;
	    out.println(indent(level) + "<a id=\"" + nodeId + 
			"\" href=\"" + uri + 
			"?viewId=" + URLEncoder.encode(viewId) + 
			"&nodePath=" + 
			URLEncoder.encode(node.getPath()) +
			"&expand=" + (!node.isExpanded()) +
			"#" + nodeId +
			"\">" + (node.isExpanded() ? "-" : "+") +
			"</a> " + node.getName() + "<br>");
	    if (node.isExpanded()) {
		out.println(indent(level + 1) + "<blockquote>");
		int kidId = 0;
		Iterator i = node.getChildren().iterator();
		while (i.hasNext()) {
		    TreeNode kid = (TreeNode) i.next();
		    renderTreeNode(kid, out, viewId, uri, level + 2, nodeId,
				   kidId++);
		}
		out.println(indent(level + 1) + "</blockquote>");
	    }
	}
    
private voidtoggleExpanded(java.lang.String path, com.mycompany.jsf.model.TreeNode root)
Locates the node with the specified path in the tree and flips its "expanded" flag.

	List kids = root.getChildren();
	boolean foundElement = false;
	TreeNode matchingNode = null;

	StringTokenizer st = new StringTokenizer(path, "/");
	// Throw away the root token
	st.nextToken();
	while (st.hasMoreTokens()) {
	    String t = st.nextToken();
	    for (int i = 0; i < kids.size(); i++) {
		TreeNode kid = (TreeNode) kids.get(i);
		if (t.equals(kid.getName())) {
		    matchingNode = kid;
		    kids = kid.getChildren();
		    foundElement = true;
		    break;
		}
	    }
	    if (!foundElement) {
		break;
	    }
	}
	if (matchingNode != null) {
	    boolean isExpanded = matchingNode.isExpanded();
	    matchingNode.setExpanded(!isExpanded);
	}