325N/A/*
325N/A * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
325N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
325N/A *
325N/A * This code is free software; you can redistribute it and/or modify it
325N/A * under the terms of the GNU General Public License version 2 only, as
325N/A * published by the Free Software Foundation. Oracle designates this
325N/A * particular file as subject to the "Classpath" exception as provided
325N/A * by Oracle in the LICENSE file that accompanied this code.
325N/A *
325N/A * This code is distributed in the hope that it will be useful, but WITHOUT
325N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
325N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
325N/A * version 2 for more details (a copy is included in the LICENSE file that
325N/A * accompanied this code).
325N/A *
325N/A * You should have received a copy of the GNU General Public License version
325N/A * 2 along with this work; if not, write to the Free Software Foundation,
325N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
325N/A *
325N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
325N/A * or visit www.oracle.com if you need additional information or have any
325N/A * questions.
325N/A *
325N/A * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
325N/A */
325N/A
325N/Apackage com.sun.xml.internal.org.jvnet.fastinfoset.sax.helpers;
325N/A
325N/Aimport com.sun.xml.internal.fastinfoset.CommonResourceBundle;
325N/Aimport com.sun.xml.internal.fastinfoset.EncodingConstants;
325N/Aimport com.sun.xml.internal.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
325N/Aimport java.io.IOException;
325N/Aimport java.util.Map;
325N/Aimport com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithm;
325N/Aimport com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmException;
325N/Aimport com.sun.xml.internal.org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
325N/Aimport com.sun.xml.internal.org.jvnet.fastinfoset.FastInfosetException;
325N/Aimport com.sun.xml.internal.org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes;
325N/Aimport org.xml.sax.Attributes;
325N/A
325N/A/**
325N/A * Default implementation of the {@link EncodingAlgorithmAttributes} interface.
325N/A *
325N/A * <p>This class provides a default implementation of the SAX2
325N/A * {@link EncodingAlgorithmAttributes} interface, with the
325N/A * addition of manipulators so that the list can be modified or
325N/A * reused.</p>
325N/A *
325N/A * <p>There are two typical uses of this class:</p>
325N/A *
325N/A * <ol>
325N/A * <li>to take a persistent snapshot of an EncodingAlgorithmAttributes object
325N/A * in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or</li>
325N/A * <li>to construct or modify an EncodingAlgorithmAttributes object in a SAX2
325N/A * driver or filter.</li>
325N/A * </ol>
325N/A */
325N/Apublic class EncodingAlgorithmAttributesImpl implements EncodingAlgorithmAttributes {
325N/A private static final int DEFAULT_CAPACITY = 8;
325N/A
325N/A private static final int URI_OFFSET = 0;
325N/A private static final int LOCALNAME_OFFSET = 1;
325N/A private static final int QNAME_OFFSET = 2;
325N/A private static final int TYPE_OFFSET = 3;
325N/A private static final int VALUE_OFFSET = 4;
325N/A private static final int ALGORITHMURI_OFFSET = 5;
325N/A
325N/A private static final int SIZE = 6;
325N/A
325N/A private Map _registeredEncodingAlgorithms;
325N/A
325N/A private int _length;
325N/A
325N/A private String[] _data;
325N/A
325N/A private int[] _algorithmIds;
325N/A
325N/A private Object[] _algorithmData;
325N/A
325N/A private String[] _alphabets;
325N/A
325N/A private boolean[] _toIndex;
325N/A
325N/A /**
325N/A * Construct a new, empty EncodingAlgorithmAttributesImpl object.
325N/A */
325N/A public EncodingAlgorithmAttributesImpl() {
325N/A this(null, null);
325N/A }
325N/A
325N/A /**
325N/A * Copy an existing Attributes object.
325N/A *
325N/A * <p>This constructor is especially useful inside a
325N/A * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
325N/A *
325N/A * @param attributes The existing Attributes object.
325N/A */
325N/A public EncodingAlgorithmAttributesImpl(Attributes attributes) {
325N/A this(null, attributes);
325N/A }
325N/A
325N/A /**
325N/A * Use registered encoding algorithms and copy an existing Attributes object.
325N/A *
325N/A * <p>This constructor is especially useful inside a
325N/A * {@link org.xml.sax.ContentHandler#startElement startElement} event.</p>
325N/A *
325N/A * @param registeredEncodingAlgorithms
325N/A * The registeredEncodingAlgorithms encoding algorithms.
325N/A * @param attributes The existing Attributes object.
325N/A */
325N/A public EncodingAlgorithmAttributesImpl(Map registeredEncodingAlgorithms,
325N/A Attributes attributes) {
325N/A _data = new String[DEFAULT_CAPACITY * SIZE];
325N/A _algorithmIds = new int[DEFAULT_CAPACITY];
325N/A _algorithmData = new Object[DEFAULT_CAPACITY];
325N/A _alphabets = new String[DEFAULT_CAPACITY];
325N/A _toIndex = new boolean[DEFAULT_CAPACITY];
325N/A
325N/A _registeredEncodingAlgorithms = registeredEncodingAlgorithms;
325N/A
325N/A if (attributes != null) {
325N/A if (attributes instanceof EncodingAlgorithmAttributes) {
325N/A setAttributes((EncodingAlgorithmAttributes)attributes);
325N/A } else {
325N/A setAttributes(attributes);
325N/A }
325N/A }
325N/A }
325N/A
325N/A /**
325N/A * Clear the attribute list for reuse.
325N/A *
325N/A */
325N/A public final void clear() {
325N/A for (int i = 0; i < _length; i++) {
325N/A _data[i * SIZE + VALUE_OFFSET] = null;
325N/A _algorithmData[i] = null;
325N/A }
325N/A _length = 0;
325N/A }
325N/A
325N/A /**
325N/A * Add an attribute to the end of the list.
325N/A *
325N/A * <p>For the sake of speed, this method does no checking
325N/A * to see if the attribute is already in the list: that is
325N/A * the responsibility of the application.</p>
325N/A *
325N/A * @param URI The Namespace URI, or the empty string if
325N/A * none is available or Namespace processing is not
325N/A * being performed.
325N/A * @param localName The local name, or the empty string if
325N/A * Namespace processing is not being performed.
325N/A * @param qName The qualified (prefixed) name, or the empty string
325N/A * if qualified names are not available.
325N/A * @param type The attribute type as a string.
325N/A * @param value The attribute value.
325N/A */
325N/A public void addAttribute(String URI, String localName, String qName,
325N/A String type, String value) {
325N/A if (_length >= _algorithmData.length) {
325N/A resize();
325N/A }
325N/A
325N/A int i = _length * SIZE;
325N/A _data[i++] = replaceNull(URI);
325N/A _data[i++] = replaceNull(localName);
325N/A _data[i++] = replaceNull(qName);
325N/A _data[i++] = replaceNull(type);
325N/A _data[i++] = replaceNull(value);
325N/A _toIndex[_length] = false;
325N/A _alphabets[_length] = null;
325N/A
325N/A _length++;
325N/A }
325N/A
325N/A /**
325N/A * Add an attribute to the end of the list.
325N/A *
325N/A * <p>For the sake of speed, this method does no checking
325N/A * to see if the attribute is already in the list: that is
325N/A * the responsibility of the application.</p>
325N/A *
325N/A * @param URI The Namespace URI, or the empty string if
325N/A * none is available or Namespace processing is not
325N/A * being performed.
325N/A * @param localName The local name, or the empty string if
325N/A * Namespace processing is not being performed.
325N/A * @param qName The qualified (prefixed) name, or the empty string
325N/A * if qualified names are not available.
325N/A * @param type The attribute type as a string.
325N/A * @param value The attribute value.
325N/A * @param index True if attribute should be indexed.
325N/A * @param alphabet The alphabet associated with the attribute value,
325N/A * may be null if there is no associated alphabet.
325N/A */
325N/A public void addAttribute(String URI, String localName, String qName,
325N/A String type, String value, boolean index, String alphabet) {
325N/A if (_length >= _algorithmData.length) {
325N/A resize();
325N/A }
325N/A
325N/A int i = _length * SIZE;
325N/A _data[i++] = replaceNull(URI);
325N/A _data[i++] = replaceNull(localName);
325N/A _data[i++] = replaceNull(qName);
325N/A _data[i++] = replaceNull(type);
325N/A _data[i++] = replaceNull(value);
325N/A _toIndex[_length] = index;
325N/A _alphabets[_length] = alphabet;
325N/A
325N/A _length++;
325N/A }
325N/A
325N/A /**
325N/A * Add an attribute with built in algorithm data to the end of the list.
325N/A *
325N/A * <p>For the sake of speed, this method does no checking
325N/A * to see if the attribute is already in the list: that is
325N/A * the responsibility of the application.</p>
325N/A *
325N/A * @param URI The Namespace URI, or the empty string if
325N/A * none is available or Namespace processing is not
325N/A * being performed.
325N/A * @param localName The local name, or the empty string if
325N/A * Namespace processing is not being performed.
325N/A * @param qName The qualified (prefixed) name, or the empty string
325N/A * if qualified names are not available.
325N/A * @param builtInAlgorithmID The built in algorithm ID.
325N/A * @param algorithmData The built in algorithm data.
325N/A */
325N/A public void addAttributeWithBuiltInAlgorithmData(String URI, String localName, String qName,
325N/A int builtInAlgorithmID, Object algorithmData) {
325N/A if (_length >= _algorithmData.length) {
325N/A resize();
325N/A }
325N/A
325N/A int i = _length * SIZE;
325N/A _data[i++] = replaceNull(URI);
325N/A _data[i++] = replaceNull(localName);
325N/A _data[i++] = replaceNull(qName);
325N/A _data[i++] = "CDATA";
325N/A _data[i++] = "";
325N/A _data[i++] = null;
325N/A _algorithmIds[_length] = builtInAlgorithmID;
325N/A _algorithmData[_length] = algorithmData;
325N/A _toIndex[_length] = false;
325N/A _alphabets[_length] = null;
325N/A
325N/A _length++;
325N/A }
325N/A
325N/A /**
325N/A * Add an attribute with algorithm data to the end of the list.
325N/A *
325N/A * <p>For the sake of speed, this method does no checking
325N/A * to see if the attribute is already in the list: that is
325N/A * the responsibility of the application.</p>
325N/A *
325N/A * @param URI The Namespace URI, or the empty string if
325N/A * none is available or Namespace processing is not
325N/A * being performed.
325N/A * @param localName The local name, or the empty string if
325N/A * Namespace processing is not being performed.
325N/A * @param qName The qualified (prefixed) name, or the empty string
325N/A * if qualified names are not available.
325N/A * @param algorithmURI The algorithm URI, or null if a built in algorithm
325N/A * @param algorithmID The algorithm ID.
325N/A * @param algorithmData The algorithm data.
325N/A */
325N/A public void addAttributeWithAlgorithmData(String URI, String localName, String qName,
325N/A String algorithmURI, int algorithmID, Object algorithmData) {
325N/A if (_length >= _algorithmData.length) {
325N/A resize();
325N/A }
325N/A
325N/A int i = _length * SIZE;
325N/A _data[i++] = replaceNull(URI);
325N/A _data[i++] = replaceNull(localName);
325N/A _data[i++] = replaceNull(qName);
325N/A _data[i++] = "CDATA";
325N/A _data[i++] = "";
325N/A _data[i++] = algorithmURI;
325N/A _algorithmIds[_length] = algorithmID;
325N/A _algorithmData[_length] = algorithmData;
325N/A _toIndex[_length] = false;
325N/A _alphabets[_length] = null;
325N/A
325N/A _length++;
325N/A }
325N/A
325N/A /**
325N/A * Replace an attribute value with algorithm data.
325N/A *
325N/A * <p>For the sake of speed, this method does no checking
325N/A * to see if the attribute is already in the list: that is
325N/A * the responsibility of the application.</p>
325N/A *
325N/A * @param index The index of the attribute whose value is to be replaced
325N/A * @param algorithmURI The algorithm URI, or null if a built in algorithm
325N/A * @param algorithmID The algorithm ID.
325N/A * @param algorithmData The algorithm data.
325N/A */
325N/A public void replaceWithAttributeAlgorithmData(int index,
325N/A String algorithmURI, int algorithmID, Object algorithmData) {
325N/A if (index < 0 || index >= _length) return;
325N/A
325N/A int i = index * SIZE;
325N/A _data[i + VALUE_OFFSET] = null;
325N/A _data[i + ALGORITHMURI_OFFSET] = algorithmURI;
325N/A _algorithmIds[index] = algorithmID;
325N/A _algorithmData[index] = algorithmData;
325N/A _toIndex[index] = false;
325N/A _alphabets[index] = null;
325N/A }
325N/A
325N/A /**
325N/A * Copy an entire Attributes object.
325N/A *
325N/A * @param atts The attributes to copy.
325N/A */
325N/A public void setAttributes(Attributes atts) {
325N/A _length = atts.getLength();
325N/A if (_length > 0) {
325N/A
325N/A if (_length >= _algorithmData.length) {
325N/A resizeNoCopy();
325N/A }
325N/A
325N/A int index = 0;
325N/A for (int i = 0; i < _length; i++) {
325N/A _data[index++] = atts.getURI(i);
325N/A _data[index++] = atts.getLocalName(i);
325N/A _data[index++] = atts.getQName(i);
325N/A _data[index++] = atts.getType(i);
325N/A _data[index++] = atts.getValue(i);
325N/A index++;
325N/A _toIndex[i] = false;
325N/A _alphabets[i] = null;
325N/A }
325N/A }
325N/A }
325N/A
325N/A /**
325N/A * Copy an entire EncodingAlgorithmAttributes object.
325N/A *
325N/A * @param atts The attributes to copy.
325N/A */
325N/A public void setAttributes(EncodingAlgorithmAttributes atts) {
325N/A _length = atts.getLength();
325N/A if (_length > 0) {
325N/A
325N/A if (_length >= _algorithmData.length) {
325N/A resizeNoCopy();
325N/A }
325N/A
325N/A int index = 0;
325N/A for (int i = 0; i < _length; i++) {
325N/A _data[index++] = atts.getURI(i);
325N/A _data[index++] = atts.getLocalName(i);
325N/A _data[index++] = atts.getQName(i);
325N/A _data[index++] = atts.getType(i);
325N/A _data[index++] = atts.getValue(i);
325N/A _data[index++] = atts.getAlgorithmURI(i);
325N/A _algorithmIds[i] = atts.getAlgorithmIndex(i);
325N/A _algorithmData[i] = atts.getAlgorithmData(i);
325N/A _toIndex[i] = false;
325N/A _alphabets[i] = null;
325N/A }
325N/A }
325N/A }
325N/A
325N/A // org.xml.sax.Attributes
325N/A
325N/A public final int getLength() {
325N/A return _length;
325N/A }
325N/A
325N/A public final String getLocalName(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _data[index * SIZE + LOCALNAME_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final String getQName(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _data[index * SIZE + QNAME_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final String getType(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _data[index * SIZE + TYPE_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final String getURI(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _data[index * SIZE + URI_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final String getValue(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A final String value = _data[index * SIZE + VALUE_OFFSET];
325N/A if (value != null) return value;
325N/A } else {
325N/A return null;
325N/A }
325N/A
325N/A if (_algorithmData[index] == null || _registeredEncodingAlgorithms == null) {
325N/A return null;
325N/A }
325N/A
325N/A try {
325N/A return _data[index * SIZE + VALUE_OFFSET] = convertEncodingAlgorithmDataToString(
325N/A _algorithmIds[index],
325N/A _data[index * SIZE + ALGORITHMURI_OFFSET],
325N/A _algorithmData[index]).toString();
325N/A } catch (IOException e) {
325N/A return null;
325N/A } catch (FastInfosetException e) {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final int getIndex(String qName) {
325N/A for (int index = 0; index < _length; index++) {
325N/A if (qName.equals(_data[index * SIZE + QNAME_OFFSET])) {
325N/A return index;
325N/A }
325N/A }
325N/A return -1;
325N/A }
325N/A
325N/A public final String getType(String qName) {
325N/A int index = getIndex(qName);
325N/A if (index >= 0) {
325N/A return _data[index * SIZE + TYPE_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final String getValue(String qName) {
325N/A int index = getIndex(qName);
325N/A if (index >= 0) {
325N/A return getValue(index);
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final int getIndex(String uri, String localName) {
325N/A for (int index = 0; index < _length; index++) {
325N/A if (localName.equals(_data[index * SIZE + LOCALNAME_OFFSET]) &&
325N/A uri.equals(_data[index * SIZE + URI_OFFSET])) {
325N/A return index;
325N/A }
325N/A }
325N/A return -1;
325N/A }
325N/A
325N/A public final String getType(String uri, String localName) {
325N/A int index = getIndex(uri, localName);
325N/A if (index >= 0) {
325N/A return _data[index * SIZE + TYPE_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final String getValue(String uri, String localName) {
325N/A int index = getIndex(uri, localName);
325N/A if (index >= 0) {
325N/A return getValue(index);
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A // EncodingAlgorithmAttributes
325N/A
325N/A public final String getAlgorithmURI(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _data[index * SIZE + ALGORITHMURI_OFFSET];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final int getAlgorithmIndex(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _algorithmIds[index];
325N/A } else {
325N/A return -1;
325N/A }
325N/A }
325N/A
325N/A public final Object getAlgorithmData(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _algorithmData[index];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A // ExtendedAttributes
325N/A
325N/A public final String getAlpababet(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _alphabets[index];
325N/A } else {
325N/A return null;
325N/A }
325N/A }
325N/A
325N/A public final boolean getToIndex(int index) {
325N/A if (index >= 0 && index < _length) {
325N/A return _toIndex[index];
325N/A } else {
325N/A return false;
325N/A }
325N/A }
325N/A
325N/A // -----
325N/A
325N/A private final String replaceNull(String s) {
325N/A return (s != null) ? s : "";
325N/A }
325N/A
325N/A private final void resizeNoCopy() {
325N/A final int newLength = _length * 3 / 2 + 1;
325N/A
325N/A _data = new String[newLength * SIZE];
325N/A _algorithmIds = new int[newLength];
325N/A _algorithmData = new Object[newLength];
325N/A }
325N/A
325N/A private final void resize() {
325N/A final int newLength = _length * 3 / 2 + 1;
325N/A
325N/A String[] data = new String[newLength * SIZE];
325N/A int[] algorithmIds = new int[newLength];
325N/A Object[] algorithmData = new Object[newLength];
325N/A String[] alphabets = new String[newLength];
325N/A boolean[] toIndex = new boolean[newLength];
325N/A
325N/A System.arraycopy(_data, 0, data, 0, _length * SIZE);
325N/A System.arraycopy(_algorithmIds, 0, algorithmIds, 0, _length);
325N/A System.arraycopy(_algorithmData, 0, algorithmData, 0, _length);
325N/A System.arraycopy(_alphabets, 0, alphabets, 0, _length);
325N/A System.arraycopy(_toIndex, 0, toIndex, 0, _length);
325N/A
325N/A _data = data;
325N/A _algorithmIds = algorithmIds;
325N/A _algorithmData = algorithmData;
325N/A _alphabets = alphabets;
325N/A _toIndex = toIndex;
325N/A }
325N/A
325N/A private final StringBuffer convertEncodingAlgorithmDataToString(
325N/A int identifier, String URI, Object data) throws FastInfosetException, IOException {
325N/A EncodingAlgorithm ea = null;
325N/A if (identifier < EncodingConstants.ENCODING_ALGORITHM_BUILTIN_END) {
325N/A ea = BuiltInEncodingAlgorithmFactory.getAlgorithm(identifier);
325N/A } else if (identifier == EncodingAlgorithmIndexes.CDATA) {
325N/A throw new EncodingAlgorithmException(
325N/A CommonResourceBundle.getInstance().getString("message.CDATAAlgorithmNotSupported"));
325N/A } else if (identifier >= EncodingConstants.ENCODING_ALGORITHM_APPLICATION_START) {
325N/A if (URI == null) {
325N/A throw new EncodingAlgorithmException(
325N/A CommonResourceBundle.getInstance().getString("message.URINotPresent") + identifier);
325N/A }
325N/A
325N/A ea = (EncodingAlgorithm)_registeredEncodingAlgorithms.get(URI);
325N/A if (ea == null) {
325N/A throw new EncodingAlgorithmException(
325N/A CommonResourceBundle.getInstance().getString("message.algorithmNotRegistered") + URI);
325N/A }
325N/A } else {
325N/A // Reserved built-in algorithms for future use
325N/A // TODO should use sax property to decide if event will be
325N/A // reported, allows for support through handler if required.
325N/A throw new EncodingAlgorithmException(
325N/A CommonResourceBundle.getInstance().getString("message.identifiers10to31Reserved"));
325N/A }
325N/A
325N/A final StringBuffer sb = new StringBuffer();
325N/A ea.convertToCharacters(data, sb);
325N/A return sb;
325N/A }
325N/A}