feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}