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 26 package com.sun.xml.internal.stream.events; 27 28 import com.sun.xml.internal.stream.util.ReadOnlyIterator; 29 import java.util.ArrayList; 30 import java.util.Collection; 31 import java.util.HashMap; 32 import java.util.Iterator; 33 import java.util.List; 34 import java.util.Map; 35 import javax.xml.namespace.NamespaceContext; 36 import javax.xml.namespace.QName; 37 import javax.xml.stream.XMLStreamConstants; 38 import javax.xml.stream.events.Attribute; 39 import javax.xml.stream.events.Namespace; 40 import javax.xml.stream.events.StartElement; 41 42 /** 43 * Implementation of StartElementEvent. 44 * 45 * @author Neeraj Bajaj Sun Microsystems,Inc. 46 * @author K.Venugopal Sun Microsystems,Inc. 47 */ 48 public class StartElementEvent extends DummyEvent 49 implements StartElement { 50 51 private Map<QName, Attribute> fAttributes; 52 private List<Namespace> fNamespaces; 53 private NamespaceContext fNamespaceContext = null; 54 private QName fQName; 55 StartElementEvent(String prefix, String uri, String localpart)56 public StartElementEvent(String prefix, String uri, String localpart) { 57 this(new QName(uri, localpart, prefix)); 58 } 59 StartElementEvent(QName qname)60 public StartElementEvent(QName qname) { 61 fQName = qname; 62 init(); 63 } 64 StartElementEvent(StartElement startelement)65 public StartElementEvent(StartElement startelement) { 66 this(startelement.getName()); 67 addAttributes(startelement.getAttributes()); 68 addNamespaceAttributes(startelement.getNamespaces()); 69 } 70 init()71 protected final void init() { 72 setEventType(XMLStreamConstants.START_ELEMENT); 73 fAttributes = new HashMap<>(); 74 fNamespaces = new ArrayList<>(); 75 } 76 77 @Override getName()78 public QName getName() { 79 return fQName; 80 } 81 setName(QName qname)82 public void setName(QName qname) { 83 this.fQName = qname; 84 } 85 86 @Override getAttributes()87 public Iterator<Attribute> getAttributes() { 88 if (fAttributes != null) { 89 Collection<Attribute> coll = fAttributes.values(); 90 return new ReadOnlyIterator<>(coll.iterator()); 91 } 92 return new ReadOnlyIterator<>(); 93 } 94 95 @Override getNamespaces()96 public Iterator<Namespace> getNamespaces() { 97 if (fNamespaces != null) { 98 return new ReadOnlyIterator<>(fNamespaces.iterator()); 99 } 100 return new ReadOnlyIterator<>(); 101 } 102 103 @Override getAttributeByName(QName qname)104 public Attribute getAttributeByName(QName qname) { 105 if (qname == null) { 106 return null; 107 } 108 return fAttributes.get(qname); 109 } 110 getNamespace()111 public String getNamespace() { 112 return fQName.getNamespaceURI(); 113 } 114 115 @Override getNamespaceURI(String prefix)116 public String getNamespaceURI(String prefix) { 117 //check that URI was supplied when creating this startElement event and prefix matches 118 if (getNamespace() != null && fQName.getPrefix().equals(prefix)) { 119 return getNamespace(); 120 } 121 //else check the namespace context 122 if (fNamespaceContext != null) { 123 return fNamespaceContext.getNamespaceURI(prefix); 124 } 125 return null; 126 } 127 128 /** 129 * <p> 130 * Return a <code>String</code> representation of this 131 * <code>StartElement</code> formatted as XML.</p> 132 * 133 * @return <code>String</code> representation of this 134 * <code>StartElement</code> formatted as XML. 135 */ 136 @Override toString()137 public String toString() { 138 139 StringBuilder startElement = new StringBuilder(); 140 141 // open element 142 startElement.append("<"); 143 startElement.append(nameAsString()); 144 145 // add any attributes 146 if (fAttributes != null) { 147 Iterator<Attribute> it = this.getAttributes(); 148 Attribute attr; 149 while (it.hasNext()) { 150 attr = it.next(); 151 startElement.append(" "); 152 startElement.append(attr.toString()); 153 } 154 } 155 156 // add any namespaces 157 if (fNamespaces != null) { 158 Iterator<Namespace> it = fNamespaces.iterator(); 159 Namespace ns; 160 while (it.hasNext()) { 161 ns = it.next(); 162 startElement.append(" "); 163 startElement.append(ns.toString()); 164 } 165 } 166 167 // close start tag 168 startElement.append(">"); 169 170 // return StartElement as a String 171 return startElement.toString(); 172 } 173 174 /** 175 * Return this event as String 176 * 177 * @return String Event returned as string. 178 */ nameAsString()179 public String nameAsString() { 180 if ("".equals(fQName.getNamespaceURI())) { 181 return fQName.getLocalPart(); 182 } 183 if (fQName.getPrefix() != null) { 184 return "['" + fQName.getNamespaceURI() + "']:" + fQName.getPrefix() 185 + ":" + fQName.getLocalPart(); 186 } else { 187 return "['" + fQName.getNamespaceURI() + "']:" + fQName.getLocalPart(); 188 } 189 } 190 191 /** 192 * Gets a read-only namespace context. If no context is available this 193 * method will return an empty namespace context. The NamespaceContext 194 * contains information about all namespaces in scope for this StartElement. 195 * 196 * @return the current namespace context 197 */ 198 @Override getNamespaceContext()199 public NamespaceContext getNamespaceContext() { 200 return fNamespaceContext; 201 } 202 setNamespaceContext(NamespaceContext nc)203 public void setNamespaceContext(NamespaceContext nc) { 204 fNamespaceContext = nc; 205 } 206 207 @Override writeAsEncodedUnicodeEx(java.io.Writer writer)208 protected void writeAsEncodedUnicodeEx(java.io.Writer writer) 209 throws java.io.IOException { 210 writer.write(toString()); 211 } 212 addAttribute(Attribute attr)213 void addAttribute(Attribute attr) { 214 if (attr.isNamespace()) { 215 fNamespaces.add((Namespace) attr); 216 } else { 217 fAttributes.put(attr.getName(), attr); 218 } 219 } 220 addAttributes(Iterator<? extends Attribute> attrs)221 final void addAttributes(Iterator<? extends Attribute> attrs) { 222 if (attrs == null) { 223 return; 224 } 225 while (attrs.hasNext()) { 226 Attribute attr = attrs.next(); 227 fAttributes.put(attr.getName(), attr); 228 } 229 } 230 addNamespaceAttribute(Namespace attr)231 void addNamespaceAttribute(Namespace attr) { 232 if (attr == null) { 233 return; 234 } 235 fNamespaces.add(attr); 236 } 237 addNamespaceAttributes(Iterator<? extends Namespace> attrs)238 final void addNamespaceAttributes(Iterator<? extends Namespace> attrs) { 239 if (attrs == null) { 240 return; 241 } 242 while (attrs.hasNext()) { 243 Namespace attr = attrs.next(); 244 fNamespaces.add(attr); 245 } 246 } 247 248 } 249