[From nobody Fri Aug 6 17:08:03 2004 Return-Path: <gberthet@xmlnetworks.com> Received: from alias.acm.org ([199.222.69.90]) by osgood.mail.atl.earthlink.net (Earthlink Mail Service) with ESMTP id 17WO9w5413Nl3pt0 for <servlets@mindspring.com>; Wed, 2 Oct 2002 14:23:18 -0400 (EDT) Received: from mibcentral.com ([12.47.45.123]) by alias.acm.org (ACM Email Forwarding Service) with ESMTP id COB73880 for <jhunter@acm.org>; Wed, 02 Oct 2002 14:24:37 -0400 Received: from gerard (12-234-40-105.client.attbi.com [12.234.40.105]) by mibcentral.com (8.11.6/8.11.6) with ESMTP id g92I5VH18067; Wed, 2 Oct 2002 13:05:31 -0500 Message-Id: <4.2.0.58.20021002104832.00c81c20@xmlnetworks.com> X-Sender: gberthet@xmlnetworks.com X-Mailer: QUALCOMM Windows Eudora Pro Version 4.2.0.58 Date: Wed, 02 Oct 2002 11:27:14 -0700 To: jhunter@acm.org From: Gerard Berthet <gberthet@xmlnetworks.com> Subject: File saving issue with XMLoutputter Cc: gberthet@xmlnetworks.com Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed X-Mozilla-Status2: 00000000 Jason, I have identified a problem re-loading an XML file after saving it using XMLOutputter. My servlet does the following: 0) Open a web page http://localhost:8080/mibide/test.html 1) Click on the "Add" link which will do: a) Read an XML file using SAXBuilder b) Add a new element using List.add() c) Save the file to disk using XMLoutputter d) Display the new file using an XSLT stylesheet (the new page include an "Add" link) 2) Repeat 1) The problem is that if step 2) is repeated too quickly, the file does not seem to be saved correctly, and therefore step d) does not show the new element added. If I wait at least 5 seconds before step 2), it works all the time. I have been working on this problem for several days but cannot figure out the root cause. Do you have any idea why this problem is occurring? Does it have to do with the OS disk caching scheme? Any help is very much appreciated. If not, thank you anyhow for the wonderful articles about JDOM and servlets. Best regards, Gerard Berthet ------------------------------------- My code looks like that: public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { URL xmlURL; String xmlSystemID; Source xmlSource; File topDir = new File("."); String topDirName = topDir.getCanonicalPath(); String filename = "test.xml"; String fqFilename = topDirName + File.separator + "webapps" + File.separator + "mibide" + File.separator + "WEB-INF" + File.separator + "xml" + File.separator + filename; String urlFilename = File.separator + "WEB-INF" + File.separator + "xml" + File.separator + filename; File fqFile = new File(fqFilename); ServletContext context = getServletContext(); SAXBuilder builder = new SAXBuilder(); // Load document in memory // ------------------------------------------------------------------ long xslLastModified = fqFile.lastModified( ); context.log("Using XML file: " + urlFilename + " with stats: " + xslLastModified); xmlURL = context.getResource(urlFilename); context.log("xmlURL2: " + xmlURL); xmlSystemID = xmlURL.toExternalForm(); Document doc = builder.build(xmlSystemID); Element rootElement = doc.getRootElement(); int numNewElements = rootElement.getChildren("new").size(); if (request.getParameter("add") != null) { Element elementToAdd = new Element("new").setText("new_value: " + (numNewElements+1)); List newElements = rootElement.getChildren("new"); context.log("Before adding, we have: " + rootElement.getChildren("new").size()); context.log("adding a new element #" + (numNewElements + 1)); newElements.add(0, elementToAdd); context.log("After adding, we have: " + rootElement.getChildren("new").size()); } // then we save the new document in the XML directory // ------------------------------------------------------------------ XMLOutputter outputter = new XMLOutputter("", false); FileOutputStream output = new FileOutputStream(fqFilename); outputter.output(doc, output); output.flush(); output.close(); context.log("saved to disk with " + rootElement.getChildren("new").size() + " new elements with stats: " + fqFile.lastModified( )); // then, display the document, for that new element // ---------------------------------------------------------------------- String xsl = "test.xsl"; topDir = new File("."); String xslFilename = topDirName + File.separator + "webapps" + File.separator + "mibide" + File.separator + "WEB-INF" + File.separator + "xsl" + File.separator + xsl; URL xslURL = context.getResource(File.separator + "WEB-INF" + File.separator + "xsl" + File.separator + xsl); String xslSystemID = xslURL.toExternalForm(); // Display modified document response.setContentType("text/html"); OutputStream outs = response.getOutputStream(); TransformerFactory transFactory = TransformerFactory.newInstance(); Transformer transform = transFactory.newTransformer(new StreamSource(xslSystemID)); context.log("About to transform " + rootElement.getChildren("new").size() + " new elements"); transform.transform(new JDOMSource(doc), new StreamResult(outs)); outs.flush(); outs.close(); context.log("completed XSLT transformation"); } catch (Exception e) { e.printStackTrace(); } } ---------------------------- And the log trace looks something like the following, where the first two elements are saved, but the third time I click on the Add button, it fails to save to disk. However, I found that if I wait a good 5 seconds between two requests to add a new element, it always saves to disk correctly. Using XML file: \WEB-INF\xml\test.xml with stats: 1033582406962 xmlURL2: jndi:/localhost/mibide\WEB-INF\xml\test.xml Before adding, we have: 0 adding a new element #1 After adding, we have: 1 saved to disk with 1 new elements with stats: 1033582413382 About to transform 1 new elements completed XSLT transformation -- Clicked on the "Add" link right away. The new element says it is added but it is not as we re-open the XML file. Using XML file: \WEB-INF\xml\test.xml with stats: 1033582413382 xmlURL2: jndi:/localhost/mibide\WEB-INF\xml\test.xml Before adding, we have: 0 adding a new element #1 After adding, we have: 1 saved to disk with 1 new elements with stats: 1033582416456 About to transform 1 new elements completed XSLT transformation -- Waited at least 5 seconds before clicking on the "Add" link. The new element is added and saved tot he file. Using XML file: \WEB-INF\xml\test.xml with stats: 1033582416456 xmlURL2: jndi:/localhost/mibide\WEB-INF\xml\test.xml Before adding, we have: 1 adding a new element #2 After adding, we have: 2 saved to disk with 2 new elements with stats: 1033582489131 About to transform 2 new elements completed XSLT transformation ----------- Here is the XML file after these 3 updates (it has only 2 new elements): <?xml version="1.0" encoding="UTF-8"?> <top><new>new_value: 2</new><new>new_value: 1</new></top> ---------------------------- Here is test.html: <html><head><title>Test page</title></head> <body> <a href="/mibide/servlet/test">View</a> <br> <a href="/mibide/servlet/test?add=y">Add</a> </body> </html> -------------------------------------------- And here is my stylesheet: <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head><title>Test</title></head> <body> <a href="/mibide/servlet/test">View</a> <br/> <a href="/mibide/servlet/test?add=y">Add</a> <br/> <table> <tr><th>New Values</th></tr> <xsl:for-each select="/top/new"> <tr><td><xsl:value-of select="."/></td></tr> </xsl:for-each> </table> </body> </html> </xsl:template> </xsl:stylesheet> ]