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 }