1 20 package org.enhydra.barracuda.core.comp.renderer.html; 21 22 import java.util.*; 23 24 import org.apache.log4j.*; 25 import org.w3c.dom.*; 26 import org.w3c.dom.html.*; 27 28 import org.enhydra.barracuda.core.comp.*; 29 import org.enhydra.barracuda.core.comp.renderer.*; 30 import org.enhydra.barracuda.core.util.dom.*; 31 import org.enhydra.barracuda.core.view.*; 32 import org.enhydra.barracuda.plankton.*; 33 34 37 public class HTMLListRenderer extends HTMLComponentRenderer { 38 39 protected static final Logger logger = Logger.getLogger(HTMLListRenderer.class.getName()); 40 41 protected BList blist = null; 42 protected ListModel model = null; 43 protected EnabledHelper eh = new EnabledHelper(); 44 45 58 public Node createDefaultNode(Document doc, BComponent comp, ViewContext vc) throws UnsupportedFormatException { Node templateNode = vc.getTemplateNode(); 63 Node defaultNode = templateNode.cloneNode(true); 64 if (logger.isInfoEnabled()) logger.info("Creating default node:"+defaultNode); 65 return defaultNode; 66 } 67 68 71 public void renderComponent(BComponent comp, View view, ViewContext vc) throws RenderException { 72 if (!(comp instanceof BList)) throw new NoSuitableRendererException("This renderer can only render BList components; comp is of type:"+comp.getClass().getName()); 74 blist = (BList) comp; 75 model = blist.getModel(); 76 Node node = view.getNode(); 77 Node origTemplateNode = vc.getTemplateNode(); 79 if (logger.isDebugEnabled()) showNodeInterfaces(view, logger); 81 82 super.renderComponent(comp, view, vc); 84 85 89 98 115 131 if (node instanceof HTMLElement) { 143 144 try { 145 if (logger.isInfoEnabled()) logger.info("Rendering list component..."); 146 147 while (node.hasChildNodes()) { 149 node.removeChild(node.getFirstChild()); 150 } 151 152 model.setViewContext(vc); 154 model.resetModel(); 155 vc.putState(ViewContext.TEMPLATE_NODE, node); 156 157 ElementFactory ef = view.getElementFactory(); 159 for (int i=0,max=model.getSize(); i<max; i++) { 160 Object item = model.getItemAt(i); 163 164 if (item instanceof List) { 166 Iterator it = ((List) item).iterator(); 167 while (it.hasNext()) { 168 addItemToList(node, vc, ef, it.next(), 1); 169 } 170 } else if (item instanceof Object []) { 172 Object itemArr[] = (Object []) item; 173 for (int j=0,jmax=itemArr.length; j<jmax; j++) { 174 addItemToList(node, vc, ef, itemArr[j], 1); 175 } 176 } else { 178 addItemToList(node, vc, ef, item, 1); 179 } 180 } 181 184 185 } catch (DOMException e) { 186 if (logger.isInfoEnabled()) logger.info("Node does not support children...rendering list as text", e); 187 188 String s = model.toString(); 190 191 BText textComp = new BText(s); 194 textComp.setView(new DefaultView(node)); 195 196 blist.addStepChild(textComp); 203 } finally { 204 vc.putState(ViewContext.TEMPLATE_NODE, origTemplateNode); model.setViewContext(null); 207 } 208 209 210 } else { 211 String errmsg = "Node does not implement HTMLElement and cannot be rendered: "+node; 212 logger.warn(errmsg); 213 throw new NoSuitableRendererException(errmsg); 214 } 215 216 eh.setEnabled(node, comp.isEnabled()); 218 } 219 220 252 protected void addItemToList(Node node, ViewContext vc, ElementFactory ef, Object item, int depth) throws RenderException { 253 if (item == null) { 254 logger.warn("Ignoring attempt to add null item to the list"); 256 } else { 257 if (logger.isDebugEnabled()) { 259 if (logger.isDebugEnabled()) { 263 if (item instanceof BComponent) logger.debug("item " + item.getClass().getName() + "@" + Integer.toHexString(item.hashCode()) + " implements the following interfaces:"); 264 else logger.debug("item "+item+" implements the following interfaces:"); 265 } 266 Iterator it = Classes.getAllInterfaces(item).iterator(); 268 while (it.hasNext()) { 269 Object o = it.next(); 270 if (logger.isDebugEnabled()) logger.debug(o.toString()); 271 } 272 } 273 274 if (item instanceof BComponent) { 277 if (logger.isDebugEnabled()) logger.debug("Getting next BComponent item: "+item+"..."); 279 BComponent wcomp = (BComponent) item; 280 281 289 if (!wcomp.hasViews()) { FormatType ft = vc.getViewCapabilities().getFormatType(); 295 Document doc = vc.getElementFactory().getDocument(); 296 297 try { 298 Renderer r = wcomp.getRenderer(ft.getDOMClass()); 301 302 303 313 Node n = r.createDefaultNode(doc, wcomp, vc); addChildToParent(node, n); 316 317 if (!wcomp.hasViews()) wcomp.addTempView(new DefaultView(n)); 319 wcomp.invalidate(); 320 322 } catch (RenderException e) { 323 logger.warn("Unable to create default view:", e); 324 } catch (DOMException e) { 325 logger.warn("Unable to create default view:", e); 326 } 327 328 } else { Iterator it = wcomp.getViews().iterator(); while (it.hasNext()) { 335 View view = (View) it.next(); 336 addChildToParent(node, view.getNode()); 337 } 338 } 339 340 blist.addStepChild(wcomp); 347 348 } else if (item instanceof Node) { 350 if (logger.isDebugEnabled()) logger.debug("Getting next Node item: "+item+"..."); 351 addChildToParent(node, (Node) item); 353 354 } else { 356 if (logger.isDebugEnabled()) logger.debug("Getting next String item: "+item+"..."); 357 String s = item.toString(); 362 363 Node templateNode = ef.getDefaultElement(); 365 Node newNode = null; 366 if (templateNode!=null) { 367 newNode = templateNode.cloneNode(true); 369 } else { 370 String targetEl = null; 372 if (node instanceof HTMLDListElement) targetEl = "DT"; 373 else if (node instanceof HTMLOListElement) targetEl = "LI"; 374 else if (node instanceof HTMLOptGroupElement) targetEl = "OPTION"; 375 else if (node instanceof HTMLSelectElement) targetEl = "OPTION"; 376 else if (node instanceof HTMLTableColElement) targetEl = "COL"; 377 else if (node instanceof HTMLTableRowElement) targetEl = "TD"; 378 else if (node instanceof HTMLUListElement) targetEl = "LI"; 379 else throw new DOMException((short) 0, "Unsupported List node"); 380 newNode = node.getOwnerDocument().createElement(targetEl); 381 } 382 383 if (newNode!=null) { 385 BText textComp = new BText(s); 387 textComp.setView(new DefaultView(newNode)); 388 blist.addStepChild(textComp); 392 addChildToParent(node, newNode); 394 395 } else { 396 throw new InvalidNodeException("Unable to create a new Text node"); 397 } 398 } 399 } 400 } 401 402 } | Popular Tags |