Hi,

     Apologies if you have seen this before, I'm resending it as I've 
just read the proto-FAQ and realised I hadn't used the corrent subject line.

    I had problems with an XSL output method of html using JDK 1.1. I
checked that the output method had been set on the transformer but it
still output with XML format tags (e.g. <BR/>).

    I dubugged through the code and found that when the
output_html.properties file was being loaded the key names were not
being fixed up correctly.

The relevant entry is :
{http\u003a//xml.apache.org/xslt}content-handler=org.apache.xalan.serialize.SerializerToHTML

    JDK 1.x didn't properly expand Unicode escape sequences in Property
key names (such as \u003a), so
org.apache.xalan.templates.OutputProperties has some code in the
loadPropertiesFile method to fix these references.

    The code gets an Enumerator for the Properties and enumerates through
each key. If the key needs fixing it removes the old key and then adds
it back with the correct key. However the Enumerator is not valid after
the modification and some of the original values (including
{http\u003a//xml.apache.org/xslt}content-handler) were being skipped as
a result and not patched (other keys appeared twice in the enumerator).

    From the JDK docs of Hashtable (which Properties inherits its 
implementation of keys() ):
  The Iterators returned by the iterator and listIterator methods of the 
Collections returned by all of Hashtable's "collection view methods" are 
fail-fast: if the Hashtable is structurally modified at any time after 
the Iterator is created, in any way except through the Iterator's own 
remove or add methods, the Iterator will throw a 
ConcurrentModificationException. Thus, in the face of concurrent 
modification, the Iterator fails quickly and cleanly, rather than 
risking arbitrary, non-deterministic behavior at an undetermined time in 
the future. The Enumerations returned by Hashtable's keys and values 
methods are not fail-fast.

    The code is structurally modifying the Properties Hashtable 
directly, without going through the Enumeration (which you can't, you 
can only do this with Iterator), so the Enumeration behaves 
non-deterministically and skips some items and visits others more than 
once. By cloning the Properties object and Enumerating the clone we 
ensure that the Properties object that we are enumerating is never 
modified. As we only want the keys this works well.

    I changed it to Enumerate a clone of the Properties object and this
seems to work.

    I'm including the patch. Could a committer please review this patch
and if it is valid make the change in cvs ?

    Thanks very much,

        Regards,

            Padraig

==========================================================
--- OutputProperties.java.orig    Wed May 23 08:43:14 2001
+++ OutputProperties.java    Fri May 25 17:32:43 2001
@@ -237,7 +237,7 @@
     // Note that we're working at the HashTable level here,
     // and not at the Properties level!  This is important
     // because we don't want to modify the default properties.
-    Enumeration keys = props.keys();
+    Enumeration keys = ((Properties)props.clone()).keys();
     while(keys.hasMoreElements())
     {
       String key = (String)keys.nextElement();
==========================================================

Padraig O'hIceadha,
Chief Technical Architect,
Gradient Solutions, a Sabre Company

--- OutputProperties.java.orig  Wed May 23 08:43:14 2001
+++ OutputProperties.java       Fri May 25 17:32:43 2001
@@ -237,7 +237,7 @@
     // Note that we're working at the HashTable level here, 
     // and not at the Properties level!  This is important 
     // because we don't want to modify the default properties.
-    Enumeration keys = props.keys();
+    Enumeration keys = ((Properties)props.clone()).keys();
     while(keys.hasMoreElements())
     {
       String key = (String)keys.nextElement();

Reply via email to