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();