1 /* 2 * Copyright (c) 2005, 2016, 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 package com.sun.xml.internal.stream.events; 26 27 import com.sun.org.apache.xerces.internal.impl.PropertyManager; 28 import java.util.List; 29 import javax.xml.stream.util.XMLEventAllocator; 30 import javax.xml.stream.*; 31 import javax.xml.stream.events.*; 32 import javax.xml.XMLConstants; 33 import javax.xml.namespace.QName; 34 import com.sun.org.apache.xerces.internal.util.NamespaceContextWrapper; 35 import com.sun.org.apache.xerces.internal.util.NamespaceSupport; 36 import javax.xml.stream.util.XMLEventConsumer; 37 38 /** 39 * Implementation of XMLEvent Allocator. 40 * 41 * @author Neeraj.bajaj@sun.com, k.venugopal@sun.com 42 */ 43 public class XMLEventAllocatorImpl implements XMLEventAllocator { 44 45 /** 46 * Creates a new instance of XMLEventAllocator 47 */ 48 public XMLEventAllocatorImpl() { 49 } 50 51 public XMLEvent allocate(XMLStreamReader xMLStreamReader) throws XMLStreamException { 52 if (xMLStreamReader == null) { 53 throw new XMLStreamException("Reader cannot be null"); 54 } 55 // allocate is not supposed to change the state of the reader so we shouldn't be calling next. 56 // return getNextEvent(xMLStreamReader); 57 return getXMLEvent(xMLStreamReader); 58 } 59 60 public void allocate(XMLStreamReader xMLStreamReader, XMLEventConsumer xMLEventConsumer) 61 throws XMLStreamException { 62 XMLEvent currentEvent = getXMLEvent(xMLStreamReader); 63 if (currentEvent != null) { 64 xMLEventConsumer.add(currentEvent); 65 } 66 67 return; 68 } 69 70 public javax.xml.stream.util.XMLEventAllocator newInstance() { 71 return new XMLEventAllocatorImpl(); 72 } 73 74 //REVISIT: shouldn't we be using XMLEventFactory to create events. 75 XMLEvent getXMLEvent(XMLStreamReader streamReader) { 76 XMLEvent event = null; 77 //returns the current event 78 int eventType = streamReader.getEventType(); 79 switch (eventType) { 80 81 case XMLEvent.START_ELEMENT: { 82 StartElementEvent startElementEvent = new StartElementEvent(getQName(streamReader)); 83 fillAttributes(startElementEvent, streamReader); 84 //we might have different XMLStreamReader so check every time for 85 //the namespace aware property. we should be setting namespace 86 //related values only when isNamespaceAware is 'true' 87 if (((Boolean) streamReader.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE))) { 88 fillNamespaceAttributes(startElementEvent, streamReader); 89 setNamespaceContext(startElementEvent, streamReader); 90 } 91 92 startElementEvent.setLocation(streamReader.getLocation()); 93 event = startElementEvent; 94 break; 95 } 96 case XMLEvent.END_ELEMENT: { 97 EndElementEvent endElementEvent = new EndElementEvent(getQName(streamReader)); 98 endElementEvent.setLocation(streamReader.getLocation()); 99 100 if (((Boolean) streamReader.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE))) { 101 fillNamespaceAttributes(endElementEvent, streamReader); 102 } 103 event = endElementEvent; 104 break; 105 } 106 case XMLEvent.PROCESSING_INSTRUCTION: { 107 ProcessingInstructionEvent piEvent = new ProcessingInstructionEvent( 108 streamReader.getPITarget(), streamReader.getPIData()); 109 piEvent.setLocation(streamReader.getLocation()); 110 event = piEvent; 111 break; 112 } 113 case XMLEvent.CHARACTERS: { 114 CharacterEvent cDataEvent = new CharacterEvent(streamReader.getText()); 115 cDataEvent.setLocation(streamReader.getLocation()); 116 event = cDataEvent; 117 break; 118 } 119 case XMLEvent.COMMENT: { 120 CommentEvent commentEvent = new CommentEvent(streamReader.getText()); 121 commentEvent.setLocation(streamReader.getLocation()); 122 event = commentEvent; 123 break; 124 } 125 case XMLEvent.START_DOCUMENT: { 126 StartDocumentEvent sdEvent = new StartDocumentEvent(); 127 sdEvent.setVersion(streamReader.getVersion()); 128 sdEvent.setEncoding(streamReader.getEncoding()); 129 if (streamReader.getCharacterEncodingScheme() != null) { 130 sdEvent.setDeclaredEncoding(true); 131 } else { 132 sdEvent.setDeclaredEncoding(false); 133 } 134 sdEvent.setStandalone(streamReader.isStandalone()); 135 sdEvent.setLocation(streamReader.getLocation()); 136 event = sdEvent; 137 break; 138 } 139 case XMLEvent.END_DOCUMENT: { 140 EndDocumentEvent endDocumentEvent = new EndDocumentEvent(); 141 endDocumentEvent.setLocation(streamReader.getLocation()); 142 event = endDocumentEvent; 143 break; 144 } 145 case XMLEvent.ENTITY_REFERENCE: { 146 EntityReferenceEvent entityEvent = new EntityReferenceEvent(streamReader.getLocalName(), 147 new EntityDeclarationImpl(streamReader.getLocalName(), streamReader.getText())); 148 entityEvent.setLocation(streamReader.getLocation()); 149 event = entityEvent; 150 break; 151 152 } 153 case XMLEvent.ATTRIBUTE: { 154 event = null; 155 break; 156 } 157 case XMLEvent.DTD: { 158 DTDEvent dtdEvent = new DTDEvent(streamReader.getText()); 159 dtdEvent.setLocation(streamReader.getLocation()); 160 @SuppressWarnings("unchecked") 161 List<EntityDeclaration> entities = (List<EntityDeclaration>) 162 streamReader.getProperty(PropertyManager.STAX_ENTITIES); 163 if (entities != null && entities.size() != 0) { 164 dtdEvent.setEntities(entities); 165 } 166 @SuppressWarnings("unchecked") 167 List<NotationDeclaration> notations = (List<NotationDeclaration>) 168 streamReader.getProperty(PropertyManager.STAX_NOTATIONS); 169 if (notations != null && !notations.isEmpty()) { 170 dtdEvent.setNotations(notations); 171 } 172 event = dtdEvent; 173 break; 174 } 175 case XMLEvent.CDATA: { 176 CharacterEvent cDataEvent = new CharacterEvent(streamReader.getText(), true); 177 cDataEvent.setLocation(streamReader.getLocation()); 178 event = cDataEvent; 179 break; 180 } 181 case XMLEvent.SPACE: { 182 CharacterEvent spaceEvent = new CharacterEvent(streamReader.getText(), false, true); 183 spaceEvent.setLocation(streamReader.getLocation()); 184 event = spaceEvent; 185 break; 186 } 187 } 188 return event; 189 } 190 191 //this function is not used.. 192 protected XMLEvent getNextEvent(XMLStreamReader streamReader) throws XMLStreamException { 193 //advance the reader to next event. 194 streamReader.next(); 195 return getXMLEvent(streamReader); 196 } 197 198 protected void fillAttributes(StartElementEvent event, XMLStreamReader xmlr) { 199 200 int len = xmlr.getAttributeCount(); 201 QName qname = null; 202 AttributeImpl attr = null; 203 NamespaceImpl nattr = null; 204 for (int i = 0; i < len; i++) { 205 qname = xmlr.getAttributeName(i); 206 //this method doesn't include namespace declarations 207 //so we can be sure that there wont be any namespace declaration as part of this function call 208 //we can avoid this check - nb. 209 /** 210 * prefix = qname.getPrefix(); localpart = qname.getLocalPart(); if 211 * (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) ) { attr = new 212 * NamespaceImpl(localpart,xmlr.getAttributeValue(i)); }else if 213 * (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)){ attr = new 214 * NamespaceImpl(xmlr.getAttributeValue(i)); }else{ attr = new 215 * AttributeImpl(); attr.setName(qname); } 216 * 217 */ 218 attr = new AttributeImpl(); 219 attr.setName(qname); 220 attr.setAttributeType(xmlr.getAttributeType(i)); 221 attr.setSpecified(xmlr.isAttributeSpecified(i)); 222 attr.setValue(xmlr.getAttributeValue(i)); 223 event.addAttribute(attr); 224 } 225 } 226 227 protected void fillNamespaceAttributes(StartElementEvent event, XMLStreamReader xmlr) { 228 int count = xmlr.getNamespaceCount(); 229 String uri = null; 230 String prefix = null; 231 NamespaceImpl attr = null; 232 for (int i = 0; i < count; i++) { 233 uri = xmlr.getNamespaceURI(i); 234 prefix = xmlr.getNamespacePrefix(i); 235 if (prefix == null) { 236 prefix = XMLConstants.DEFAULT_NS_PREFIX; 237 } 238 attr = new NamespaceImpl(prefix, uri); 239 event.addNamespaceAttribute(attr); 240 } 241 } 242 243 protected void fillNamespaceAttributes(EndElementEvent event, XMLStreamReader xmlr) { 244 int count = xmlr.getNamespaceCount(); 245 String uri = null; 246 String prefix = null; 247 NamespaceImpl attr = null; 248 for (int i = 0; i < count; i++) { 249 uri = xmlr.getNamespaceURI(i); 250 prefix = xmlr.getNamespacePrefix(i); 251 if (prefix == null) { 252 prefix = XMLConstants.DEFAULT_NS_PREFIX; 253 } 254 attr = new NamespaceImpl(prefix, uri); 255 event.addNamespace(attr); 256 } 257 } 258 259 //Revisit : Creating a new Namespacecontext for now. 260 //see if we can do better job. 261 private void setNamespaceContext(StartElementEvent event, XMLStreamReader xmlr) { 262 NamespaceContextWrapper contextWrapper = (NamespaceContextWrapper) xmlr.getNamespaceContext(); 263 NamespaceSupport ns = new NamespaceSupport(contextWrapper.getNamespaceContext()); 264 event.setNamespaceContext(new NamespaceContextWrapper(ns)); 265 } 266 267 private QName getQName(XMLStreamReader xmlr) { 268 return new QName(xmlr.getNamespaceURI(), xmlr.getLocalName(), 269 xmlr.getPrefix()); 270 } 271 }