/* * 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; } }