KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > tree > TreeTag


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.bridge.jsp.taglib.tree;
11
12
13 import javax.servlet.jsp.JspTagException JavaDoc;
14 import javax.servlet.jsp.tagext.*;
15
16 import java.io.IOException JavaDoc;
17 import java.util.Stack JavaDoc;
18
19 import org.mmbase.bridge.util.*;
20 import org.mmbase.bridge.*;
21 import org.mmbase.bridge.jsp.taglib.util.*;
22 import org.mmbase.bridge.jsp.taglib.debug.TimerTag;
23 import org.mmbase.bridge.jsp.taglib.*;
24 import org.mmbase.bridge.jsp.taglib.containers.*;
25
26 import org.mmbase.util.logging.*;
27
28
29 /**
30  * Implements mm:tree. Which works about like this
31 <pre>
32  &lt;mm:relatednodescontainer type="object" searchdirs="destination"&gt;
33   &lt;mm:tree type="object" searchdir="destination" maxdepth="8"&gt;
34     &lt;mm:grow&gt;
35       &lt;ul class="&lt;mm:depth" /&gt;"&gt;&lt;mm:onshrink&gt;&lt;/ul&gt;&lt;/mm:onshrink&gt;
36     &lt;/mm:grow&gt;
37     &lt;li&gt;&lt;mm:depth /&gt;: &lt;mm:nodeinfo type="guitype" /&gt;: &lt;mm:field name="number" /&gt; &lt;mm:function name="gui" escape="none" /&gt;
38
39     &lt;mm:onshrink&gt;&lt;/li&gt;&lt;/mm:onshrink&gt;
40
41     &lt;mm:shrink /&gt;
42
43     &lt;mm:last&gt;SIZE : &lt;mm:size /&gt;&lt;/mm:last&gt;
44
45   &lt;/mm:tree&gt;
46 &lt;/mm:relatednodescontainer&gt;
47 </pre>
48  * @author Michiel Meeuwissen
49  * @since MMBase-1.7
50  * @version $Id: TreeTag.java,v 1.18 2006/08/28 12:30:36 michiel Exp $
51  */

