All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jvnet.fastinfoset.sax.helpers.EncodingAlgorithmAttributesImpl Maven / Gradle / Ivy

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2004-2018 Oracle and/or its affiliates. All rights reserved.
 *
 * Oracle licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jvnet.fastinfoset.sax.helpers;

import com.sun.xml.fastinfoset.CommonResourceBundle;
import com.sun.xml.fastinfoset.EncodingConstants;
import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
import java.io.IOException;
import java.util.Map;
import org.jvnet.fastinfoset.EncodingAlgorithm;
import org.jvnet.fastinfoset.EncodingAlgorithmException;
import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
import org.jvnet.fastinfoset.FastInfosetException;
import org.jvnet.fastinfoset.sax.EncodingAlgorithmAttributes;
import org.xml.sax.Attributes;

/**
 * Default implementation of the {@link EncodingAlgorithmAttributes} interface.
 *
 * 

This class provides a default implementation of the SAX2 * {@link EncodingAlgorithmAttributes} interface, with the * addition of manipulators so that the list can be modified or * reused.

* *

There are two typical uses of this class:

* *
    *
  1. to take a persistent snapshot of an EncodingAlgorithmAttributes object * in a {@link org.xml.sax.ContentHandler#startElement startElement} event; or
  2. *
  3. to construct or modify an EncodingAlgorithmAttributes object in a SAX2 * driver or filter.
  4. *
*/ public class EncodingAlgorithmAttributesImpl implements EncodingAlgorithmAttributes { private static final int DEFAULT_CAPACITY = 8; private static final int URI_OFFSET = 0; private static final int LOCALNAME_OFFSET = 1; private static final int QNAME_OFFSET = 2; private static final int TYPE_OFFSET = 3; private static final int VALUE_OFFSET = 4; private static final int ALGORITHMURI_OFFSET = 5; private static final int SIZE = 6; private Map _registeredEncodingAlgorithms; private int _length; private String[] _data; private int[] _algorithmIds; private Object[] _algorithmData; private String[] _alphabets; private boolean[] _toIndex; /** * Construct a new, empty EncodingAlgorithmAttributesImpl object. */ public EncodingAlgorithmAttributesImpl() { this(null, null); } /** * Copy an existing Attributes object. * *

This constructor is especially useful inside a * {@link org.xml.sax.ContentHandler#startElement startElement} event.

* * @param attributes The existing Attributes object. */ public EncodingAlgorithmAttributesImpl(Attributes attributes) { this(null, attributes); } /** * Use registered encoding algorithms and copy an existing Attributes object. * *

This constructor is especially useful inside a * {@link org.xml.sax.ContentHandler#startElement startElement} event.

* * @param registeredEncodingAlgorithms * The registeredEncodingAlgorithms encoding algorithms. * @param attributes The existing Attributes object. */ public EncodingAlgorithmAttributesImpl(Map registeredEncodingAlgorithms, Attributes attributes) { _data = new String[DEFAULT_CAPACITY * SIZE]; _algorithmIds = new int[DEFAULT_CAPACITY]; _algorithmData = new Object[DEFAULT_CAPACITY]; _alphabets = new String[DEFAULT_CAPACITY]; _toIndex = new boolean[DEFAULT_CAPACITY]; _registeredEncodingAlgorithms = registeredEncodingAlgorithms; if (attributes != null) { if (attributes instanceof EncodingAlgorithmAttributes) { setAttributes((EncodingAlgorithmAttributes)attributes); } else { setAttributes(attributes); } } } /** * Clear the attribute list for reuse. * */ public final void clear() { for (int i = 0; i < _length; i++) { _data[i * SIZE + VALUE_OFFSET] = null; _algorithmData[i] = null; } _length = 0; } /** * Add an attribute to the end of the list. * *

For the sake of speed, this method does no checking * to see if the attribute is already in the list: that is * the responsibility of the application.

* * @param URI The Namespace URI, or the empty string if * none is available or Namespace processing is not * being performed. * @param localName The local name, or the empty string if * Namespace processing is not being performed. * @param qName The qualified (prefixed) name, or the empty string * if qualified names are not available. * @param type The attribute type as a string. * @param value The attribute value. */ public void addAttribute(String URI, String localName, String qName, String type, String value) { if (_length >= _algorithmData.length) { resize(); } int i = _length * SIZE; _data[i++] = replaceNull(URI); _data[i++] = replaceNull(localName); _data[i++] = replaceNull(qName); _data[i++] = replaceNull(type); _data[i++] = replaceNull(value); _toIndex[_length] = false; _alphabets[_length] = null; _length++; } /** * Add an attribute to the end of the list. * *

For the sake of speed, this method does no checking * to see if the attribute is already in the list: that is * the responsibility of the application.

* * @param URI The Namespace URI, or the empty string if * none is available or Namespace processing is not * being performed. * @param localName The local name, or the empty string if * Namespace processing is not being performed. * @param qName The qualified (prefixed) name, or the empty string * if qualified names are not available. * @param type The attribute type as a string. * @param value The attribute value. * @param index True if attribute should be indexed. * @param alphabet The alphabet associated with the attribute value, * may be null if there is no associated alphabet. */ public void addAttribute(String URI, String localName, String qName, String type, String value, boolean index, String alphabet) { if (_length >= _algorithmData.length) { resize(); } int i = _length * SIZE; _data[i++] = replaceNull(URI); _data[i++] = replaceNull(localName); _data[i++] = replaceNull(qName); _data[i++] = replaceNull(type); _data[i++] = replaceNull(value); _toIndex[_length] = index; _alphabets[_length] = alphabet; _length++; } /** * Add an attribute with built in algorithm data to the end of the list. * *

For the sake of speed, this method does no checking * to see if the attribute is already in the list: that is * the responsibility of the application.

* * @param URI The Namespace URI, or the empty string if * none is available or Namespace processing is not * being performed. * @param localName The local name, or the empty string if * Namespace processing is not being performed. * @param qName The qualified (prefixed) name, or the empty string * if qualified names are not available. * @param builtInAlgorithmID The built in algorithm ID. * @param algorithmData The built in algorithm data. */ public void addAttributeWithBuiltInAlgorithmData(String URI, String localName, String qName, int builtInAlgorithmID, Object algorithmData) { if (_length >= _algorithmData.length) { resize(); } int i = _length * SIZE; _data[i++] = replaceNull(URI); _data[i++] = replaceNull(localName); _data[i++] = replaceNull(qName); _data[i++] = "CDATA"; _data[i++] = ""; _data[i++] = null; _algorithmIds[_length] = builtInAlgorithmID; _algorithmData[_length] = algorithmData; _toIndex[_length] = false; _alphabets[_length] = null; _length++; } /** * Add an attribute with algorithm data to the end of the list. * *

For the sake of speed, this method does no checking * to see if the attribute is already in the list: that is * the responsibility of the application.

* * @param URI The Namespace URI, or the empty string if * none is available or Namespace processing is not * being performed. * @param localName The local name, or the empty string if * Namespace processing is not being performed. * @param qName The qualified (prefixed) name, or the empty string * if qualified names are not available. * @param algorithmURI The algorithm URI, or null if a built in algorithm * @param algorithmID The algorithm ID. * @param algorithmData The algorithm data. */ public void addAttributeWithAlgorithmData(String URI, String localName, String qName, String algorithmURI, int algorithmID, Object algorithmData) { if (_length >= _algorithmData.length) { resize(); } int i = _length * SIZE; _data[i++] = replaceNull(URI); _data[i++] = replaceNull(localName); _data[i++] = replaceNull(qName); _data[i++] = "CDATA"; _data[i++] = ""; _data[i++] = algorithmURI; _algorithmIds[_length] = algorithmID; _algorithmData[_length] = algorithmData; _toIndex[_length] = false; _alphabets[_length] = null; _length++; } /** * Replace an attribute value with algorithm data. * *

For the sake of speed, this method does no checking * to see if the attribute is already in the list: that is * the responsibility of the application.

* * @param index The index of the attribute whose value is to be replaced * @param algorithmURI The algorithm URI, or null if a built in algorithm * @param algorithmID The algorithm ID. * @param algorithmData The algorithm data. */ public void replaceWithAttributeAlgorithmData(int index, String algorithmURI, int algorithmID, Object algorithmData) { if (index < 0 || index >= _length) return; int i = index * SIZE; _data[i + VALUE_OFFSET] = null; _data[i + ALGORITHMURI_OFFSET] = algorithmURI; _algorithmIds[index] = algorithmID; _algorithmData[index] = algorithmData; _toIndex[index] = false; _alphabets[index] = null; } /** * Copy an entire Attributes object. * * @param atts The attributes to copy. */ public void setAttributes(Attributes atts) { _length = atts.getLength(); if (_length > 0) { if (_length >= _algorithmData.length) { resizeNoCopy(); } int index = 0; for (int i = 0; i < _length; i++) { _data[index++] = atts.getURI(i); _data[index++] = atts.getLocalName(i); _data[index++] = atts.getQName(i); _data[index++] = atts.getType(i); _data[index++] = atts.getValue(i); index++; _toIndex[i] = false; _alphabets[i] = null; } } } /** * Copy an entire EncodingAlgorithmAttributes object. * * @param atts The attributes to copy. */ public void setAttributes(EncodingAlgorithmAttributes atts) { _length = atts.getLength(); if (_length > 0) { if (_length >= _algorithmData.length) { resizeNoCopy(); } int index = 0; for (int i = 0; i < _length; i++) { _data[index++] = atts.getURI(i); _data[index++] = atts.getLocalName(i); _data[index++] = atts.getQName(i); _data[index++] = atts.getType(i); _data[index++] = atts.getValue(i); _data[index++] = atts.getAlgorithmURI(i); _algorithmIds[i] = atts.getAlgorithmIndex(i); _algorithmData[i] = atts.getAlgorithmData(i); _toIndex[i] = false; _alphabets[i] = null; } } } // org.xml.sax.Attributes public final int getLength() { return _length; } public final String getLocalName(int index) { if (index >= 0 && index < _length) { return _data[index * SIZE + LOCALNAME_OFFSET]; } else { return null; } } public final String getQName(int index) { if (index >= 0 && index < _length) { return _data[index * SIZE + QNAME_OFFSET]; } else { return null; } } public final String getType(int index) { if (index >= 0 && index < _length) { return _data[index * SIZE + TYPE_OFFSET]; } else { return null; } } public final String getURI(int index) { if (index >= 0 && index < _length) { return _data[index * SIZE + URI_OFFSET]; } else { return null; } } public final String getValue(int index) { if (index >= 0 && index < _length) { final String value = _data[index * SIZE + VALUE_OFFSET]; if (value != null) return value; } else { return null; } if (_algorithmData[index] == null || _registeredEncodingAlgorithms == null) { return null; } try { return _data[index * SIZE + VALUE_OFFSET] = convertEncodingAlgorithmDataToString( _algorithmIds[index], _data[index * SIZE + ALGORITHMURI_OFFSET], _algorithmData[index]).toString(); } catch (IOException e) { return null; } catch (FastInfosetException e) { return null; } } public final int getIndex(String qName) { for (int index = 0; index < _length; index++) { if (qName.equals(_data[index * SIZE + QNAME_OFFSET])) { return index; } } return -1; } public final String getType(String qName) { int index = getIndex(qName); if (index >= 0) { return _data[index * SIZE + TYPE_OFFSET]; } else { return null; } } public final String getValue(String qName) { int index = getIndex(qName); if (index >= 0) { return getValue(index); } else { return null; } } public final int getIndex(String uri, String localName) { for (int index = 0; index < _length; index++) { if (localName.equals(_data[index * SIZE + LOCALNAME_OFFSET]) && uri.equals(_data[index * SIZE + URI_OFFSET])) { return index; } } return -1; } public final String getType(String uri, String localName) { int index = getIndex(uri, localName); if (index >= 0) { return _data[index * SIZE + TYPE_OFFSET]; } else { return null; } } public final String getValue(String uri, String localName) { int index = getIndex(uri, localName); if (index >= 0) { return getValue(index); } else { return null; } } // EncodingAlgorithmAttributes public final String getAlgorithmURI(int index) { if (index >= 0 && index < _length) { return _data[index * SIZE + ALGORITHMURI_OFFSET]; } else { return null; } } public final int getAlgorithmIndex(int index) { if (index >= 0 && index < _length) { return _algorithmIds[index]; } else { return -1; } } public final Object getAlgorithmData(int index) { if (index >= 0 && index < _length) { return _algorithmData[index]; } else { return null; } } // ExtendedAttributes public final String getAlpababet(int index) { if (index >= 0 && index < _length) { return _alphabets[index]; } else { return null; } } public final boolean getToIndex(int index) { if (index >= 0 && index < _length) { return _toIndex[index]; } else { return false; } } // ----- private final String replaceNull(String s) { return (s != null) ? s : ""; } private final void resizeNoCopy() { final int newLength = _length * 3 / 2 + 1; _data = new String[newLength * SIZE]; _algorithmIds = new int[newLength]; _algorithmData = new Object[newLength]; } private final void resize() { final int newLength = _length * 3 / 2 + 1; String[] data = new String[newLength * SIZE]; int[] algorithmIds = new int[newLength]; Object[] algorithmData = new Object[newLength]; String[] alphabets = new String[newLength]; boolean[] toIndex = new boolean[newLength]; System.arraycopy(_data, 0, data, 0, _length * SIZE); System.arraycopy(_algorithmIds, 0, algorithmIds, 0, _length); System.arraycopy(_algorithmData, 0, algorithmData, 0, _length); System.arraycopy(_alphabets, 0, alphabets, 0, _length); System.arraycopy(_toIndex, 0, toIndex, 0, _length); _data = data; _algorithmIds = algorithmIds; _algorithmData = algorithmData; _alphabets = alphabets; _toIndex = toIndex; } 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; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy