< prev index next >

src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/SAX2StAXEventWriter.java

Print this page


   1 /*
   2  * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.org.apache.xalan.internal.xsltc.trax;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Collection;
  30 import java.util.Collections;
  31 import java.util.HashMap;
  32 import java.util.Iterator;
  33 import java.util.List;
  34 import java.util.Map;
  35 import javax.xml.stream.XMLEventFactory;
  36 import javax.xml.stream.XMLEventWriter;
  37 import javax.xml.stream.XMLStreamException;
  38 import javax.xml.stream.events.*;
  39 import org.xml.sax.Attributes;
  40 import org.xml.sax.SAXException;
  41 import org.xml.sax.ext.Locator2;
  42 
  43 /**
  44  * @author Sunitha Reddy
  45  */
  46 public class SAX2StAXEventWriter extends SAX2StAXBaseWriter {
  47 
  48 
  49     private XMLEventWriter writer;
  50 
  51 
  52     private XMLEventFactory eventFactory;
  53 
  54 
  55     private List<Collection<Namespace>> namespaceStack = new ArrayList<>();
  56 
  57 
  58     private boolean needToCallStartDocument = false;
  59 
  60 
  61     public SAX2StAXEventWriter() {
  62 
  63         eventFactory = XMLEventFactory.newInstance();
  64 
  65     }
  66 
  67 
  68     public SAX2StAXEventWriter(XMLEventWriter writer) {
  69 
  70         this.writer = writer;
  71         eventFactory = XMLEventFactory.newInstance();
  72 
  73     }
  74 
  75     public SAX2StAXEventWriter(XMLEventWriter writer,
  76             XMLEventFactory factory) {
  77 
  78         this.writer = writer;
  79         if (factory != null) {
  80 
  81             this.eventFactory = factory;
  82 
  83         } else {
  84 
  85             eventFactory = XMLEventFactory.newInstance();
  86 
  87         }
  88 
  89     }
  90 
  91     public XMLEventWriter getEventWriter() {
  92 
  93         return writer;
  94 
  95     }
  96 
  97 
  98     public void setEventWriter(XMLEventWriter writer) {
  99 
 100         this.writer = writer;
 101 
 102     }
 103 
 104 
 105     public XMLEventFactory getEventFactory() {
 106 
 107         return eventFactory;
 108 
 109     }
 110 
 111 
 112     public void setEventFactory(XMLEventFactory factory) {
 113 
 114         this.eventFactory = factory;
 115 
 116     }
 117 
 118     public void startDocument() throws SAXException {
 119 
 120         super.startDocument();
 121 
 122         namespaceStack.clear();
 123 
 124         eventFactory.setLocation(getCurrentLocation());
 125 
 126         // Encoding and version info will be available only after startElement
 127         // is called for first time. So, defer START_DOCUMENT event of StAX till
 128         // that point of time.
 129         needToCallStartDocument = true;
 130     }
 131 
 132     private void writeStartDocument() throws SAXException {

 133         try {
 134             if (docLocator == null)
 135                 writer.add(eventFactory.createStartDocument());
 136             else {
 137                 try{
 138                     writer.add(eventFactory.createStartDocument(((Locator2)docLocator).getEncoding(),((Locator2)docLocator).getXMLVersion()));
 139                 } catch(ClassCastException e){
 140                     writer.add(eventFactory.createStartDocument());
 141                 }
 142             }
 143         } catch (XMLStreamException e) {
 144             throw new SAXException(e);
 145         }
 146         needToCallStartDocument = false;
 147     }
 148 
 149     public void endDocument() throws SAXException {
 150 
 151         eventFactory.setLocation(getCurrentLocation());
 152 
 153         try {
 154 
 155             writer.add(eventFactory.createEndDocument());
 156 
 157         } catch (XMLStreamException e) {
 158 
 159             throw new SAXException(e);
 160 
 161         }
 162 
 163         super.endDocument();
 164 
 165         // clear the namespaces
 166         namespaceStack.clear();
 167 
 168     }
 169 
 170     @SuppressWarnings({"rawtypes", "unchecked"})
 171     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
 172 
 173         if (needToCallStartDocument) {
 174             writeStartDocument();
 175         }
 176 
 177         // set document location
 178         eventFactory.setLocation(getCurrentLocation());
 179 
 180         // create attribute and namespace events
 181         Collection[] events = {null, null};
 182         createStartEvents(attributes, events);
 183 
 184         namespaceStack.add(events[0]);
 185 
 186         try {
 187 
 188             String[] qname = {null, null};
 189             parseQName(qName, qname);
 190 
 191             writer.add(eventFactory.createStartElement(qname[0], uri,
 192                     qname[1], events[1].iterator(), events[0].iterator()));
 193 
 194         } catch (XMLStreamException e) {
 195 
 196             throw new SAXException(e);
 197 
 198         } finally {
 199 
 200             super.startElement(uri, localName, qName, attributes);
 201 
 202         }
 203 
 204     }
 205 
 206     public void endElement(String uri, String localName, String qName)
 207             throws SAXException {
 208 
 209         super.endElement(uri, localName, qName);
 210 
 211         eventFactory.setLocation(getCurrentLocation());
 212 
 213         // parse name
 214         String[] qname = {null, null};
 215         parseQName(qName, qname);
 216 
 217         // get namespaces
 218         Collection<Namespace> nsList = namespaceStack.remove(namespaceStack.size() - 1);
 219         Iterator<Namespace> nsIter = nsList.iterator();
 220 
 221         try {
 222 
 223             writer.add(eventFactory.createEndElement(qname[0], uri, qname[1],
 224                     nsIter));
 225 
 226         } catch (XMLStreamException e) {
 227 
 228             throw new SAXException(e);
 229 
 230         }
 231 
 232     }
 233 
 234     public void comment(char[] ch, int start, int length) throws SAXException {
 235         if (needToCallStartDocument) {
 236             // Drat. We were trying to postpone this until the first element so that we could get
 237             // the locator, but we can't output a comment before the start document, so we're just
 238             // going to have to do without the locator if it hasn't been set yet.
 239             writeStartDocument();
 240         }
 241 
 242         super.comment(ch, start, length);
 243 
 244         eventFactory.setLocation(getCurrentLocation());
 245         try {
 246 
 247             writer.add(eventFactory.createComment(new String(ch, start,
 248                     length)));
 249 
 250         } catch (XMLStreamException e) {
 251 
 252             throw new SAXException(e);
 253 
 254         }
 255 
 256     }
 257 
 258     public void characters(char[] ch, int start, int length)
 259             throws SAXException {
 260 
 261         super.characters(ch, start, length);
 262 
 263         try {
 264 
 265             if (!isCDATA) {
 266 
 267                 eventFactory.setLocation(getCurrentLocation());
 268                 writer.add(eventFactory.createCharacters(new String(ch,
 269                         start, length)));
 270 
 271             }
 272 
 273         } catch (XMLStreamException e) {
 274 
 275             throw new SAXException(e);
 276 
 277         }
 278 
 279     }
 280 
 281     public void ignorableWhitespace(char[] ch, int start, int length)
 282             throws SAXException {
 283 
 284         super.ignorableWhitespace(ch, start, length);
 285         characters(ch, start, length);
 286 
 287     }
 288 
 289     public void processingInstruction(String target, String data)
 290             throws SAXException {
 291 
 292         if (needToCallStartDocument) {
 293             // Drat. We were trying to postpone this until the first element so that we could get
 294             // the locator, but we can't output a PI before the start document, so we're just
 295             // going to have to do without the locator if it hasn't been set yet.
 296             writeStartDocument();
 297         }
 298 
 299         super.processingInstruction(target, data);
 300         try {
 301 
 302             writer.add(eventFactory.createProcessingInstruction(target, data));
 303 
 304         } catch (XMLStreamException e) {
 305 
 306             throw new SAXException(e);
 307 
 308         }
 309 
 310     }
 311 
 312     public void endCDATA() throws SAXException {
 313 
 314         eventFactory.setLocation(getCurrentLocation());
 315         try {
 316 
 317             writer.add(eventFactory.createCData(CDATABuffer.toString()));
 318 
 319         } catch (XMLStreamException e) {
 320 
 321             throw new SAXException(e);
 322 
 323         }
 324 
 325         super.endCDATA();
 326 
 327     }
 328 
 329     @SuppressWarnings({"rawtypes", "unchecked"})
 330     protected void createStartEvents(Attributes attributes, Collection<Attribute>[] events) {
 331 
 332         Map<String, Attribute> nsMap = null;
 333         List<Attribute> attrs = null;
 334 
 335         // create namespaces
 336         if (namespaces != null) {
 337             final int nDecls = namespaces.size();
 338             for (int i = 0; i < nDecls; i++) {
 339                 final String prefix = namespaces.get(i++);
 340                 String uri = namespaces.get(i);
 341                 Namespace ns = createNamespace(prefix, uri);
 342                 if (nsMap == null) {
 343                     nsMap = new HashMap<>();
 344                 }
 345                 nsMap.put(prefix, ns);
 346             }


 356             String attrLocal = qname[1];
 357 
 358             String attrQName = attributes.getQName(i);
 359             String attrValue = attributes.getValue(i);
 360             String attrURI = attributes.getURI(i);
 361 
 362             if ("xmlns".equals(attrQName) || "xmlns".equals(attrPrefix)) {
 363                 // namespace declaration disguised as an attribute. If the
 364                 // namespace has already been declared, skip it, otherwise
 365                 // write it as an namespace
 366                 if (nsMap == null) {
 367                     nsMap = new HashMap<>();
 368                 }
 369 
 370                 if (!nsMap.containsKey(attrLocal)) {
 371                     Namespace ns = createNamespace(attrLocal, attrValue);
 372                     nsMap.put(attrLocal, ns);
 373                 }
 374 
 375             } else {
 376 
 377                 Attribute attribute;
 378                 if (attrPrefix.length() > 0) {
 379 
 380                     attribute = eventFactory.createAttribute(attrPrefix,
 381                             attrURI, attrLocal, attrValue);
 382 
 383                 } else {
 384 
 385                     attribute = eventFactory.createAttribute(attrLocal,
 386                             attrValue);
 387 
 388                 }
 389 
 390                 if (attrs == null) {
 391                     attrs = new ArrayList<>();
 392                 }
 393                 attrs.add(attribute);
 394 
 395             }
 396         }
 397 
 398         events[0] = (nsMap == null ? Collections.EMPTY_LIST : nsMap.values());
 399         events[1] = (attrs == null ? Collections.EMPTY_LIST : attrs);
 400 
 401     }
 402 
 403     protected Namespace createNamespace(String prefix, String uri) {
 404 
 405         if (prefix == null || prefix.length() == 0) {
 406 
 407             return eventFactory.createNamespace(uri);
 408 
 409         } else {
 410 
 411             return eventFactory.createNamespace(prefix, uri);
 412 
 413         }
 414 
 415     }
 416 
 417 }
   1 /*
   2  * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.org.apache.xalan.internal.xsltc.trax;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Collection;
  30 import java.util.Collections;
  31 import java.util.HashMap;
  32 import java.util.Iterator;
  33 import java.util.List;
  34 import java.util.Map;
  35 import javax.xml.stream.XMLEventFactory;
  36 import javax.xml.stream.XMLEventWriter;
  37 import javax.xml.stream.XMLStreamException;
  38 import javax.xml.stream.events.*;
  39 import org.xml.sax.Attributes;
  40 import org.xml.sax.SAXException;

  41 
  42 /**
  43  * @author Sunitha Reddy
  44  */
  45 public class SAX2StAXEventWriter extends SAX2StAXBaseWriter {
  46 

  47     private XMLEventWriter writer;
  48 

  49     private XMLEventFactory eventFactory;
  50 

  51     private List<Collection<Namespace>> namespaceStack = new ArrayList<>();
  52 

  53     private boolean needToCallStartDocument = false;
  54 

  55     public SAX2StAXEventWriter() {

  56         eventFactory = XMLEventFactory.newInstance();

  57     }
  58 

  59     public SAX2StAXEventWriter(XMLEventWriter writer) {

  60         this.writer = writer;
  61         eventFactory = XMLEventFactory.newInstance();

  62     }
  63 
  64     public SAX2StAXEventWriter(XMLEventWriter writer,
  65             XMLEventFactory factory) {
  66 
  67         this.writer = writer;
  68         if (factory != null) {

  69             this.eventFactory = factory;

  70         } else {

  71             eventFactory = XMLEventFactory.newInstance();

  72         }

  73     }
  74 
  75     public XMLEventWriter getEventWriter() {

  76         return writer;

  77     }
  78 

  79     public void setEventWriter(XMLEventWriter writer) {

  80         this.writer = writer;

  81     }
  82 

  83     public XMLEventFactory getEventFactory() {

  84         return eventFactory;

  85     }
  86 

  87     public void setEventFactory(XMLEventFactory factory) {

  88         this.eventFactory = factory;

  89     }
  90 
  91     public void startDocument() throws SAXException {

  92         super.startDocument();

  93         namespaceStack.clear();

  94         eventFactory.setLocation(getCurrentLocation());
  95 
  96         // Encoding and version info will be available only after startElement
  97         // is called for first time. So, defer START_DOCUMENT event of StAX till
  98         // that point of time.
  99         needToCallStartDocument = true;
 100     }
 101 
 102     void writeStartDocument() throws SAXException {
 103         super.writeStartDocument();
 104         try {
 105             writer.add(eventFactory.createStartDocument(encoding, xmlVersion));








 106         } catch (XMLStreamException e) {
 107             throw new SAXException(e);
 108         }
 109         needToCallStartDocument = false;
 110     }
 111 
 112     public void endDocument() throws SAXException {

 113         eventFactory.setLocation(getCurrentLocation());
 114 
 115         try {

 116             writer.add(eventFactory.createEndDocument());

 117         } catch (XMLStreamException e) {

 118             throw new SAXException(e);

 119         }
 120 
 121         super.endDocument();
 122 
 123         // clear the namespaces
 124         namespaceStack.clear();
 125 
 126     }
 127 
 128     @SuppressWarnings({"rawtypes", "unchecked"})
 129     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

 130         if (needToCallStartDocument) {
 131             writeStartDocument();
 132         }
 133 
 134         // set document location
 135         eventFactory.setLocation(getCurrentLocation());
 136 
 137         // create attribute and namespace events
 138         Collection[] events = {null, null};
 139         createStartEvents(attributes, events);
 140 
 141         namespaceStack.add(events[0]);
 142 
 143         try {

 144             String[] qname = {null, null};
 145             parseQName(qName, qname);
 146 
 147             writer.add(eventFactory.createStartElement(qname[0], uri,
 148                     qname[1], events[1].iterator(), events[0].iterator()));

 149         } catch (XMLStreamException e) {

 150             throw new SAXException(e);

 151         } finally {

 152             super.startElement(uri, localName, qName, attributes);

 153         }
 154 
 155     }
 156 
 157     public void endElement(String uri, String localName, String qName)
 158             throws SAXException {
 159 
 160         super.endElement(uri, localName, qName);
 161 
 162         eventFactory.setLocation(getCurrentLocation());
 163 
 164         // parse name
 165         String[] qname = {null, null};
 166         parseQName(qName, qname);
 167 
 168         // get namespaces
 169         Collection<Namespace> nsList = namespaceStack.remove(namespaceStack.size() - 1);
 170         Iterator<Namespace> nsIter = nsList.iterator();
 171 
 172         try {

 173             writer.add(eventFactory.createEndElement(qname[0], uri, qname[1],
 174                     nsIter));

 175         } catch (XMLStreamException e) {

 176             throw new SAXException(e);

 177         }

 178     }
 179 
 180     public void comment(char[] ch, int start, int length) throws SAXException {
 181         if (needToCallStartDocument) {
 182             // Drat. We were trying to postpone this until the first element so that we could get
 183             // the locator, but we can't output a comment before the start document, so we're just
 184             // going to have to do without the locator if it hasn't been set yet.
 185             writeStartDocument();
 186         }
 187 
 188         super.comment(ch, start, length);
 189 
 190         eventFactory.setLocation(getCurrentLocation());
 191         try {

 192             writer.add(eventFactory.createComment(new String(ch, start,
 193                     length)));

 194         } catch (XMLStreamException e) {

 195             throw new SAXException(e);

 196         }

 197     }
 198 
 199     public void characters(char[] ch, int start, int length)
 200             throws SAXException {
 201 
 202         super.characters(ch, start, length);
 203 
 204         try {

 205             if (!isCDATA) {

 206                 eventFactory.setLocation(getCurrentLocation());
 207                 writer.add(eventFactory.createCharacters(new String(ch,
 208                         start, length)));

 209             }
 210 
 211         } catch (XMLStreamException e) {

 212             throw new SAXException(e);

 213         }

 214     }
 215 
 216     public void ignorableWhitespace(char[] ch, int start, int length)
 217             throws SAXException {
 218 
 219         super.ignorableWhitespace(ch, start, length);
 220         characters(ch, start, length);

 221     }
 222 
 223     public void processingInstruction(String target, String data)
 224             throws SAXException {
 225 
 226         if (needToCallStartDocument) {
 227             // Drat. We were trying to postpone this until the first element so that we could get
 228             // the locator, but we can't output a PI before the start document, so we're just
 229             // going to have to do without the locator if it hasn't been set yet.
 230             writeStartDocument();
 231         }
 232 
 233         super.processingInstruction(target, data);
 234         try {

 235             writer.add(eventFactory.createProcessingInstruction(target, data));

 236         } catch (XMLStreamException e) {

 237             throw new SAXException(e);

 238         }

 239     }
 240 
 241     public void endCDATA() throws SAXException {
 242 
 243         eventFactory.setLocation(getCurrentLocation());
 244         try {

 245             writer.add(eventFactory.createCData(CDATABuffer.toString()));

 246         } catch (XMLStreamException e) {

 247             throw new SAXException(e);

 248         }
 249 
 250         super.endCDATA();

 251     }
 252 
 253     @SuppressWarnings({"rawtypes", "unchecked"})
 254     protected void createStartEvents(Attributes attributes, Collection<Attribute>[] events) {
 255 
 256         Map<String, Attribute> nsMap = null;
 257         List<Attribute> attrs = null;
 258 
 259         // create namespaces
 260         if (namespaces != null) {
 261             final int nDecls = namespaces.size();
 262             for (int i = 0; i < nDecls; i++) {
 263                 final String prefix = namespaces.get(i++);
 264                 String uri = namespaces.get(i);
 265                 Namespace ns = createNamespace(prefix, uri);
 266                 if (nsMap == null) {
 267                     nsMap = new HashMap<>();
 268                 }
 269                 nsMap.put(prefix, ns);
 270             }


 280             String attrLocal = qname[1];
 281 
 282             String attrQName = attributes.getQName(i);
 283             String attrValue = attributes.getValue(i);
 284             String attrURI = attributes.getURI(i);
 285 
 286             if ("xmlns".equals(attrQName) || "xmlns".equals(attrPrefix)) {
 287                 // namespace declaration disguised as an attribute. If the
 288                 // namespace has already been declared, skip it, otherwise
 289                 // write it as an namespace
 290                 if (nsMap == null) {
 291                     nsMap = new HashMap<>();
 292                 }
 293 
 294                 if (!nsMap.containsKey(attrLocal)) {
 295                     Namespace ns = createNamespace(attrLocal, attrValue);
 296                     nsMap.put(attrLocal, ns);
 297                 }
 298 
 299             } else {

 300                 Attribute attribute;
 301                 if (attrPrefix.length() > 0) {

 302                     attribute = eventFactory.createAttribute(attrPrefix,
 303                             attrURI, attrLocal, attrValue);

 304                 } else {

 305                     attribute = eventFactory.createAttribute(attrLocal,
 306                             attrValue);

 307                 }
 308 
 309                 if (attrs == null) {
 310                     attrs = new ArrayList<>();
 311                 }
 312                 attrs.add(attribute);

 313             }
 314         }
 315 
 316         events[0] = (nsMap == null ? Collections.EMPTY_LIST : nsMap.values());
 317         events[1] = (attrs == null ? Collections.EMPTY_LIST : attrs);

 318     }
 319 
 320     protected Namespace createNamespace(String prefix, String uri) {

 321         if (prefix == null || prefix.length() == 0) {

 322             return eventFactory.createNamespace(uri);

 323         } else {

 324             return eventFactory.createNamespace(prefix, uri);

 325         }

 326     }

 327 }
< prev index next >