diff options
Diffstat (limited to 'gnu/xml/transform/StreamSerializer.java')
-rw-r--r-- | gnu/xml/transform/StreamSerializer.java | 197 |
1 files changed, 162 insertions, 35 deletions
diff --git a/gnu/xml/transform/StreamSerializer.java b/gnu/xml/transform/StreamSerializer.java index 46bded37c..eb045393d 100644 --- a/gnu/xml/transform/StreamSerializer.java +++ b/gnu/xml/transform/StreamSerializer.java @@ -15,8 +15,8 @@ General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA -02111-1307 USA. +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and @@ -48,6 +48,7 @@ import java.nio.charset.CharsetEncoder; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import javax.xml.XMLConstants; import org.w3c.dom.Attr; @@ -72,6 +73,82 @@ public class StreamSerializer static final int KET = 0x3e; // > static final int EQ = 0x3d; // = + /** + * HTML 4.01 boolean attributes + */ + static final Map HTML_BOOLEAN_ATTRIBUTES = new HashMap(); + static + { + HashSet set; + + set = new HashSet(); + set.add("nohref"); + HTML_BOOLEAN_ATTRIBUTES.put("area", set); + + set = new HashSet(); + set.add("ismap"); + HTML_BOOLEAN_ATTRIBUTES.put("img", set); + + set = new HashSet(); + set.add("declare"); + HTML_BOOLEAN_ATTRIBUTES.put("object", set); + + set = new HashSet(); + set.add("noshade"); + HTML_BOOLEAN_ATTRIBUTES.put("hr", set); + + set = new HashSet(); + set.add("compact"); + HTML_BOOLEAN_ATTRIBUTES.put("dl", set); + HTML_BOOLEAN_ATTRIBUTES.put("ol", set); + HTML_BOOLEAN_ATTRIBUTES.put("ul", set); + HTML_BOOLEAN_ATTRIBUTES.put("dir", set); + HTML_BOOLEAN_ATTRIBUTES.put("menu", set); + + set = new HashSet(); + set.add("checked"); + set.add("disabled"); + set.add("readonly"); + set.add("ismap"); + HTML_BOOLEAN_ATTRIBUTES.put("input", set); + + set = new HashSet(); + set.add("multiple"); + set.add("disabled"); + HTML_BOOLEAN_ATTRIBUTES.put("select", set); + + set = new HashSet(); + set.add("disabled"); + HTML_BOOLEAN_ATTRIBUTES.put("optgroup", set); + + set = new HashSet(); + set.add("selected"); + set.add("disabled"); + HTML_BOOLEAN_ATTRIBUTES.put("option", set); + + set = new HashSet(); + set.add("disabled"); + set.add("readonly"); + HTML_BOOLEAN_ATTRIBUTES.put("textarea", set); + + set = new HashSet(); + set.add("disabled"); + HTML_BOOLEAN_ATTRIBUTES.put("button", set); + + set = new HashSet(); + set.add("nowrap"); + HTML_BOOLEAN_ATTRIBUTES.put("th", set); + HTML_BOOLEAN_ATTRIBUTES.put("td", set); + + set = new HashSet(); + set.add("noresize"); + HTML_BOOLEAN_ATTRIBUTES.put("frame", set); + + set = new HashSet(); + set.add("defer"); + HTML_BOOLEAN_ATTRIBUTES.put("script", set); + } + protected final String encoding; final Charset charset; final CharsetEncoder encoder; @@ -118,17 +195,28 @@ public class StreamSerializer serialize(node, out, false); } - void serialize(final Node node, final OutputStream out, + void serialize(Node node, final OutputStream out, boolean convertToCdata) throws IOException { + while (node != null) + { + Node next = node.getNextSibling(); + doSerialize(node, out, convertToCdata); + node = next; + } + } + + private void doSerialize(final Node node, final OutputStream out, + boolean convertToCdata) + throws IOException + { if (out == null) { throw new NullPointerException("no output stream"); } String value, prefix; Node children; - Node next = node.getNextSibling(); String uri = node.getNamespaceURI(); boolean defined = false; short nt = node.getNodeType(); @@ -149,7 +237,12 @@ public class StreamSerializer { break; } - define(nsuri, node.getLocalName()); + String name = node.getLocalName(); + if (name == null) + { + name = node.getNodeName(); + } + define(nsuri, name); } else if (uri != null && !isDefined(uri)) { @@ -167,7 +260,8 @@ public class StreamSerializer out.write(encodeText(a_nodeName)); String a_nodeValue = node.getNodeValue(); if (mode == Stylesheet.OUTPUT_HTML && - a_nodeName.equals(a_nodeValue)) + a_nodeName.equals(a_nodeValue) && + isHTMLBoolean((Attr) node, a_nodeName)) { break; } @@ -324,11 +418,18 @@ public class StreamSerializer for (Node ctx = html.getFirstChild(); ctx != null; ctx = ctx.getNextSibling()) { - if (ctx.getNodeType() == Node.ELEMENT_NODE && - "head".equalsIgnoreCase(ctx.getLocalName())) + if (ctx.getNodeType() == Node.ELEMENT_NODE) { - head = ctx; - break; + String name = ctx.getLocalName(); + if (name == null) + { + name = ctx.getNodeName(); + } + if ("head".equalsIgnoreCase(name)) + { + head = ctx; + break; + } } } if (head == null) @@ -358,32 +459,39 @@ public class StreamSerializer for (Node ctx = head.getFirstChild(); ctx != null; ctx = ctx.getNextSibling()) { - if (ctx.getNodeType() == Node.ELEMENT_NODE && - "meta".equalsIgnoreCase(ctx.getLocalName())) + if (ctx.getNodeType() == Node.ELEMENT_NODE) { - NamedNodeMap metaAttrs = ctx.getAttributes(); - int len = metaAttrs.getLength(); - String httpEquiv = null; - Node content = null; - for (int i = 0; i < len; i++) + String name = ctx.getLocalName(); + if (name == null) { - Node attr = metaAttrs.item(i); - String attrName = attr.getNodeName(); - if ("http-equiv".equalsIgnoreCase(attrName)) + name = ctx.getNodeName(); + } + if ("meta".equalsIgnoreCase(name)) + { + NamedNodeMap metaAttrs = ctx.getAttributes(); + int len = metaAttrs.getLength(); + String httpEquiv = null; + Node content = null; + for (int i = 0; i < len; i++) { - httpEquiv = attr.getNodeValue(); + Node attr = metaAttrs.item(i); + String attrName = attr.getNodeName(); + if ("http-equiv".equalsIgnoreCase(attrName)) + { + httpEquiv = attr.getNodeValue(); + } + else if ("content".equalsIgnoreCase(attrName)) + { + content = attr; + } } - else if ("content".equalsIgnoreCase(attrName)) + if ("Content-Type".equalsIgnoreCase(httpEquiv)) { - content = attr; + meta = ctx; + metaContent = content; + break; } } - if ("Content-Type".equalsIgnoreCase(httpEquiv)) - { - meta = ctx; - metaContent = content; - break; - } } } if (meta == null) @@ -466,10 +574,6 @@ public class StreamSerializer { undefine(uri); } - if (next != null) - { - serialize(next, out, convertToCdata); - } } boolean isDefined(String uri) @@ -523,12 +627,20 @@ public class StreamSerializer text = buf.toString(); } ByteBuffer encoded = encoder.encode(CharBuffer.wrap(text)); + int len = encoded.limit() - encoded.position(); if (encoded.hasArray()) { - return encoded.array(); + byte[] ret = encoded.array(); + if (ret.length > len) + { + // Why? + byte[] ret2 = new byte[len]; + System.arraycopy(ret, 0, ret2, 0, len); + ret = ret2; + } + return ret; } encoded.flip(); - int len = encoded.limit() - encoded.position(); byte[] ret = new byte[len]; encoded.get(ret, 0, len); return ret; @@ -632,4 +744,19 @@ public class StreamSerializer } } + boolean isHTMLBoolean(Attr attr, String attrName) + { + attrName = attrName.toLowerCase(); + Node element = attr.getOwnerElement(); + String elementName = element.getLocalName(); + if (elementName == null) + { + elementName = element.getNodeName(); + } + elementName = elementName.toLowerCase(); + Collection attributes = + (Collection) HTML_BOOLEAN_ATTRIBUTES.get(elementName); + return (attributes != null && attributes.contains(attrName)); + } + } |