1
2
3
4
5
6
7 package net.sf.tacos.components.tree;
8
9 import java.util.Stack;
10 import org.apache.tapestry.AbstractComponent;
11 import org.apache.tapestry.IMarkupWriter;
12 import org.apache.tapestry.IRequestCycle;
13 import org.apache.tapestry.engine.NullWriter;
14
15
16
17
18
19 public abstract class TreeHelper extends AbstractComponent {
20
21 private Stack stack;
22
23 public abstract TreeIterator getTreeIterator();
24
25 private Stack getCycleStack(IRequestCycle cycle) {
26 Stack currStack = (Stack) cycle.getAttribute(TreeHelper.class.getName());
27 if (currStack == null) {
28 currStack = new Stack();
29 }
30 return currStack;
31 }
32
33 private void setCycleStack(IRequestCycle cycle, Stack currStack) {
34 cycle.setAttribute(TreeHelper.class.getName(), currStack);
35 }
36
37 protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
38 stack = getCycleStack(cycle);
39 if (getTreeIterator() == null) {
40 finalRenderComponent();
41 } else {
42 int diff = getTreeIterator().getDepth() - getTreeIterator().getPreviousDepth();
43 boolean empty = stack.empty();
44
45 if (writer == NullWriter.getSharedInstance() && cycle.getResponseBuilder().isDynamic()
46 && (empty || stack.peek()==writer)) {
47 renderBody(writer, cycle);
48 return;
49 }
50
51 if (empty) {
52 stack.push(writer.getNestedWriter());
53 diff = 0;
54 }
55 IMarkupWriter writerGive = (IMarkupWriter) stack.peek();
56 normalRenderComponent(writerGive, cycle, diff, empty);
57 }
58
59 setCycleStack(cycle, stack);
60 }
61
62 protected void finalRenderComponent() {
63 while (!stack.empty()) {
64 IMarkupWriter inner = (IMarkupWriter) stack.pop();
65 inner.close();
66 }
67 stack = null;
68 return;
69 }
70
71 protected void normalRenderComponent(IMarkupWriter writer, IRequestCycle cycle,
72 int diff, boolean empty) {
73
74 if (diff==0) {
75 if (!empty)
76 writer.end();
77
78 writer.begin("div");
79 renderIdAttribute(writer, cycle);
80 writer.closeTag();
81 renderBody(writer, cycle);
82 } else if (diff>0) {
83 writer = writer.getNestedWriter();
84 stack.push(writer);
85
86 writer.begin("div");
87 renderIdAttribute(writer, cycle);
88 writer.closeTag();
89 renderBody(writer, cycle);
90 } else {
91 writer = (IMarkupWriter) stack.pop();
92 for (int c = diff; c < 0 && !stack.empty(); c++) {
93 writer.close();
94 writer = (IMarkupWriter) stack.pop();
95 }
96 if (stack.empty() && cycle.getResponseBuilder().isDynamic()) {
97 renderBody(NullWriter.getSharedInstance(), cycle);
98 writer.close();
99 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 }