src/share/jaxws_classes/com/sun/xml/internal/fastinfoset/sax/SAXDocumentSerializerWithPrefixMapping.java

changeset 0
373ffda63c9a
equal deleted inserted replaced
-1:000000000000 0:373ffda63c9a
1 /*
2 * Copyright (c) 2004, 2011, 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 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
27
28 package com.sun.xml.internal.fastinfoset.sax;
29
30 import com.sun.xml.internal.fastinfoset.EncodingConstants;
31 import com.sun.xml.internal.fastinfoset.QualifiedName;
32 import com.sun.xml.internal.fastinfoset.util.KeyIntMap;
33 import com.sun.xml.internal.fastinfoset.util.LocalNameQualifiedNamesMap;
34 import com.sun.xml.internal.fastinfoset.util.StringIntMap;
35 import java.io.IOException;
36 import java.util.HashMap;
37 import org.xml.sax.SAXException;
38 import java.util.Map;
39 import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
40 import com.sun.xml.internal.org.jvnet.fastinfoset.RestrictedAlphabet;
41 import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes;
42 import org.xml.sax.Attributes;
43
44 /**
45 * The Fast Infoset SAX serializer that maps prefixes to user specified prefixes
46 * that are specified in a namespace URI to prefix map.
47 * <p>
48 * This serializer will not preserve the original prefixes and this serializer
49 * should not be used when prefixes need to be preserved, such as the case
50 * when there are qualified names in content.
51 * <p>
52 * A namespace URI to prefix map is utilized such that the prefixes
53 * in the map are utilized rather than the prefixes specified in
54 * the qualified name for elements and attributes.
55 * <p>
56 * Any namespace declarations with a namespace URI that is not present in
57 * the map are added.
58 * <p>
59 */
60 public class SAXDocumentSerializerWithPrefixMapping extends SAXDocumentSerializer {
61 protected Map _namespaceToPrefixMapping;
62 protected Map _prefixToPrefixMapping;
63 protected String _lastCheckedNamespace;
64 protected String _lastCheckedPrefix;
65
66 protected StringIntMap _declaredNamespaces;
67
68 public SAXDocumentSerializerWithPrefixMapping(Map namespaceToPrefixMapping) {
69 // Use the local name to look up elements/attributes
70 super(true);
71 _namespaceToPrefixMapping = new HashMap(namespaceToPrefixMapping);
72 _prefixToPrefixMapping = new HashMap();
73
74 // Empty prefix
75 _namespaceToPrefixMapping.put("", "");
76 // 'xml' prefix
77 _namespaceToPrefixMapping.put(EncodingConstants.XML_NAMESPACE_NAME, EncodingConstants.XML_NAMESPACE_PREFIX);
78
79 _declaredNamespaces = new StringIntMap(4);
80 }
81
82 public final void startPrefixMapping(String prefix, String uri) throws SAXException {
83 try {
84 if (_elementHasNamespaces == false) {
85 encodeTermination();
86
87 // Mark the current buffer position to flag attributes if necessary
88 mark();
89 _elementHasNamespaces = true;
90
91 // Write out Element byte with namespaces
92 write(EncodingConstants.ELEMENT | EncodingConstants.ELEMENT_NAMESPACES_FLAG);
93
94 _declaredNamespaces.clear();
95 _declaredNamespaces.obtainIndex(uri);
96 } else {
97 if (_declaredNamespaces.obtainIndex(uri) != KeyIntMap.NOT_PRESENT) {
98 final String p = getPrefix(uri);
99 if (p != null) {
100 _prefixToPrefixMapping.put(prefix, p);
101 }
102 return;
103 }
104 }
105
106 final String p = getPrefix(uri);
107 if (p != null) {
108 encodeNamespaceAttribute(p, uri);
109 _prefixToPrefixMapping.put(prefix, p);
110 } else {
111 putPrefix(uri, prefix);
112 encodeNamespaceAttribute(prefix, uri);
113 }
114
115 } catch (IOException e) {
116 throw new SAXException("startElement", e);
117 }
118 }
119
120 protected final void encodeElement(String namespaceURI, String qName, String localName) throws IOException {
121 LocalNameQualifiedNamesMap.Entry entry = _v.elementName.obtainEntry(localName);
122 if (entry._valueIndex > 0) {
123 if (encodeElementMapEntry(entry, namespaceURI)) return;
124 // Check the entry is a member of the read only map
125 if (_v.elementName.isQNameFromReadOnlyMap(entry._value[0])) {
126 entry = _v.elementName.obtainDynamicEntry(localName);
127 if (entry._valueIndex > 0) {
128 if (encodeElementMapEntry(entry, namespaceURI)) return;
129 }
130 }
131 }
132
133 encodeLiteralElementQualifiedNameOnThirdBit(namespaceURI, getPrefix(namespaceURI),
134 localName, entry);
135 }
136
137 protected boolean encodeElementMapEntry(LocalNameQualifiedNamesMap.Entry entry, String namespaceURI) throws IOException {
138 QualifiedName[] names = entry._value;
139 for (int i = 0; i < entry._valueIndex; i++) {
140 if ((namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
141 encodeNonZeroIntegerOnThirdBit(names[i].index);
142 return true;
143 }
144 }
145 return false;
146 }
147
148
149 protected final void encodeAttributes(Attributes atts) throws IOException, FastInfosetException {
150 boolean addToTable;
151 boolean mustToBeAddedToTable;
152 String value;
153 if (atts instanceof EncodingAlgorithmAttributes) {
154 final EncodingAlgorithmAttributes eAtts = (EncodingAlgorithmAttributes)atts;
155 Object data;
156 String alphabet;
157 for (int i = 0; i < eAtts.getLength(); i++) {
158 final String uri = atts.getURI(i);
159 if (encodeAttribute(uri, atts.getQName(i), atts.getLocalName(i))) {
160 data = eAtts.getAlgorithmData(i);
161 // If data is null then there is no algorithm data
162 if (data == null) {
163 value = eAtts.getValue(i);
164 addToTable = isAttributeValueLengthMatchesLimit(value.length());
165 mustToBeAddedToTable = eAtts.getToIndex(i);
166 alphabet = eAtts.getAlpababet(i);
167 if (alphabet == null) {
168 if (uri == "http://www.w3.org/2001/XMLSchema-instance" ||
169 uri.equals("http://www.w3.org/2001/XMLSchema-instance")) {
170 value = convertQName(value);
171 }
172 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, mustToBeAddedToTable);
173 } else if (alphabet == RestrictedAlphabet.DATE_TIME_CHARACTERS) {
174 encodeDateTimeNonIdentifyingStringOnFirstBit(
175 value, addToTable, mustToBeAddedToTable);
176 } else if (alphabet == RestrictedAlphabet.NUMERIC_CHARACTERS) {
177 encodeNumericNonIdentifyingStringOnFirstBit(
178 value, addToTable, mustToBeAddedToTable);
179 } else {
180 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, mustToBeAddedToTable);
181 }
182 } else {
183 encodeNonIdentifyingStringOnFirstBit(eAtts.getAlgorithmURI(i),
184 eAtts.getAlgorithmIndex(i), data);
185 }
186 }
187 }
188 } else {
189 for (int i = 0; i < atts.getLength(); i++) {
190 final String uri = atts.getURI(i);
191 if (encodeAttribute(atts.getURI(i), atts.getQName(i), atts.getLocalName(i))) {
192 value = atts.getValue(i);
193 addToTable = isAttributeValueLengthMatchesLimit(value.length());
194
195 if (uri == "http://www.w3.org/2001/XMLSchema-instance" ||
196 uri.equals("http://www.w3.org/2001/XMLSchema-instance")) {
197 value = convertQName(value);
198 }
199 encodeNonIdentifyingStringOnFirstBit(value, _v.attributeValue, addToTable, false);
200 }
201 }
202 }
203 _b = EncodingConstants.TERMINATOR;
204 _terminate = true;
205 }
206
207 private String convertQName(String qName) {
208 int i = qName.indexOf(':');
209 String prefix = "";
210 String localName = qName;
211 if (i != -1) {
212 prefix = qName.substring(0, i);
213 localName = qName.substring(i + 1);
214 }
215
216 String p = (String)_prefixToPrefixMapping.get(prefix);
217 if (p != null) {
218 if (p.length() == 0)
219 return localName;
220 else
221 return p + ":" + localName;
222 } else {
223 return qName;
224 }
225 }
226
227 protected final boolean encodeAttribute(String namespaceURI, String qName, String localName) throws IOException {
228 LocalNameQualifiedNamesMap.Entry entry = _v.attributeName.obtainEntry(localName);
229 if (entry._valueIndex > 0) {
230 if (encodeAttributeMapEntry(entry, namespaceURI)) return true;
231 // Check the entry is a member of the read only map
232 if (_v.attributeName.isQNameFromReadOnlyMap(entry._value[0])) {
233 entry = _v.attributeName.obtainDynamicEntry(localName);
234 if (entry._valueIndex > 0) {
235 if (encodeAttributeMapEntry(entry, namespaceURI)) return true;
236 }
237 }
238 }
239
240 return encodeLiteralAttributeQualifiedNameOnSecondBit(namespaceURI, getPrefix(namespaceURI),
241 localName, entry);
242 }
243
244 protected boolean encodeAttributeMapEntry(LocalNameQualifiedNamesMap.Entry entry, String namespaceURI) throws IOException {
245 QualifiedName[] names = entry._value;
246 for (int i = 0; i < entry._valueIndex; i++) {
247 if ((namespaceURI == names[i].namespaceName || namespaceURI.equals(names[i].namespaceName))) {
248 encodeNonZeroIntegerOnSecondBitFirstBitZero(names[i].index);
249 return true;
250 }
251 }
252 return false;
253 }
254
255 protected final String getPrefix(String namespaceURI) {
256 if (_lastCheckedNamespace == namespaceURI) return _lastCheckedPrefix;
257
258 _lastCheckedNamespace = namespaceURI;
259 return _lastCheckedPrefix = (String)_namespaceToPrefixMapping.get(namespaceURI);
260 }
261
262 protected final void putPrefix(String namespaceURI, String prefix) {
263 _namespaceToPrefixMapping.put(namespaceURI, prefix);
264
265 _lastCheckedNamespace = namespaceURI;
266 _lastCheckedPrefix = prefix;
267 }
268 }

mercurial