Re: Using Jivan in a Barracuda App
Jacob Kjome <[email protected]>
| Newsgroups | gmane.comp.java.enhydra.barracuda.general |
|---|---|
| Message-ID | <[email protected]> |
David, can you try out Arno's JivanDOMWriter and report on whether that fixes your issue? We can get this into Barracuda shortly after that. Jake At 12:28 PM 11/24/2003 +0100, you wrote: >Hi David, Jake, > >DefaultDOMWriter is really a class from XMLC. As Jake said, it should be >called XMLCDOMWriter. Using Jivan to create the DOM and XMLC to serialize >it, may result in strange behaviour, since XMLC is trying to correct HTML, >while Jivan is not. (Even when outputting, XMLC is calling Tidy for pretty >printing and change the DOM as Tidy thinks.) > >Anyway, this might be the source of the bug. So I went ahead and wrote a >JivanDOMWriter, which should be used to output DOM created with Jivan. It >also takes advantage of the speed improvement in Jivan serialization, >which will speed up you the process by serveral times. > >I haven't done testing on this class, so I would appreciate if you can >give it a try and let me know if this solves your problem. > >-Arno > > >Jacob Kjome wrote: > >>Hi David, >>So, when you load up a document with Jivan and modify it directly with >>Jivan or via the standard DOM interfaces and then render it with >>DefaultDOMWriter, it works fine, but when you use BTemplate you get the >>data you expect along with extraneous empty elements as well? Do I have >>it straight so far? That's certainly odd. I can't say that I've >>experimented much with Jivan and BTemplate. Just with standard DOM >>modifications. >>Christian, any idea? Arno, any thoughts here? >> >>Jake >>At 03:05 PM 11/22/2003 -0500, you wrote: >> >>>If I load a document with Jivan and then render it with DefaultDOMWriter >>>everything works fine. However, If I use the page to create a BTemplate >>>component to customize it using a TemplateModel, then the page does not >>>render >>>correctly, especially when rendering tables. I end up getting a blank >>><TD></TD> >>>between each cell in the table and a blank <TR></TR> between each row. >>> >>>Can a document loaded with Jivan be used in a BTemplate component? Am I >>>doing >>>something wrong? Any ideas? >>> >>>Thanks in advance, >>>David Robison >>> >>>Quoting David R Robison <[email protected]>: >>> >>> > Thanks for the info... >>> > The problem I'm now having is in modifying the loaded HTML file. Here is >>> > my code: >>> > >>> > class RenderSitePageHandler extends DefaultBaseEventListener { >>> > public void handleViewEvent(ViewEventContext context) >>> throws >>> > EventException, >>> > ServletException, IOException { >>> > HttpServletRequest req = context.getRequest(); >>> > >>> > //get the XMLC object >>> > Document page = >>> > >>> DefaultDOMLoader.getGlobalInstance().getDOM("/WEB-INF/jivan/SitePage.html"); >>> > DocumentFactory docFactory = >>> DocumentFactory.getInstance(); >>> > docFactory.docManFor(page).repair(page); >>> > >>> > //create a template component and render it >>> > Node node = page.getElementById("SiteForm"); >>> > BTemplate templateComp = new BTemplate(new >>> SiteModel(context)); >>> > templateComp.setView(new >>> DefaultTemplateView(node)); >>> > try {templateComp.render(new >>> DefaultViewContext(context));} >>> > catch (RenderException re) {logger.warn("Render >>> err:"+re);} >>> > >>> > //now actually render the page >>> > new DefaultDOMWriter().write(page, >>> context.getResponse()); >>> > } >>> > } >>> > >>> > If I comment out the section where I create a template componet then the >>> > page >>> > renders fine. If not, then, when I write out the DOM, I get an empty >>> > <td></td> >>> > between each cell in my table and an empty <tr></tr> between each row. >>> > I'm not >>> > adding new rows to the table, just populating a form that uses tables. >>> > >>> > Any idea? Am I missing something? >>> > >>> > Thanks in advance, >>> > David >>> > >>> > Quoting Jacob Kjome <[email protected]>: >>> > >>> > > DefaultDOMWriter uses XMLC to format the DOM. You can create your >>> > own >>> > > >>> > > DOMWriter if you want. This is actually why I wanted to rename >>> > > DefaultDOMWriter to XMLCDOMWriter. Calling is "Default" hides its >>> > > implementation too much, and the whole point to switch out >>> > > implementations >>> > > at will anyway, not use a single default one. The DOMLoader is the >>> > more >>> > > >>> > > generic of the 3 interfaces. Anyway, knowing that, you can create >>> > your >>> > > own >>> > > DOMWriter implementation that doesn't use XMLC's DOM formatter. Oh, >>> > and >>> > > I >>> > > forgot, there still is a dependency on XMLC via the >>> > > XMLCDeferredParsingDOMFactory instance created by default in the >>> > > DefaultDOMLoader. Hmm.... Those should really be separated more. >>> > > Maybe >>> > > we should add another getGlobalInstance() that takes a DOMFactory as >>> > a >>> > > >>> > > parameter and have the default dom factory loaded up via reflection. >>> > >>> > > That >>> > > way, DefaultDOMLoader would be much more generic. Anyway... >>> > > >>> > > >>> > > Here are some ways to use the JivanDOMFactory.... >>> > > >>> > > First do... >>> > > DefaultDOMLoader loader = DefaultDOMLoader.getGlobalInstance(); >>> > > >>> > > Then, either use the object repository assember as shown by Thelmo >>> > below >>> > > >>> > > (except change XMLCDeferredParsingDOMFactory to JivanDOMFactory) or >>> > use >>> > > the >>> > > following... >>> > > >>> > > >>> > > JivanDOMFactory jfactory = new JivanDOMFactory(); >>> > > jfactory.setServletContext(getServletContext()); >>> > > loader.setDefaultDOMFactory(jfactory); >>> > > >>> > > //note that you can also choose to set the default dom factory to >>> > > something >>> > > else and use Jivan for a specific fully qualified class name (String) >>> > or >>> > > >>> > > file path such as.... >>> > > String docPath = "/WEB-INF/mydocs/myfile.html"; >>> > > loader.registerDOMFactory(jfactory, docPath); >>> > > >>> > > >>> > > Then do.... >>> > > >>> > > Document doc = loader.getDOM(docPath); >>> > > >>> > > >>> > > Of course, you can skip the DOMLoader as you did before, but at that >>> > > point, >>> > > you might as well just load things as described here... >>> > > http://www.jivan.org/parser/samples.html >>> > > >>> > > You can also look at how JivanDOMFactory is implemented to for an >>> > > example >>> > > of how to use it directly. >>> > > >>> > > Hope that clears things up a bit. >>> > > >>> > > Jake >>> > > >>> > > At 01:18 PM 11/18/2003 -0500, you wrote: >>> > > >Thanks, when I try this without the xmlc.jar file, it complains >>> > that >>> > > the >>> > > >class >>> > > > >>> > > >org/enhydra/xml/io/DOMFormatter >>> > > > >>> > > >is not found. Is the xmlc.jar files still required? >>> > > > >>> > > >david >>> > > > >>> > > >Thelmo Loisio wrote: >>> > > >> >>> > > >>On Tue, 2003-11-18 at 17:19, David R Robison wrote: >>> > > >> >>> > > >>> >>> > > >>>Do you have an example of what to set in the object-repository to >>> > use >>> > > jivan? >>> > > >>>David >>> > > >>> >>> > > >> >>> > > >> >>> > > >> >From the contrib package here it is snippet from >>> > > >>object-repository.xml... >>> > > >> >>> > > >><object name="$df" >>> > > >>> > >>class="org.enhydra.barracuda.core.util.dom.XMLCDeferredParsingDOMFac >>> to ry"> >>> > > >> <!-- set the servlet context so that the dom factory can >>> > > read >>> > > >>web.xml context params --> >>> > > >> <method name="setServletContext" arg="$sc"/> >>> > > >> </object> >>> > > >> >>> > > >> <object >>> > > class="org.enhydra.barracuda.core.util.dom.DefaultDOMLoader"> >>> > > >> <method name="getGlobalInstance" return="$dl"/> >>> > > >> </object> >>> > > >> >>> > > >>... and from java within an handleViewEvent method... >>> > > >> >>> > > >>Document page = >>> > > >>DefaultDOMLoader.getGlobalInstance().getDOM(WaitHTML.class, >>> > > >>context.getViewCapabilities().getClientLocale()); >>> > > >> >>> > > >> >>> > > >> >>> > > > >>> > > > >>> > > >-- >>> > > > >>> > > >David R Robison >>> > > >Open Roads Consulting, Inc. >>> > > >708 S. Battlefield Blvd., Chesapeake, VA 23322 >>> > > >phone: (757) 546-3401 >>> > > >e-mail: >>> > > >>> > ><mailto:[email protected]>drrobison@openroadsconsulti >>> ng .com >>> > > >web: <http://openroadsconsulting.com>http://openroadsconsulting.com >>> > > >>> > > _______________________________________________ >>> > > Barracuda mailing list >>> > > [email protected] >>> > > http://barracudamvc.org/lists/listinfo/barracuda >>> > > >>> > _______________________________________________ >>> > Barracuda mailing list >>> > [email protected] >>> > http://barracudamvc.org/lists/listinfo/barracuda >>> > >>>_______________________________________________ >>>Barracuda mailing list >>>[email protected] >>>http://barracudamvc.org/lists/listinfo/barracuda >> >>_______________________________________________ >>Barracuda mailing list >>[email protected] >>http://barracudamvc.org/lists/listinfo/barracuda > > >package org.enhydra.barracuda.core.util.dom; > >import java.io.IOException; >import java.io.OutputStream; >import java.io.PrintWriter; >import java.io.Writer; > >import javax.servlet.http.HttpServletResponse; > >import org.apache.log4j.Logger; >import org.jivan.html.document.DocumentFactory; >import org.jivan.html.document.DocumentManager; >import org.w3c.dom.Element; >import org.w3c.dom.Node; >import org.w3c.dom.html.HTMLDocument; > >/** This class is a specialized DOMWriter for Jivan. It calls the Jivan >serializers > * for output to a Outputstream or java.io.Writer. > * > * The root node of the tree to be outputted must be either a Document or > Element. > * This means DocumentFragments are not supported. (other node types don't > * really make sense here) > * > * After printout, the subtree is being repaired and ready to be used again. > * @author Arno, [email protected] > */ >public class JivanDOMWriter implements DOMWriter { > > protected static final Logger logger = > Logger.getLogger(JivanDOMWriter.class.getName()); > > // prevent the HTML pages from being cached by the browser > protected boolean preventCaching = false; > // how long can the page be cached by browser > protected int maxAge = 0; //csc_061202.1 - added > > /** > * Createing a DOMWriter for outputting a DOM created by Jivan > */ > public JivanDOMWriter() { > super(); > } > > /* (non-Javadoc) > * @see > org.enhydra.barracuda.core.util.dom.DOMWriter#write(org.w3c.dom.Node, > java.io.OutputStream) > */ > public void write(Node node, OutputStream out) throws IOException { > if (node.getNodeType()==Node.DOCUMENT_NODE) { > >DocumentFactory.getInstance().docManFor(node).serialize(out); > } else { > write(node, new PrintWriter(out)); > } > } > > /** > * output of the Document of this node using a writer for the output. > * After serialization, the Document is being repaired. > */ > public void write(Node node, Writer writer) throws IOException { > switch(node.getNodeType()) { > case Node.DOCUMENT_NODE: > >DocumentFactory.getInstance().docManFor(node).serialize(writer); > break; > case Node.ELEMENT_NODE: > DocumentManager man = > DocumentFactory.getInstance().docManFor(node); > writer.write(man.serialize((Element)node, > true)); > default: > throw new IllegalArgumentException("Only > Elements and Dcument can be serialized, not "+node); > } > } > > /** > * Write a DOM to a ServletResponse object. This method will > * automatically set the content type for you. > * This method is copied from DefaultDOMWriter. It should really be > * abstracted from a common base class. > * > * @param node a DOM node, which belongs to the Document to be > written out > * @param resp the HttpServletResponse object > */ > public void write(Node node, HttpServletResponse resp) throws > IOException { > //set the response type (TODO:need to support WML as well) > String responseType = "text/xml"; > if (node instanceof HTMLDocument) responseType = "text/html"; > if (logger.isDebugEnabled()) logger.debug("Setting the > response type:"+responseType); > resp.setContentType(responseType); > > //if we need to prevent caching > if (preventCaching) { > //add the appropriate headers to the response > if (logger.isDebugEnabled()) > logger.debug("updating resp hdr to prevent caching"); > resp.setHeader("Pragma","no-cache"); > resp.setHeader("Cache-Control","no-cache"); > resp.setDateHeader("Expires", > System.currentTimeMillis()); > > //csc_061202.1 - added > //otherwise explicitly give it a max-age (this will > generally allow browsers like > //IE to page back in history without reloading, but if > the user actually revisits the > //URL, then it will still be reloaded) > } else { > resp.setHeader("Cache-Control","max-age="+maxAge); > resp.setDateHeader("Last-Modified", > System.currentTimeMillis()); > } > > //write the dom > write(node, resp.getWriter()); > } > > /** > * @return Returns the maxAge. > */ > public int getMaxAge() { > return maxAge; > } > > /** > * @param maxAge The maxAge to set. > */ > public void setMaxAge(int maxAge) { > this.maxAge = maxAge; > } > > /** > * @return Returns the preventCaching. > */ > public boolean isPreventCaching() { > return preventCaching; > } > > /** > * @param preventCaching The preventCaching to set. > */ > public void setPreventCaching(boolean preventCaching) { > this.preventCaching = preventCaching; > } > >}