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 }