1 10 package org.mmbase.bridge.jsp.taglib; 11 12 import org.mmbase.bridge.jsp.taglib.util.*; 13 import org.mmbase.bridge.jsp.taglib.debug.TimerTag; 14 15 import javax.servlet.jsp.*; 16 import javax.servlet.jsp.tagext.*; 17 import javax.servlet.jsp.jstl.core.*; 18 19 import java.io.IOException ; 20 import java.util.*; 21 22 import org.mmbase.bridge.*; 23 import org.mmbase.storage.search.*; 24 import org.mmbase.util.Casting; 25 import org.mmbase.util.logging.Logger; 26 import org.mmbase.util.logging.Logging; 27 28 34 35 public class NodeListHelper implements ListProvider { 36 37 private static final Logger log = Logging.getLoggerInstance(NodeListHelper.class); 38 39 private final ContextReferrerTag thisTag; 40 private final NodeProviderHelper nodeHelper; 41 42 public NodeListHelper(ContextReferrerTag thisTag, NodeProviderHelper nodeHelper) { 43 this.thisTag = thisTag; 44 this.nodeHelper = nodeHelper; 45 } 46 47 public String getId() { 48 try { 49 return (String ) thisTag.id.getValue(thisTag); 50 } catch (JspTagException j) { 51 throw new RuntimeException (j); 52 } 53 } 54 55 59 protected Attribute max = Attribute.NULL; 60 61 65 protected Attribute offset = Attribute.NULL; 66 67 protected Attribute comparator = Attribute.NULL; 68 69 protected Attribute add = Attribute.NULL; 70 protected Attribute retain = Attribute.NULL; 71 protected Attribute remove= Attribute.NULL; 72 73 74 77 private ContextCollector collector; 78 79 80 84 protected boolean changed = true; 85 86 92 protected NodeIterator nodeIterator; 93 protected NodeList returnList; 94 95 98 protected int currentItemIndex= -1; 99 100 103 protected int timerHandle = -1; 104 105 private String previousValue = null; 106 107 public int getIndex() { 108 return currentItemIndex; 109 } 110 111 public int getIndexOffset() { 112 return 1; 113 } 114 115 public void remove() { 116 nodeIterator.remove(); 117 } 118 119 123 public void setMax(String m) throws JspTagException { 124 max = thisTag.getAttribute(m); 125 } 126 127 public Attribute getMax() { 128 return max; 129 } 130 131 135 public void setOffset(String o) throws JspTagException { 136 offset = thisTag.getAttribute(o); 137 } 138 139 public Attribute getOffset() { 140 return offset; 141 } 142 143 public void setComparator(String c) throws JspTagException { 144 comparator = thisTag.getAttribute(c); 145 } 146 147 150 public void setAdd(String a) throws JspTagException { 151 add = thisTag.getAttribute(a); 152 } 153 154 157 public void setRetain(String a) throws JspTagException { 158 retain = thisTag.getAttribute(a); 159 } 160 161 164 public void setRemove(String a) throws JspTagException { 165 remove = thisTag.getAttribute(a); 166 } 167 168 169 170 public String getComparator() throws JspTagException { 171 return comparator.getString(thisTag); 172 } 173 174 public NodeList getReturnList() { 175 return returnList; 176 } 177 178 public ContextContainer getContextContainer() throws JspTagException { 179 if (collector == null) return thisTag.getContextProvider().getContextContainer(); return collector; 181 } 182 public PageContext getPageContext() throws JspTagException { 183 return thisTag.getPageContext(); 184 } 185 186 public int setReturnValues(NodeList nodes, boolean trim) throws JspTagException { 187 Cloud cloud = null; 188 if (cloud == null) { 189 Query q = (Query) nodes.getProperty(NodeList.QUERY_PROPERTY); 190 if (q != null) cloud = q.getCloud(); 191 } 192 if (cloud == null && nodes.size() > 0) { 193 cloud = nodes.getNode(0).getCloud(); 194 } 195 196 if (add != Attribute.NULL) { 197 Object addObject = thisTag.getObjectConditional(add.getString(thisTag)); 198 if (addObject != null) { 199 if (addObject instanceof Collection) { 200 nodes.addAll((Collection) addObject); 201 } else { 202 nodes.add(Casting.toNode(addObject, cloud)); 203 } 204 } 205 } 206 if (retain != Attribute.NULL) { 207 Object retainObject = thisTag.getObjectConditional(retain.getString(thisTag)); 208 if (retainObject != null) { 209 if (retainObject instanceof Collection) { 210 nodes.retainAll((Collection) retainObject); 211 } else { 212 nodes.retainAll(Collections.singletonList((Casting.toNode(retainObject, cloud)))); 213 } 214 } 215 } 216 if (remove != Attribute.NULL) { 217 Object removeObject = thisTag.getObjectConditional(remove.getString(thisTag)); 218 if (removeObject != null) { 219 if (removeObject instanceof Collection) { 220 nodes.removeAll((Collection) removeObject); 221 } else { 222 nodes.remove((Casting.toNode(removeObject, cloud))); 223 } 224 } 225 } 226 ListSorter.sort(nodes, (String ) comparator.getValue(thisTag), thisTag); 227 228 if (trim && (max != Attribute.NULL || offset != Attribute.NULL)) { 229 int currentSize = nodes.size(); 230 231 int maxi = max.getInt(thisTag, currentSize); 232 int maxx = (maxi > currentSize ? currentSize : maxi); 233 234 int offseti = offset.getInt(thisTag, 0); 235 236 int to = maxx + offseti; 237 if (to >= currentSize) { 238 to = currentSize; 239 } 240 if (offseti >= currentSize) { 241 offseti = currentSize; 242 } 243 if (offseti < 0) { 244 offseti = 0; 245 } 246 nodes = nodes.subNodeList(offseti, to); 247 248 } 249 returnList = nodes; 250 251 FormatterTag f = (FormatterTag) thisTag.findParentTag(FormatterTag.class, null, false); 253 if (f != null && f.wantXML()) { 254 f.getGenerator().add(nodes); 255 f.setCloud(cloud); 256 } 257 258 nodeIterator = returnList.nodeIterator(); 259 currentItemIndex= -1; 260 previousValue = null; 261 changed = true; 262 263 if (nodeIterator.hasNext()) { 264 setNext(); return ContextReferrerTag.EVAL_BODY; 266 } else { 267 return Tag.SKIP_BODY; 268 } 269 } 270 271 public void doStartTagHelper() throws JspTagException { 272 collector = new ContextCollector(thisTag.getContextProvider()); 274 275 TagSupport t = thisTag.findParentTag(TimerTag.class, null, false); 277 if (t != null) { 278 timerHandle = ((TimerTag)t).startTimer(getId(), getClass().getName()); 279 } 280 290 291 } 292 293 public int doAfterBody() throws JspTagException { 294 log.debug("doafterbody"); 295 if (getId() != null) { 296 thisTag.getContextProvider().getContextContainer().unRegister(getId()); 297 } 298 299 if (collector != null) { log.debug("copying to collector"); 301 collector.doAfterBody(); 302 } 303 if (nodeIterator.hasNext()){ 304 setNext(); 305 return IterationTag.EVAL_BODY_AGAIN; 306 } else { 307 log.debug("writing body"); 308 if (ContextReferrerTag.EVAL_BODY == BodyTag.EVAL_BODY_BUFFERED) { 309 BodyContent bodyContent = thisTag.getBodyContent(); 310 if (bodyContent != null) { 311 try { 312 bodyContent.writeOut(bodyContent.getEnclosingWriter()); 313 } catch (IOException ioe){ 314 throw new TaglibException(ioe); 315 } 316 } 317 } 318 return Tag.SKIP_BODY; 319 } 320 } 321 322 public int doEndTag() throws JspTagException { 323 if (getId() != null) { 324 thisTag.getContextProvider().getContextContainer().register(getId(), returnList, false); } 326 TagSupport t = thisTag.findParentTag(TimerTag.class, null, false); 327 if (t != null) { 328 ((TimerTag)t).haltTimer(timerHandle); 329 } 330 331 return EVAL_PAGE; 332 } 333 334 335 339 protected String getFirstOrderedField(NodeList returnList, NodeManager nextNodeManager) { 340 363 String listOrder = (String ) returnList.getProperty("orderby"); 366 if (listOrder != null && ! "".equals(listOrder)) { 367 String [] fa = listOrder.trim().split("\\s*,\\s*"); 370 int i = 0; 371 while(i < fa.length && ! nextNodeManager.hasField(fa[i])) { 372 i++; 373 } 374 return i < fa.length ? fa[i] : null; 375 } else { 376 return null; 377 } 378 } 380 381 public void setNext() throws JspTagException { 382 try { 383 currentItemIndex ++; 384 Node next = nodeIterator.nextNode(); 385 while (next == null) { 386 log.warn("Found null in node list " + returnList + " skipping"); 387 currentItemIndex ++; 388 if (nodeIterator.hasNext()) { 389 next = nodeIterator.nextNode(); 390 } else { 391 return; 392 } 393 } 394 NodeManager nextNodeManager = next.getNodeManager(); 395 if (nextNodeManager == null) throw new RuntimeException ("Found node " + next + " has no NodeManager"); 396 String orderField = getFirstOrderedField(returnList, nextNodeManager); 397 if (orderField != null) { 398 String value = "" + next.getValue(orderField); 399 if (previousValue != null) { 400 if (value.equals(previousValue)) { 401 changed = false; 402 } else { 403 changed = true; 404 } 405 } 406 previousValue = value; 407 408 } 409 nodeHelper.setNodeVar(next); 410 nodeHelper.fillVars(); 411 } catch (BridgeException be) { log.warn(be.getMessage(), be); 413 } 414 } 415 416 420 public boolean isChanged() { 421 return changed; 422 } 423 424 public int size() { 425 return returnList.size(); 426 } 427 428 public Object getCurrent() { 429 return nodeHelper.getNodeVar(); 430 } 431 432 public LoopTagStatus getLoopStatus() { 433 return new ListProviderLoopTagStatus(this); 434 } 435 436 public void release() { 437 doFinally(); 438 } 439 440 public void doFinally() { 441 if (collector != null) { 442 try { 443 collector.release(thisTag.getPageContext(), thisTag.getContextProvider().getContextContainer()); 444 collector = null; 445 } catch (Exception e) { 446 } 447 } 448 if (nodeHelper != null) { 449 nodeHelper.doFinally(); 450 } 451 nodeIterator = null; 452 returnList = null; 453 previousValue = null; 454 } 455 public int doStartTag() throws JspTagException { 457 return -1; 458 } 459 public Tag getParent() { 461 return null; 462 } 463 public void setParent(Tag tag) { 465 466 } 467 public void setPageContext(PageContext pc) { 469 } 470 471 472 473 } 474 | Popular Tags |