1/* 2 * Copyright (c) 2004, 2013, 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 28package com.sun.xml.internal.fastinfoset.sax; 29 30import com.sun.xml.internal.fastinfoset.EncodingConstants; 31import com.sun.xml.internal.fastinfoset.QualifiedName; 32import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory; 33import java.io.IOException; 34import java.util.Map; 35import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm; 36import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException; 37import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes; 38import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException; 39 40import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes; 41import com.sun.xml.internal.fastinfoset.CommonResourceBundle; 42 43public class AttributesHolder implements EncodingAlgorithmAttributes { 44 private static final int DEFAULT_CAPACITY = 8; 45 46 private Map _registeredEncodingAlgorithms; 47 48 private int _attributeCount; 49 50 private QualifiedName[] _names; 51 private String[] _values; 52 53 private String[] _algorithmURIs; 54 private int[] _algorithmIds; 55 private Object[] _algorithmData; 56 57 public AttributesHolder() { 58 _names = new QualifiedName[DEFAULT_CAPACITY]; 59 _values = new String[DEFAULT_CAPACITY]; 60 61 _algorithmURIs = new String[DEFAULT_CAPACITY]; 62 _algorithmIds = new int[DEFAULT_CAPACITY]; 63 _algorithmData = new Object[DEFAULT_CAPACITY]; 64 } 65 66 public AttributesHolder(Map registeredEncodingAlgorithms) { 67 this(); 68 _registeredEncodingAlgorithms = registeredEncodingAlgorithms; 69 } 70 71 // org.xml.sax.Attributes 72 73 public final int getLength() { 74 return _attributeCount; 75 } 76 77 public final String getLocalName(int index) { 78 return _names[index].localName; 79 } 80 81 public final String getQName(int index) { 82 return _names[index].getQNameString(); 83 } 84 85 public final String getType(int index) { 86 return "CDATA"; 87 } 88 89 public final String getURI(int index) { 90 return _names[index].namespaceName; 91 } 92 93 public final String getValue(int index) { 94 final String value = _values[index]; 95 if (value != null) { 96 return value; 97 } 98 99 if (_algorithmData[index] == null || 100 (_algorithmIds[index] >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START && 101 _registeredEncodingAlgorithms == null)) { 102 return null; 103 } 104 105 try { 106 return _values[index] = convertEncodingAlgorithmDataToString( 107 _algorithmIds[index], 108 _algorithmURIs[index], 109 _algorithmData[index]).toString(); 110 } catch (IOException e) { 111 return null; 112 } catch (FastInfosetException e) { 113 return null; 114 } 115 } 116 117 public final int getIndex(String qName) { 118 int i = qName.indexOf(':'); 119 String prefix = ""; 120 String localName = qName; 121 if (i >= 0) { 122 prefix = qName.substring(0, i); 123 localName = qName.substring(i + 1); 124 } 125 126 for (i = 0; i < _attributeCount; i++) { 127 QualifiedName name = _names[i]; 128 if (localName.equals(name.localName) && 129 prefix.equals(name.prefix)) { 130 return i; 131 } 132 } 133 return -1; 134 } 135 136 public final String getType(String qName) { 137 int index = getIndex(qName); 138 if (index >= 0) { 139 return "CDATA"; 140 } else { 141 return null; 142 } 143 } 144 145 public final String getValue(String qName) { 146 int index = getIndex(qName); 147 if (index >= 0) { 148 return _values[index]; 149 } else { 150 return null; 151 } 152 } 153 154 public final int getIndex(String uri, String localName) { 155 for (int i = 0; i < _attributeCount; i++) { 156 QualifiedName name = _names[i]; 157 if (localName.equals(name.localName) && 158 uri.equals(name.namespaceName)) { 159 return i; 160 } 161 } 162 return -1; 163 } 164 165 public final String getType(String uri, String localName) { 166 int index = getIndex(uri, localName); 167 if (index >= 0) { 168 return "CDATA"; 169 } else { 170 return null; 171 } 172 } 173 174 public final String getValue(String uri, String localName) { 175 int index = getIndex(uri, localName); 176 if (index >= 0) { 177 return _values[index]; 178 } else { 179 return null; 180 } 181 } 182 183 public final void clear() { 184 for (int i = 0; i < _attributeCount; i++) { 185 _values[i] = null; 186 _algorithmData[i] = null; 187 } 188 _attributeCount = 0; 189 } 190 191 // EncodingAlgorithmAttributes 192 193 public final String getAlgorithmURI(int index) { 194 return _algorithmURIs[index]; 195 } 196 197 public final int getAlgorithmIndex(int index) { 198 return _algorithmIds[index]; 199 } 200 201 public final Object getAlgorithmData(int index) { 202 return _algorithmData[index]; 203 } 204 205 public String getAlpababet(int index) { 206 return null; 207 } 208 209 public boolean getToIndex(int index) { 210 return false; 211 } 212 213 // ----- 214 215 public final void addAttribute(QualifiedName name, String value) { 216 if (_attributeCount == _names.length) { 217 resize(); 218 } 219 _names[_attributeCount] = name; 220 _values[_attributeCount++] = value; 221 } 222 223 public final void addAttributeWithAlgorithmData(QualifiedName name, String URI, int id, Object data) { 224 if (_attributeCount == _names.length) { 225 resize(); 226 } 227 _names[_attributeCount] = name; 228 _values[_attributeCount] = null; 229 230 _algorithmURIs[_attributeCount] = URI; 231 _algorithmIds[_attributeCount] = id; 232 _algorithmData[_attributeCount++] = data; 233 } 234 235 public final QualifiedName getQualifiedName(int index) { 236 return _names[index]; 237 } 238 239 public final String getPrefix(int index) { 240 return _names[index].prefix; 241 } 242 243 private final void resize() { 244 final int newLength = _attributeCount * 3 / 2 + 1; 245 246 QualifiedName[] names = new QualifiedName[newLength]; 247 String[] values = new String[newLength]; 248 249 String[] algorithmURIs = new String[newLength]; 250 int[] algorithmIds = new int[newLength]; 251 Object[] algorithmData = new Object[newLength]; 252 253 System.arraycopy(_names, 0, names, 0, _attributeCount); 254 System.arraycopy(_values, 0, values, 0, _attributeCount); 255 256 System.arraycopy(_algorithmURIs, 0, algorithmURIs, 0, _attributeCount); 257 System.arraycopy(_algorithmIds, 0, algorithmIds, 0, _attributeCount); 258 System.arraycopy(_algorithmData, 0, algorithmData, 0, _attributeCount); 259 260 _names = names; 261 _values = values; 262 263 _algorithmURIs = algorithmURIs; 264 _algorithmIds = algorithmIds; 265 _algorithmData = algorithmData; 266 } 267 268 private final StringBuffer convertEncodingAlgorithmDataToString(int identifier, String URI, Object data) throws FastInfosetException, IOException { 269 EncodingAlgorithm ea = null; 270 if (identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) { 271 ea = BuiltInEncodingAlgorithmFactory.getAlgorithm(identifier); 272 } else if (identifier == EncodingAlgorithmIndexes.CDATA) { 273 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported")); 274 } else if (identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) { 275 if (URI == null) { 276 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.URINotPresent") + identifier); 277 } 278 279 ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI); 280 if (ea == null) { 281 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.algorithmNotRegistered") + URI); 282 } 283 } else { 284 // Reserved built-in algorithms for future use 285 // TODO should use sax property to decide if event will be 286 // reported, allows for support through handler if required. 287 throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved")); 288 } 289 290 final StringBuffer sb = new StringBuffer(); 291 ea.convertToCharacters(data, sb); 292 return sb; 293 } 294 295} 296