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 writer.begin("div"); 078 renderIdAttribute(writer, cycle); 079 writer.closeTag(); 080 renderBody(writer, cycle); 081 } else if (diff>0) { 082 writer = writer.getNestedWriter(); 083 stack.push(writer); 084 085 writer.begin("div"); 086 renderIdAttribute(writer, cycle); 087 writer.closeTag(); 088 renderBody(writer, cycle); 089 } else { 090 writer = (IMarkupWriter) stack.pop(); 091 for (int c = diff; c < 0; c++) { 092 writer.close(); 093 writer = (IMarkupWriter) stack.pop(); 094 } 095 if (stack.size()==0 && cycle.getResponseBuilder().isDynamic()) { 096 renderBody(NullWriter.getSharedInstance(), cycle); 097 writer.close(); 098 stack.push(NullWriter.getSharedInstance()); 099 return; 100 } 101 stack.push(writer); 102 renderBody(writer, cycle); 103 } 104 105 } 106 107 }