feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
/**
|
||||
* Base class for classes that creates {@link MutableXMLStreamBuffer}
|
||||
* and from infoset in API-specific form.
|
||||
*/
|
||||
public class AbstractCreator extends AbstractCreatorProcessor {
|
||||
|
||||
protected MutableXMLStreamBuffer _buffer;
|
||||
|
||||
public void setXMLStreamBuffer(MutableXMLStreamBuffer buffer) {
|
||||
if (buffer == null) {
|
||||
throw new NullPointerException("buffer cannot be null");
|
||||
}
|
||||
setBuffer(buffer);
|
||||
}
|
||||
|
||||
public MutableXMLStreamBuffer getXMLStreamBuffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
|
||||
protected final void createBuffer() {
|
||||
setBuffer(new MutableXMLStreamBuffer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called whenever a new tree is stored on the buffer.
|
||||
*/
|
||||
protected final void increaseTreeCount() {
|
||||
_buffer.treeCount++;
|
||||
}
|
||||
|
||||
protected final void setBuffer(MutableXMLStreamBuffer buffer) {
|
||||
_buffer = buffer;
|
||||
|
||||
_currentStructureFragment = _buffer.getStructure();
|
||||
_structure = _currentStructureFragment.getArray();
|
||||
_structurePtr = 0;
|
||||
|
||||
_currentStructureStringFragment = _buffer.getStructureStrings();
|
||||
_structureStrings = _currentStructureStringFragment.getArray();
|
||||
_structureStringsPtr = 0;
|
||||
|
||||
_currentContentCharactersBufferFragment = _buffer.getContentCharactersBuffer();
|
||||
_contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray();
|
||||
_contentCharactersBufferPtr = 0;
|
||||
|
||||
_currentContentObjectFragment = _buffer.getContentObjects();
|
||||
_contentObjects = _currentContentObjectFragment.getArray();
|
||||
_contentObjectsPtr = 0;
|
||||
}
|
||||
|
||||
protected final void setHasInternedStrings(boolean hasInternedStrings) {
|
||||
_buffer.setHasInternedStrings(hasInternedStrings);
|
||||
}
|
||||
|
||||
protected final void storeStructure(int b) {
|
||||
_structure[_structurePtr++] = (byte)b;
|
||||
if (_structurePtr == _structure.length) {
|
||||
resizeStructure();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void resizeStructure() {
|
||||
_structurePtr = 0;
|
||||
if (_currentStructureFragment.getNext() != null) {
|
||||
_currentStructureFragment = _currentStructureFragment.getNext();
|
||||
_structure = _currentStructureFragment.getArray();
|
||||
} else {
|
||||
_structure = new byte[_structure.length];
|
||||
_currentStructureFragment = new FragmentedArray(_structure, _currentStructureFragment);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void storeStructureString(String s) {
|
||||
_structureStrings[_structureStringsPtr++] = s;
|
||||
if (_structureStringsPtr == _structureStrings.length) {
|
||||
resizeStructureStrings();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void resizeStructureStrings() {
|
||||
_structureStringsPtr = 0;
|
||||
if (_currentStructureStringFragment.getNext() != null) {
|
||||
_currentStructureStringFragment = _currentStructureStringFragment.getNext();
|
||||
_structureStrings = _currentStructureStringFragment.getArray();
|
||||
} else {
|
||||
_structureStrings = new String[_structureStrings.length];
|
||||
_currentStructureStringFragment = new FragmentedArray(_structureStrings, _currentStructureStringFragment);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void storeContentString(String s) {
|
||||
storeContentObject(s);
|
||||
}
|
||||
|
||||
protected final void storeContentCharacters(int type, char[] ch, int start, int length) {
|
||||
if (_contentCharactersBufferPtr + length >= _contentCharactersBuffer.length) {
|
||||
if (length >= 512) {
|
||||
storeStructure(type | CONTENT_TYPE_CHAR_ARRAY_COPY);
|
||||
storeContentCharactersCopy(ch, start, length);
|
||||
return;
|
||||
}
|
||||
resizeContentCharacters();
|
||||
}
|
||||
|
||||
if (length < CHAR_ARRAY_LENGTH_SMALL_SIZE) {
|
||||
storeStructure(type);
|
||||
storeStructure(length);
|
||||
System.arraycopy(ch, start, _contentCharactersBuffer, _contentCharactersBufferPtr, length);
|
||||
_contentCharactersBufferPtr += length;
|
||||
} else if (length < CHAR_ARRAY_LENGTH_MEDIUM_SIZE) {
|
||||
storeStructure(type | CHAR_ARRAY_LENGTH_MEDIUM);
|
||||
storeStructure(length >> 8);
|
||||
storeStructure(length & 255);
|
||||
System.arraycopy(ch, start, _contentCharactersBuffer, _contentCharactersBufferPtr, length);
|
||||
_contentCharactersBufferPtr += length;
|
||||
} else {
|
||||
storeStructure(type | CONTENT_TYPE_CHAR_ARRAY_COPY);
|
||||
storeContentCharactersCopy(ch, start, length);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void resizeContentCharacters() {
|
||||
_contentCharactersBufferPtr = 0;
|
||||
if (_currentContentCharactersBufferFragment.getNext() != null) {
|
||||
_currentContentCharactersBufferFragment = _currentContentCharactersBufferFragment.getNext();
|
||||
_contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray();
|
||||
} else {
|
||||
_contentCharactersBuffer = new char[_contentCharactersBuffer.length];
|
||||
_currentContentCharactersBufferFragment = new FragmentedArray(_contentCharactersBuffer,
|
||||
_currentContentCharactersBufferFragment);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void storeContentCharactersCopy(char[] ch, int start, int length) {
|
||||
char[] copyOfCh = new char[length];
|
||||
System.arraycopy(ch, start, copyOfCh, 0, length);
|
||||
storeContentObject(copyOfCh);
|
||||
}
|
||||
|
||||
protected final Object peekAtContentObject() {
|
||||
return _contentObjects[_contentObjectsPtr];
|
||||
}
|
||||
|
||||
protected final void storeContentObject(Object s) {
|
||||
_contentObjects[_contentObjectsPtr++] = s;
|
||||
if (_contentObjectsPtr == _contentObjects.length) {
|
||||
resizeContentObjects();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void resizeContentObjects() {
|
||||
_contentObjectsPtr = 0;
|
||||
if (_currentContentObjectFragment.getNext() != null) {
|
||||
_currentContentObjectFragment = _currentContentObjectFragment.getNext();
|
||||
_contentObjects = _currentContentObjectFragment.getArray();
|
||||
} else {
|
||||
_contentObjects = new Object[_contentObjects.length];
|
||||
_currentContentObjectFragment = new FragmentedArray(_contentObjects, _currentContentObjectFragment);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
@SuppressWarnings("PointlessBitwiseExpression")
|
||||
public abstract class AbstractCreatorProcessor {
|
||||
/**
|
||||
* Flag on a T_DOCUMENT to indicate if a fragment
|
||||
*/
|
||||
protected static final int FLAG_DOCUMENT_FRAGMENT = 1 << 0;
|
||||
|
||||
/*
|
||||
* Flags on T_ELEMENT, T_ATTRIBUTE, T_NAMESPACE_ATTRIBUTE
|
||||
* to indicate namespace information is represent
|
||||
*/
|
||||
protected static final int FLAG_PREFIX = 1 << 0;
|
||||
protected static final int FLAG_URI = 1 << 1;
|
||||
protected static final int FLAG_QUALIFIED_NAME = 1 << 2;
|
||||
|
||||
/*
|
||||
* Types of content for T_TEXT and T_COMMENT
|
||||
* <p>
|
||||
* Highest 2 bits of lower nibble are used.
|
||||
*/
|
||||
protected static final int CONTENT_TYPE_CHAR_ARRAY = 0 << 2;
|
||||
protected static final int CONTENT_TYPE_CHAR_ARRAY_COPY = 1 << 2;
|
||||
protected static final int CONTENT_TYPE_STRING = 2 << 2;
|
||||
protected static final int CONTENT_TYPE_OBJECT = 3 << 2;
|
||||
|
||||
/*
|
||||
* Size of the length of character content for CONTENT_TYPE_CHAR_ARRAY
|
||||
* <p>
|
||||
* Last bit of lower nibble is used.
|
||||
*/
|
||||
protected static final int CHAR_ARRAY_LENGTH_SMALL = 0;
|
||||
protected static final int CHAR_ARRAY_LENGTH_MEDIUM = 1;
|
||||
protected static final int CHAR_ARRAY_LENGTH_SMALL_SIZE = 1 << 8;
|
||||
protected static final int CHAR_ARRAY_LENGTH_MEDIUM_SIZE = 1 << 16;
|
||||
|
||||
/*
|
||||
* Types of value for T_ATTRIBUTE
|
||||
* <p>
|
||||
* Highest bit of lower nibble is used.
|
||||
*/
|
||||
protected static final int VALUE_TYPE_STRING = 0;
|
||||
protected static final int VALUE_TYPE_OBJECT = 1 << 3;
|
||||
|
||||
/*
|
||||
* Mask for types.
|
||||
* <p>
|
||||
* Highest nibble is used.
|
||||
*/
|
||||
protected static final int TYPE_MASK = 0xF0;
|
||||
protected static final int T_DOCUMENT = 0x10;
|
||||
protected static final int T_ELEMENT = 0x20;
|
||||
protected static final int T_ATTRIBUTE = 0x30;
|
||||
protected static final int T_NAMESPACE_ATTRIBUTE = 0x40;
|
||||
protected static final int T_TEXT = 0x50;
|
||||
protected static final int T_COMMENT = 0x60;
|
||||
protected static final int T_PROCESSING_INSTRUCTION = 0x70;
|
||||
protected static final int T_UNEXPANDED_ENTITY_REFERENCE = 0x80;
|
||||
protected static final int T_END = 0x90;
|
||||
|
||||
/*
|
||||
* Composed types.
|
||||
* <p>
|
||||
* One octet is used.
|
||||
*/
|
||||
protected static final int T_DOCUMENT_FRAGMENT = T_DOCUMENT | FLAG_DOCUMENT_FRAGMENT;
|
||||
|
||||
protected static final int T_ELEMENT_U_LN_QN = T_ELEMENT | FLAG_URI | FLAG_QUALIFIED_NAME;
|
||||
protected static final int T_ELEMENT_P_U_LN = T_ELEMENT | FLAG_PREFIX | FLAG_URI;
|
||||
protected static final int T_ELEMENT_U_LN = T_ELEMENT | FLAG_URI;
|
||||
protected static final int T_ELEMENT_LN = T_ELEMENT;
|
||||
|
||||
protected static final int T_NAMESPACE_ATTRIBUTE_P = T_NAMESPACE_ATTRIBUTE | FLAG_PREFIX;
|
||||
protected static final int T_NAMESPACE_ATTRIBUTE_P_U = T_NAMESPACE_ATTRIBUTE | FLAG_PREFIX | FLAG_URI;
|
||||
protected static final int T_NAMESPACE_ATTRIBUTE_U = T_NAMESPACE_ATTRIBUTE | FLAG_URI;
|
||||
|
||||
protected static final int T_ATTRIBUTE_U_LN_QN = T_ATTRIBUTE | FLAG_URI | FLAG_QUALIFIED_NAME;
|
||||
protected static final int T_ATTRIBUTE_P_U_LN = T_ATTRIBUTE | FLAG_PREFIX | FLAG_URI;
|
||||
protected static final int T_ATTRIBUTE_U_LN = T_ATTRIBUTE | FLAG_URI;
|
||||
protected static final int T_ATTRIBUTE_LN = T_ATTRIBUTE;
|
||||
protected static final int T_ATTRIBUTE_U_LN_QN_OBJECT = T_ATTRIBUTE_U_LN_QN | VALUE_TYPE_OBJECT;
|
||||
protected static final int T_ATTRIBUTE_P_U_LN_OBJECT = T_ATTRIBUTE_P_U_LN | VALUE_TYPE_OBJECT;
|
||||
protected static final int T_ATTRIBUTE_U_LN_OBJECT = T_ATTRIBUTE_U_LN | VALUE_TYPE_OBJECT;
|
||||
protected static final int T_ATTRIBUTE_LN_OBJECT = T_ATTRIBUTE_LN | VALUE_TYPE_OBJECT;
|
||||
|
||||
protected static final int T_TEXT_AS_CHAR_ARRAY = T_TEXT;
|
||||
protected static final int T_TEXT_AS_CHAR_ARRAY_SMALL = T_TEXT | CHAR_ARRAY_LENGTH_SMALL;
|
||||
protected static final int T_TEXT_AS_CHAR_ARRAY_MEDIUM = T_TEXT | CHAR_ARRAY_LENGTH_MEDIUM;
|
||||
protected static final int T_TEXT_AS_CHAR_ARRAY_COPY = T_TEXT | CONTENT_TYPE_CHAR_ARRAY_COPY;
|
||||
protected static final int T_TEXT_AS_STRING = T_TEXT | CONTENT_TYPE_STRING;
|
||||
protected static final int T_TEXT_AS_OBJECT = T_TEXT | CONTENT_TYPE_OBJECT;
|
||||
|
||||
protected static final int T_COMMENT_AS_CHAR_ARRAY = T_COMMENT;
|
||||
protected static final int T_COMMENT_AS_CHAR_ARRAY_SMALL = T_COMMENT | CHAR_ARRAY_LENGTH_SMALL;
|
||||
protected static final int T_COMMENT_AS_CHAR_ARRAY_MEDIUM = T_COMMENT | CHAR_ARRAY_LENGTH_MEDIUM;
|
||||
protected static final int T_COMMENT_AS_CHAR_ARRAY_COPY = T_COMMENT | CONTENT_TYPE_CHAR_ARRAY_COPY;
|
||||
protected static final int T_COMMENT_AS_STRING = T_COMMENT | CONTENT_TYPE_STRING;
|
||||
|
||||
protected static final int T_END_OF_BUFFER = -1;
|
||||
|
||||
protected FragmentedArray<byte[]> _currentStructureFragment;
|
||||
protected byte[] _structure;
|
||||
protected int _structurePtr;
|
||||
|
||||
protected FragmentedArray<String[]> _currentStructureStringFragment;
|
||||
protected String[] _structureStrings;
|
||||
protected int _structureStringsPtr;
|
||||
|
||||
protected FragmentedArray<char[]> _currentContentCharactersBufferFragment;
|
||||
protected char[] _contentCharactersBuffer;
|
||||
protected int _contentCharactersBufferPtr;
|
||||
|
||||
protected FragmentedArray<Object[]> _currentContentObjectFragment;
|
||||
protected Object[] _contentObjects;
|
||||
protected int _contentObjectsPtr;
|
||||
}
|
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
/**
|
||||
* Base class for classes that processes {@link XMLStreamBuffer}
|
||||
* and produces infoset in API-specific form.
|
||||
*/
|
||||
public abstract class AbstractProcessor extends AbstractCreatorProcessor {
|
||||
protected static final int STATE_ILLEGAL = 0;
|
||||
|
||||
protected static final int STATE_DOCUMENT = 1;
|
||||
protected static final int STATE_DOCUMENT_FRAGMENT = 2;
|
||||
protected static final int STATE_ELEMENT_U_LN_QN = 3;
|
||||
protected static final int STATE_ELEMENT_P_U_LN = 4;
|
||||
protected static final int STATE_ELEMENT_U_LN = 5;
|
||||
protected static final int STATE_ELEMENT_LN = 6;
|
||||
protected static final int STATE_TEXT_AS_CHAR_ARRAY_SMALL = 7;
|
||||
protected static final int STATE_TEXT_AS_CHAR_ARRAY_MEDIUM = 8;
|
||||
protected static final int STATE_TEXT_AS_CHAR_ARRAY_COPY = 9;
|
||||
protected static final int STATE_TEXT_AS_STRING = 10;
|
||||
protected static final int STATE_TEXT_AS_OBJECT = 11;
|
||||
protected static final int STATE_COMMENT_AS_CHAR_ARRAY_SMALL = 12;
|
||||
protected static final int STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM = 13;
|
||||
protected static final int STATE_COMMENT_AS_CHAR_ARRAY_COPY = 14;
|
||||
protected static final int STATE_COMMENT_AS_STRING = 15;
|
||||
protected static final int STATE_PROCESSING_INSTRUCTION = 16;
|
||||
protected static final int STATE_END = 17;
|
||||
private static final int[] _eiiStateTable = new int[256];
|
||||
|
||||
protected static final int STATE_NAMESPACE_ATTRIBUTE = 1;
|
||||
protected static final int STATE_NAMESPACE_ATTRIBUTE_P = 2;
|
||||
protected static final int STATE_NAMESPACE_ATTRIBUTE_P_U = 3;
|
||||
protected static final int STATE_NAMESPACE_ATTRIBUTE_U = 4;
|
||||
private static final int[] _niiStateTable = new int[256];
|
||||
|
||||
protected static final int STATE_ATTRIBUTE_U_LN_QN = 1;
|
||||
protected static final int STATE_ATTRIBUTE_P_U_LN = 2;
|
||||
protected static final int STATE_ATTRIBUTE_U_LN = 3;
|
||||
protected static final int STATE_ATTRIBUTE_LN = 4;
|
||||
protected static final int STATE_ATTRIBUTE_U_LN_QN_OBJECT = 5;
|
||||
protected static final int STATE_ATTRIBUTE_P_U_LN_OBJECT = 6;
|
||||
protected static final int STATE_ATTRIBUTE_U_LN_OBJECT = 7;
|
||||
protected static final int STATE_ATTRIBUTE_LN_OBJECT = 8;
|
||||
private static final int[] _aiiStateTable = new int[256];
|
||||
|
||||
static {
|
||||
/*
|
||||
* Create a state table from information items and options.
|
||||
* The swtich statement using such states will often generate a more
|
||||
* efficient byte code representation that can be hotspotted using
|
||||
* jump tables.
|
||||
*/
|
||||
_eiiStateTable[T_DOCUMENT] = STATE_DOCUMENT;
|
||||
_eiiStateTable[T_DOCUMENT_FRAGMENT] = STATE_DOCUMENT_FRAGMENT;
|
||||
_eiiStateTable[T_ELEMENT_U_LN_QN] = STATE_ELEMENT_U_LN_QN;
|
||||
_eiiStateTable[T_ELEMENT_P_U_LN] = STATE_ELEMENT_P_U_LN;
|
||||
_eiiStateTable[T_ELEMENT_U_LN] = STATE_ELEMENT_U_LN;
|
||||
_eiiStateTable[T_ELEMENT_LN] = STATE_ELEMENT_LN;
|
||||
_eiiStateTable[T_TEXT_AS_CHAR_ARRAY_SMALL] = STATE_TEXT_AS_CHAR_ARRAY_SMALL;
|
||||
_eiiStateTable[T_TEXT_AS_CHAR_ARRAY_MEDIUM] = STATE_TEXT_AS_CHAR_ARRAY_MEDIUM;
|
||||
_eiiStateTable[T_TEXT_AS_CHAR_ARRAY_COPY] = STATE_TEXT_AS_CHAR_ARRAY_COPY;
|
||||
_eiiStateTable[T_TEXT_AS_STRING] = STATE_TEXT_AS_STRING;
|
||||
_eiiStateTable[T_TEXT_AS_OBJECT] = STATE_TEXT_AS_OBJECT;
|
||||
_eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_SMALL] = STATE_COMMENT_AS_CHAR_ARRAY_SMALL;
|
||||
_eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_MEDIUM] = STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM;
|
||||
_eiiStateTable[T_COMMENT_AS_CHAR_ARRAY_COPY] = STATE_COMMENT_AS_CHAR_ARRAY_COPY;
|
||||
_eiiStateTable[T_COMMENT_AS_STRING] = STATE_COMMENT_AS_STRING;
|
||||
_eiiStateTable[T_PROCESSING_INSTRUCTION] = STATE_PROCESSING_INSTRUCTION;
|
||||
_eiiStateTable[T_END] = STATE_END;
|
||||
|
||||
_niiStateTable[T_NAMESPACE_ATTRIBUTE] = STATE_NAMESPACE_ATTRIBUTE;
|
||||
_niiStateTable[T_NAMESPACE_ATTRIBUTE_P] = STATE_NAMESPACE_ATTRIBUTE_P;
|
||||
_niiStateTable[T_NAMESPACE_ATTRIBUTE_P_U] = STATE_NAMESPACE_ATTRIBUTE_P_U;
|
||||
_niiStateTable[T_NAMESPACE_ATTRIBUTE_U] = STATE_NAMESPACE_ATTRIBUTE_U;
|
||||
|
||||
_aiiStateTable[T_ATTRIBUTE_U_LN_QN] = STATE_ATTRIBUTE_U_LN_QN;
|
||||
_aiiStateTable[T_ATTRIBUTE_P_U_LN] = STATE_ATTRIBUTE_P_U_LN;
|
||||
_aiiStateTable[T_ATTRIBUTE_U_LN] = STATE_ATTRIBUTE_U_LN;
|
||||
_aiiStateTable[T_ATTRIBUTE_LN] = STATE_ATTRIBUTE_LN;
|
||||
_aiiStateTable[T_ATTRIBUTE_U_LN_QN_OBJECT] = STATE_ATTRIBUTE_U_LN_QN_OBJECT;
|
||||
_aiiStateTable[T_ATTRIBUTE_P_U_LN_OBJECT] = STATE_ATTRIBUTE_P_U_LN_OBJECT;
|
||||
_aiiStateTable[T_ATTRIBUTE_U_LN_OBJECT] = STATE_ATTRIBUTE_U_LN_OBJECT;
|
||||
_aiiStateTable[T_ATTRIBUTE_LN_OBJECT] = STATE_ATTRIBUTE_LN_OBJECT;
|
||||
}
|
||||
|
||||
protected XMLStreamBuffer _buffer;
|
||||
|
||||
/**
|
||||
* True if this processor should create a fragment of XML, without the start/end document markers.
|
||||
*/
|
||||
protected boolean _fragmentMode;
|
||||
|
||||
protected boolean _stringInterningFeature = false;
|
||||
|
||||
/**
|
||||
* Number of remaining XML element trees that should be visible
|
||||
* through this {@link AbstractProcessor}.
|
||||
*/
|
||||
protected int _treeCount;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #setBuffer(XMLStreamBuffer, boolean)}
|
||||
*/
|
||||
protected final void setBuffer(XMLStreamBuffer buffer) {
|
||||
setBuffer(buffer,buffer.isFragment());
|
||||
}
|
||||
protected final void setBuffer(XMLStreamBuffer buffer, boolean fragmentMode) {
|
||||
_buffer = buffer;
|
||||
_fragmentMode = fragmentMode;
|
||||
|
||||
_currentStructureFragment = _buffer.getStructure();
|
||||
_structure = _currentStructureFragment.getArray();
|
||||
_structurePtr = _buffer.getStructurePtr();
|
||||
|
||||
_currentStructureStringFragment = _buffer.getStructureStrings();
|
||||
_structureStrings = _currentStructureStringFragment.getArray();
|
||||
_structureStringsPtr = _buffer.getStructureStringsPtr();
|
||||
|
||||
_currentContentCharactersBufferFragment = _buffer.getContentCharactersBuffer();
|
||||
_contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray();
|
||||
_contentCharactersBufferPtr = _buffer.getContentCharactersBufferPtr();
|
||||
|
||||
_currentContentObjectFragment = _buffer.getContentObjects();
|
||||
_contentObjects = _currentContentObjectFragment.getArray();
|
||||
_contentObjectsPtr = _buffer.getContentObjectsPtr();
|
||||
|
||||
_stringInterningFeature = _buffer.hasInternedStrings();
|
||||
_treeCount = _buffer.treeCount;
|
||||
}
|
||||
|
||||
protected final int peekStructure() {
|
||||
if (_structurePtr < _structure.length) {
|
||||
return _structure[_structurePtr] & 255;
|
||||
}
|
||||
|
||||
return readFromNextStructure(0);
|
||||
}
|
||||
|
||||
protected final int readStructure() {
|
||||
if (_structurePtr < _structure.length) {
|
||||
return _structure[_structurePtr++] & 255;
|
||||
}
|
||||
|
||||
return readFromNextStructure(1);
|
||||
}
|
||||
|
||||
protected final int readEiiState() {
|
||||
return _eiiStateTable[readStructure()];
|
||||
}
|
||||
|
||||
protected static int getEIIState(int item) {
|
||||
return _eiiStateTable[item];
|
||||
}
|
||||
|
||||
protected static int getNIIState(int item) {
|
||||
return _niiStateTable[item];
|
||||
}
|
||||
|
||||
protected static int getAIIState(int item) {
|
||||
return _aiiStateTable[item];
|
||||
}
|
||||
|
||||
protected final int readStructure16() {
|
||||
return (readStructure() << 8) | readStructure();
|
||||
}
|
||||
|
||||
private int readFromNextStructure(int v) {
|
||||
_structurePtr = v;
|
||||
_currentStructureFragment = _currentStructureFragment.getNext();
|
||||
_structure = _currentStructureFragment.getArray();
|
||||
return _structure[0] & 255;
|
||||
}
|
||||
|
||||
protected final String readStructureString() {
|
||||
if (_structureStringsPtr < _structureStrings.length) {
|
||||
return _structureStrings[_structureStringsPtr++];
|
||||
}
|
||||
|
||||
_structureStringsPtr = 1;
|
||||
_currentStructureStringFragment = _currentStructureStringFragment.getNext();
|
||||
_structureStrings = _currentStructureStringFragment.getArray();
|
||||
return _structureStrings[0];
|
||||
}
|
||||
|
||||
protected final String readContentString() {
|
||||
return (String)readContentObject();
|
||||
}
|
||||
|
||||
protected final char[] readContentCharactersCopy() {
|
||||
return (char[])readContentObject();
|
||||
}
|
||||
|
||||
protected final int readContentCharactersBuffer(int length) {
|
||||
if (_contentCharactersBufferPtr + length < _contentCharactersBuffer.length) {
|
||||
final int start = _contentCharactersBufferPtr;
|
||||
_contentCharactersBufferPtr += length;
|
||||
return start;
|
||||
}
|
||||
|
||||
_contentCharactersBufferPtr = length;
|
||||
_currentContentCharactersBufferFragment = _currentContentCharactersBufferFragment.getNext();
|
||||
_contentCharactersBuffer = _currentContentCharactersBufferFragment.getArray();
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected final Object readContentObject() {
|
||||
if (_contentObjectsPtr < _contentObjects.length) {
|
||||
return _contentObjects[_contentObjectsPtr++];
|
||||
}
|
||||
|
||||
_contentObjectsPtr = 1;
|
||||
_currentContentObjectFragment = _currentContentObjectFragment.getNext();
|
||||
_contentObjects = _currentContentObjectFragment.getArray();
|
||||
return _contentObjects[0];
|
||||
}
|
||||
|
||||
protected final StringBuilder _qNameBuffer = new StringBuilder();
|
||||
|
||||
protected final String getQName(String prefix, String localName) {
|
||||
_qNameBuffer.append(prefix).append(':').append(localName);
|
||||
final String qName = _qNameBuffer.toString();
|
||||
_qNameBuffer.setLength(0);
|
||||
return (_stringInterningFeature) ? qName.intern() : qName;
|
||||
}
|
||||
|
||||
protected final String getPrefixFromQName(String qName) {
|
||||
int pIndex = qName.indexOf(':');
|
||||
if (_stringInterningFeature) {
|
||||
return (pIndex != -1) ? qName.substring(0,pIndex).intern() : "";
|
||||
} else {
|
||||
return (pIndex != -1) ? qName.substring(0,pIndex) : "";
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import org.xml.sax.Attributes;
|
||||
|
||||
/**
|
||||
* Class for holding attributes.
|
||||
*
|
||||
* Since it implements {@link Attributes}, this class follows the SAX convention
|
||||
* of using "" instead of null.
|
||||
*/
|
||||
@SuppressWarnings({"PointlessArithmeticExpression"})
|
||||
public final class AttributesHolder implements Attributes {
|
||||
private static final int DEFAULT_CAPACITY = 8;
|
||||
private static final int ITEM_SIZE = 1 << 3;
|
||||
|
||||
private static final int PREFIX = 0;
|
||||
private static final int URI = 1;
|
||||
private static final int LOCAL_NAME = 2;
|
||||
private static final int QNAME = 3;
|
||||
private static final int TYPE = 4;
|
||||
private static final int VALUE = 5;
|
||||
|
||||
private int _attributeCount;
|
||||
|
||||
private String[] _strings;
|
||||
|
||||
public AttributesHolder() {
|
||||
_strings = new String[DEFAULT_CAPACITY * ITEM_SIZE];
|
||||
}
|
||||
|
||||
public final int getLength() {
|
||||
return _attributeCount;
|
||||
}
|
||||
|
||||
public final String getPrefix(int index) {
|
||||
return (index >= 0 && index < _attributeCount) ?
|
||||
_strings[(index << 3) + PREFIX] : null;
|
||||
}
|
||||
|
||||
public final String getLocalName(int index) {
|
||||
return (index >= 0 && index < _attributeCount) ?
|
||||
_strings[(index << 3) + LOCAL_NAME] : null;
|
||||
}
|
||||
|
||||
public final String getQName(int index) {
|
||||
return (index >= 0 && index < _attributeCount) ?
|
||||
_strings[(index << 3) + QNAME] : null;
|
||||
}
|
||||
|
||||
public final String getType(int index) {
|
||||
return (index >= 0 && index < _attributeCount) ?
|
||||
_strings[(index << 3) + TYPE] : null;
|
||||
}
|
||||
|
||||
public final String getURI(int index) {
|
||||
return (index >= 0 && index < _attributeCount) ?
|
||||
_strings[(index << 3) + URI] : null;
|
||||
}
|
||||
|
||||
public final String getValue(int index) {
|
||||
return (index >= 0 && index < _attributeCount) ?
|
||||
_strings[(index << 3) + VALUE] : null;
|
||||
}
|
||||
|
||||
public final int getIndex(String qName) {
|
||||
for (int i = 0; i < _attributeCount; i++) {
|
||||
if (qName.equals(_strings[(i << 3) + QNAME])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public final String getType(String qName) {
|
||||
final int i = (getIndex(qName) << 3) + TYPE;
|
||||
return (i >= 0) ? _strings[i] : null;
|
||||
}
|
||||
|
||||
public final String getValue(String qName) {
|
||||
final int i = (getIndex(qName) << 3) + VALUE;
|
||||
return (i >= 0) ? _strings[i] : null;
|
||||
}
|
||||
|
||||
public final int getIndex(String uri, String localName) {
|
||||
for (int i = 0; i < _attributeCount; i++) {
|
||||
if (localName.equals(_strings[(i << 3) + LOCAL_NAME]) &&
|
||||
uri.equals(_strings[(i << 3) + URI])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public final String getType(String uri, String localName) {
|
||||
final int i = (getIndex(uri, localName) << 3) + TYPE;
|
||||
return (i >= 0) ? _strings[i] : null;
|
||||
}
|
||||
|
||||
public final String getValue(String uri, String localName) {
|
||||
final int i = (getIndex(uri, localName) << 3) + VALUE;
|
||||
return (i >= 0) ? _strings[i] : null;
|
||||
}
|
||||
|
||||
public final void clear() {
|
||||
if (_attributeCount > 0) {
|
||||
for (int i = 0; i < _attributeCount; i++) {
|
||||
_strings[(i << 3) + VALUE] = null;
|
||||
}
|
||||
_attributeCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an attribute using a qualified name that contains the
|
||||
* prefix and local name.
|
||||
*
|
||||
* @param uri
|
||||
* This can be empty but not null, just like everywhere else in SAX.
|
||||
*/
|
||||
public final void addAttributeWithQName(String uri, String localName, String qName, String type, String value) {
|
||||
final int i = _attributeCount << 3;
|
||||
if (i == _strings.length) {
|
||||
resize(i);
|
||||
}
|
||||
|
||||
_strings[i + PREFIX] = null;
|
||||
_strings[i + URI] = uri;
|
||||
_strings[i + LOCAL_NAME] = localName;
|
||||
_strings[i + QNAME] = qName;
|
||||
_strings[i + TYPE] = type;
|
||||
_strings[i + VALUE] = value;
|
||||
|
||||
_attributeCount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an attribute using a prefix.
|
||||
*
|
||||
* @param prefix
|
||||
* This can be empty but not null, just like everywhere else in SAX.
|
||||
* @param uri
|
||||
* This can be empty but not null, just like everywhere else in SAX.
|
||||
*/
|
||||
public final void addAttributeWithPrefix(String prefix, String uri, String localName, String type, String value) {
|
||||
final int i = _attributeCount << 3;
|
||||
if (i == _strings.length) {
|
||||
resize(i);
|
||||
}
|
||||
|
||||
_strings[i + PREFIX] = prefix;
|
||||
_strings[i + URI] = uri;
|
||||
_strings[i + LOCAL_NAME] = localName;
|
||||
_strings[i + QNAME] = null;
|
||||
_strings[i + TYPE] = type;
|
||||
_strings[i + VALUE] = value;
|
||||
|
||||
_attributeCount++;
|
||||
}
|
||||
|
||||
private void resize(int length) {
|
||||
final int newLength = length * 2;
|
||||
final String[] strings = new String[newLength];
|
||||
System.arraycopy(_strings, 0, strings, 0, length);
|
||||
_strings = strings;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Simple utility ensuring that the value is cached only in case it is non-internal implementation
|
||||
*/
|
||||
abstract class ContextClassloaderLocal<V> {
|
||||
|
||||
private static final String FAILED_TO_CREATE_NEW_INSTANCE = "FAILED_TO_CREATE_NEW_INSTANCE";
|
||||
|
||||
private WeakHashMap<ClassLoader, V> CACHE = new WeakHashMap<ClassLoader, V>();
|
||||
|
||||
public V get() throws Error {
|
||||
ClassLoader tccl = getContextClassLoader();
|
||||
V instance = CACHE.get(tccl);
|
||||
if (instance == null) {
|
||||
instance = createNewInstance();
|
||||
CACHE.put(tccl, instance);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void set(V instance) {
|
||||
CACHE.put(getContextClassLoader(), instance);
|
||||
}
|
||||
|
||||
protected abstract V initialValue() throws Exception;
|
||||
|
||||
private V createNewInstance() {
|
||||
try {
|
||||
return initialValue();
|
||||
} catch (Exception e) {
|
||||
throw new Error(format(FAILED_TO_CREATE_NEW_INSTANCE, getClass().getName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String format(String property, Object... args) {
|
||||
String text = ResourceBundle.getBundle(ContextClassloaderLocal.class.getName()).getString(property);
|
||||
return MessageFormat.format(text, args);
|
||||
}
|
||||
|
||||
private static ClassLoader getContextClassLoader() {
|
||||
return (ClassLoader)
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
ClassLoader cl = null;
|
||||
try {
|
||||
cl = Thread.currentThread().getContextClassLoader();
|
||||
} catch (SecurityException ex) {
|
||||
}
|
||||
return cl;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
final class FragmentedArray<T> {
|
||||
private T _item;
|
||||
private FragmentedArray<T> _next;
|
||||
private FragmentedArray<T> _previous;
|
||||
|
||||
FragmentedArray(T item) {
|
||||
this(item, null);
|
||||
}
|
||||
|
||||
FragmentedArray(T item, FragmentedArray<T> previous) {
|
||||
setArray(item);
|
||||
if (previous != null) {
|
||||
previous._next = this;
|
||||
_previous = previous;
|
||||
}
|
||||
}
|
||||
|
||||
T getArray() {
|
||||
return _item;
|
||||
}
|
||||
|
||||
void setArray(T item) {
|
||||
assert(item.getClass().isArray());
|
||||
|
||||
_item = item;
|
||||
}
|
||||
|
||||
FragmentedArray<T> getNext() {
|
||||
return _next;
|
||||
}
|
||||
|
||||
void setNext(FragmentedArray<T> next) {
|
||||
_next = next;
|
||||
if (next != null) {
|
||||
next._previous = this;
|
||||
}
|
||||
}
|
||||
|
||||
FragmentedArray<T> getPrevious() {
|
||||
return _previous;
|
||||
}
|
||||
|
||||
void setPrevious(FragmentedArray<T> previous) {
|
||||
_previous = previous;
|
||||
if (previous != null) {
|
||||
previous._next = this;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.sax.Properties;
|
||||
import com.sun.xml.internal.stream.buffer.sax.SAXBufferCreator;
|
||||
import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferCreator;
|
||||
import com.sun.xml.internal.stream.buffer.stax.StreamWriterBufferCreator;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
*
|
||||
* A mutable stream-based buffer of an XML infoset.
|
||||
*
|
||||
* <p>
|
||||
* A MutableXMLStreamBuffer is created using specific SAX and StAX-based
|
||||
* creators. Utility methods on MutableXMLStreamBuffer are provided for
|
||||
* such functionality that utilize SAX and StAX-based creators.
|
||||
*
|
||||
* <p>
|
||||
* Once instantiated the same instance of a MutableXMLStreamBuffer may be reused for
|
||||
* creation to reduce the amount of Objects instantiated and garbage
|
||||
* collected that are required for internally representing an XML infoset.
|
||||
*
|
||||
* <p>
|
||||
* A MutableXMLStreamBuffer is not designed to be created and processed
|
||||
* concurrently. If done so unspecified behaviour may occur.
|
||||
*/
|
||||
public class MutableXMLStreamBuffer extends XMLStreamBuffer {
|
||||
/**
|
||||
* The default array size for the arrays used in internal representation
|
||||
* of the XML infoset.
|
||||
*/
|
||||
public static final int DEFAULT_ARRAY_SIZE = 512;
|
||||
|
||||
/**
|
||||
* Create a new MutableXMLStreamBuffer using the
|
||||
* {@link MutableXMLStreamBuffer#DEFAULT_ARRAY_SIZE}.
|
||||
*/
|
||||
public MutableXMLStreamBuffer() {
|
||||
this(DEFAULT_ARRAY_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the system identifier for this buffer.
|
||||
* @param systemId The system identifier.
|
||||
*/
|
||||
public void setSystemId(String systemId) {
|
||||
this.systemId = systemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new MutableXMLStreamBuffer.
|
||||
*
|
||||
* @param size
|
||||
* The size of the arrays used in the internal representation
|
||||
* of the XML infoset.
|
||||
* @throws NegativeArraySizeException
|
||||
* If the <code>size</code> argument is less than <code>0</code>.
|
||||
*/
|
||||
public MutableXMLStreamBuffer(int size) {
|
||||
_structure = new FragmentedArray<byte[]>(new byte[size]);
|
||||
_structureStrings = new FragmentedArray<String[]>(new String[size]);
|
||||
_contentCharactersBuffer = new FragmentedArray<char[]>(new char[4096]);
|
||||
_contentObjects = new FragmentedArray<Object[]>(new Object[size]);
|
||||
|
||||
// Set the first element of structure array to indicate an empty buffer
|
||||
// that has not been created
|
||||
_structure.getArray()[0] = (byte) AbstractCreatorProcessor.T_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create contents of a buffer from a XMLStreamReader.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is created by consuming the events on the XMLStreamReader using
|
||||
* an instance of {@link StreamReaderBufferCreator}.
|
||||
*
|
||||
* @param reader
|
||||
* A XMLStreamReader to read from to create.
|
||||
*/
|
||||
public void createFromXMLStreamReader(XMLStreamReader reader) throws XMLStreamException {
|
||||
reset();
|
||||
StreamReaderBufferCreator c = new StreamReaderBufferCreator(this);
|
||||
c.create(reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create contents of a buffer from a XMLStreamWriter.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is created by consuming events on a XMLStreamWriter using
|
||||
* an instance of {@link StreamWriterBufferCreator}.
|
||||
*/
|
||||
public XMLStreamWriter createFromXMLStreamWriter() {
|
||||
reset();
|
||||
return new StreamWriterBufferCreator(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create contents of a buffer from a {@link SAXBufferCreator}.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is created by consuming events from a {@link ContentHandler} using
|
||||
* an instance of {@link SAXBufferCreator}.
|
||||
*
|
||||
* @return The {@link SAXBufferCreator} to create from.
|
||||
*/
|
||||
public SAXBufferCreator createFromSAXBufferCreator() {
|
||||
reset();
|
||||
SAXBufferCreator c = new SAXBufferCreator();
|
||||
c.setBuffer(this);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create contents of a buffer from a {@link XMLReader} and {@link InputStream}.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is created by using an instance of {@link SAXBufferCreator}
|
||||
* and registering associated handlers on the {@link XMLReader}.
|
||||
*
|
||||
* @param reader
|
||||
* The {@link XMLReader} to use for parsing.
|
||||
* @param in
|
||||
* The {@link InputStream} to be parsed.
|
||||
*/
|
||||
public void createFromXMLReader(XMLReader reader, InputStream in) throws SAXException, IOException {
|
||||
createFromXMLReader(reader, in, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create contents of a buffer from a {@link XMLReader} and {@link InputStream}.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is reset (see {@link #reset}) before creation.
|
||||
*
|
||||
* <p>
|
||||
* The MutableXMLStreamBuffer is created by using an instance of {@link SAXBufferCreator}
|
||||
* and registering associated handlers on the {@link XMLReader}.
|
||||
*
|
||||
* @param reader
|
||||
* The {@link XMLReader} to use for parsing.
|
||||
* @param in
|
||||
* The {@link InputStream} to be parsed.
|
||||
* @param systemId
|
||||
* The system ID of the input stream.
|
||||
*/
|
||||
public void createFromXMLReader(XMLReader reader, InputStream in, String systemId) throws SAXException, IOException {
|
||||
reset();
|
||||
SAXBufferCreator c = new SAXBufferCreator(this);
|
||||
|
||||
reader.setContentHandler(c);
|
||||
reader.setDTDHandler(c);
|
||||
reader.setProperty(Properties.LEXICAL_HANDLER_PROPERTY, c);
|
||||
|
||||
c.create(reader, in, systemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the MutableXMLStreamBuffer.
|
||||
*
|
||||
* <p>
|
||||
* This method will reset the MutableXMLStreamBuffer to a state of being "uncreated"
|
||||
* similar to the state of a newly instantiated MutableXMLStreamBuffer.
|
||||
*
|
||||
* <p>
|
||||
* As many Objects as possible will be retained for reuse in future creation.
|
||||
*/
|
||||
public void reset() {
|
||||
// Reset the ptrs in arrays to 0
|
||||
_structurePtr =
|
||||
_structureStringsPtr =
|
||||
_contentCharactersBufferPtr =
|
||||
_contentObjectsPtr = 0;
|
||||
|
||||
// Set the first element of structure array to indicate an empty buffer
|
||||
// that has not been created
|
||||
_structure.getArray()[0] = (byte)AbstractCreatorProcessor.T_END;
|
||||
|
||||
// Clean up content objects
|
||||
_contentObjects.setNext(null);
|
||||
final Object[] o = _contentObjects.getArray();
|
||||
for (int i = 0; i < o.length; i++) {
|
||||
if (o[i] != null) {
|
||||
o[i] = null;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
treeCount = 0;
|
||||
|
||||
/*
|
||||
* TODO consider truncating the size of _structureStrings and
|
||||
* _contentCharactersBuffer to limit the memory used by the buffer
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
protected void setHasInternedStrings(boolean hasInternedStrings) {
|
||||
_hasInternedStrings = hasInternedStrings;
|
||||
}
|
||||
}
|
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2014, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.sax.SAXBufferProcessor;
|
||||
import com.sun.xml.internal.stream.buffer.stax.StreamReaderBufferProcessor;
|
||||
import com.sun.xml.internal.stream.buffer.stax.StreamWriterBufferProcessor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.dom.DOMResult;
|
||||
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.DTDHandler;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* An immutable stream-based buffer of an XML infoset.
|
||||
*
|
||||
* <p>
|
||||
* A XMLStreamBuffer is an abstract class. It is immutable with
|
||||
* respect to the methods on the class, which are non-modifying in terms
|
||||
* of state.
|
||||
*
|
||||
* <p>
|
||||
* A XMLStreamBuffer can be processed using specific SAX and StAX-based
|
||||
* processors. Utility methods on XMLStreamBuffer are provided for
|
||||
* such functionality that utilize SAX and StAX-based processors.
|
||||
* The same instance of a XMLStreamBuffer may be processed
|
||||
* multiple times and concurrently by more than one processor.
|
||||
*
|
||||
* <p>
|
||||
* There are two concrete implementations of XMLStreamBuffer.
|
||||
* The first, {@link MutableXMLStreamBuffer}, can be instantiated for the creation
|
||||
* of a buffer using SAX and StAX-based creators, and from which may be
|
||||
* processed as an XMLStreamBuffer. The second,
|
||||
* {@link XMLStreamBufferMark}, can be instantiated to mark into an existing
|
||||
* buffer that is being created or processed. This allows a subtree of
|
||||
* {@link XMLStreamBuffer} to be treated as its own {@link XMLStreamBuffer}.
|
||||
*
|
||||
* <p>
|
||||
* A XMLStreamBuffer can represent a complete XML infoset or a subtree
|
||||
* of an XML infoset. It is also capable of representing a "forest",
|
||||
* where the buffer represents multiple adjacent XML elements, although
|
||||
* in this mode there are restrictions about how you can consume such
|
||||
* forest, because not all XML APIs handle forests very well.
|
||||
*/
|
||||
public abstract class XMLStreamBuffer {
|
||||
|
||||
/**
|
||||
* In scope namespaces on a fragment
|
||||
*/
|
||||
protected Map<String,String> _inscopeNamespaces = Collections.emptyMap();
|
||||
|
||||
/**
|
||||
* True if the buffer was created from a parser that interns Strings
|
||||
* as specified by the SAX interning features
|
||||
*/
|
||||
protected boolean _hasInternedStrings;
|
||||
|
||||
/**
|
||||
* Fragmented array to hold structural information
|
||||
*/
|
||||
protected FragmentedArray<byte[]> _structure;
|
||||
protected int _structurePtr;
|
||||
|
||||
/**
|
||||
* Fragmented array to hold structural information as strings
|
||||
*/
|
||||
protected FragmentedArray<String[]> _structureStrings;
|
||||
protected int _structureStringsPtr;
|
||||
|
||||
/**
|
||||
* Fragmented array to hold content information in a shared char[]
|
||||
*/
|
||||
protected FragmentedArray<char[]> _contentCharactersBuffer;
|
||||
protected int _contentCharactersBufferPtr;
|
||||
|
||||
/**
|
||||
* Fragmented array to hold content information as objects
|
||||
*/
|
||||
protected FragmentedArray<Object[]> _contentObjects;
|
||||
protected int _contentObjectsPtr;
|
||||
|
||||
/**
|
||||
* Number of trees in this stream buffer.
|
||||
*
|
||||
* <p>
|
||||
* 1 if there's only one, which is the normal case. When the buffer
|
||||
* holds a forest, this value is greater than 1. If the buffer is empty, then 0.
|
||||
*
|
||||
* <p>
|
||||
* Notice that we cannot infer this value by looking at the {@link FragmentedArray}s,
|
||||
* because this {@link XMLStreamBuffer} maybe a view of a portion of another bigger
|
||||
* {@link XMLStreamBuffer}.
|
||||
*/
|
||||
protected int treeCount;
|
||||
|
||||
/**
|
||||
* The system identifier associated with the buffer
|
||||
*/
|
||||
protected String systemId;
|
||||
|
||||
/**
|
||||
* Is the buffer created by creator.
|
||||
*
|
||||
* @return
|
||||
* <code>true</code> if the buffer has been created.
|
||||
*/
|
||||
public final boolean isCreated() {
|
||||
return _structure.getArray()[0] != AbstractCreatorProcessor.T_END;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the buffer a representation of a fragment of an XML infoset.
|
||||
*
|
||||
* @return
|
||||
* <code>true</code> if the buffer is a representation of a fragment
|
||||
* of an XML infoset.
|
||||
*/
|
||||
public final boolean isFragment() {
|
||||
return (isCreated() && (_structure.getArray()[_structurePtr] & AbstractCreatorProcessor.TYPE_MASK)
|
||||
!= AbstractCreatorProcessor.T_DOCUMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the buffer a representation of a fragment of an XML infoset
|
||||
* that is an element (and its contents).
|
||||
*
|
||||
* @return
|
||||
* <code>true</code> if the buffer a representation
|
||||
* of a fragment of an XML infoset that is an element (and its contents).
|
||||
*/
|
||||
public final boolean isElementFragment() {
|
||||
return (isCreated() && (_structure.getArray()[_structurePtr] & AbstractCreatorProcessor.TYPE_MASK)
|
||||
== AbstractCreatorProcessor.T_ELEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ture if this buffer represents a forest, which is
|
||||
* are more than one adjacent XML elements.
|
||||
*/
|
||||
public final boolean isForest() {
|
||||
return isCreated() && treeCount>1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system identifier associated with the buffer.
|
||||
* @return The system identifier.
|
||||
*/
|
||||
public final String getSystemId() {
|
||||
return systemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the in-scope namespaces.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* The in-scope namespaces will be empty if the buffer is not a
|
||||
* fragment ({@link #isFragment} returns <code>false</code>).
|
||||
*
|
||||
* The in-scope namespace will correspond to the in-scope namespaces of the
|
||||
* fragment if the buffer is a fragment ({@link #isFragment}
|
||||
* returns <code>false</code>). The in-scope namespaces will include any
|
||||
* namespace delcarations on an element if the fragment correspond to that
|
||||
* of an element ({@link #isElementFragment} returns <code>false</code>).
|
||||
*
|
||||
* @return
|
||||
* The in-scope namespaces of the XMLStreamBuffer.
|
||||
* Prefix to namespace URI.
|
||||
*/
|
||||
public final Map<String,String> getInscopeNamespaces() {
|
||||
return _inscopeNamespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the buffer been created using Strings that have been interned
|
||||
* for certain properties of information items. The Strings that are interned
|
||||
* are those that correspond to Strings that are specified by the SAX API
|
||||
* "string-interning" property
|
||||
* (see <a href="http://java.sun.com/j2se/1.5.0/docs/api/org/xml/sax/package-summary.html#package_description">here</a>).
|
||||
*
|
||||
* <p>
|
||||
* An buffer may have been created, for example, from an XML document parsed
|
||||
* using the Xerces SAX parser. The Xerces SAX parser will have interned certain Strings
|
||||
* according to the SAX string interning property.
|
||||
* This method enables processors to avoid the duplication of
|
||||
* String interning if such a feature is required by a procesing application and the
|
||||
* buffer being processed was created using Strings that have been interned.
|
||||
*
|
||||
* @return
|
||||
* <code>true</code> if the buffer has been created using Strings that
|
||||
* have been interned.
|
||||
*/
|
||||
public final boolean hasInternedStrings() {
|
||||
return _hasInternedStrings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the contents of the buffer as a {@link XMLStreamReader}.
|
||||
*
|
||||
* @return
|
||||
* A an instance of a {@link StreamReaderBufferProcessor}. Always non-null.
|
||||
*/
|
||||
public final StreamReaderBufferProcessor readAsXMLStreamReader() throws XMLStreamException {
|
||||
return new StreamReaderBufferProcessor(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents of the buffer to an XMLStreamWriter.
|
||||
*
|
||||
* <p>
|
||||
* The XMLStreamBuffer will be written out to the XMLStreamWriter using
|
||||
* an instance of {@link StreamWriterBufferProcessor}.
|
||||
*
|
||||
* @param writer
|
||||
* A XMLStreamWriter to write to.
|
||||
* @param writeAsFragment
|
||||
* If true, {@link XMLStreamWriter} will not receive {@link XMLStreamWriter#writeStartDocument()}
|
||||
* nor {@link XMLStreamWriter#writeEndDocument()}. This is desirable behavior when
|
||||
* you are writing the contents of a buffer into a bigger document.
|
||||
*/
|
||||
public final void writeToXMLStreamWriter(XMLStreamWriter writer, boolean writeAsFragment) throws XMLStreamException {
|
||||
StreamWriterBufferProcessor p = new StreamWriterBufferProcessor(this,writeAsFragment);
|
||||
p.process(writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #writeToXMLStreamWriter(XMLStreamWriter, boolean)}
|
||||
*/
|
||||
public final void writeToXMLStreamWriter(XMLStreamWriter writer) throws XMLStreamException {
|
||||
writeToXMLStreamWriter(writer, this.isFragment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of the buffer from a {@link XMLReader}.
|
||||
*
|
||||
* @return
|
||||
* A an instance of a {@link SAXBufferProcessor}.
|
||||
* @deprecated
|
||||
* Use {@link #readAsXMLReader(boolean)}
|
||||
*/
|
||||
public final SAXBufferProcessor readAsXMLReader() {
|
||||
return new SAXBufferProcessor(this,isFragment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the contents of the buffer from a {@link XMLReader}.
|
||||
*
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
* @return
|
||||
* A an instance of a {@link SAXBufferProcessor}.
|
||||
*/
|
||||
public final SAXBufferProcessor readAsXMLReader(boolean produceFragmentEvent) {
|
||||
return new SAXBufferProcessor(this,produceFragmentEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents of the buffer to a {@link ContentHandler}.
|
||||
*
|
||||
* <p>
|
||||
* If the <code>handler</code> is also an instance of other SAX-based
|
||||
* handlers, such as {@link LexicalHandler}, than corresponding SAX events
|
||||
* will be reported to those handlers.
|
||||
*
|
||||
* @param handler
|
||||
* The ContentHandler to receive SAX events.
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
*
|
||||
* @throws SAXException
|
||||
* if a parsing fails, or if {@link ContentHandler} throws a {@link SAXException}.
|
||||
*/
|
||||
public final void writeTo(ContentHandler handler, boolean produceFragmentEvent) throws SAXException {
|
||||
SAXBufferProcessor p = readAsXMLReader(produceFragmentEvent);
|
||||
p.setContentHandler(handler);
|
||||
if (p instanceof LexicalHandler) {
|
||||
p.setLexicalHandler((LexicalHandler)handler);
|
||||
}
|
||||
if (p instanceof DTDHandler) {
|
||||
p.setDTDHandler((DTDHandler)handler);
|
||||
}
|
||||
if (p instanceof ErrorHandler) {
|
||||
p.setErrorHandler((ErrorHandler)handler);
|
||||
}
|
||||
p.process();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #writeTo(ContentHandler,boolean)}
|
||||
*/
|
||||
public final void writeTo(ContentHandler handler) throws SAXException {
|
||||
writeTo(handler,isFragment());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the contents of the buffer to a {@link ContentHandler} with errors
|
||||
* report to a {@link ErrorHandler}.
|
||||
*
|
||||
* <p>
|
||||
* If the <code>handler</code> is also an instance of other SAX-based
|
||||
* handlers, such as {@link LexicalHandler}, than corresponding SAX events
|
||||
* will be reported to those handlers.
|
||||
*
|
||||
* @param handler
|
||||
* The ContentHandler to receive SAX events.
|
||||
* @param errorHandler
|
||||
* The ErrorHandler to receive error events.
|
||||
*
|
||||
* @throws SAXException
|
||||
* if a parsing fails and {@link ErrorHandler} throws a {@link SAXException},
|
||||
* or if {@link ContentHandler} throws a {@link SAXException}.
|
||||
*/
|
||||
public final void writeTo(ContentHandler handler, ErrorHandler errorHandler, boolean produceFragmentEvent) throws SAXException {
|
||||
SAXBufferProcessor p = readAsXMLReader(produceFragmentEvent);
|
||||
p.setContentHandler(handler);
|
||||
if (p instanceof LexicalHandler) {
|
||||
p.setLexicalHandler((LexicalHandler)handler);
|
||||
}
|
||||
if (p instanceof DTDHandler) {
|
||||
p.setDTDHandler((DTDHandler)handler);
|
||||
}
|
||||
|
||||
p.setErrorHandler(errorHandler);
|
||||
|
||||
p.process();
|
||||
}
|
||||
|
||||
public final void writeTo(ContentHandler handler, ErrorHandler errorHandler) throws SAXException {
|
||||
writeTo(handler, errorHandler, isFragment());
|
||||
}
|
||||
|
||||
private static final ContextClassloaderLocal<TransformerFactory> trnsformerFactory = new ContextClassloaderLocal<TransformerFactory>() {
|
||||
@Override
|
||||
protected TransformerFactory initialValue() throws Exception {
|
||||
return TransformerFactory.newInstance();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes out the contents of this buffer as DOM node and append that to the given node.
|
||||
*
|
||||
* Faster implementation would be desirable.
|
||||
*
|
||||
* @return
|
||||
* The newly added child node.
|
||||
*/
|
||||
public final Node writeTo(Node n) throws XMLStreamBufferException {
|
||||
try {
|
||||
Transformer t = trnsformerFactory.get().newTransformer();
|
||||
t.transform(new XMLStreamBufferSource(this), new DOMResult(n));
|
||||
return n.getLastChild();
|
||||
} catch (TransformerException e) {
|
||||
throw new XMLStreamBufferException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new buffer from a XMLStreamReader.
|
||||
*
|
||||
* @param reader
|
||||
* A XMLStreamReader to read from to create.
|
||||
* @return XMLStreamBuffer the created buffer
|
||||
* @see MutableXMLStreamBuffer#createFromXMLStreamReader(XMLStreamReader)
|
||||
*/
|
||||
public static XMLStreamBuffer createNewBufferFromXMLStreamReader(XMLStreamReader reader)
|
||||
throws XMLStreamException {
|
||||
MutableXMLStreamBuffer b = new MutableXMLStreamBuffer();
|
||||
b.createFromXMLStreamReader(reader);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new buffer from a {@link XMLReader} and {@link InputStream}.
|
||||
*
|
||||
* @param reader
|
||||
* The {@link XMLReader} to use for parsing.
|
||||
* @param in
|
||||
* The {@link InputStream} to be parsed.
|
||||
* @return XMLStreamBuffer the created buffer
|
||||
* @see MutableXMLStreamBuffer#createFromXMLReader(XMLReader, InputStream)
|
||||
*/
|
||||
public static XMLStreamBuffer createNewBufferFromXMLReader(XMLReader reader, InputStream in) throws SAXException, IOException {
|
||||
MutableXMLStreamBuffer b = new MutableXMLStreamBuffer();
|
||||
b.createFromXMLReader(reader, in);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new buffer from a {@link XMLReader} and {@link InputStream}.
|
||||
*
|
||||
* @param reader
|
||||
* The {@link XMLReader} to use for parsing.
|
||||
* @param in
|
||||
* The {@link InputStream} to be parsed.
|
||||
* @param systemId
|
||||
* The system ID of the input stream.
|
||||
* @return XMLStreamBuffer the created buffer
|
||||
* @see MutableXMLStreamBuffer#createFromXMLReader(XMLReader, InputStream, String)
|
||||
*/
|
||||
public static XMLStreamBuffer createNewBufferFromXMLReader(XMLReader reader, InputStream in,
|
||||
String systemId) throws SAXException, IOException {
|
||||
MutableXMLStreamBuffer b = new MutableXMLStreamBuffer();
|
||||
b.createFromXMLReader(reader, in, systemId);
|
||||
return b;
|
||||
}
|
||||
|
||||
protected final FragmentedArray<byte[]> getStructure() {
|
||||
return _structure;
|
||||
}
|
||||
|
||||
protected final int getStructurePtr() {
|
||||
return _structurePtr;
|
||||
}
|
||||
|
||||
protected final FragmentedArray<String[]> getStructureStrings() {
|
||||
return _structureStrings;
|
||||
}
|
||||
|
||||
protected final int getStructureStringsPtr() {
|
||||
return _structureStringsPtr;
|
||||
}
|
||||
|
||||
protected final FragmentedArray<char[]> getContentCharactersBuffer() {
|
||||
return _contentCharactersBuffer;
|
||||
}
|
||||
|
||||
protected final int getContentCharactersBufferPtr() {
|
||||
return _contentCharactersBufferPtr;
|
||||
}
|
||||
|
||||
protected final FragmentedArray<Object[]> getContentObjects() {
|
||||
return _contentObjects;
|
||||
}
|
||||
|
||||
protected final int getContentObjectsPtr() {
|
||||
return _contentObjectsPtr;
|
||||
}
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
public class XMLStreamBufferException extends Exception {
|
||||
|
||||
public XMLStreamBufferException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public XMLStreamBufferException(String message, Exception e) {
|
||||
super(message, e);
|
||||
}
|
||||
|
||||
public XMLStreamBufferException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A mark into a buffer.
|
||||
*
|
||||
* <p>
|
||||
* A mark can be processed in the same manner as a XMLStreamBuffer.
|
||||
*
|
||||
* <p>
|
||||
* A mark will share a sub set of information of the buffer that is
|
||||
* marked. If the buffer is directly or indirectly associated with a
|
||||
* (mutable) {@link XMLStreamBuffer} which is reset and/or re-created
|
||||
* then this will invalidate the mark and processing behvaiour of the mark
|
||||
* is undefined. It is the responsibility of the application to manage the
|
||||
* relationship between the marked XMLStreamBuffer and one or more marks.
|
||||
*/
|
||||
public class XMLStreamBufferMark extends XMLStreamBuffer {
|
||||
|
||||
/**
|
||||
* Create a mark from the buffer that is being created.
|
||||
*
|
||||
* <p>
|
||||
* A mark will be created from the current position of creation of the
|
||||
* {@link XMLStreamBuffer} that is being created by a {@link AbstractCreator}.
|
||||
*
|
||||
* @param inscopeNamespaces
|
||||
* The in-scope namespaces on the fragment of XML infoset that is
|
||||
* to be marked.
|
||||
*
|
||||
* @param src
|
||||
* The {@link AbstractCreator} or {@link AbstractProcessor} from which the current
|
||||
* position of creation of the XMLStreamBuffer will be taken as the mark.
|
||||
*/
|
||||
public XMLStreamBufferMark(Map<String,String> inscopeNamespaces, AbstractCreatorProcessor src) {
|
||||
if(inscopeNamespaces != null) {
|
||||
_inscopeNamespaces = inscopeNamespaces;
|
||||
}
|
||||
|
||||
_structure = src._currentStructureFragment;
|
||||
_structurePtr = src._structurePtr;
|
||||
|
||||
_structureStrings = src._currentStructureStringFragment;
|
||||
_structureStringsPtr = src._structureStringsPtr;
|
||||
|
||||
_contentCharactersBuffer = src._currentContentCharactersBufferFragment;
|
||||
_contentCharactersBufferPtr = src._contentCharactersBufferPtr;
|
||||
|
||||
_contentObjects = src._currentContentObjectFragment;
|
||||
_contentObjectsPtr = src._contentObjectsPtr;
|
||||
treeCount = 1; // TODO: define a way to create a mark over a forest
|
||||
}
|
||||
}
|
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.sax.SAXBufferCreator;
|
||||
import javax.xml.transform.sax.SAXResult;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
/**
|
||||
* A JAXP Result implementation that supports the serialization to an
|
||||
* {@link MutableXMLStreamBuffer} for use by applications that expect a Result.
|
||||
*
|
||||
* <p>
|
||||
* Reuse of a XMLStreamBufferResult more than once will require that the
|
||||
* MutableXMLStreamBuffer is reset by called
|
||||
* {@link #.getXMLStreamBuffer()}.reset(), or by calling
|
||||
* {@link #.setXMLStreamBuffer()} with a new instance of
|
||||
* {@link MutableXMLStreamBuffer}.
|
||||
*
|
||||
* <p>
|
||||
* The derivation of XMLStreamBufferResult from SAXResult is an implementation
|
||||
* detail.
|
||||
*
|
||||
* <p>General applications shall not call the following methods:
|
||||
* <ul>
|
||||
* <li>setHandler</li>
|
||||
* <li>setLexicalHandler</li>
|
||||
* <li>setSystemId</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class XMLStreamBufferResult extends SAXResult {
|
||||
protected MutableXMLStreamBuffer _buffer;
|
||||
protected SAXBufferCreator _bufferCreator;
|
||||
|
||||
/**
|
||||
* The default XMLStreamBufferResult constructor.
|
||||
*
|
||||
* <p>
|
||||
* A {@link MutableXMLStreamBuffer} is instantiated and used.
|
||||
*/
|
||||
public XMLStreamBufferResult() {
|
||||
setXMLStreamBuffer(new MutableXMLStreamBuffer());
|
||||
}
|
||||
|
||||
/**
|
||||
* XMLStreamBufferResult constructor.
|
||||
*
|
||||
* @param buffer the {@link MutableXMLStreamBuffer} to use.
|
||||
*/
|
||||
public XMLStreamBufferResult(MutableXMLStreamBuffer buffer) {
|
||||
setXMLStreamBuffer(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link MutableXMLStreamBuffer} that is used.
|
||||
*
|
||||
* @return the {@link MutableXMLStreamBuffer}.
|
||||
*/
|
||||
public MutableXMLStreamBuffer getXMLStreamBuffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link MutableXMLStreamBuffer} to use.
|
||||
*
|
||||
* @param buffer the {@link MutableXMLStreamBuffer}.
|
||||
*/
|
||||
public void setXMLStreamBuffer(MutableXMLStreamBuffer buffer) {
|
||||
if (buffer == null) {
|
||||
throw new NullPointerException("buffer cannot be null");
|
||||
}
|
||||
_buffer = buffer;
|
||||
setSystemId(_buffer.getSystemId());
|
||||
|
||||
if (_bufferCreator != null) {
|
||||
_bufferCreator.setXMLStreamBuffer(_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
public ContentHandler getHandler() {
|
||||
if (_bufferCreator == null) {
|
||||
_bufferCreator = new SAXBufferCreator(_buffer);
|
||||
setHandler(_bufferCreator);
|
||||
} else if (super.getHandler() == null) {
|
||||
setHandler(_bufferCreator);
|
||||
}
|
||||
|
||||
return _bufferCreator;
|
||||
}
|
||||
|
||||
public LexicalHandler getLexicalHandler() {
|
||||
return (LexicalHandler) getHandler();
|
||||
}
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.sax.SAXBufferProcessor;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import javax.xml.transform.sax.SAXSource;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
/**
|
||||
* A JAXP Source implementation that supports the parsing
|
||||
* of {@link XMLStreamBuffer} for use by applications that expect a Source.
|
||||
*
|
||||
* <p>
|
||||
* The derivation of XMLStreamBufferSource from SAXSource is an implementation
|
||||
* detail.
|
||||
*
|
||||
* <p>Applications shall obey the following restrictions:
|
||||
* <ul>
|
||||
* <li>The setXMLReader and setInputSource shall not be called.</li>
|
||||
* <li>The XMLReader object obtained by the getXMLReader method shall
|
||||
* be used only for parsing the InputSource object returned by
|
||||
* the getInputSource method.</li>
|
||||
* <li>The InputSource object obtained by the getInputSource method shall
|
||||
* be used only for being parsed by the XMLReader object returned by
|
||||
* the getXMLReader method.</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class XMLStreamBufferSource extends SAXSource {
|
||||
protected XMLStreamBuffer _buffer;
|
||||
protected SAXBufferProcessor _bufferProcessor;
|
||||
|
||||
/**
|
||||
* XMLStreamBufferSource constructor.
|
||||
*
|
||||
* @param buffer the {@link XMLStreamBuffer} to use.
|
||||
*/
|
||||
public XMLStreamBufferSource(XMLStreamBuffer buffer) {
|
||||
super(new InputSource(
|
||||
new ByteArrayInputStream(new byte[0])));
|
||||
setXMLStreamBuffer(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link XMLStreamBuffer} that is used.
|
||||
*
|
||||
* @return the {@link XMLStreamBuffer}.
|
||||
*/
|
||||
public XMLStreamBuffer getXMLStreamBuffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link XMLStreamBuffer} to use.
|
||||
*
|
||||
* @param buffer the {@link XMLStreamBuffer}.
|
||||
*/
|
||||
public void setXMLStreamBuffer(XMLStreamBuffer buffer) {
|
||||
if (buffer == null) {
|
||||
throw new NullPointerException("buffer cannot be null");
|
||||
}
|
||||
_buffer = buffer;
|
||||
|
||||
if (_bufferProcessor != null) {
|
||||
_bufferProcessor.setBuffer(_buffer,false);
|
||||
}
|
||||
}
|
||||
|
||||
public XMLReader getXMLReader() {
|
||||
if (_bufferProcessor == null) {
|
||||
_bufferProcessor = new SAXBufferProcessor(_buffer,false);
|
||||
setXMLReader(_bufferProcessor);
|
||||
} else if (super.getXMLReader() == null) {
|
||||
setXMLReader(_bufferProcessor);
|
||||
}
|
||||
|
||||
return _bufferProcessor;
|
||||
}
|
||||
}
|
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.sax;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
public class DefaultWithLexicalHandler extends DefaultHandler implements LexicalHandler {
|
||||
|
||||
public void comment(char[] ch, int start, int length) throws SAXException { }
|
||||
|
||||
public void startDTD(String name, String publicId, String systemId) throws SAXException { }
|
||||
|
||||
public void endDTD() throws SAXException { }
|
||||
|
||||
public void startEntity(String name) throws SAXException { }
|
||||
|
||||
public void endEntity(String name) throws SAXException { }
|
||||
|
||||
public void startCDATA() throws SAXException { }
|
||||
|
||||
public void endCDATA() throws SAXException { }
|
||||
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.sax;
|
||||
|
||||
public class Features {
|
||||
public static final String NAMESPACES_FEATURE =
|
||||
"http://xml.org/sax/features/namespaces";
|
||||
public static final String NAMESPACE_PREFIXES_FEATURE =
|
||||
"http://xml.org/sax/features/namespace-prefixes";
|
||||
public static final String EXTERNAL_GENERAL_ENTITIES =
|
||||
"http://xml.org/sax/features/external-general-entities";
|
||||
public static final String EXTERNAL_PARAMETER_ENTITIES =
|
||||
"http://xml.org/sax/features/external-parameter-entities";
|
||||
public static final String STRING_INTERNING_FEATURE =
|
||||
"http://xml.org/sax/features/string-interning";
|
||||
}
|
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.sax;
|
||||
|
||||
public class Properties {
|
||||
public static final String LEXICAL_HANDLER_PROPERTY =
|
||||
"http://xml.org/sax/properties/lexical-handler";
|
||||
}
|
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.sax;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.AbstractCreator;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.DTDHandler;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.Locator;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
|
||||
/**
|
||||
* Writes into {@link MutableXMLStreamBuffer} from SAX.
|
||||
*
|
||||
* TODO
|
||||
* Implement the marking the stream on the element when an ID
|
||||
* attribute on the element is defined
|
||||
*/
|
||||
public class SAXBufferCreator extends AbstractCreator
|
||||
implements EntityResolver, DTDHandler, ContentHandler, ErrorHandler, LexicalHandler {
|
||||
protected String[] _namespaceAttributes;
|
||||
|
||||
protected int _namespaceAttributesPtr;
|
||||
|
||||
private int depth = 0;
|
||||
|
||||
public SAXBufferCreator() {
|
||||
_namespaceAttributes = new String[16 * 2];
|
||||
}
|
||||
|
||||
public SAXBufferCreator(MutableXMLStreamBuffer buffer) {
|
||||
this();
|
||||
setBuffer(buffer);
|
||||
}
|
||||
|
||||
public MutableXMLStreamBuffer create(XMLReader reader, InputStream in) throws IOException, SAXException {
|
||||
return create(reader, in, null);
|
||||
}
|
||||
|
||||
public MutableXMLStreamBuffer create(XMLReader reader, InputStream in, String systemId) throws IOException, SAXException {
|
||||
if (_buffer == null) {
|
||||
createBuffer();
|
||||
}
|
||||
_buffer.setSystemId(systemId);
|
||||
reader.setContentHandler(this);
|
||||
reader.setProperty(Properties.LEXICAL_HANDLER_PROPERTY, this);
|
||||
|
||||
try {
|
||||
setHasInternedStrings(reader.getFeature(Features.STRING_INTERNING_FEATURE));
|
||||
} catch (SAXException e) {
|
||||
}
|
||||
|
||||
|
||||
if (systemId != null) {
|
||||
InputSource s = new InputSource(systemId);
|
||||
s.setByteStream(in);
|
||||
reader.parse(s);
|
||||
} else {
|
||||
reader.parse(new InputSource(in));
|
||||
}
|
||||
|
||||
return getXMLStreamBuffer();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
_buffer = null;
|
||||
_namespaceAttributesPtr = 0;
|
||||
depth=0;
|
||||
}
|
||||
|
||||
public void startDocument() throws SAXException {
|
||||
storeStructure(T_DOCUMENT);
|
||||
}
|
||||
|
||||
public void endDocument() throws SAXException {
|
||||
storeStructure(T_END);
|
||||
}
|
||||
|
||||
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||
cacheNamespaceAttribute(prefix, uri);
|
||||
}
|
||||
|
||||
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||
storeQualifiedName(T_ELEMENT_LN,
|
||||
uri, localName, qName);
|
||||
|
||||
// Has namespaces attributes
|
||||
if (_namespaceAttributesPtr > 0) {
|
||||
storeNamespaceAttributes();
|
||||
}
|
||||
|
||||
// Has attributes
|
||||
if (attributes.getLength() > 0) {
|
||||
storeAttributes(attributes);
|
||||
}
|
||||
depth++;
|
||||
}
|
||||
|
||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||
storeStructure(T_END);
|
||||
if(--depth==0)
|
||||
increaseTreeCount(); // one tree processed
|
||||
}
|
||||
|
||||
public void characters(char ch[], int start, int length) throws SAXException {
|
||||
storeContentCharacters(T_TEXT_AS_CHAR_ARRAY, ch, start, length);
|
||||
}
|
||||
|
||||
public void ignorableWhitespace(char ch[], int start, int length) throws SAXException {
|
||||
characters(ch, start, length);
|
||||
}
|
||||
|
||||
public void processingInstruction(String target, String data) throws SAXException {
|
||||
storeStructure(T_PROCESSING_INSTRUCTION);
|
||||
storeStructureString(target);
|
||||
storeStructureString(data);
|
||||
}
|
||||
|
||||
public void comment(char[] ch, int start, int length) throws SAXException {
|
||||
storeContentCharacters(T_COMMENT_AS_CHAR_ARRAY, ch, start, length);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
private void cacheNamespaceAttribute(String prefix, String uri) {
|
||||
_namespaceAttributes[_namespaceAttributesPtr++] = prefix;
|
||||
_namespaceAttributes[_namespaceAttributesPtr++] = uri;
|
||||
|
||||
if (_namespaceAttributesPtr == _namespaceAttributes.length) {
|
||||
final String[] namespaceAttributes = new String[_namespaceAttributesPtr * 2];
|
||||
System.arraycopy(_namespaceAttributes, 0, namespaceAttributes, 0, _namespaceAttributesPtr);
|
||||
_namespaceAttributes = namespaceAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
private void storeNamespaceAttributes() {
|
||||
for (int i = 0; i < _namespaceAttributesPtr; i += 2) {
|
||||
int item = T_NAMESPACE_ATTRIBUTE;
|
||||
if (_namespaceAttributes[i].length() > 0) {
|
||||
item |= FLAG_PREFIX;
|
||||
storeStructureString(_namespaceAttributes[i]);
|
||||
}
|
||||
if (_namespaceAttributes[i + 1].length() > 0) {
|
||||
item |= FLAG_URI;
|
||||
storeStructureString(_namespaceAttributes[i + 1]);
|
||||
}
|
||||
storeStructure(item);
|
||||
}
|
||||
_namespaceAttributesPtr = 0;
|
||||
}
|
||||
|
||||
private void storeAttributes(Attributes attributes) {
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
// Skip NS attributes. Some versions of JDK seem to send wrong local name
|
||||
// Also it is not stored correctly by the following.
|
||||
if (attributes.getQName(i).startsWith("xmlns"))
|
||||
continue;
|
||||
storeQualifiedName(T_ATTRIBUTE_LN,
|
||||
attributes.getURI(i),
|
||||
attributes.getLocalName(i),
|
||||
attributes.getQName(i));
|
||||
|
||||
storeStructureString(attributes.getType(i));
|
||||
storeContentString(attributes.getValue(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void storeQualifiedName(int item, String uri, String localName, String qName) {
|
||||
if (uri.length() > 0) {
|
||||
item |= FLAG_URI;
|
||||
storeStructureString(uri);
|
||||
}
|
||||
|
||||
storeStructureString(localName);
|
||||
|
||||
if (qName.indexOf(':') >= 0) {
|
||||
item |= FLAG_QUALIFIED_NAME;
|
||||
storeStructureString(qName);
|
||||
}
|
||||
|
||||
storeStructure(item);
|
||||
}
|
||||
|
||||
|
||||
// Empty methods for SAX handlers
|
||||
|
||||
// Entity resolver handler
|
||||
|
||||
public InputSource resolveEntity (String publicId, String systemId)
|
||||
throws IOException, SAXException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// DTD handler
|
||||
|
||||
public void notationDecl (String name, String publicId, String systemId)
|
||||
throws SAXException
|
||||
{ }
|
||||
|
||||
public void unparsedEntityDecl (String name, String publicId,
|
||||
String systemId, String notationName)
|
||||
throws SAXException
|
||||
{ }
|
||||
|
||||
// Content handler
|
||||
|
||||
public void setDocumentLocator (Locator locator) { }
|
||||
|
||||
public void endPrefixMapping (String prefix) throws SAXException { }
|
||||
|
||||
public void skippedEntity (String name) throws SAXException { }
|
||||
|
||||
// Lexical handler
|
||||
|
||||
public void startDTD(String name, String publicId, String systemId) throws SAXException { }
|
||||
|
||||
public void endDTD() throws SAXException { }
|
||||
|
||||
public void startEntity(String name) throws SAXException { }
|
||||
|
||||
public void endEntity(String name) throws SAXException { }
|
||||
|
||||
public void startCDATA() throws SAXException { }
|
||||
|
||||
public void endCDATA() throws SAXException { }
|
||||
|
||||
// Error handler
|
||||
|
||||
public void warning(SAXParseException e) throws SAXException { }
|
||||
|
||||
public void error(SAXParseException e) throws SAXException { }
|
||||
|
||||
public void fatalError(SAXParseException e) throws SAXException
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
}
|
@@ -0,0 +1,727 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.sax;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.AbstractProcessor;
|
||||
import com.sun.xml.internal.stream.buffer.AttributesHolder;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.DTDHandler;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.ErrorHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXNotRecognizedException;
|
||||
import org.xml.sax.SAXNotSupportedException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.ext.LexicalHandler;
|
||||
import org.xml.sax.helpers.LocatorImpl;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A processor of a {@link XMLStreamBuffer} that that reads the XML infoset as
|
||||
* {@link XMLReader}.
|
||||
*/
|
||||
public class SAXBufferProcessor extends AbstractProcessor implements XMLReader {
|
||||
/**
|
||||
* Reference to entity resolver.
|
||||
*/
|
||||
protected EntityResolver _entityResolver = DEFAULT_LEXICAL_HANDLER;
|
||||
|
||||
/**
|
||||
* Reference to dtd handler.
|
||||
*/
|
||||
protected DTDHandler _dtdHandler = DEFAULT_LEXICAL_HANDLER;
|
||||
|
||||
/**
|
||||
* Reference to content handler.
|
||||
*/
|
||||
protected ContentHandler _contentHandler = DEFAULT_LEXICAL_HANDLER;
|
||||
|
||||
/**
|
||||
* Reference to error handler.
|
||||
*/
|
||||
protected ErrorHandler _errorHandler = DEFAULT_LEXICAL_HANDLER;
|
||||
|
||||
/**
|
||||
* Reference to lexical handler.
|
||||
*/
|
||||
protected LexicalHandler _lexicalHandler = DEFAULT_LEXICAL_HANDLER;
|
||||
|
||||
/**
|
||||
* SAX Namespace attributes features
|
||||
*/
|
||||
protected boolean _namespacePrefixesFeature = false;
|
||||
|
||||
protected AttributesHolder _attributes = new AttributesHolder();
|
||||
|
||||
protected String[] _namespacePrefixes = new String[16];
|
||||
protected int _namespacePrefixesIndex;
|
||||
|
||||
protected int[] _namespaceAttributesStartingStack = new int[16];
|
||||
protected int[] _namespaceAttributesStack = new int[16];
|
||||
protected int _namespaceAttributesStackIndex;
|
||||
|
||||
public SAXBufferProcessor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #SAXBufferProcessor(XMLStreamBuffer, boolean)}
|
||||
*/
|
||||
public SAXBufferProcessor(XMLStreamBuffer buffer) {
|
||||
setXMLStreamBuffer(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
*/
|
||||
public SAXBufferProcessor(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
|
||||
setXMLStreamBuffer(buffer,produceFragmentEvent);
|
||||
}
|
||||
|
||||
public boolean getFeature(String name)
|
||||
throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
if (name.equals(Features.NAMESPACES_FEATURE)) {
|
||||
return true;
|
||||
} else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
|
||||
return _namespacePrefixesFeature;
|
||||
} else if (name.equals(Features.EXTERNAL_GENERAL_ENTITIES)) {
|
||||
return true;
|
||||
} else if (name.equals(Features.EXTERNAL_PARAMETER_ENTITIES)) {
|
||||
return true;
|
||||
} else if (name.equals(Features.STRING_INTERNING_FEATURE)) {
|
||||
return _stringInterningFeature;
|
||||
} else {
|
||||
throw new SAXNotRecognizedException(
|
||||
"Feature not supported: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFeature(String name, boolean value)
|
||||
throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
if (name.equals(Features.NAMESPACES_FEATURE)) {
|
||||
if (!value) {
|
||||
throw new SAXNotSupportedException(name + ":" + value);
|
||||
}
|
||||
} else if (name.equals(Features.NAMESPACE_PREFIXES_FEATURE)) {
|
||||
_namespacePrefixesFeature = value;
|
||||
} else if (name.equals(Features.EXTERNAL_GENERAL_ENTITIES)) {
|
||||
// ignore
|
||||
} else if (name.equals(Features.EXTERNAL_PARAMETER_ENTITIES)) {
|
||||
// ignore
|
||||
} else if (name.equals(Features.STRING_INTERNING_FEATURE)) {
|
||||
if (value != _stringInterningFeature) {
|
||||
throw new SAXNotSupportedException(name + ":" + value);
|
||||
}
|
||||
} else {
|
||||
throw new SAXNotRecognizedException(
|
||||
"Feature not supported: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getProperty(String name)
|
||||
throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
|
||||
return getLexicalHandler();
|
||||
} else {
|
||||
throw new SAXNotRecognizedException("Property not recognized: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void setProperty(String name, Object value)
|
||||
throws SAXNotRecognizedException, SAXNotSupportedException {
|
||||
if (name.equals(Properties.LEXICAL_HANDLER_PROPERTY)) {
|
||||
if (value instanceof LexicalHandler) {
|
||||
setLexicalHandler((LexicalHandler)value);
|
||||
} else {
|
||||
throw new SAXNotSupportedException(Properties.LEXICAL_HANDLER_PROPERTY);
|
||||
}
|
||||
} else {
|
||||
throw new SAXNotRecognizedException("Property not recognized: " + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void setEntityResolver(EntityResolver resolver) {
|
||||
_entityResolver = resolver;
|
||||
}
|
||||
|
||||
public EntityResolver getEntityResolver() {
|
||||
return _entityResolver;
|
||||
}
|
||||
|
||||
public void setDTDHandler(DTDHandler handler) {
|
||||
_dtdHandler = handler;
|
||||
}
|
||||
|
||||
public DTDHandler getDTDHandler() {
|
||||
return _dtdHandler;
|
||||
}
|
||||
|
||||
public void setContentHandler(ContentHandler handler) {
|
||||
_contentHandler = handler;
|
||||
}
|
||||
|
||||
public ContentHandler getContentHandler() {
|
||||
return _contentHandler;
|
||||
}
|
||||
|
||||
public void setErrorHandler(ErrorHandler handler) {
|
||||
_errorHandler = handler;
|
||||
}
|
||||
|
||||
public ErrorHandler getErrorHandler() {
|
||||
return _errorHandler;
|
||||
}
|
||||
|
||||
public void setLexicalHandler(LexicalHandler handler) {
|
||||
_lexicalHandler = handler;
|
||||
}
|
||||
|
||||
public LexicalHandler getLexicalHandler() {
|
||||
return _lexicalHandler;
|
||||
}
|
||||
|
||||
public void parse(InputSource input) throws IOException, SAXException {
|
||||
// InputSource is ignored
|
||||
process();
|
||||
}
|
||||
|
||||
public void parse(String systemId) throws IOException, SAXException {
|
||||
// systemId is ignored
|
||||
process();
|
||||
}
|
||||
|
||||
/**
|
||||
* Short-hand for {@link #setXMLStreamBuffer(XMLStreamBuffer)} then {@link #process()}.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #process(XMLStreamBuffer, boolean)}
|
||||
*/
|
||||
public final void process(XMLStreamBuffer buffer) throws SAXException {
|
||||
setXMLStreamBuffer(buffer);
|
||||
process();
|
||||
}
|
||||
|
||||
/**
|
||||
* Short-hand for {@link #setXMLStreamBuffer(XMLStreamBuffer,boolean)} then {@link #process()}.
|
||||
*
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
*/
|
||||
public final void process(XMLStreamBuffer buffer, boolean produceFragmentEvent) throws SAXException {
|
||||
setXMLStreamBuffer(buffer);
|
||||
process();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the parser to read from the beginning of the given {@link XMLStreamBuffer}.
|
||||
*
|
||||
* @deprecated
|
||||
* Use {@link #setXMLStreamBuffer(XMLStreamBuffer, boolean)}.
|
||||
*/
|
||||
public void setXMLStreamBuffer(XMLStreamBuffer buffer) {
|
||||
setBuffer(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the parser to read from the beginning of the given {@link XMLStreamBuffer}.
|
||||
*
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
*/
|
||||
public void setXMLStreamBuffer(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
|
||||
if(!produceFragmentEvent && _treeCount>1)
|
||||
throw new IllegalStateException("Can't write a forest to a full XML infoset");
|
||||
setBuffer(buffer,produceFragmentEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the sub-tree (or a whole document) that {@link XMLStreamBuffer}
|
||||
* points to, and sends events to handlers.
|
||||
*
|
||||
* <p>
|
||||
* TODO:
|
||||
* We probably need two modes for a sub-tree event generation. One for
|
||||
* firing a sub-tree as if it's a whole document (in which case start/endDocument
|
||||
* and appropriate additional namespace bindings are necessary), and the other
|
||||
* mode for firing a subtree as a subtree, like it does today.
|
||||
* A stream buffer SAX feature could be used to specify this.
|
||||
*
|
||||
* @throws SAXException
|
||||
* Follow the same semantics as {@link XMLReader#parse(InputSource)}.
|
||||
*/
|
||||
public final void process() throws SAXException {
|
||||
if(!_fragmentMode) {
|
||||
LocatorImpl nullLocator = new LocatorImpl();
|
||||
nullLocator.setSystemId(_buffer.getSystemId());
|
||||
nullLocator.setLineNumber(-1);
|
||||
nullLocator.setColumnNumber(-1);
|
||||
_contentHandler.setDocumentLocator(nullLocator);
|
||||
|
||||
_contentHandler.startDocument();
|
||||
// TODO: if we are writing a fragment stream buffer as a full XML document,
|
||||
// we need to declare in-scope namespaces as if they are on the root element.
|
||||
}
|
||||
|
||||
while (_treeCount>0) {
|
||||
final int item = readEiiState();
|
||||
switch(item) {
|
||||
case STATE_DOCUMENT:
|
||||
processDocument();
|
||||
_treeCount--;
|
||||
break;
|
||||
case STATE_END:
|
||||
// Empty buffer
|
||||
return;
|
||||
case STATE_ELEMENT_U_LN_QN:
|
||||
processElement(readStructureString(), readStructureString(), readStructureString(), isInscope());
|
||||
_treeCount--;
|
||||
break;
|
||||
case STATE_ELEMENT_P_U_LN:
|
||||
{
|
||||
final String prefix = readStructureString();
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
processElement(uri, localName, getQName(prefix, localName),isInscope());
|
||||
_treeCount--;
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_U_LN: {
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
processElement(uri, localName, localName,isInscope());
|
||||
_treeCount--;
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_LN:
|
||||
{
|
||||
final String localName = readStructureString();
|
||||
processElement("", localName, localName,isInscope());
|
||||
_treeCount--;
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
|
||||
processCommentAsCharArraySmall();
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
|
||||
processCommentAsCharArrayMedium();
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
|
||||
processCommentAsCharArrayCopy();
|
||||
break;
|
||||
case STATE_COMMENT_AS_STRING:
|
||||
processComment(readContentString());
|
||||
break;
|
||||
case STATE_PROCESSING_INSTRUCTION:
|
||||
processProcessingInstruction(readStructureString(), readStructureString());
|
||||
break;
|
||||
default:
|
||||
throw reportFatalError("Illegal state for DIIs: "+item);
|
||||
}
|
||||
}
|
||||
|
||||
if(!_fragmentMode)
|
||||
_contentHandler.endDocument();
|
||||
}
|
||||
|
||||
private void processCommentAsCharArraySmall() throws SAXException {
|
||||
final int length = readStructure();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
processComment(_contentCharactersBuffer, start, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Report a fatal error and abort.
|
||||
*
|
||||
* This is necessary to follow the SAX semantics of error handling.
|
||||
*/
|
||||
private SAXParseException reportFatalError(String msg) throws SAXException {
|
||||
SAXParseException spe = new SAXParseException(msg, null);
|
||||
if(_errorHandler!=null)
|
||||
_errorHandler.fatalError(spe);
|
||||
return spe;
|
||||
}
|
||||
|
||||
private boolean isInscope() {
|
||||
return _buffer.getInscopeNamespaces().size() > 0;
|
||||
}
|
||||
|
||||
private void processDocument() throws SAXException {
|
||||
while(true) {
|
||||
int item = readEiiState();
|
||||
switch(item) {
|
||||
case STATE_ELEMENT_U_LN_QN:
|
||||
processElement(readStructureString(), readStructureString(), readStructureString(),isInscope());
|
||||
break;
|
||||
case STATE_ELEMENT_P_U_LN:
|
||||
{
|
||||
final String prefix = readStructureString();
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
processElement(uri, localName, getQName(prefix, localName),isInscope());
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_U_LN: {
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
processElement(uri, localName, localName,isInscope());
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_LN:
|
||||
{
|
||||
final String localName = readStructureString();
|
||||
processElement("", localName, localName,isInscope());
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
|
||||
processCommentAsCharArraySmall();
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
|
||||
processCommentAsCharArrayMedium();
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
|
||||
processCommentAsCharArrayCopy();
|
||||
break;
|
||||
case STATE_COMMENT_AS_STRING:
|
||||
processComment(readContentString());
|
||||
break;
|
||||
case STATE_PROCESSING_INSTRUCTION:
|
||||
processProcessingInstruction(readStructureString(), readStructureString());
|
||||
break;
|
||||
case STATE_END:
|
||||
return;
|
||||
default:
|
||||
throw reportFatalError("Illegal state for child of DII: "+item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void processElement(String uri, String localName, String qName, boolean inscope) throws SAXException {
|
||||
boolean hasAttributes = false;
|
||||
boolean hasNamespaceAttributes = false;
|
||||
int item = peekStructure();
|
||||
Set<String> prefixSet = inscope ? new HashSet<String>() : Collections.<String>emptySet();
|
||||
if ((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE) {
|
||||
cacheNamespacePrefixStartingIndex();
|
||||
hasNamespaceAttributes = true;
|
||||
item = processNamespaceAttributes(item, inscope, prefixSet);
|
||||
}
|
||||
if (inscope) {
|
||||
readInscopeNamespaces(prefixSet);
|
||||
}
|
||||
|
||||
if ((item & TYPE_MASK) == T_ATTRIBUTE) {
|
||||
hasAttributes = true;
|
||||
processAttributes(item);
|
||||
}
|
||||
|
||||
_contentHandler.startElement(uri, localName, qName, _attributes);
|
||||
|
||||
if (hasAttributes) {
|
||||
_attributes.clear();
|
||||
}
|
||||
|
||||
do {
|
||||
item = readEiiState();
|
||||
switch(item) {
|
||||
case STATE_ELEMENT_U_LN_QN:
|
||||
processElement(readStructureString(), readStructureString(), readStructureString(), false);
|
||||
break;
|
||||
case STATE_ELEMENT_P_U_LN:
|
||||
{
|
||||
final String p = readStructureString();
|
||||
final String u = readStructureString();
|
||||
final String ln = readStructureString();
|
||||
processElement(u, ln, getQName(p, ln),false);
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_U_LN: {
|
||||
final String u = readStructureString();
|
||||
final String ln = readStructureString();
|
||||
processElement(u, ln, ln,false);
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_LN: {
|
||||
final String ln = readStructureString();
|
||||
processElement("", ln, ln,false);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_SMALL:
|
||||
{
|
||||
final int length = readStructure();
|
||||
int start = readContentCharactersBuffer(length);
|
||||
_contentHandler.characters(_contentCharactersBuffer, start, length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM:
|
||||
{
|
||||
final int length = readStructure16();
|
||||
int start = readContentCharactersBuffer(length);
|
||||
_contentHandler.characters(_contentCharactersBuffer, start, length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_COPY:
|
||||
{
|
||||
final char[] ch = readContentCharactersCopy();
|
||||
|
||||
_contentHandler.characters(ch, 0, ch.length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_STRING:
|
||||
{
|
||||
final String s = readContentString();
|
||||
_contentHandler.characters(s.toCharArray(), 0, s.length());
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_OBJECT:
|
||||
{
|
||||
final CharSequence c = (CharSequence)readContentObject();
|
||||
final String s = c.toString();
|
||||
_contentHandler.characters(s.toCharArray(), 0, s.length());
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_SMALL:
|
||||
processCommentAsCharArraySmall();
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM:
|
||||
processCommentAsCharArrayMedium();
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_COPY:
|
||||
processCommentAsCharArrayCopy();
|
||||
break;
|
||||
case T_COMMENT_AS_STRING:
|
||||
processComment(readContentString());
|
||||
break;
|
||||
case STATE_PROCESSING_INSTRUCTION:
|
||||
processProcessingInstruction(readStructureString(), readStructureString());
|
||||
break;
|
||||
case STATE_END:
|
||||
break;
|
||||
default:
|
||||
throw reportFatalError("Illegal state for child of EII: "+item);
|
||||
}
|
||||
} while(item != STATE_END);
|
||||
|
||||
_contentHandler.endElement(uri, localName, qName);
|
||||
|
||||
if (hasNamespaceAttributes) {
|
||||
processEndPrefixMapping();
|
||||
}
|
||||
}
|
||||
|
||||
private void readInscopeNamespaces(Set<String> prefixSet) throws SAXException {
|
||||
for (Map.Entry<String, String> e : _buffer.getInscopeNamespaces().entrySet()) {
|
||||
String key = fixNull(e.getKey());
|
||||
// If the prefix is already written, do not write the prefix
|
||||
if (!prefixSet.contains(key)) {
|
||||
processNamespaceAttribute(key,e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static String fixNull(String s) {
|
||||
if (s == null) return "";
|
||||
else return s;
|
||||
}
|
||||
private void processCommentAsCharArrayCopy() throws SAXException {
|
||||
final char[] ch = readContentCharactersCopy();
|
||||
processComment(ch, 0, ch.length);
|
||||
}
|
||||
|
||||
private void processCommentAsCharArrayMedium() throws SAXException {
|
||||
final int length = readStructure16();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
processComment(_contentCharactersBuffer, start, length);
|
||||
}
|
||||
|
||||
private void processEndPrefixMapping() throws SAXException {
|
||||
final int end = _namespaceAttributesStack[--_namespaceAttributesStackIndex];
|
||||
// final int start = (_namespaceAttributesStackIndex > 0) ? _namespaceAttributesStack[_namespaceAttributesStackIndex] : 0;
|
||||
final int start = (_namespaceAttributesStackIndex >= 0) ? _namespaceAttributesStartingStack[_namespaceAttributesStackIndex] : 0;
|
||||
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
_contentHandler.endPrefixMapping(_namespacePrefixes[i]);
|
||||
}
|
||||
_namespacePrefixesIndex = start;
|
||||
}
|
||||
|
||||
private int processNamespaceAttributes(int item,boolean collectPrefixes, Set<String> prefixSet) throws SAXException {
|
||||
do {
|
||||
String prefix;
|
||||
switch(getNIIState(item)) {
|
||||
case STATE_NAMESPACE_ATTRIBUTE:
|
||||
// Undeclaration of default namespace
|
||||
processNamespaceAttribute("", "");
|
||||
if(collectPrefixes) {
|
||||
prefixSet.add("");
|
||||
}
|
||||
break;
|
||||
case STATE_NAMESPACE_ATTRIBUTE_P:
|
||||
// Undeclaration of namespace
|
||||
prefix = readStructureString();
|
||||
processNamespaceAttribute(prefix, "");
|
||||
if(collectPrefixes) {
|
||||
prefixSet.add(prefix);
|
||||
}
|
||||
break;
|
||||
case STATE_NAMESPACE_ATTRIBUTE_P_U:
|
||||
// Declaration with prefix
|
||||
prefix = readStructureString();
|
||||
processNamespaceAttribute(prefix, readStructureString());
|
||||
if(collectPrefixes) {
|
||||
prefixSet.add(prefix);
|
||||
}
|
||||
break;
|
||||
case STATE_NAMESPACE_ATTRIBUTE_U:
|
||||
// Default declaration
|
||||
processNamespaceAttribute("", readStructureString());
|
||||
if(collectPrefixes) {
|
||||
prefixSet.add("");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw reportFatalError("Illegal state: "+item);
|
||||
}
|
||||
readStructure();
|
||||
|
||||
item = peekStructure();
|
||||
} while((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE);
|
||||
|
||||
|
||||
cacheNamespacePrefixIndex();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void processAttributes(int item) throws SAXException {
|
||||
do {
|
||||
switch(getAIIState(item)) {
|
||||
case STATE_ATTRIBUTE_U_LN_QN:
|
||||
_attributes.addAttributeWithQName(readStructureString(), readStructureString(), readStructureString(), readStructureString(), readContentString());
|
||||
break;
|
||||
case STATE_ATTRIBUTE_P_U_LN:
|
||||
{
|
||||
final String p = readStructureString();
|
||||
final String u = readStructureString();
|
||||
final String ln = readStructureString();
|
||||
_attributes.addAttributeWithQName(u, ln, getQName(p, ln), readStructureString(), readContentString());
|
||||
break;
|
||||
}
|
||||
case STATE_ATTRIBUTE_U_LN: {
|
||||
final String u = readStructureString();
|
||||
final String ln = readStructureString();
|
||||
_attributes.addAttributeWithQName(u, ln, ln, readStructureString(), readContentString());
|
||||
break;
|
||||
}
|
||||
case STATE_ATTRIBUTE_LN: {
|
||||
final String ln = readStructureString();
|
||||
_attributes.addAttributeWithQName("", ln, ln, readStructureString(), readContentString());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw reportFatalError("Illegal state: "+item);
|
||||
}
|
||||
readStructure();
|
||||
|
||||
item = peekStructure();
|
||||
} while((item & TYPE_MASK) == T_ATTRIBUTE);
|
||||
}
|
||||
|
||||
private void processNamespaceAttribute(String prefix, String uri) throws SAXException {
|
||||
_contentHandler.startPrefixMapping(prefix, uri);
|
||||
|
||||
if (_namespacePrefixesFeature) {
|
||||
// Add the namespace delcaration as an attribute
|
||||
if (prefix != "") {
|
||||
_attributes.addAttributeWithQName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, prefix,
|
||||
getQName(XMLConstants.XMLNS_ATTRIBUTE, prefix),
|
||||
"CDATA", uri);
|
||||
} else {
|
||||
_attributes.addAttributeWithQName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE,
|
||||
XMLConstants.XMLNS_ATTRIBUTE,
|
||||
"CDATA", uri);
|
||||
}
|
||||
}
|
||||
|
||||
cacheNamespacePrefix(prefix);
|
||||
}
|
||||
|
||||
private void cacheNamespacePrefix(String prefix) {
|
||||
if (_namespacePrefixesIndex == _namespacePrefixes.length) {
|
||||
final String[] namespaceAttributes = new String[_namespacePrefixesIndex * 3 / 2 + 1];
|
||||
System.arraycopy(_namespacePrefixes, 0, namespaceAttributes, 0, _namespacePrefixesIndex);
|
||||
_namespacePrefixes = namespaceAttributes;
|
||||
}
|
||||
|
||||
_namespacePrefixes[_namespacePrefixesIndex++] = prefix;
|
||||
}
|
||||
|
||||
private void cacheNamespacePrefixIndex() {
|
||||
if (_namespaceAttributesStackIndex == _namespaceAttributesStack.length) {
|
||||
final int[] namespaceAttributesStack = new int[_namespaceAttributesStackIndex * 3 /2 + 1];
|
||||
System.arraycopy(_namespaceAttributesStack, 0, namespaceAttributesStack, 0, _namespaceAttributesStackIndex);
|
||||
_namespaceAttributesStack = namespaceAttributesStack;
|
||||
}
|
||||
|
||||
_namespaceAttributesStack[_namespaceAttributesStackIndex++] = _namespacePrefixesIndex;
|
||||
}
|
||||
|
||||
private void cacheNamespacePrefixStartingIndex() {
|
||||
if (_namespaceAttributesStackIndex == _namespaceAttributesStartingStack.length) {
|
||||
final int[] namespaceAttributesStart = new int[_namespaceAttributesStackIndex * 3 /2 + 1];
|
||||
System.arraycopy(_namespaceAttributesStartingStack, 0, namespaceAttributesStart, 0, _namespaceAttributesStackIndex);
|
||||
_namespaceAttributesStartingStack = namespaceAttributesStart;
|
||||
}
|
||||
_namespaceAttributesStartingStack[_namespaceAttributesStackIndex] = _namespacePrefixesIndex;
|
||||
}
|
||||
|
||||
private void processComment(String s) throws SAXException {
|
||||
processComment(s.toCharArray(), 0, s.length());
|
||||
}
|
||||
|
||||
private void processComment(char[] ch, int start, int length) throws SAXException {
|
||||
_lexicalHandler.comment(ch, start, length);
|
||||
}
|
||||
|
||||
private void processProcessingInstruction(String target, String data) throws SAXException {
|
||||
_contentHandler.processingInstruction(target, data);
|
||||
}
|
||||
|
||||
private static final DefaultWithLexicalHandler DEFAULT_LEXICAL_HANDLER = new DefaultWithLexicalHandler();
|
||||
}
|
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.stax;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
|
||||
|
||||
/**
|
||||
* A helper class for managing the declaration of namespaces.
|
||||
* <p>
|
||||
* A namespace is declared on a namespace context.
|
||||
* Namespace contexts are pushed on and popped off the namespace context stack.
|
||||
* <p>
|
||||
* A declared namespace will be in scope iff the context that it was declared on
|
||||
* has not been popped off the stack.
|
||||
* <p>
|
||||
* When instantiated the namespace stack consists of the root namespace context,
|
||||
* which contains, by default, the "xml" and "xmlns" declarations.
|
||||
* Namespaces may be declarations may be declared on the root context.
|
||||
* The root context cannot be popped but can be reset to contain just the
|
||||
* "xml" and "xmlns" declarations.
|
||||
* <p>
|
||||
* Implementation note: determining the prefix from a namespace URI
|
||||
* (or vice versa) is efficient when there are few namespace
|
||||
* declarations i.e. what is considered to be the case for namespace
|
||||
* declarations in 'average' XML documents. The look up of a namespace URI
|
||||
* given a prefix is performed in O(n) time. The look up of a prefix given
|
||||
* a namespace URI is performed in O(2n) time.
|
||||
* <p>
|
||||
* The implementation does not scale when there are many namespace
|
||||
* declarations. TODO: Use a hash map when there are many namespace
|
||||
* declarations.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
*/
|
||||
final public class NamespaceContexHelper implements NamespaceContextEx {
|
||||
private static int DEFAULT_SIZE = 8;
|
||||
|
||||
// The prefixes of the namespace declarations
|
||||
private String[] prefixes = new String[DEFAULT_SIZE];
|
||||
// The URIs of the namespace declarations
|
||||
private String[] namespaceURIs = new String[DEFAULT_SIZE];
|
||||
// Current position to store the next namespace declaration
|
||||
private int namespacePosition;
|
||||
|
||||
// The namespace contexts
|
||||
private int[] contexts = new int[DEFAULT_SIZE];
|
||||
// Current position to store the next namespace context
|
||||
private int contextPosition;
|
||||
|
||||
/**
|
||||
* Create a new NamespaceContexHelper.
|
||||
*
|
||||
*/
|
||||
public NamespaceContexHelper() {
|
||||
// The default namespace declarations that are always in scope
|
||||
prefixes[0] = "xml";
|
||||
namespaceURIs[0] = "http://www.w3.org/XML/1998/namespace";
|
||||
prefixes[1] = "xmlns";
|
||||
namespaceURIs[1] = "http://www.w3.org/2000/xmlns/";
|
||||
|
||||
namespacePosition = 2;
|
||||
}
|
||||
|
||||
|
||||
// NamespaceContext interface
|
||||
|
||||
public String getNamespaceURI(String prefix) {
|
||||
if (prefix == null) throw new IllegalArgumentException();
|
||||
|
||||
prefix = prefix.intern();
|
||||
|
||||
for (int i = namespacePosition - 1; i >= 0; i--) {
|
||||
final String declaredPrefix = prefixes[i];
|
||||
if (declaredPrefix == prefix) {
|
||||
return namespaceURIs[i];
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getPrefix(String namespaceURI) {
|
||||
if (namespaceURI == null) throw new IllegalArgumentException();
|
||||
|
||||
for (int i = namespacePosition - 1; i >= 0; i--) {
|
||||
final String declaredNamespaceURI = namespaceURIs[i];
|
||||
if (declaredNamespaceURI == namespaceURI || declaredNamespaceURI.equals(namespaceURI)) {
|
||||
final String declaredPrefix = prefixes[i];
|
||||
|
||||
// Check if prefix is out of scope
|
||||
for (++i; i < namespacePosition; i++)
|
||||
if (declaredPrefix == prefixes[i])
|
||||
return null;
|
||||
|
||||
return declaredPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Iterator getPrefixes(String namespaceURI) {
|
||||
if (namespaceURI == null) throw new IllegalArgumentException();
|
||||
|
||||
List<String> l = new ArrayList<String>();
|
||||
|
||||
NAMESPACE_LOOP: for (int i = namespacePosition - 1; i >= 0; i--) {
|
||||
final String declaredNamespaceURI = namespaceURIs[i];
|
||||
if (declaredNamespaceURI == namespaceURI || declaredNamespaceURI.equals(namespaceURI)) {
|
||||
final String declaredPrefix = prefixes[i];
|
||||
|
||||
// Check if prefix is out of scope
|
||||
for (int j = i + 1; j < namespacePosition; j++)
|
||||
if (declaredPrefix == prefixes[j])
|
||||
continue NAMESPACE_LOOP;
|
||||
|
||||
l.add(declaredPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
return l.iterator();
|
||||
}
|
||||
|
||||
// NamespaceContextEx interface
|
||||
|
||||
public Iterator<NamespaceContextEx.Binding> iterator() {
|
||||
if (namespacePosition == 2)
|
||||
return Collections.EMPTY_LIST.iterator();
|
||||
|
||||
final List<NamespaceContextEx.Binding> namespaces =
|
||||
new ArrayList<NamespaceContextEx.Binding>(namespacePosition);
|
||||
|
||||
NAMESPACE_LOOP: for (int i = namespacePosition - 1; i >= 2; i--) {
|
||||
final String declaredPrefix = prefixes[i];
|
||||
|
||||
// Check if prefix is out of scope
|
||||
for (int j = i + 1; j < namespacePosition; j++) {
|
||||
if (declaredPrefix == prefixes[j])
|
||||
continue NAMESPACE_LOOP;
|
||||
|
||||
namespaces.add(new NamespaceBindingImpl(i));
|
||||
}
|
||||
}
|
||||
|
||||
return namespaces.iterator();
|
||||
}
|
||||
|
||||
final private class NamespaceBindingImpl implements NamespaceContextEx.Binding {
|
||||
int index;
|
||||
|
||||
NamespaceBindingImpl(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefixes[index];
|
||||
}
|
||||
|
||||
public String getNamespaceURI() {
|
||||
return namespaceURIs[index];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare a default namespace.
|
||||
* <p>
|
||||
* @param namespaceURI the namespace URI to declare, may be null.
|
||||
*/
|
||||
public void declareDefaultNamespace(String namespaceURI) {
|
||||
declareNamespace("", namespaceURI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare a namespace.
|
||||
* <p>
|
||||
* The namespace will be declared on the current namespace context.
|
||||
* <p>
|
||||
* The namespace can be removed by popping the current namespace
|
||||
* context, or, if the declaration occured in the root context, by
|
||||
* reseting the namespace context.
|
||||
* <p>
|
||||
* A default namespace can be declared by passing <code>""</code> as
|
||||
* the value of the prefix parameter.
|
||||
* A namespace may be undeclared by passing <code>null</code> as the
|
||||
* value of the namespaceURI parameter.
|
||||
* <p>
|
||||
* @param prefix the namespace prefix to declare, may not be null.
|
||||
* @param namespaceURI the namespace URI to declare, may be null.
|
||||
* @throws IllegalArgumentException, if the prefix is null.
|
||||
*/
|
||||
public void declareNamespace(String prefix, String namespaceURI) {
|
||||
if (prefix == null) throw new IllegalArgumentException();
|
||||
|
||||
prefix = prefix.intern();
|
||||
// Ignore the "xml" or "xmlns" declarations
|
||||
if (prefix == "xml" || prefix == "xmlns")
|
||||
return;
|
||||
|
||||
// Check for undeclaration
|
||||
if (namespaceURI != null)
|
||||
namespaceURI = namespaceURI.intern();
|
||||
|
||||
if (namespacePosition == namespaceURIs.length)
|
||||
resizeNamespaces();
|
||||
|
||||
// Add new declaration
|
||||
prefixes[namespacePosition] = prefix;
|
||||
namespaceURIs[namespacePosition++] = namespaceURI;
|
||||
}
|
||||
|
||||
private void resizeNamespaces() {
|
||||
final int newLength = namespaceURIs.length * 3 / 2 + 1;
|
||||
|
||||
String[] newPrefixes = new String[newLength];
|
||||
System.arraycopy(prefixes, 0, newPrefixes, 0, prefixes.length);
|
||||
prefixes = newPrefixes;
|
||||
|
||||
String[] newNamespaceURIs = new String[newLength];
|
||||
System.arraycopy(namespaceURIs, 0, newNamespaceURIs, 0, namespaceURIs.length);
|
||||
namespaceURIs = newNamespaceURIs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a namespace context on the stack.
|
||||
*/
|
||||
public void pushContext() {
|
||||
if (contextPosition == contexts.length)
|
||||
resizeContexts();
|
||||
|
||||
contexts[contextPosition++] = namespacePosition;
|
||||
}
|
||||
|
||||
private void resizeContexts() {
|
||||
int[] newContexts = new int[contexts.length * 3 / 2 + 1];
|
||||
System.arraycopy(contexts, 0, newContexts, 0, contexts.length);
|
||||
contexts = newContexts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the namespace context off the stack.
|
||||
* <p>
|
||||
* Namespaces declared within the context (to be popped)
|
||||
* will be removed and no longer be in scope.
|
||||
*/
|
||||
public void popContext() {
|
||||
if (contextPosition > 0) {
|
||||
namespacePosition = contexts[--contextPosition];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset namespace contexts.
|
||||
* <p>
|
||||
* Pop all namespace contexts and reset the root context.
|
||||
*/
|
||||
public void resetContexts() {
|
||||
namespacePosition = 2;
|
||||
}
|
||||
}
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.stax;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.AbstractCreator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* {@link AbstractCreator} with additional convenience code.
|
||||
*
|
||||
* @author Paul Sandoz
|
||||
* @author Venu
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
abstract class StreamBufferCreator extends AbstractCreator {
|
||||
|
||||
private boolean checkAttributeValue = false;
|
||||
|
||||
protected List<String> attributeValuePrefixes = new ArrayList<String>();
|
||||
|
||||
protected void storeQualifiedName(int item, String prefix, String uri, String localName) {
|
||||
if (uri != null && uri.length() > 0) {
|
||||
if (prefix != null && prefix.length() > 0) {
|
||||
item |= FLAG_PREFIX;
|
||||
storeStructureString(prefix);
|
||||
}
|
||||
|
||||
item |= FLAG_URI;
|
||||
storeStructureString(uri);
|
||||
}
|
||||
|
||||
storeStructureString(localName);
|
||||
|
||||
storeStructure(item);
|
||||
}
|
||||
|
||||
protected final void storeNamespaceAttribute(String prefix, String uri) {
|
||||
int item = T_NAMESPACE_ATTRIBUTE;
|
||||
|
||||
if (prefix != null && prefix.length() > 0) {
|
||||
item |= FLAG_PREFIX;
|
||||
storeStructureString(prefix);
|
||||
}
|
||||
|
||||
if (uri != null && uri.length() > 0) {
|
||||
item |= FLAG_URI;
|
||||
storeStructureString(uri);
|
||||
}
|
||||
|
||||
storeStructure(item);
|
||||
}
|
||||
|
||||
protected final void storeAttribute(String prefix, String uri, String localName, String type, String value) {
|
||||
storeQualifiedName(T_ATTRIBUTE_LN, prefix, uri, localName);
|
||||
|
||||
storeStructureString(type);
|
||||
storeContentString(value);
|
||||
if(checkAttributeValue && value.indexOf("://") == -1){ // the condition after && avoids looking inside URIs
|
||||
int firstIndex = value.indexOf(":");
|
||||
int lastIndex = value.lastIndexOf(":"); // Check last index of : as some SAML namespace have multiple ":"s
|
||||
if(firstIndex != -1 && lastIndex == firstIndex){
|
||||
String valuePrefix = value.substring(0, firstIndex);
|
||||
if(!attributeValuePrefixes.contains(valuePrefix)){
|
||||
attributeValuePrefixes.add(valuePrefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final List getAttributeValuePrefixes(){
|
||||
return attributeValuePrefixes;
|
||||
}
|
||||
|
||||
protected final void storeProcessingInstruction(String target, String data) {
|
||||
storeStructure(T_PROCESSING_INSTRUCTION);
|
||||
storeStructureString(target);
|
||||
storeStructureString(data);
|
||||
}
|
||||
|
||||
public final boolean isCheckAttributeValue(){
|
||||
return checkAttributeValue;
|
||||
}
|
||||
|
||||
public final void setCheckAttributeValue(boolean value){
|
||||
this.checkAttributeValue = value;
|
||||
}
|
||||
}
|
@@ -0,0 +1,383 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.stax;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamReaderEx;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Create a buffer using an {@link XMLStreamReader}.
|
||||
* <p>
|
||||
* TODO: Implement the marking the stream on the element when an ID
|
||||
* attribute on the element is defined
|
||||
*/
|
||||
public class StreamReaderBufferCreator extends StreamBufferCreator {
|
||||
private int _eventType;
|
||||
private boolean _storeInScopeNamespacesOnElementFragment;
|
||||
private Map<String, Integer> _inScopePrefixes;
|
||||
|
||||
/**
|
||||
* Create a stream reader buffer creator.
|
||||
* <p>
|
||||
* A stream buffer will be created for storing the infoset
|
||||
* from a stream reader.
|
||||
*/
|
||||
public StreamReaderBufferCreator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a stream reader buffer creator using a mutable stream buffer.
|
||||
* <p>
|
||||
* @param buffer the mutable stream buffer.
|
||||
*/
|
||||
public StreamReaderBufferCreator(MutableXMLStreamBuffer buffer) {
|
||||
setBuffer(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the buffer from a stream reader.
|
||||
* <p>
|
||||
* The stream reader must be positioned at the start of the document
|
||||
* or the start of an element.
|
||||
* <p>
|
||||
* If the stream is positioned at the start of the document then the
|
||||
* whole document is stored and after storing the stream will be positioned
|
||||
* at the end of the document.
|
||||
* <p>
|
||||
* If the stream is positioned at the start of an element then the
|
||||
* element and all its children will be stored and after storing the stream
|
||||
* will be positioned at the next event after the end of the element.
|
||||
* <p>
|
||||
* @return the mutable stream buffer.
|
||||
* @throws XMLStreamException if the stream reader is not positioned at
|
||||
* the start of the document or at an element.
|
||||
*/
|
||||
public MutableXMLStreamBuffer create(XMLStreamReader reader) throws XMLStreamException {
|
||||
if (_buffer == null) {
|
||||
createBuffer();
|
||||
}
|
||||
store(reader);
|
||||
|
||||
return getXMLStreamBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the buffer from a stream reader that is an element fragment.
|
||||
* <p>
|
||||
* The stream reader will be moved to the position of the next start of
|
||||
* an element if the stream reader is not already positioned at the start
|
||||
* of an element.
|
||||
* <p>
|
||||
* The element and all its children will be stored and after storing the stream
|
||||
* will be positioned at the next event after the end of the element.
|
||||
* <p>
|
||||
* @param storeInScopeNamespaces true if in-scope namespaces of the element
|
||||
* fragment should be stored.
|
||||
* @return the mutable stream buffer.
|
||||
* @throws XMLStreamException if the stream reader cannot be positioned at
|
||||
* the start of an element.
|
||||
*/
|
||||
public MutableXMLStreamBuffer createElementFragment(XMLStreamReader reader,
|
||||
boolean storeInScopeNamespaces) throws XMLStreamException {
|
||||
if (_buffer == null) {
|
||||
createBuffer();
|
||||
}
|
||||
|
||||
if (!reader.hasNext()) {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
_storeInScopeNamespacesOnElementFragment = storeInScopeNamespaces;
|
||||
|
||||
_eventType = reader.getEventType();
|
||||
if (_eventType != XMLStreamReader.START_ELEMENT) {
|
||||
do {
|
||||
_eventType = reader.next();
|
||||
} while(_eventType != XMLStreamReader.START_ELEMENT && _eventType != XMLStreamReader.END_DOCUMENT);
|
||||
}
|
||||
|
||||
if (storeInScopeNamespaces) {
|
||||
_inScopePrefixes = new HashMap<String,Integer>();
|
||||
}
|
||||
|
||||
storeElementAndChildren(reader);
|
||||
|
||||
return getXMLStreamBuffer();
|
||||
}
|
||||
|
||||
private void store(XMLStreamReader reader) throws XMLStreamException {
|
||||
if (!reader.hasNext()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_eventType = reader.getEventType();
|
||||
switch (_eventType) {
|
||||
case XMLStreamReader.START_DOCUMENT:
|
||||
storeDocumentAndChildren(reader);
|
||||
break;
|
||||
case XMLStreamReader.START_ELEMENT:
|
||||
storeElementAndChildren(reader);
|
||||
break;
|
||||
default:
|
||||
throw new XMLStreamException("XMLStreamReader not positioned at a document or element");
|
||||
}
|
||||
|
||||
increaseTreeCount();
|
||||
}
|
||||
|
||||
private void storeDocumentAndChildren(XMLStreamReader reader) throws XMLStreamException {
|
||||
storeStructure(T_DOCUMENT);
|
||||
|
||||
_eventType = reader.next();
|
||||
while (_eventType != XMLStreamReader.END_DOCUMENT) {
|
||||
switch (_eventType) {
|
||||
case XMLStreamReader.START_ELEMENT:
|
||||
storeElementAndChildren(reader);
|
||||
continue;
|
||||
case XMLStreamReader.COMMENT:
|
||||
storeComment(reader);
|
||||
break;
|
||||
case XMLStreamReader.PROCESSING_INSTRUCTION:
|
||||
storeProcessingInstruction(reader);
|
||||
break;
|
||||
}
|
||||
_eventType = reader.next();
|
||||
}
|
||||
|
||||
storeStructure(T_END);
|
||||
}
|
||||
|
||||
private void storeElementAndChildren(XMLStreamReader reader) throws XMLStreamException {
|
||||
if (reader instanceof XMLStreamReaderEx) {
|
||||
storeElementAndChildrenEx((XMLStreamReaderEx)reader);
|
||||
} else {
|
||||
storeElementAndChildrenNoEx(reader);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeElementAndChildrenEx(XMLStreamReaderEx reader) throws XMLStreamException {
|
||||
int depth = 1;
|
||||
if (_storeInScopeNamespacesOnElementFragment) {
|
||||
storeElementWithInScopeNamespaces(reader);
|
||||
} else {
|
||||
storeElement(reader);
|
||||
}
|
||||
|
||||
while(depth > 0) {
|
||||
_eventType = reader.next();
|
||||
switch (_eventType) {
|
||||
case XMLStreamReader.START_ELEMENT:
|
||||
depth++;
|
||||
storeElement(reader);
|
||||
break;
|
||||
case XMLStreamReader.END_ELEMENT:
|
||||
depth--;
|
||||
storeStructure(T_END);
|
||||
break;
|
||||
case XMLStreamReader.NAMESPACE:
|
||||
storeNamespaceAttributes(reader);
|
||||
break;
|
||||
case XMLStreamReader.ATTRIBUTE:
|
||||
storeAttributes(reader);
|
||||
break;
|
||||
case XMLStreamReader.SPACE:
|
||||
case XMLStreamReader.CHARACTERS:
|
||||
case XMLStreamReader.CDATA: {
|
||||
CharSequence c = reader.getPCDATA();
|
||||
if (c instanceof Base64Data) {
|
||||
storeStructure(T_TEXT_AS_OBJECT);
|
||||
//Instead of clone the Base64Data, the original Base64Data instance is used here to preserve the DataHandler
|
||||
storeContentObject(c);
|
||||
} else {
|
||||
storeContentCharacters(T_TEXT_AS_CHAR_ARRAY,
|
||||
reader.getTextCharacters(), reader.getTextStart(),
|
||||
reader.getTextLength());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XMLStreamReader.COMMENT:
|
||||
storeComment(reader);
|
||||
break;
|
||||
case XMLStreamReader.PROCESSING_INSTRUCTION:
|
||||
storeProcessingInstruction(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move to next item after the end of the element
|
||||
* that has been stored
|
||||
*/
|
||||
_eventType = reader.next();
|
||||
}
|
||||
|
||||
private void storeElementAndChildrenNoEx(XMLStreamReader reader) throws XMLStreamException {
|
||||
int depth = 1;
|
||||
if (_storeInScopeNamespacesOnElementFragment) {
|
||||
storeElementWithInScopeNamespaces(reader);
|
||||
} else {
|
||||
storeElement(reader);
|
||||
}
|
||||
|
||||
while(depth > 0) {
|
||||
_eventType = reader.next();
|
||||
switch (_eventType) {
|
||||
case XMLStreamReader.START_ELEMENT:
|
||||
depth++;
|
||||
storeElement(reader);
|
||||
break;
|
||||
case XMLStreamReader.END_ELEMENT:
|
||||
depth--;
|
||||
storeStructure(T_END);
|
||||
break;
|
||||
case XMLStreamReader.NAMESPACE:
|
||||
storeNamespaceAttributes(reader);
|
||||
break;
|
||||
case XMLStreamReader.ATTRIBUTE:
|
||||
storeAttributes(reader);
|
||||
break;
|
||||
case XMLStreamReader.SPACE:
|
||||
case XMLStreamReader.CHARACTERS:
|
||||
case XMLStreamReader.CDATA: {
|
||||
storeContentCharacters(T_TEXT_AS_CHAR_ARRAY,
|
||||
reader.getTextCharacters(), reader.getTextStart(),
|
||||
reader.getTextLength());
|
||||
break;
|
||||
}
|
||||
case XMLStreamReader.COMMENT:
|
||||
storeComment(reader);
|
||||
break;
|
||||
case XMLStreamReader.PROCESSING_INSTRUCTION:
|
||||
storeProcessingInstruction(reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Move to next item after the end of the element
|
||||
* that has been stored
|
||||
*/
|
||||
_eventType = reader.next();
|
||||
}
|
||||
|
||||
private void storeElementWithInScopeNamespaces(XMLStreamReader reader) {
|
||||
storeQualifiedName(T_ELEMENT_LN,
|
||||
reader.getPrefix(), reader.getNamespaceURI(), reader.getLocalName());
|
||||
|
||||
if (reader.getNamespaceCount() > 0) {
|
||||
storeNamespaceAttributes(reader);
|
||||
}
|
||||
|
||||
if (reader.getAttributeCount() > 0) {
|
||||
storeAttributes(reader);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeElement(XMLStreamReader reader) {
|
||||
storeQualifiedName(T_ELEMENT_LN,
|
||||
reader.getPrefix(), reader.getNamespaceURI(), reader.getLocalName());
|
||||
|
||||
if (reader.getNamespaceCount() > 0) {
|
||||
storeNamespaceAttributes(reader);
|
||||
}
|
||||
|
||||
if (reader.getAttributeCount() > 0) {
|
||||
storeAttributes(reader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A low level method a create a structure element explicitly. This is useful when xsb is
|
||||
* created from a fragment's XMLStreamReader and inscope namespaces can be passed using
|
||||
* this method. Note that there is no way to enumerate namespaces from XMLStreamReader.
|
||||
*
|
||||
* For e.g: Say the SOAP message is as follows
|
||||
*
|
||||
* <S:Envelope xmlns:n1=".."><S:Body><ns2:A> ...
|
||||
*
|
||||
* when xsb is to be created using a reader that is at <ns2:A> tag, the inscope
|
||||
* namespace like 'n1' can be passed using this method.
|
||||
*
|
||||
* WARNING: Instead of using this, try other methods(if you don't know what you are
|
||||
* doing).
|
||||
*
|
||||
* @param ns an array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }.
|
||||
*/
|
||||
public void storeElement(String nsURI, String localName, String prefix, String[] ns) {
|
||||
storeQualifiedName(T_ELEMENT_LN, prefix, nsURI, localName);
|
||||
storeNamespaceAttributes(ns);
|
||||
}
|
||||
|
||||
/**
|
||||
* A low level method a create a structure element explicitly. This is
|
||||
* required to support {@link #storeElement} method.
|
||||
*
|
||||
* WARNING: Instead of using this, try other methods(if you don't know what
|
||||
* you are doing).
|
||||
*/
|
||||
public void storeEndElement() {
|
||||
storeStructure(T_END);
|
||||
}
|
||||
|
||||
private void storeNamespaceAttributes(XMLStreamReader reader) {
|
||||
int count = reader.getNamespaceCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
storeNamespaceAttribute(reader.getNamespacePrefix(i), reader.getNamespaceURI(i));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ns an array of the even length of the form { prefix0, uri0, prefix1, uri1, ... }.
|
||||
*/
|
||||
private void storeNamespaceAttributes(String[] ns) {
|
||||
for (int i = 0; i < ns.length; i=i+2) {
|
||||
storeNamespaceAttribute(ns[i], ns[i+1]);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeAttributes(XMLStreamReader reader) {
|
||||
int count = reader.getAttributeCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
storeAttribute(reader.getAttributePrefix(i), reader.getAttributeNamespace(i), reader.getAttributeLocalName(i),
|
||||
reader.getAttributeType(i), reader.getAttributeValue(i));
|
||||
}
|
||||
}
|
||||
|
||||
private void storeComment(XMLStreamReader reader) {
|
||||
storeContentCharacters(T_COMMENT_AS_CHAR_ARRAY,
|
||||
reader.getTextCharacters(), reader.getTextStart(), reader.getTextLength());
|
||||
}
|
||||
|
||||
private void storeProcessingInstruction(XMLStreamReader reader) {
|
||||
storeProcessingInstruction(reader.getPITarget(), reader.getPIData());
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.stax;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.MutableXMLStreamBuffer;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.NamespaceContextEx;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
|
||||
|
||||
import javax.activation.DataHandler;
|
||||
import javax.xml.namespace.NamespaceContext;
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* {@link XMLStreamWriter} that fills {@link MutableXMLStreamBuffer}.
|
||||
* <p>
|
||||
* TODO: need to retain all attributes/namespaces and then store all namespaces
|
||||
* before the attributes. Currently it is necessary for the caller to ensure
|
||||
* all namespaces are written before attributes and the caller must not intermix
|
||||
* calls to the writeNamespace and writeAttribute methods.
|
||||
*
|
||||
*/
|
||||
public class StreamWriterBufferCreator extends StreamBufferCreator implements XMLStreamWriterEx {
|
||||
private final NamespaceContexHelper namespaceContext = new NamespaceContexHelper();
|
||||
|
||||
/**
|
||||
* Nesting depth of the element.
|
||||
* This field is ultimately used to keep track of the # of trees we created in
|
||||
* the buffer.
|
||||
*/
|
||||
private int depth=0;
|
||||
|
||||
public StreamWriterBufferCreator() {
|
||||
setXMLStreamBuffer(new MutableXMLStreamBuffer());
|
||||
}
|
||||
|
||||
public StreamWriterBufferCreator(MutableXMLStreamBuffer buffer) {
|
||||
setXMLStreamBuffer(buffer);
|
||||
}
|
||||
|
||||
// XMLStreamWriter
|
||||
|
||||
public Object getProperty(String str) throws IllegalArgumentException {
|
||||
return null; //return null for all the property names instead of
|
||||
//throwing unsupported operation exception.
|
||||
}
|
||||
|
||||
public void close() throws XMLStreamException {
|
||||
}
|
||||
|
||||
public void flush() throws XMLStreamException {
|
||||
}
|
||||
|
||||
public NamespaceContextEx getNamespaceContext() {
|
||||
return namespaceContext;
|
||||
}
|
||||
|
||||
public void setNamespaceContext(NamespaceContext namespaceContext) throws XMLStreamException {
|
||||
/*
|
||||
* It is really unclear from the JavaDoc how to implement this method.
|
||||
*/
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void setDefaultNamespace(String namespaceURI) throws XMLStreamException {
|
||||
setPrefix("", namespaceURI);
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix, String namespaceURI) throws XMLStreamException {
|
||||
namespaceContext.declareNamespace(prefix, namespaceURI);
|
||||
}
|
||||
|
||||
public String getPrefix(String namespaceURI) throws XMLStreamException {
|
||||
return namespaceContext.getPrefix(namespaceURI);
|
||||
}
|
||||
|
||||
|
||||
public void writeStartDocument() throws XMLStreamException {
|
||||
writeStartDocument("", "");
|
||||
}
|
||||
|
||||
public void writeStartDocument(String version) throws XMLStreamException {
|
||||
writeStartDocument("", "");
|
||||
}
|
||||
|
||||
public void writeStartDocument(String encoding, String version) throws XMLStreamException {
|
||||
namespaceContext.resetContexts();
|
||||
|
||||
storeStructure(T_DOCUMENT);
|
||||
}
|
||||
|
||||
public void writeEndDocument() throws XMLStreamException {
|
||||
storeStructure(T_END);
|
||||
}
|
||||
|
||||
public void writeStartElement(String localName) throws XMLStreamException {
|
||||
namespaceContext.pushContext();
|
||||
depth++;
|
||||
|
||||
final String defaultNamespaceURI = namespaceContext.getNamespaceURI("");
|
||||
|
||||
if (defaultNamespaceURI == null)
|
||||
storeQualifiedName(T_ELEMENT_LN, null, null, localName);
|
||||
else
|
||||
storeQualifiedName(T_ELEMENT_LN, null, defaultNamespaceURI, localName);
|
||||
}
|
||||
|
||||
public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
|
||||
namespaceContext.pushContext();
|
||||
depth++;
|
||||
|
||||
final String prefix = namespaceContext.getPrefix(namespaceURI);
|
||||
if (prefix == null) {
|
||||
throw new XMLStreamException();
|
||||
}
|
||||
|
||||
namespaceContext.pushContext();
|
||||
storeQualifiedName(T_ELEMENT_LN, prefix, namespaceURI, localName);
|
||||
}
|
||||
|
||||
public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
|
||||
namespaceContext.pushContext();
|
||||
depth++;
|
||||
|
||||
storeQualifiedName(T_ELEMENT_LN, prefix, namespaceURI, localName);
|
||||
}
|
||||
|
||||
public void writeEmptyElement(String localName) throws XMLStreamException {
|
||||
writeStartElement(localName);
|
||||
writeEndElement();
|
||||
}
|
||||
|
||||
public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
|
||||
writeStartElement(namespaceURI, localName);
|
||||
writeEndElement();
|
||||
}
|
||||
|
||||
public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
|
||||
writeStartElement(prefix, localName, namespaceURI);
|
||||
writeEndElement();
|
||||
}
|
||||
|
||||
public void writeEndElement() throws XMLStreamException {
|
||||
namespaceContext.popContext();
|
||||
|
||||
storeStructure(T_END);
|
||||
if(--depth==0)
|
||||
increaseTreeCount();
|
||||
}
|
||||
|
||||
public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
|
||||
storeNamespaceAttribute(null, namespaceURI);
|
||||
}
|
||||
|
||||
public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
|
||||
if ("xmlns".equals(prefix))
|
||||
prefix = null;
|
||||
storeNamespaceAttribute(prefix, namespaceURI);
|
||||
}
|
||||
|
||||
|
||||
public void writeAttribute(String localName, String value) throws XMLStreamException {
|
||||
storeAttribute(null, null, localName, "CDATA", value);
|
||||
}
|
||||
|
||||
public void writeAttribute(String namespaceURI, String localName, String value) throws XMLStreamException {
|
||||
final String prefix = namespaceContext.getPrefix(namespaceURI);
|
||||
if (prefix == null) {
|
||||
// TODO
|
||||
throw new XMLStreamException();
|
||||
}
|
||||
|
||||
writeAttribute(prefix, namespaceURI, localName, value);
|
||||
}
|
||||
|
||||
public void writeAttribute(String prefix, String namespaceURI, String localName, String value) throws XMLStreamException {
|
||||
storeAttribute(prefix, namespaceURI, localName, "CDATA", value);
|
||||
}
|
||||
|
||||
public void writeCData(String data) throws XMLStreamException {
|
||||
storeStructure(T_TEXT_AS_STRING);
|
||||
storeContentString(data);
|
||||
}
|
||||
|
||||
public void writeCharacters(String charData) throws XMLStreamException {
|
||||
storeStructure(T_TEXT_AS_STRING);
|
||||
storeContentString(charData);
|
||||
}
|
||||
|
||||
public void writeCharacters(char[] buf, int start, int len) throws XMLStreamException {
|
||||
storeContentCharacters(T_TEXT_AS_CHAR_ARRAY, buf, start, len);
|
||||
}
|
||||
|
||||
public void writeComment(String str) throws XMLStreamException {
|
||||
storeStructure(T_COMMENT_AS_STRING);
|
||||
storeContentString(str);
|
||||
}
|
||||
|
||||
public void writeDTD(String str) throws XMLStreamException {
|
||||
// not support. just ignore.
|
||||
}
|
||||
|
||||
public void writeEntityRef(String str) throws XMLStreamException {
|
||||
storeStructure(T_UNEXPANDED_ENTITY_REFERENCE);
|
||||
storeContentString(str);
|
||||
}
|
||||
|
||||
public void writeProcessingInstruction(String target) throws XMLStreamException {
|
||||
writeProcessingInstruction(target, "");
|
||||
}
|
||||
|
||||
public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
|
||||
storeProcessingInstruction(target, data);
|
||||
}
|
||||
|
||||
// XMLStreamWriterEx
|
||||
|
||||
public void writePCDATA(CharSequence charSequence) throws XMLStreamException {
|
||||
if (charSequence instanceof Base64Data) {
|
||||
storeStructure(T_TEXT_AS_OBJECT);
|
||||
storeContentObject(((Base64Data)charSequence).clone());
|
||||
} else {
|
||||
writeCharacters(charSequence.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void writeBinary(byte[] bytes, int offset, int length, String endpointURL) throws XMLStreamException {
|
||||
Base64Data d = new Base64Data();
|
||||
byte b[] = new byte[length];
|
||||
System.arraycopy(bytes, offset, b, 0, length);
|
||||
d.set(b, length, null, true);
|
||||
storeStructure(T_TEXT_AS_OBJECT);
|
||||
storeContentObject(d);
|
||||
}
|
||||
|
||||
public void writeBinary(DataHandler dataHandler) throws XMLStreamException {
|
||||
Base64Data d = new Base64Data();
|
||||
d.set(dataHandler);
|
||||
storeStructure(T_TEXT_AS_OBJECT);
|
||||
storeContentObject(d);
|
||||
}
|
||||
|
||||
public OutputStream writeBinary(String endpointURL) throws XMLStreamException {
|
||||
// TODO
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
@@ -0,0 +1,525 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2012, 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.
|
||||
*/
|
||||
|
||||
package com.sun.xml.internal.stream.buffer.stax;
|
||||
|
||||
import com.sun.xml.internal.stream.buffer.AbstractProcessor;
|
||||
import com.sun.xml.internal.stream.buffer.XMLStreamBuffer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.sun.xml.internal.org.jvnet.staxex.Base64Data;
|
||||
import com.sun.xml.internal.org.jvnet.staxex.XMLStreamWriterEx;
|
||||
|
||||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.XMLStreamWriter;
|
||||
|
||||
|
||||
/**
|
||||
* A processor of a {@link XMLStreamBuffer} that writes the XML infoset to a
|
||||
* {@link XMLStreamWriter}.
|
||||
*
|
||||
* @author Paul.Sandoz@Sun.Com
|
||||
* @author K.Venugopal@sun.com
|
||||
*/
|
||||
public class StreamWriterBufferProcessor extends AbstractProcessor {
|
||||
|
||||
|
||||
public StreamWriterBufferProcessor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #StreamWriterBufferProcessor(XMLStreamBuffer, boolean)}
|
||||
*/
|
||||
public StreamWriterBufferProcessor(XMLStreamBuffer buffer) {
|
||||
setXMLStreamBuffer(buffer,buffer.isFragment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
*/
|
||||
public StreamWriterBufferProcessor(XMLStreamBuffer buffer,boolean produceFragmentEvent) {
|
||||
setXMLStreamBuffer(buffer,produceFragmentEvent);
|
||||
}
|
||||
|
||||
public final void process(XMLStreamBuffer buffer, XMLStreamWriter writer) throws XMLStreamException {
|
||||
setXMLStreamBuffer(buffer,buffer.isFragment());
|
||||
process(writer);
|
||||
}
|
||||
|
||||
public void process(XMLStreamWriter writer) throws XMLStreamException {
|
||||
if(_fragmentMode){
|
||||
writeFragment(writer);
|
||||
}else{
|
||||
write(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #setXMLStreamBuffer(XMLStreamBuffer, boolean)}
|
||||
*/
|
||||
public void setXMLStreamBuffer(XMLStreamBuffer buffer) {
|
||||
setBuffer(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param produceFragmentEvent
|
||||
* True to generate fragment SAX events without start/endDocument.
|
||||
* False to generate a full document SAX events.
|
||||
*/
|
||||
public void setXMLStreamBuffer(XMLStreamBuffer buffer, boolean produceFragmentEvent) {
|
||||
setBuffer(buffer,produceFragmentEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a full XML infoset event to the given writer,
|
||||
* including start/end document.
|
||||
* Any inscope namespaces present will be written as namespace
|
||||
* delcarations on each top-level element.
|
||||
*/
|
||||
public void write(XMLStreamWriter writer) throws XMLStreamException{
|
||||
|
||||
if(!_fragmentMode) {
|
||||
if(_treeCount>1)
|
||||
throw new IllegalStateException("forest cannot be written as a full infoset");
|
||||
writer.writeStartDocument();
|
||||
}
|
||||
|
||||
while(true) {
|
||||
int item = getEIIState(peekStructure());
|
||||
writer.flush();
|
||||
|
||||
switch(item) {
|
||||
case STATE_DOCUMENT:
|
||||
readStructure(); //skip
|
||||
break;
|
||||
case STATE_ELEMENT_U_LN_QN:
|
||||
case STATE_ELEMENT_P_U_LN:
|
||||
case STATE_ELEMENT_U_LN:
|
||||
case STATE_ELEMENT_LN:
|
||||
writeFragment(writer);
|
||||
break;
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: {
|
||||
readStructure();
|
||||
final int length = readStructure();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
final String comment = new String(_contentCharactersBuffer, start, length);
|
||||
writer.writeComment(comment);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: {
|
||||
readStructure();
|
||||
final int length = readStructure16();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
final String comment = new String(_contentCharactersBuffer, start, length);
|
||||
writer.writeComment(comment);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_COPY: {
|
||||
readStructure();
|
||||
final char[] ch = readContentCharactersCopy();
|
||||
writer.writeComment(new String(ch));
|
||||
break;
|
||||
}
|
||||
case STATE_PROCESSING_INSTRUCTION:
|
||||
readStructure();
|
||||
writer.writeProcessingInstruction(readStructureString(), readStructureString());
|
||||
break;
|
||||
case STATE_END: // done
|
||||
readStructure();
|
||||
writer.writeEndDocument();
|
||||
return;
|
||||
default:
|
||||
throw new XMLStreamException("Invalid State "+item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the buffer as a fragment, meaning
|
||||
* the writer will not receive start/endDocument events.
|
||||
* Any inscope namespaces present will be written as namespace
|
||||
* delcarations on each top-level element.
|
||||
* <p>
|
||||
* If {@link XMLStreamBuffer} has a forest, this method will write all the forests.
|
||||
*/
|
||||
public void writeFragment(XMLStreamWriter writer) throws XMLStreamException {
|
||||
if (writer instanceof XMLStreamWriterEx) {
|
||||
writeFragmentEx((XMLStreamWriterEx)writer);
|
||||
} else {
|
||||
writeFragmentNoEx(writer);
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFragmentEx(XMLStreamWriterEx writer) throws XMLStreamException {
|
||||
int depth = 0; // used to determine when we are done with a tree.
|
||||
|
||||
int item = getEIIState(peekStructure());
|
||||
if(item==STATE_DOCUMENT)
|
||||
readStructure(); // skip STATE_DOCUMENT
|
||||
|
||||
do {
|
||||
|
||||
item = readEiiState();
|
||||
|
||||
switch(item) {
|
||||
case STATE_DOCUMENT:
|
||||
throw new AssertionError();
|
||||
case STATE_ELEMENT_U_LN_QN: {
|
||||
depth ++;
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
final String prefix = getPrefixFromQName(readStructureString());
|
||||
writer.writeStartElement(prefix,localName,uri);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_P_U_LN: {
|
||||
depth ++;
|
||||
final String prefix = readStructureString();
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
writer.writeStartElement(prefix,localName,uri);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_U_LN: {
|
||||
depth ++;
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
writer.writeStartElement("",localName,uri);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_LN: {
|
||||
depth ++;
|
||||
final String localName = readStructureString();
|
||||
writer.writeStartElement(localName);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_SMALL: {
|
||||
final int length = readStructure();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
writer.writeCharacters(_contentCharactersBuffer,start,length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM: {
|
||||
final int length = readStructure16();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
writer.writeCharacters(_contentCharactersBuffer,start,length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_COPY: {
|
||||
char[] c = readContentCharactersCopy();
|
||||
writer.writeCharacters(c,0,c.length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_STRING: {
|
||||
final String s = readContentString();
|
||||
writer.writeCharacters(s);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_OBJECT: {
|
||||
final CharSequence c = (CharSequence)readContentObject();
|
||||
writer.writePCDATA(c);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: {
|
||||
final int length = readStructure();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
final String comment = new String(_contentCharactersBuffer, start, length);
|
||||
writer.writeComment(comment);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: {
|
||||
final int length = readStructure16();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
final String comment = new String(_contentCharactersBuffer, start, length);
|
||||
writer.writeComment(comment);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_COPY: {
|
||||
final char[] ch = readContentCharactersCopy();
|
||||
writer.writeComment(new String(ch));
|
||||
break;
|
||||
}
|
||||
case STATE_PROCESSING_INSTRUCTION:
|
||||
writer.writeProcessingInstruction(readStructureString(), readStructureString());
|
||||
break;
|
||||
case STATE_END:
|
||||
writer.writeEndElement();
|
||||
depth --;
|
||||
if(depth==0)
|
||||
_treeCount--;
|
||||
break;
|
||||
default:
|
||||
throw new XMLStreamException("Invalid State "+item);
|
||||
}
|
||||
} while(depth>0 || _treeCount>0);
|
||||
|
||||
}
|
||||
|
||||
public void writeFragmentNoEx(XMLStreamWriter writer) throws XMLStreamException {
|
||||
int depth = 0;
|
||||
|
||||
int item = getEIIState(peekStructure());
|
||||
if(item==STATE_DOCUMENT)
|
||||
readStructure(); // skip STATE_DOCUMENT
|
||||
|
||||
do {
|
||||
item = readEiiState();
|
||||
|
||||
switch(item) {
|
||||
case STATE_DOCUMENT:
|
||||
throw new AssertionError();
|
||||
case STATE_ELEMENT_U_LN_QN: {
|
||||
depth ++;
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
final String prefix = getPrefixFromQName(readStructureString());
|
||||
writer.writeStartElement(prefix,localName,uri);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_P_U_LN: {
|
||||
depth ++;
|
||||
final String prefix = readStructureString();
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
writer.writeStartElement(prefix,localName,uri);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_U_LN: {
|
||||
depth ++;
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
writer.writeStartElement("",localName,uri);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_ELEMENT_LN: {
|
||||
depth ++;
|
||||
final String localName = readStructureString();
|
||||
writer.writeStartElement(localName);
|
||||
writeAttributes(writer, isInscope(depth));
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_SMALL: {
|
||||
final int length = readStructure();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
writer.writeCharacters(_contentCharactersBuffer,start,length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_MEDIUM: {
|
||||
final int length = readStructure16();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
writer.writeCharacters(_contentCharactersBuffer,start,length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_CHAR_ARRAY_COPY: {
|
||||
char[] c = readContentCharactersCopy();
|
||||
writer.writeCharacters(c,0,c.length);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_STRING: {
|
||||
final String s = readContentString();
|
||||
writer.writeCharacters(s);
|
||||
break;
|
||||
}
|
||||
case STATE_TEXT_AS_OBJECT: {
|
||||
final CharSequence c = (CharSequence)readContentObject();
|
||||
if (c instanceof Base64Data) {
|
||||
try {
|
||||
Base64Data bd = (Base64Data)c;
|
||||
bd.writeTo(writer);
|
||||
} catch (IOException e) {
|
||||
throw new XMLStreamException(e);
|
||||
}
|
||||
} else {
|
||||
writer.writeCharacters(c.toString());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_SMALL: {
|
||||
final int length = readStructure();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
final String comment = new String(_contentCharactersBuffer, start, length);
|
||||
writer.writeComment(comment);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_MEDIUM: {
|
||||
final int length = readStructure16();
|
||||
final int start = readContentCharactersBuffer(length);
|
||||
final String comment = new String(_contentCharactersBuffer, start, length);
|
||||
writer.writeComment(comment);
|
||||
break;
|
||||
}
|
||||
case STATE_COMMENT_AS_CHAR_ARRAY_COPY: {
|
||||
final char[] ch = readContentCharactersCopy();
|
||||
writer.writeComment(new String(ch));
|
||||
break;
|
||||
}
|
||||
case STATE_PROCESSING_INSTRUCTION:
|
||||
writer.writeProcessingInstruction(readStructureString(), readStructureString());
|
||||
break;
|
||||
case STATE_END:
|
||||
writer.writeEndElement();
|
||||
depth --;
|
||||
if(depth==0)
|
||||
_treeCount--;
|
||||
break;
|
||||
default:
|
||||
throw new XMLStreamException("Invalid State "+item);
|
||||
}
|
||||
} while(depth > 0 || _treeCount>0);
|
||||
|
||||
}
|
||||
|
||||
private boolean isInscope(int depth) {
|
||||
return _buffer.getInscopeNamespaces().size() > 0 && depth ==1;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param inscope: true means write inscope namespaces
|
||||
*/
|
||||
private void writeAttributes(XMLStreamWriter writer, boolean inscope) throws XMLStreamException {
|
||||
// prefixSet to collect prefixes that are written before writing inscope namespaces
|
||||
Set<String> prefixSet = inscope ? new HashSet<String>() : Collections.<String>emptySet();
|
||||
int item = peekStructure();
|
||||
if ((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE) {
|
||||
// Skip the namespace declarations on the element
|
||||
// they will have been added already
|
||||
item = writeNamespaceAttributes(item, writer, inscope, prefixSet);
|
||||
}
|
||||
if (inscope) {
|
||||
writeInscopeNamespaces(writer, prefixSet);
|
||||
}
|
||||
if ((item & TYPE_MASK) == T_ATTRIBUTE) {
|
||||
writeAttributes(item, writer);
|
||||
}
|
||||
}
|
||||
|
||||
private static String fixNull(String s) {
|
||||
if (s == null) return "";
|
||||
else return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* @param prefixSet: already written prefixes
|
||||
*/
|
||||
private void writeInscopeNamespaces(XMLStreamWriter writer, Set<String> prefixSet) throws XMLStreamException {
|
||||
for (Map.Entry<String, String> e : _buffer.getInscopeNamespaces().entrySet()) {
|
||||
String key = fixNull(e.getKey());
|
||||
// If the prefix is already written, do not write the prefix
|
||||
if (!prefixSet.contains(key)) {
|
||||
writer.writeNamespace(key, e.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int writeNamespaceAttributes(int item, XMLStreamWriter writer, boolean collectPrefixes, Set<String> prefixSet) throws XMLStreamException {
|
||||
do {
|
||||
switch(getNIIState(item)){
|
||||
case STATE_NAMESPACE_ATTRIBUTE:
|
||||
// Undeclaration of default namespace
|
||||
writer.writeDefaultNamespace("");
|
||||
if (collectPrefixes) {
|
||||
prefixSet.add("");
|
||||
}
|
||||
break;
|
||||
case STATE_NAMESPACE_ATTRIBUTE_P:
|
||||
// Undeclaration of namespace
|
||||
// Declaration with prefix
|
||||
String prefix = readStructureString();
|
||||
writer.writeNamespace(prefix, "");
|
||||
if (collectPrefixes) {
|
||||
prefixSet.add(prefix);
|
||||
}
|
||||
break;
|
||||
case STATE_NAMESPACE_ATTRIBUTE_P_U:
|
||||
// Declaration with prefix
|
||||
prefix = readStructureString();
|
||||
writer.writeNamespace(prefix, readStructureString());
|
||||
if (collectPrefixes) {
|
||||
prefixSet.add(prefix);
|
||||
}
|
||||
break;
|
||||
case STATE_NAMESPACE_ATTRIBUTE_U:
|
||||
// Default declaration
|
||||
writer.writeDefaultNamespace(readStructureString());
|
||||
if (collectPrefixes) {
|
||||
prefixSet.add("");
|
||||
}
|
||||
break;
|
||||
}
|
||||
readStructure();
|
||||
|
||||
item = peekStructure();
|
||||
} while((item & TYPE_MASK) == T_NAMESPACE_ATTRIBUTE);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private void writeAttributes(int item, XMLStreamWriter writer) throws XMLStreamException {
|
||||
do {
|
||||
switch(getAIIState(item)) {
|
||||
case STATE_ATTRIBUTE_U_LN_QN: {
|
||||
final String uri = readStructureString();
|
||||
final String localName = readStructureString();
|
||||
final String prefix = getPrefixFromQName(readStructureString());
|
||||
writer.writeAttribute(prefix,uri,localName,readContentString());
|
||||
break;
|
||||
}
|
||||
case STATE_ATTRIBUTE_P_U_LN:
|
||||
writer.writeAttribute(readStructureString(), readStructureString(),
|
||||
readStructureString(), readContentString());
|
||||
break;
|
||||
case STATE_ATTRIBUTE_U_LN:
|
||||
writer.writeAttribute(readStructureString(), readStructureString(), readContentString());
|
||||
break;
|
||||
case STATE_ATTRIBUTE_LN:
|
||||
writer.writeAttribute(readStructureString(), readContentString());
|
||||
break;
|
||||
}
|
||||
// Ignore the attribute type
|
||||
readStructureString();
|
||||
|
||||
readStructure();
|
||||
|
||||
item = peekStructure();
|
||||
} while((item & TYPE_MASK) == T_ATTRIBUTE);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user