52 public class TreeTag extends AbstractNodeProviderTag implements TreeProvider, QueryContainerReferrer {
53     private static final Logger log = Logging.getLoggerInstance(TreeTag.class);
54
55     private TreeList tree;
56     private TreeIterator iterator;
57
58     private Stack JavaDoc shrinkStack;
59
60     private int previousDepth = -1;
61     private int depth = 0;
62     private int nextDepth = 1;
63     private int initialDepth;
64     private int index;
65
66     private Node nextNode;
67
68     /**
69      * Lists do implement ContextProvider
70      */

71     private ContextCollector collector;
72     protected int timerHandle = -1;
73
74
75     protected Attribute container = Attribute.NULL;
76     protected Attribute nodeManager = Attribute.NULL;
77     protected Attribute role = Attribute.NULL;
78     protected Attribute searchDir = Attribute.NULL;
79     protected Attribute maxDepth = Attribute.NULL;
80     protected Attribute orderby = Attribute.NULL;
81     protected Attribute directions = Attribute.NULL;
82     protected Attribute max = Attribute.NULL;
83
84     public void setContainer(String JavaDoc c) throws JspTagException JavaDoc {
85         container = getAttribute(c);
86     }
87
88     public void setType(String JavaDoc n) throws JspTagException JavaDoc {
89         nodeManager = getAttribute(n);
90     }
91
92     public void setRole(String JavaDoc r) throws JspTagException JavaDoc {
93         role = getAttribute(r);
94     }
95     public void setSearchdir(String JavaDoc sd) throws JspTagException JavaDoc {
96         searchDir = getAttribute(sd);
97     }
98     public void setMaxdepth(String JavaDoc md) throws JspTagException JavaDoc {
99         maxDepth = getAttribute(md);
100     }
101
102     /**
103      * @since MMBase 1.7.1
104      */

105     public void setOrderby(String JavaDoc o) throws JspTagException JavaDoc {
106         orderby = getAttribute(o);
107     }
108     /**
109      * @since MMBase 1.7.1
110      */

111     public void setDirections(String JavaDoc d) throws JspTagException JavaDoc {
112         directions = getAttribute(d);
113     }
114
115
116     public Stack JavaDoc getShrinkStack() {
117         return shrinkStack;
118     }
119
120     public void setMax(String JavaDoc m) throws JspTagException JavaDoc {
121         max = getAttribute(m);
122     }
123
124
125     // ContextProvider implementation
126
public ContextContainer getContextContainer() throws JspTagException JavaDoc {
127         if (collector == null) return getContextProvider().getContextContainer(); // to make sure old-style implemntation work (which do not initialize container)
128
return collector.getContextContainer();
129     }
130
131
132     public int size() {
133         return tree.size();
134     }
135     public int getIndex() {
136         return index;
137     }
138
139     public int getIndexOffset() {
140         return 1;
141     }
142     public boolean isChanged() {
143         return true;
144     }
145
146     public Object JavaDoc getCurrent() {
147         return getNodeVar();
148     }
149
150     public void remove() {
151         iterator.remove();
152     }
153
154     public int getPreviousDepth() {
155         return previousDepth;
156     }
157     public int getDepth() {
158         return depth;
159     }
160     public int getNextDepth() {
161         return nextDepth;
162     }
163
164
165     protected void noSpecification() throws JspTagException JavaDoc {
166         if (nodeManager != Attribute.NULL) {
167             throw new JspTagException JavaDoc("'type' attribute does not make sense with 'referid' attribute");
168         }
169         if (role != Attribute.NULL) {
170             throw new JspTagException JavaDoc("'role' attribute does not make sense with 'referid' attribute");
171         }
172         if (searchDir!= Attribute.NULL) {
173             throw new JspTagException JavaDoc("'searchdir' attribute does not make sense with 'referid' attribute");
174         }
175     }
176
177     /**
178      * Performs the search
179      */

180     public int doStartTag() throws JspTagException JavaDoc {
181         log.debug("starttag");
182         shrinkStack = new Stack JavaDoc();
183         collector = new ContextCollector(getContextProvider());
184
185         // serve parent timer tag:
186
TagSupport t = findParentTag(TimerTag.class, null, false);
187         if (t != null) {
188             timerHandle = ((TimerTag)t).startTimer(getId(), getClass().getName());
189         }
190
191         if (getReferid() != null) {
192             Object JavaDoc o = getObject(getReferid());
193             if (! (o instanceof TreeList)) {
194                 throw new JspTagException JavaDoc("Context variable " + getReferid() + " is not a TreeList");
195             }
196             noSpecification();
197
198             if (getReferid().equals(getId())) { // in such a case, don't whine
199
getContextProvider().getContextContainer().unRegister(getId());
200             }
201             tree = (TreeList) o;
202         } else {
203             tree = null;
204             if (parentNodeId == Attribute.NULL) {
205                 TreeContainerTag c = (TreeContainerTag) findParentTag(TreeContainerTag.class, (String JavaDoc) container.getValue(this), false);
206                 if (c != null) {
207                     GrowingTreeList growingTree = c.getTree();
208                     if (! "".equals(maxDepth.getString(this))) {
209                         growingTree.setMaxDepth(maxDepth.getInt(this, 5));
210                     }
211                     tree = growingTree;
212                     noSpecification();
213                 }
214             }
215             if (tree == null) {
216                 NodeQuery query = TreeContainerTag.getStartQuery(this, container, parentNodeId);
217                 GrowingTreeList growingTree = new GrowingTreeList(query, maxDepth.getInt(this, 5),
218                                                                   getCloudVar().getNodeManager(nodeManager.getString(this)),
219                                                                   role.getString(this),
220                                                                   searchDir.getString(this));
221                 Query template = growingTree.getTemplate();
222                 if (orderby != Attribute.NULL) {
223                     Queries.addSortOrders(template, (String JavaDoc) orderby.getValue(this), (String JavaDoc) directions.getValue(this));
224                 }
225                 tree = growingTree;
226             }
227
228         }
229         if (max != Attribute.NULL) {
230             tree.setMax(max.getInt(this, -1));
231         }
232         iterator = tree.treeIterator();
233
234         // returnList is known, now we can serve parent formatter tag
235
FormatterTag f = (FormatterTag) findParentTag(FormatterTag.class, null, false);
236         if (f != null && f.wantXML()) {
237             f.getGenerator().add(tree);
238             f.setCloud(tree.getCloud());
239         }
240
241
242         if (iterator.hasNext()) {
243             index = 0;
244             previousDepth = iterator.currentDepth();
245             initialDepth = previousDepth;
246             Node node = iterator.nextNode();
247             setNodeVar(node);
248             fillVars();
249             depth = iterator.currentDepth();
250
251             if (iterator.hasNext()) {
252                 nextNode = iterator.nextNode();
253                 nextDepth = iterator.currentDepth();
254                 log.debug("hasnext " + nextDepth);
255             } else {
256                 nextNode = null;
257                 nextDepth = initialDepth;
258                 log.debug("no next " + nextDepth);
259
260             }
261             return EVAL_BODY;
262         } else {
263             return SKIP_BODY;
264         }
265
266
267     }
268     public void doInitBody() throws JspTagException JavaDoc {
269         log.debug("initbody");
270     }
271
272
273     public int doAfterBody() throws JspTagException JavaDoc {
274         log.debug("afterbody");
275         super.doAfterBody();
276         if (getId() != null) {
277             getContextProvider().getContextContainer().unRegister(getId());
278         }
279
280         collector.doAfterBody();
281
282         if (nextNode != null) {
283             log.debug("using next-node");
284             setNodeVar(nextNode);
285             fillVars();
286             previousDepth = depth;
287             depth = nextDepth;
288
289             if (iterator.hasNext()) {
290                 nextNode = iterator.nextNode();
291                 nextDepth = iterator.currentDepth();
292                 log.debug("has next " + nextDepth);
293             } else {
294                 nextNode = null;
295                 nextDepth = initialDepth;
296                 log.debug("no next " + nextDepth);
297             }
298             index++;
299             return EVAL_BODY_AGAIN;
300         } else {
301             if (EVAL_BODY == EVAL_BODY_BUFFERED) {
302                 log.debug("writing body");
303                 if (bodyContent != null) {
304                     try {
305                         bodyContent.writeOut(bodyContent.getEnclosingWriter());
306                     } catch (IOException JavaDoc ioe){
307                         throw new TaglibException(ioe);
308                     }
309                 }
310             }
311             return SKIP_BODY;
312         }
313
314     }
315
316     public int doEndTag() throws JspTagException JavaDoc {
317         log.debug("endtag");
318         if (getId() != null) {
319             getContextProvider().getContextContainer().register(getId(), tree, false); // use false because check was done in doStartTag (and doAfterBody not always called).
320
}
321         TagSupport t = findParentTag(TimerTag.class, null, false);
322         if (t != null) {
323             ((TimerTag)t).haltTimer(timerHandle);
324         }
325         // dereference for gc
326
tree = null;
327         iterator = null;
328         shrinkStack = null;
329         nextNode = null;
330         collector = null;
331         return super.doEndTag();
332     }
333
334     public javax.servlet.jsp.jstl.core.LoopTagStatus getLoopStatus() {
335         return new ListProviderLoopTagStatus(this);
336     }
337
338
339
340
341 }
342
343
Popular Tags