blob: afca1160afb0e1525261d102dceb1e905ebc0e97 [file] [log] [blame]
/*
* Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
* THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
*/
package com.sun.xml.internal.fastinfoset.sax;
import com.sun.xml.internal.fastinfoset.EncodingConstants;
import com.sun.xml.internal.fastinfoset.QualifiedName;
import com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
import java.io.IOException;
import java.util.Map;
import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm;
import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
import com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
import com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
import com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes;
import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
public class AttributesHolder implements EncodingAlgorithmAttributes {
private static final int DEFAULT_CAPACITY = 8;
private Map _registeredEncodingAlgorithms;
private int _attributeCount;
private QualifiedName[] _names;
private String[] _values;
private String[] _algorithmURIs;
private int[] _algorithmIds;
private Object[] _algorithmData;
public AttributesHolder() {
_names = new QualifiedName[DEFAULT_CAPACITY];
_values = new String[DEFAULT_CAPACITY];
_algorithmURIs = new String[DEFAULT_CAPACITY];
_algorithmIds = new int[DEFAULT_CAPACITY];
_algorithmData = new Object[DEFAULT_CAPACITY];
}
public AttributesHolder(Map registeredEncodingAlgorithms) {
this();
_registeredEncodingAlgorithms = registeredEncodingAlgorithms;
}
// org.xml.sax.Attributes
public final int getLength() {
return _attributeCount;
}
public final String getLocalName(int index) {
return _names[index].localName;
}
public final String getQName(int index) {
return _names[index].getQNameString();
}
public final String getType(int index) {
return "CDATA";
}
public final String getURI(int index) {
return _names[index].namespaceName;
}
public final String getValue(int index) {
final String value = _values[index];
if (value != null) {
return value;
}
if (_algorithmData[index] == null ||
(_algorithmIds[index] >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START &&
_registeredEncodingAlgorithms == null)) {
return null;
}
try {
return _values[index] = convertEncodingAlgorithmDataToString(
_algorithmIds[index],
_algorithmURIs[index],
_algorithmData[index]).toString();
} catch (IOException e) {
return null;
} catch (FastInfosetException e) {
return null;
}
}
public final int getIndex(String qName) {
int i = qName.indexOf(':');
String prefix = "";
String localName = qName;
if (i >= 0) {
prefix = qName.substring(0, i);
localName = qName.substring(i + 1);
}
for (i = 0; i < _attributeCount; i++) {
QualifiedName name = _names[i];
if (localName.equals(name.localName) &&
prefix.equals(name.prefix)) {
return i;
}
}
return -1;
}
public final String getType(String qName) {
int index = getIndex(qName);
if (index >= 0) {
return "CDATA";
} else {
return null;
}
}
public final String getValue(String qName) {
int index = getIndex(qName);
if (index >= 0) {
return _values[index];
} else {
return null;
}
}
public final int getIndex(String uri, String localName) {
for (int i = 0; i < _attributeCount; i++) {
QualifiedName name = _names[i];
if (localName.equals(name.localName) &&
uri.equals(name.namespaceName)) {
return i;
}
}
return -1;
}
public final String getType(String uri, String localName) {
int index = getIndex(uri, localName);
if (index >= 0) {
return "CDATA";
} else {
return null;
}
}
public final String getValue(String uri, String localName) {
int index = getIndex(uri, localName);
if (index >= 0) {
return _values[index];
} else {
return null;
}
}
public final void clear() {
for (int i = 0; i < _attributeCount; i++) {
_values[i] = null;
_algorithmData[i] = null;
}
_attributeCount = 0;
}
// EncodingAlgorithmAttributes
public final String getAlgorithmURI(int index) {
return _algorithmURIs[index];
}
public final int getAlgorithmIndex(int index) {
return _algorithmIds[index];
}
public final Object getAlgorithmData(int index) {
return _algorithmData[index];
}
public String getAlpababet(int index) {
return null;
}
public boolean getToIndex(int index) {
return false;
}
// -----
public final void addAttribute(QualifiedName name, String value) {
if (_attributeCount == _names.length) {
resize();
}
_names[_attributeCount] = name;
_values[_attributeCount++] = value;
}
public final void addAttributeWithAlgorithmData(QualifiedName name, String URI, int id, Object data) {
if (_attributeCount == _names.length) {
resize();
}
_names[_attributeCount] = name;
_values[_attributeCount] = null;
_algorithmURIs[_attributeCount] = URI;
_algorithmIds[_attributeCount] = id;
_algorithmData[_attributeCount++] = data;
}
public final QualifiedName getQualifiedName(int index) {
return _names[index];
}
public final String getPrefix(int index) {
return _names[index].prefix;
}
private final void resize() {
final int newLength = _attributeCount * 3 / 2 + 1;
QualifiedName[] names = new QualifiedName[newLength];
String[] values = new String[newLength];
String[] algorithmURIs = new String[newLength];
int[] algorithmIds = new int[newLength];
Object[] algorithmData = new Object[newLength];
System.arraycopy(_names, 0, names, 0, _attributeCount);
System.arraycopy(_values, 0, values, 0, _attributeCount);
System.arraycopy(_algorithmURIs, 0, algorithmURIs, 0, _attributeCount);
System.arraycopy(_algorithmIds, 0, algorithmIds, 0, _attributeCount);
System.arraycopy(_algorithmData, 0, algorithmData, 0, _attributeCount);
_names = names;
_values = values;
_algorithmURIs = algorithmURIs;
_algorithmIds = algorithmIds;
_algorithmData = algorithmData;
}
private final StringBuffer convertEncodingAlgorithmDataToString(int identifier, String URI, Object data) throws FastInfosetException, IOException {
EncodingAlgorithm ea = null;
if (identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
ea = BuiltInEncodingAlgorithmFactory.getAlgorithm(identifier);
} else if (identifier == EncodingAlgorithmIndexes.CDATA) {
throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
} else if (identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
if (URI == null) {
throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.URINotPresent") + identifier);
}
ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
if (ea == null) {
throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.algorithmNotRegistered") + URI);
}
} else {
// Reserved built-in algorithms for future use
// TODO should use sax property to decide if event will be
// reported, allows for support through handler if required.
throw new EncodingAlgorithmException(CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
}
final StringBuffer sb = new StringBuffer();
ea.convertToCharacters(data, sb);
return sb;
}
}