src/share/jaxws_classes/com/sun/xml/internal/ws/encoding/TagInfoset.java

Fri, 14 Feb 2014 11:13:45 +0100

author
mkos
date
Fri, 14 Feb 2014 11:13:45 +0100
changeset 515
6cd506508147
parent 397
b99d7e355d4b
child 637
9c07ef4934dd
permissions
-rw-r--r--

8026188: Enhance envelope factory
Summary: Avoiding caching data initialized via TCCL in static context; fix also reviewed by Alexander Fomin
Reviewed-by: ahgross, mgrebac, skoivu

ohair@286 1 /*
mkos@397 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
ohair@286 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
ohair@286 4 *
ohair@286 5 * This code is free software; you can redistribute it and/or modify it
ohair@286 6 * under the terms of the GNU General Public License version 2 only, as
ohair@286 7 * published by the Free Software Foundation. Oracle designates this
ohair@286 8 * particular file as subject to the "Classpath" exception as provided
ohair@286 9 * by Oracle in the LICENSE file that accompanied this code.
ohair@286 10 *
ohair@286 11 * This code is distributed in the hope that it will be useful, but WITHOUT
ohair@286 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
ohair@286 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
ohair@286 14 * version 2 for more details (a copy is included in the LICENSE file that
ohair@286 15 * accompanied this code).
ohair@286 16 *
ohair@286 17 * You should have received a copy of the GNU General Public License version
ohair@286 18 * 2 along with this work; if not, write to the Free Software Foundation,
ohair@286 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
ohair@286 20 *
ohair@286 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
ohair@286 22 * or visit www.oracle.com if you need additional information or have any
ohair@286 23 * questions.
ohair@286 24 */
ohair@286 25
ohair@286 26 package com.sun.xml.internal.ws.encoding;
ohair@286 27
mkos@397 28 import java.util.List;
mkos@397 29
ohair@286 30 import org.xml.sax.helpers.AttributesImpl;
ohair@286 31 import org.xml.sax.ContentHandler;
ohair@286 32 import org.xml.sax.SAXException;
ohair@286 33
ohair@286 34 import javax.xml.stream.XMLStreamReader;
ohair@286 35 import javax.xml.stream.XMLStreamWriter;
ohair@286 36 import javax.xml.stream.XMLStreamException;
ohair@286 37
ohair@286 38 import com.sun.xml.internal.ws.message.stream.StreamMessage;
ohair@286 39 import com.sun.xml.internal.ws.encoding.StreamSOAPCodec;
ohair@286 40 import com.sun.istack.internal.Nullable;
ohair@286 41 import com.sun.istack.internal.NotNull;
ohair@286 42
ohair@286 43 /**
ohair@286 44 * Complete infoset about a start tag.
ohair@286 45 *
ohair@286 46 * <p>
ohair@286 47 * This is used between {@link StreamMessage} and {@link StreamSOAPCodec}
ohair@286 48 * to capture the infoset of the s:Envelope, s:Header, and s:Body elements.
ohair@286 49 *
ohair@286 50 *
ohair@286 51 * <h3>Design Note</h3>
ohair@286 52 * <p>
ohair@286 53 * Since StAX and SAX uses different null vs empty string convention, one has
ohair@286 54 * to choose which format we store things. It can go either way, but I'm assuming
ohair@286 55 * that we'll be using StAX more in JAX-WS, so things are kept in the StAX style
ohair@286 56 * in this class.
ohair@286 57 *
ohair@286 58 * @author Kohsuke Kawaguchi
ohair@286 59 */
ohair@286 60 public final class TagInfoset {
ohair@286 61 /**
ohair@286 62 * Namespace declarations on this tag. Read-only.
ohair@286 63 *
ohair@286 64 * This is an array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }.
ohair@286 65 *
ohair@286 66 * URIs/prefixes can be null (StAX-style)
ohair@286 67 */
ohair@286 68 public final @NotNull String[] ns;
ohair@286 69 /**
ohair@286 70 * Attributes on this tag. Read-only.
ohair@286 71 */
ohair@286 72 public final @NotNull AttributesImpl atts;
ohair@286 73
ohair@286 74 /**
ohair@286 75 * Prefix of the start tag in stax-style.
ohair@286 76 */
ohair@286 77 public final @Nullable String prefix;
ohair@286 78
ohair@286 79 /**
ohair@286 80 * Namespace URI of the start tag in stax-style.
ohair@286 81 */
ohair@286 82 public final @Nullable String nsUri;
ohair@286 83
ohair@286 84 /**
ohair@286 85 * Local name of the start tag.
ohair@286 86 */
ohair@286 87 public final @NotNull String localName;
ohair@286 88
ohair@286 89 /**
ohair@286 90 * Lazily computed QName (i.e., "foo:bar")
ohair@286 91 */
ohair@286 92 private @Nullable String qname;
ohair@286 93
ohair@286 94 public TagInfoset(String nsUri, String localName, String prefix, AttributesImpl atts, String... ns) {
ohair@286 95 this.nsUri = nsUri;
ohair@286 96 this.prefix = prefix;
ohair@286 97 this.localName = localName;
ohair@286 98 this.atts = atts;
ohair@286 99 this.ns = ns;
ohair@286 100 }
ohair@286 101
ohair@286 102 /**
ohair@286 103 * Fills a {@link TagInfoset} object by the current element
ohair@286 104 * that the reader points to.
ohair@286 105 */
ohair@286 106 public TagInfoset(XMLStreamReader reader) {
ohair@286 107 prefix = reader.getPrefix();
ohair@286 108 nsUri = reader.getNamespaceURI();
ohair@286 109 localName = reader.getLocalName();
ohair@286 110
ohair@286 111 int nsc = reader.getNamespaceCount();
ohair@286 112 if(nsc>0) {
ohair@286 113 ns = new String[nsc*2];
ohair@286 114 for(int i=0; i<nsc; i++){
ohair@286 115 ns[i*2 ] = fixNull(reader.getNamespacePrefix(i));
ohair@286 116 ns[i*2+1] = fixNull(reader.getNamespaceURI(i));
ohair@286 117 }
ohair@286 118 } else {
ohair@286 119 ns = EMPTY_ARRAY;
ohair@286 120 }
ohair@286 121
ohair@286 122 int ac = reader.getAttributeCount();
ohair@286 123 if(ac>0) {
ohair@286 124 atts = new AttributesImpl();
ohair@286 125 StringBuilder sb = new StringBuilder();
ohair@286 126 for(int i=0; i< ac;i++){
ohair@286 127 sb.setLength(0);
ohair@286 128 String prefix = reader.getAttributePrefix(i);
ohair@286 129 String localName = reader.getAttributeLocalName(i);
ohair@286 130
ohair@286 131 String qname;
ohair@286 132 if(prefix != null && prefix.length()!=0){
ohair@286 133 sb.append(prefix);
ohair@286 134 sb.append(":");
ohair@286 135 sb.append(localName);
ohair@286 136 qname = sb.toString();
ohair@286 137 } else {
ohair@286 138 qname = localName;
ohair@286 139 }
ohair@286 140
ohair@286 141 atts.addAttribute(
ohair@286 142 fixNull(reader.getAttributeNamespace(i)),
ohair@286 143 localName,
ohair@286 144 qname,
ohair@286 145 reader.getAttributeType(i),
ohair@286 146 reader.getAttributeValue(i));
ohair@286 147 }
ohair@286 148 } else {
ohair@286 149 atts = EMPTY_ATTRIBUTES;
ohair@286 150 }
ohair@286 151 }
ohair@286 152
ohair@286 153 /**
ohair@286 154 * Writes the start element event.
ohair@286 155 */
ohair@286 156 public void writeStart(ContentHandler contentHandler) throws SAXException {
ohair@286 157 for( int i=0; i<ns.length; i+=2 )
ohair@286 158 contentHandler.startPrefixMapping(fixNull(ns[i]),fixNull(ns[i+1]));
ohair@286 159 contentHandler.startElement(fixNull(nsUri), localName ,getQName(), atts);
ohair@286 160 }
ohair@286 161
ohair@286 162 /**
ohair@286 163 * Writes the end element event.
ohair@286 164 */
ohair@286 165 public void writeEnd(ContentHandler contentHandler) throws SAXException{
ohair@286 166 contentHandler.endElement(fixNull(nsUri),localName,getQName());
ohair@286 167 for( int i=ns.length-2; i>=0; i-=2 ) {
ohair@286 168 contentHandler.endPrefixMapping(fixNull(ns[i]));
ohair@286 169 }
ohair@286 170 }
ohair@286 171
ohair@286 172 /**
ohair@286 173 * Writes the start element event.
ohair@286 174 */
ohair@286 175 public void writeStart(XMLStreamWriter w) throws XMLStreamException {
ohair@286 176 // write start tag.
ohair@286 177 if(prefix==null) {
ohair@286 178 if(nsUri==null)
ohair@286 179 w.writeStartElement(localName);
ohair@286 180 else {
ohair@286 181 //fix Null prefix. otherwise throws XMLStreamException,
ohair@286 182 // if the namespace URI has not been bound to a prefix
ohair@286 183 w.writeStartElement("",localName,nsUri);
ohair@286 184 }
ohair@286 185 } else {
ohair@286 186 w.writeStartElement(prefix,localName,nsUri);
ohair@286 187 }
ohair@286 188
ohair@286 189 for( int i=0; i<ns.length; i+=2 ) {
ohair@286 190 w.writeNamespace(ns[i],ns[i+1]);
ohair@286 191 }
ohair@286 192
ohair@286 193 for( int i=0; i<atts.getLength(); i++ ) {
ohair@286 194 String nsUri = atts.getURI(i);
ohair@286 195 if(nsUri==null || nsUri.length() ==0) {
ohair@286 196 w.writeAttribute(atts.getLocalName(i),atts.getValue(i));
ohair@286 197 } else {
ohair@286 198 String rawName = atts.getQName(i);
ohair@286 199 String prefix = rawName.substring(0,rawName.indexOf(':'));
ohair@286 200 w.writeAttribute(prefix,nsUri,atts.getLocalName(i),atts.getValue(i));
ohair@286 201 }
ohair@286 202 }
ohair@286 203 }
ohair@286 204
ohair@286 205 private String getQName() {
ohair@286 206 if(qname!=null) return qname;
ohair@286 207
ohair@286 208 StringBuilder sb = new StringBuilder();
ohair@286 209 if(prefix!=null){
ohair@286 210 sb.append(prefix);
ohair@286 211 sb.append(':');
ohair@286 212 sb.append(localName);
ohair@286 213 qname = sb.toString();
ohair@286 214 } else {
ohair@286 215 qname = localName;
ohair@286 216 }
ohair@286 217 return qname;
ohair@286 218 }
ohair@286 219 private static String fixNull(String s) {
ohair@286 220 if(s==null) return "";
ohair@286 221 else return s;
ohair@286 222 }
ohair@286 223
ohair@286 224 private static final String[] EMPTY_ARRAY = new String[0];
ohair@286 225 private static final AttributesImpl EMPTY_ATTRIBUTES = new AttributesImpl();
mkos@397 226
mkos@397 227 public String getNamespaceURI(String prefix) {
mkos@397 228 int size = ns.length/2;
mkos@397 229 for(int i=0; i<size; i++){
mkos@397 230 String p = ns[i*2 ];
mkos@397 231 String n = ns[i*2+1];
mkos@397 232 if (prefix.equals(p)) return n;
mkos@397 233 }
mkos@397 234 return null;
mkos@397 235 }
mkos@397 236
mkos@397 237 public String getPrefix(String namespaceURI) {
mkos@397 238 int size = ns.length/2;
mkos@397 239 for(int i=0; i<size; i++){
mkos@397 240 String p = ns[i*2 ];
mkos@397 241 String n = ns[i*2+1];
mkos@397 242 if (namespaceURI.equals(n)) return p;
mkos@397 243 }
mkos@397 244 return null;
mkos@397 245 }
mkos@397 246 //Who wants this?
mkos@397 247 public List<String> allPrefixes(String namespaceURI) {
mkos@397 248 int size = ns.length/2;
mkos@397 249 List<String> l = new java.util.ArrayList<String>();
mkos@397 250 for(int i=0; i<size; i++){
mkos@397 251 String p = ns[i*2 ];
mkos@397 252 String n = ns[i*2+1];
mkos@397 253 if (namespaceURI.equals(n)) l.add(p);
mkos@397 254 }
mkos@397 255 return l;
mkos@397 256 }
ohair@286 257 }

mercurial