src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java

changeset 1443
dffc222439a1
parent 514
29a761eaff0d
child 1546
dc8316632248
child 1609
09b083e0759c
     1.1 --- a/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java	Tue May 16 13:28:58 2017 -0700
     1.2 +++ b/src/share/jaxws_classes/com/sun/xml/internal/bind/v2/runtime/output/XMLStreamWriterOutput.java	Sun Jun 18 23:18:45 2017 +0100
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -26,15 +26,16 @@
    1.11  package com.sun.xml.internal.bind.v2.runtime.output;
    1.12  
    1.13  import java.io.IOException;
    1.14 +import java.io.Writer;
    1.15  import java.lang.reflect.Constructor;
    1.16  
    1.17  import javax.xml.stream.XMLStreamException;
    1.18  import javax.xml.stream.XMLStreamWriter;
    1.19  
    1.20 +import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;
    1.21  import com.sun.xml.internal.bind.v2.runtime.JAXBContextImpl;
    1.22  import com.sun.xml.internal.bind.v2.runtime.XMLSerializer;
    1.23  
    1.24 -import com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl;
    1.25  import org.xml.sax.SAXException;
    1.26  
    1.27  /**
    1.28 @@ -53,7 +54,7 @@
    1.29       * Creates a new {@link XmlOutput} from a {@link XMLStreamWriter}.
    1.30       * This method recognizes an FI StAX writer.
    1.31       */
    1.32 -    public static XmlOutput create(XMLStreamWriter out, JAXBContextImpl context) {
    1.33 +    public static XmlOutput create(XMLStreamWriter out, JAXBContextImpl context, CharacterEscapeHandler escapeHandler) {
    1.34          // try optimized path
    1.35          final Class writerClass = out.getClass();
    1.36          if (writerClass==FI_STAX_WRITER_CLASS) {
    1.37 @@ -69,17 +70,26 @@
    1.38              }
    1.39          }
    1.40  
    1.41 +        CharacterEscapeHandler xmlStreamEscapeHandler = escapeHandler != null ?
    1.42 +                escapeHandler : NewLineEscapeHandler.theInstance;
    1.43 +
    1.44          // otherwise the normal writer.
    1.45 -        return new XMLStreamWriterOutput(out);
    1.46 +        return new XMLStreamWriterOutput(out, xmlStreamEscapeHandler);
    1.47      }
    1.48  
    1.49  
    1.50      private final XMLStreamWriter out;
    1.51  
    1.52 +    private final CharacterEscapeHandler escapeHandler;
    1.53 +
    1.54 +    private final XmlStreamOutWriterAdapter writerWrapper;
    1.55 +
    1.56      protected final char[] buf = new char[256];
    1.57  
    1.58 -    protected XMLStreamWriterOutput(XMLStreamWriter out) {
    1.59 +    protected XMLStreamWriterOutput(XMLStreamWriter out, CharacterEscapeHandler escapeHandler) {
    1.60          this.out = out;
    1.61 +        this.escapeHandler = escapeHandler;
    1.62 +        this.writerWrapper = new XmlStreamOutWriterAdapter(out);
    1.63      }
    1.64  
    1.65      // not called if we are generating fragments
    1.66 @@ -137,7 +147,7 @@
    1.67      public void text(String value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
    1.68          if(needsSeparatingWhitespace)
    1.69              out.writeCharacters(" ");
    1.70 -        out.writeCharacters(value);
    1.71 +        escapeHandler.escape(value.toCharArray(), 0, value.length(), false, writerWrapper);
    1.72      }
    1.73  
    1.74      public void text(Pcdata value, boolean needsSeparatingWhitespace) throws IOException, SAXException, XMLStreamException {
    1.75 @@ -207,4 +217,82 @@
    1.76          }
    1.77      }
    1.78  
    1.79 +
    1.80 +    /**
    1.81 +     * Performs character escaping only for new lines.
    1.82 +     */
    1.83 +    private static class NewLineEscapeHandler implements CharacterEscapeHandler {
    1.84 +
    1.85 +        public static final NewLineEscapeHandler theInstance = new NewLineEscapeHandler();
    1.86 +
    1.87 +        @Override
    1.88 +        public void escape(char[] ch, int start, int length, boolean isAttVal, Writer out) throws IOException {
    1.89 +            int limit = start+length;
    1.90 +            int lastEscaped = start;
    1.91 +
    1.92 +            for (int i = start; i < limit; i++) {
    1.93 +                char c = ch[i];
    1.94 +                if (c == '\r' || c == '\n') {
    1.95 +                    if (i != lastEscaped) {
    1.96 +                        out.write(ch, lastEscaped, i - lastEscaped);
    1.97 +                    }
    1.98 +                    lastEscaped = i + 1;
    1.99 +                    if (out instanceof XmlStreamOutWriterAdapter) {
   1.100 +                        try {
   1.101 +                            ((XmlStreamOutWriterAdapter)out).writeEntityRef("#x" + Integer.toHexString(c));
   1.102 +                        } catch (XMLStreamException e) {
   1.103 +                            throw new IOException("Error writing xml stream", e);
   1.104 +                        }
   1.105 +                    } else {
   1.106 +                        out.write("&#x");
   1.107 +                        out.write(Integer.toHexString(c));
   1.108 +                        out.write(';');
   1.109 +                    }
   1.110 +                }
   1.111 +            }
   1.112 +            if (lastEscaped != limit) {
   1.113 +                out.write(ch, lastEscaped, length - lastEscaped);
   1.114 +            }
   1.115 +        }
   1.116 +    }
   1.117 +
   1.118 +    private static final class XmlStreamOutWriterAdapter extends Writer {
   1.119 +
   1.120 +        private final XMLStreamWriter writer;
   1.121 +
   1.122 +        private XmlStreamOutWriterAdapter(XMLStreamWriter writer) {
   1.123 +            this.writer = writer;
   1.124 +        }
   1.125 +
   1.126 +        @Override
   1.127 +        public void write(char[] cbuf, int off, int len) throws IOException {
   1.128 +            try {
   1.129 +                writer.writeCharacters(cbuf, off, len);
   1.130 +            } catch (XMLStreamException e) {
   1.131 +                throw new IOException("Error writing XML stream", e);
   1.132 +            }
   1.133 +        }
   1.134 +
   1.135 +        public void writeEntityRef(String entityReference) throws XMLStreamException {
   1.136 +            writer.writeEntityRef(entityReference);
   1.137 +        }
   1.138 +
   1.139 +        @Override
   1.140 +        public void flush() throws IOException {
   1.141 +            try {
   1.142 +                writer.flush();
   1.143 +            } catch (XMLStreamException e) {
   1.144 +                throw new IOException("Error flushing XML stream", e);
   1.145 +            }
   1.146 +        }
   1.147 +
   1.148 +        @Override
   1.149 +        public void close() throws IOException {
   1.150 +            try {
   1.151 +                writer.close();
   1.152 +            } catch (XMLStreamException e) {
   1.153 +                throw new IOException("Error closing XML stream", e);
   1.154 +            }
   1.155 +        }
   1.156 +    }
   1.157  }

mercurial