001 /* 002 * TreeHelper.java 003 * 004 * Created on February 4, 2007, 11:54 PM 005 */ 006 007 package net.sf.tacos.components.tree; 008 009 import java.util.Stack; 010 import org.apache.tapestry.AbstractComponent; 011 import org.apache.tapestry.IMarkupWriter; 012 import org.apache.tapestry.IRequestCycle; 013 import org.apache.tapestry.engine.NullWriter; 014 015 /** 016 * 017 * @author andyhot 018 */ 019 public abstract class TreeHelper extends AbstractComponent { 020 021 private Stack stack; 022 023 public abstract TreeIterator getTreeIterator(); 024 025 private Stack getCycleStack(IRequestCycle cycle) { 026 Stack currStack = (Stack) cycle.getAttribute(TreeHelper.class.getName()); 027 if (currStack == null) { 028 currStack = new Stack(); 029 } 030 return currStack; 031 } 032 033 private void setCycleStack(IRequestCycle cycle, Stack currStack) { 034 cycle.setAttribute(TreeHelper.class.getName(), currStack); 035 } 036 037 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) { 038 stack = getCycleStack(cycle); 039 if (getTreeIterator() == null) { 040 finalRenderComponent(); 041 } else { 042 int diff = getTreeIterator().getDepth() - getTreeIterator().getPreviousDepth(); 043 boolean empty = stack.empty(); 044 045 if (writer == NullWriter.getSharedInstance() && cycle.getResponseBuilder().isDynamic() 046 && (empty || stack.peek()==writer)) { 047 renderBody(writer, cycle); 048 return; 049 } 050 051 if (empty) { 052 stack.push(writer.getNestedWriter()); 053 diff = 0; 054 } 055 IMarkupWriter writerGive = (IMarkupWriter) stack.peek(); 056 normalRenderComponent(writerGive, cycle, diff, empty); 057 } 058 059 setCycleStack(cycle, stack); 060 } 061 062 protected void finalRenderComponent() { 063 while (!stack.empty()) { 064 IMarkupWriter inner = (IMarkupWriter) stack.pop(); 065 inner.close(); 066 } 067 stack = null; 068 return; 069 } 070 071 protected void normalRenderComponent(IMarkupWriter writer, IRequestCycle cycle, 072 int diff, boolean empty) { 073 //System.out.println("Doing: " + getClientId() + " Diff:" + diff + "Wr:" + writer); 074 if (diff==0) { 075 if (!empty) 076 writer.end(); 077 078 writer.begin("div"); 079 renderIdAttribute(writer, cycle); 080 writer.closeTag(); 081 renderBody(writer, cycle); 082 } else if (diff>0) { 083 writer = writer.getNestedWriter(); 084 stack.push(writer); 085 086 writer.begin("div"); 087 renderIdAttribute(writer, cycle); 088 writer.closeTag(); 089 renderBody(writer, cycle); 090 } else { 091 writer = (IMarkupWriter) stack.pop(); 092 for (int c = diff; c < 0 && !stack.empty(); c++) { 093 writer.close(); 094 writer = (IMarkupWriter) stack.pop(); 095 } 096 if (stack.empty() && cycle.getResponseBuilder().isDynamic()) { 097 renderBody(NullWriter.getSharedInstance(), cycle); 098 writer.close(); 099 stack.push(NullWriter.getSharedInstance()); 100 return; 101 } 102 103 writer.end(); 104 stack.push(writer); 105 106 writer.begin("div"); 107 renderIdAttribute(writer, cycle); 108 writer.closeTag(); 109 renderBody(writer, cycle); 110 } 111 112 } 113 114 }