KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > bridge > jsp > taglib > AbstractNodeListTag


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;
11
12
13 import java.util.*;
14 import org.mmbase.util.Casting;
15
16 import javax.servlet.jsp.JspTagException JavaDoc;
17 import javax.servlet.jsp.tagext.*;
18 import javax.servlet.jsp.jstl.core.*;
19 import javax.servlet.http.HttpServletRequest JavaDoc;
20
21 import org.mmbase.bridge.*;
22 import org.mmbase.bridge.jsp.taglib.util.*;
23 import org.mmbase.storage.search.*;
24 import org.mmbase.util.logging.*;
25
26 /**
27  * AbstractNodeListTag, provides basic functionality for listing objects
28  * stored in MMBase
29  *
30  * @author Kees Jongenburger
31  * @author Michiel Meeuwissen
32  * @author Pierre van Rooden
33  * @version $Id: AbstractNodeListTag.java,v 1.75 2006/08/03 17:14:59 michiel Exp $
34  */

35
36 abstract public class AbstractNodeListTag extends AbstractNodeProviderTag implements BodyTag, ListProvider {
37     private static final Logger log = Logging.getLoggerInstance(AbstractNodeListTag.class);
38
39     private static final int QUERY_WARN_SIZE = 1000;
40
41     /**
42      * Holds the list of fields to sort the list on.
43      * The sort itself is implementation specific.
44      */

45     protected Attribute orderby = Attribute.NULL;
46
47     /**
48      * Holds the direction to sort the list on (per field in {@link #orderby}).
49      * The sort itself is implementation specific.
50      */

51     protected Attribute directions = Attribute.NULL;
52
53     /**
54      * Holds the clause used to filter the list.
55      * This is either a SQL-clause, with MMBase fields in brackets,
56      * a altavista-like search, preceded with the keyword ALTA, or
57      * a MMBase database node search, preceded with the keyord MMNODE.
58      * The filter itself is implementation specific (not all lists may implement this!).
59      */

60     protected Attribute constraints = Attribute.NULL;
61
62     final protected NodeListHelper listHelper = new NodeListHelper(this, nodeHelper);
63
64     private Query generatingQuery;
65
66     protected NodeList getReturnList() {
67         return listHelper.getReturnList();
68     }
69
70     public Object JavaDoc getCurrent() {
71         return listHelper.getCurrent();
72     }
73
74     public int getIndex() {
75         return listHelper.getIndex();
76     }
77     public int getIndexOffset() {
78         return listHelper.getIndexOffset();
79     }
80
81     public void remove() {
82         listHelper.remove();
83     }
84
85     public Query getGeneratingQuery() {
86         return generatingQuery;
87     }
88
89     /**
90      * Sets the fields to sort on.
91      * @param orderby A comma separated list of fields on which the returned
92      * nodes should be sorted
93      */

94     public void setOrderby(String JavaDoc orderby) throws JspTagException JavaDoc {
95         this.orderby = getAttribute(orderby);
96     }
97
98     /**
99      * Sets the direction to sort on
100      * @param directions the selection query for the object we are looking for
101      * direction
102      */

103     public void setDirections(String JavaDoc directions) throws JspTagException JavaDoc {
104         this.directions = getAttribute(directions);
105     }
106
107     /**
108      * Set the list maximum
109      * @param max the max number of values returned
110      */

111     public void setMax(String JavaDoc max) throws JspTagException JavaDoc {
112         listHelper.setMax(max);
113     }
114
115     /**
116      * Set the list offset
117      * @param o Offset for the returned list.
118      */

119     public void setOffset(String JavaDoc o) throws JspTagException JavaDoc {
120         listHelper.setOffset(o);
121     }
122
123     public void setComparator(String JavaDoc c) throws JspTagException JavaDoc {
124         listHelper.setComparator(c);
125     }
126     public void setAdd(String JavaDoc c) throws JspTagException JavaDoc {
127         listHelper.setAdd(c);
128     }
129     public void setRetain(String JavaDoc c) throws JspTagException JavaDoc {
130         listHelper.setRetain(c);
131     }
132     public void setRemove(String JavaDoc c) throws JspTagException JavaDoc {
133         listHelper.setRemove(c);
134     }
135
136
137     /**
138      * Sets the selection query
139      * @param where the selection query
140      */

141     public void setConstraints(String JavaDoc where) throws JspTagException JavaDoc {
142         constraints = getAttribute(where);
143     }
144
145     protected static class NodesAndTrim {
146         boolean needsTrim;
147         NodeList nodeList;
148     }
149
150     protected final NodesAndTrim getNodesAndTrim(Query query) throws JspTagException JavaDoc {
151         return getNodesAndTrim(query, 0);
152     }
153
154     /**
155      *
156      * @param more How many more than max must be queried (if something will be subtracted later)
157      * @since MMBase-1.7
158      * @return true If successful
159      */

160     protected NodesAndTrim getNodesAndTrim(Query query, int more) throws JspTagException JavaDoc {
161         generatingQuery = query;
162         NodesAndTrim result = new NodesAndTrim();
163         if (listHelper.getComparator().equals("")) {
164             if (listHelper.getMax() != Attribute.NULL) {
165                 int m = listHelper.getMax().getInt(this, -1);
166                 if (m != -1) {
167                     query.setMaxNumber(m + more);
168                 }
169             }
170             if (listHelper.getOffset() != Attribute.NULL) {
171                 query.setOffset(listHelper.getOffset().getInt(this, 0));
172             }
173
174             if (query instanceof NodeQuery) {
175                 NodeQuery nq = (NodeQuery) query;
176                 result.nodeList = nq.getNodeManager().getList(nq);
177             } else {
178                 result.nodeList = query.getCloud().getList(query);
179             }
180             result.needsTrim = more > 0;
181         } else {
182             // using comparator, doing max and offset programmaticly, otherwise the comparator is loosing most of its use
183
if (query instanceof NodeQuery) {
184                 NodeQuery nq = (NodeQuery) query;
185                 result.nodeList = nq.getNodeManager().getList(nq);
186             } else {
187                 result.nodeList = query.getCloud().getList(query);
188             }
189
190             // give a warning if what you are doing right now is not very smart
191
if(result.nodeList.size() > QUERY_WARN_SIZE) {
192                 log.warn("Trying to use compare on a query with result size " + result.nodeList.size() + " > " + QUERY_WARN_SIZE + " in page " +
193                          ((HttpServletRequest JavaDoc)pageContext.getRequest()).getRequestURI() + "." +
194                          " Note that the attribute 'max' will in combination with the 'comparator' attribute not set a limit on the query" +
195                          " (but the result will be limited afterwards). You might want to limit the query in another way (use a container?)");
196             }
197             result.needsTrim = true;
198         }
199         return result;
200     }
201
202     // ContextProvider implementation
203
public ContextContainer getContextContainer() throws JspTagException JavaDoc {
204         return listHelper.getContextContainer();
205     }
206
207     protected static final int NOT_HANDLED = -100;
208
209     protected int doStartTagHelper() throws JspTagException JavaDoc {
210         log.debug("doStartTaghelper");
211
212         listHelper.doStartTagHelper();
213
214         if (getReferid() != null) {
215             Object JavaDoc o = getObject(getReferid());
216             if (! (o instanceof NodeList)) {
217                 if (o instanceof Collection) {
218                     NodeList list = getCloudVar().createNodeList();
219                     list.addAll((Collection) o);
220                     o = list;
221                 } else {
222                     throw new JspTagException JavaDoc("Context variable " + getReferid() + " is not a NodeList (or some other Collection of Nodes), but" + (o == null ? "NULL" : "a " + o.getClass()));
223                 }
224             }
225             if (orderby != Attribute.NULL) {
226                 throw new JspTagException JavaDoc("'orderby' attribute does not make sense with 'referid' attribute");
227             }
228
229             if (directions != Attribute.NULL) {
230                 throw new JspTagException JavaDoc("'directions' attribute does not make sense with 'referid' attribute");
231             }
232             if (constraints != Attribute.NULL) {
233                 throw new JspTagException JavaDoc("'contraints' attribute does not make sense with 'referid' attribute");
234             }
235             if (getReferid().equals(getId())) { // in such a case, don't whine
236
getContextProvider().getContextContainer().unRegister(getId());
237             }
238             return setReturnValues((NodeList) o, true);
239         }
240         return NOT_HANDLED;
241     }
242
243     /**
244      * Creates the node iterator and sets appropriate variables (such as listsize)
245      * from a passed node list.
246      * The list is assumed to be already sorted and trimmed.
247      * @param nodes the nodelist to create the iterator from
248      * @return EVAL_BODY_BUFFERED if the resulting list is not empty, SKIP_BODY if the
249      * list is empty. THis value should be passed as the result of {
250      * @link #doStartTag}.
251      */

252     protected int setReturnValues(NodeList nodes) throws JspTagException JavaDoc {
253         return setReturnValues(nodes, false);
254     }
255
256     /**
257      * Creates the node iterator and sets appropriate variables (such as listsize).
258      * Takes a node list, and trims it using the offset and
259      * max attributes if so indicated.
260      * The list is assumed to be already sorted.
261      * @param nodes the nodelist to create the iterator from
262      * @param trim if true, trim the list using offset and max
263      * (if false, it is assumed the calling routine already did so)
264      * @return EVAL_BODY_BUFFERED if the resulting list is not empty, SKIP_BODY if the
265      * list is empty. This value should be passed as the result of {@link #doStartTag}.
266      */

267     protected int setReturnValues(NodeList nodes, boolean trim) throws JspTagException JavaDoc {
268         Query query = (Query) nodes.getProperty(NodeList.QUERY_PROPERTY);
269
270         if (query != null) {
271             // get changeOn value for mm:changed tag
272
List ls = query.getSortOrders();
273             if (ls.size() > 0) {
274                 StepField sf= ((SortOrder)ls.get(0)).getField();
275                 if (query instanceof NodeQuery) {
276                     nodes.setProperty("orderby", sf.getFieldName());
277                 } else {
278                     nodes.setProperty("orderby", sf.getStep().getAlias() + '.' + sf.getFieldName());
279                 }
280             }
281         } else {
282             if (orderby != Attribute.NULL) nodes.setProperty("orderby", orderby.getString(this));
283         }
284
285         return listHelper.setReturnValues(nodes, trim);
286     }
287
288
289     public int doAfterBody() throws JspTagException JavaDoc {
290         super.doAfterBody();
291         return listHelper.doAfterBody();
292     }
293
294     public int doEndTag() throws JspTagException JavaDoc {
295         listHelper.doEndTag();
296         return super.doEndTag();
297     }
298
299     public void doFinally() {
300         generatingQuery = null;
301         listHelper.doFinally();
302         super.doFinally();
303     }
304
305     /**
306      * If you order a list, then the 'changed' property will be
307      * true if the field on which you order changed value.
308      **/

309     public boolean isChanged() {
310         return listHelper.isChanged();
311     }
312
313     public int size() {
314         return listHelper.size();
315     }
316
317     public LoopTagStatus getLoopStatus() {
318         return listHelper.getLoopStatus();
319     }
320
321 }
322
323
Popular Tags