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,476 @@
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream;
import java.io.InputStream;
import java.io.Reader;
import java.io.IOException;
import com.sun.xml.internal.stream.util.BufferAllocator;
import com.sun.xml.internal.stream.util.ThreadLocalBufferAllocator;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
/**
* Entity information.
*
* @author
*/
public abstract class Entity {
//
// Data
//
//xxx why dont we declare the type of entities, like assign integer for external/ internal etc..
/** Entity name. */
public String name;
// whether this entity's declaration was found in the internal
// or external subset
public boolean inExternalSubset;
//
// Constructors
//
/** Default constructor. */
public Entity() {
clear();
} // <init>()
/** Constructs an entity. */
public Entity(String name, boolean inExternalSubset) {
this.name = name;
this.inExternalSubset = inExternalSubset;
} // <init>(String)
//
// Public methods
//
/** Returns true if this entity was declared in the external subset. */
public boolean isEntityDeclInExternalSubset() {
return inExternalSubset;
}
/** Returns true if this is an external entity. */
public abstract boolean isExternal();
/** Returns true if this is an unparsed entity. */
public abstract boolean isUnparsed();
/** Clears the entity. */
public void clear() {
name = null;
inExternalSubset = false;
} // clear()
/** Sets the values of the entity. */
public void setValues(Entity entity) {
name = entity.name;
inExternalSubset = entity.inExternalSubset;
} // setValues(Entity)
/**
* Internal entity.
*
* @author nb131165
*/
public static class InternalEntity
extends Entity {
//
// Data
//
/** Text value of entity. */
public String text;
//
// Constructors
//
/** Default constructor. */
public InternalEntity() {
clear();
} // <init>()
/** Constructs an internal entity. */
public InternalEntity(String name, String text, boolean inExternalSubset) {
super(name,inExternalSubset);
this.text = text;
} // <init>(String,String)
//
// Entity methods
//
/** Returns true if this is an external entity. */
public final boolean isExternal() {
return false;
} // isExternal():boolean
/** Returns true if this is an unparsed entity. */
public final boolean isUnparsed() {
return false;
} // isUnparsed():boolean
/** Clears the entity. */
public void clear() {
super.clear();
text = null;
} // clear()
/** Sets the values of the entity. */
public void setValues(Entity entity) {
super.setValues(entity);
text = null;
} // setValues(Entity)
/** Sets the values of the entity. */
public void setValues(InternalEntity entity) {
super.setValues(entity);
text = entity.text;
} // setValues(InternalEntity)
} // class InternalEntity
/**
* External entity.
*
* @author nb131165
*/
public static class ExternalEntity
extends Entity {
//
// Data
//
/** container for all relevant entity location information. */
public XMLResourceIdentifier entityLocation;
/** Notation name for unparsed entity. */
public String notation;
//
// Constructors
//
/** Default constructor. */
public ExternalEntity() {
clear();
} // <init>()
/** Constructs an internal entity. */
public ExternalEntity(String name, XMLResourceIdentifier entityLocation,
String notation, boolean inExternalSubset) {
super(name,inExternalSubset);
this.entityLocation = entityLocation;
this.notation = notation;
} // <init>(String,XMLResourceIdentifier, String)
//
// Entity methods
//
/** Returns true if this is an external entity. */
public final boolean isExternal() {
return true;
} // isExternal():boolean
/** Returns true if this is an unparsed entity. */
public final boolean isUnparsed() {
return notation != null;
} // isUnparsed():boolean
/** Clears the entity. */
public void clear() {
super.clear();
entityLocation = null;
notation = null;
} // clear()
/** Sets the values of the entity. */
public void setValues(Entity entity) {
super.setValues(entity);
entityLocation = null;
notation = null;
} // setValues(Entity)
/** Sets the values of the entity. */
public void setValues(ExternalEntity entity) {
super.setValues(entity);
entityLocation = entity.entityLocation;
notation = entity.notation;
} // setValues(ExternalEntity)
} // class ExternalEntity
/**
* Entity state.
*
* @author nb131165
*/
public static class ScannedEntity
extends Entity {
/** Default buffer size (4096). */
public static final int DEFAULT_BUFFER_SIZE = 8192;
//4096;
/**
* Buffer size. We get this value from a property. The default size
* is used if the input buffer size property is not specified.
* REVISIT: do we need a property for internal entity buffer size?
*/
public int fBufferSize = DEFAULT_BUFFER_SIZE;
/** Default buffer size before we've finished with the XMLDecl: */
public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 28;
/** Default internal entity buffer size (1024). */
public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024;
//
// Data
//
// i/o
/** XXX let these field remain public right now, though we have defined methods for them.
* Input stream. */
public InputStream stream;
/** XXX let these field remain public right now, though we have defined methods for them.
* Reader. */
public Reader reader;
// locator information
/** entity location information */
public XMLResourceIdentifier entityLocation;
// encoding
/** Auto-detected encoding. */
public String encoding;
// status
/** True if in a literal. */
public boolean literal;
// whether this is an external or internal scanned entity
public boolean isExternal;
//each 'external' parsed entity may have xml/text declaration containing version information
public String version ;
// buffer
/** Character buffer. */
public char[] ch = null;
/** Position in character buffer at any point of time. */
public int position;
/** Count of characters present in buffer. */
public int count;
/** Line number. */
public int lineNumber = 1;
/** Column number. */
public int columnNumber = 1;
/** Encoding has been set externally for eg: using DOMInput*/
boolean declaredEncoding = false;
// status
/**
* Encoding has been set externally, for example
* using a SAX InputSource or a DOM LSInput.
*/
boolean externallySpecifiedEncoding = false;
/** XML version. **/
public String xmlVersion = "1.0";
/** This variable is used to calculate the current position in the XML stream.
* Note that fCurrentEntity.position maintains the position relative to
* the buffer.
* At any point of time absolute position in the XML stream can be calculated
* as fTotalCountTillLastLoad + fCurrentEntity.position
*/
public int fTotalCountTillLastLoad ;
/** This variable stores the number of characters read during the load()
* operation. It is used to calculate fTotalCountTillLastLoad
*/
public int fLastCount ;
/** Base character offset for computing absolute character offset. */
public int baseCharOffset;
/** Start position in character buffer. */
public int startPosition;
// to allow the reader/inputStream to behave efficiently:
public boolean mayReadChunks;
// to know that prolog is read
public boolean xmlDeclChunkRead = false;
// flag to indicate whether the Entity is a General Entity
public boolean isGE = false;
/** returns the name of the current encoding
* @return current encoding name
*/
public String getEncodingName(){
return encoding ;
}
/**each 'external' parsed entity may have xml/text declaration containing version information
* @return String version of the enity, for an internal entity version would be null
*/
public String getEntityVersion(){
return version ;
}
/** each 'external' parsed entity may have xml/text declaration containing version information
* @param String version of the external parsed entity
*/
public void setEntityVersion(String version){
this.version = version ;
}
/** Returns the java.io.Reader associated with this entity.Readers are used
* to read from the file. Readers wrap any particular InputStream that was
* used to open the entity.
* @return java.io.Reader Reader associated with this entity
*/
public Reader getEntityReader(){
return reader;
}
/** if entity was opened using the stream, return the associated inputstream
* with this entity
*@return java.io.InputStream InputStream associated with this entity
*/
public InputStream getEntityInputStream(){
return stream;
}
//
// Constructors
//
/** Constructs a scanned entity. */
public ScannedEntity(boolean isGE, String name,
XMLResourceIdentifier entityLocation,
InputStream stream, Reader reader,
String encoding, boolean literal, boolean mayReadChunks, boolean isExternal) {
this.isGE = isGE;
this.name = name ;
this.entityLocation = entityLocation;
this.stream = stream;
this.reader = reader;
this.encoding = encoding;
this.literal = literal;
this.mayReadChunks = mayReadChunks;
this.isExternal = isExternal;
final int size = isExternal ? fBufferSize : DEFAULT_INTERNAL_BUFFER_SIZE;
BufferAllocator ba = ThreadLocalBufferAllocator.getBufferAllocator();
ch = ba.getCharBuffer(size);
if (ch == null) {
this.ch = new char[size];
}
} // <init>(StringXMLResourceIdentifier,InputStream,Reader,String,boolean, boolean)
/**
* Release any resources associated with this entity.
*/
public void close() throws IOException {
BufferAllocator ba = ThreadLocalBufferAllocator.getBufferAllocator();
ba.returnCharBuffer(ch);
ch = null;
reader.close();
}
//
// Entity methods
//
/** Returns whether the encoding of this entity was externally specified. **/
public boolean isEncodingExternallySpecified() {
return externallySpecifiedEncoding;
}
/** Sets whether the encoding of this entity was externally specified. **/
public void setEncodingExternallySpecified(boolean value) {
externallySpecifiedEncoding = value;
}
public boolean isDeclaredEncoding() {
return declaredEncoding;
}
public void setDeclaredEncoding(boolean value) {
declaredEncoding = value;
}
/** Returns true if this is an external entity. */
public final boolean isExternal() {
return isExternal;
} // isExternal():boolean
/** Returns true if this is an unparsed entity. */
public final boolean isUnparsed() {
return false;
} // isUnparsed():boolean
//
// Object methods
//
/** Returns a string representation of this object. */
public String toString() {
StringBuffer str = new StringBuffer();
str.append("name=\""+name+'"');
str.append(",ch="+ new String(ch));
str.append(",position="+position);
str.append(",count="+count);
return str.toString();
} // toString():String
} // class ScannedEntity
} // class Entity

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2005, 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;
import java.util.NoSuchElementException;
import javax.xml.stream.EventFilter;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.EventReaderDelegate;
/**
*
* @author Neeraj Bajaj, Sun Microsystems
*
*/
public class EventFilterSupport extends EventReaderDelegate {
//maintain a reference to EventFilter
EventFilter fEventFilter ;
/** Creates a new instance of EventFilterSupport */
public EventFilterSupport(XMLEventReader eventReader, EventFilter eventFilter) {
setParent(eventReader);
fEventFilter = eventFilter;
}
public Object next(){
try{
return nextEvent();
}catch(XMLStreamException ex){
throw new NoSuchElementException();
}
}
public boolean hasNext(){
try{
return peek() != null ? true : false ;
}catch(XMLStreamException ex){
return false;
}
}
public XMLEvent nextEvent()throws XMLStreamException{
if(super.hasNext()){
//get the next event by calling XMLEventReader
XMLEvent event = super.nextEvent();
//if this filter accepts this event then return this event
if(fEventFilter.accept(event)){
return event;
}
else{
return nextEvent();
}
}else{
throw new NoSuchElementException();
}
}//nextEvent()
public XMLEvent nextTag() throws XMLStreamException{
if(super.hasNext()){
XMLEvent event = super.nextTag();
//if the filter accepts this event return this event.
if(fEventFilter.accept(event)){
return event;
}
else{
return nextTag();
}
}else{
throw new NoSuchElementException();
}
}
public XMLEvent peek() throws XMLStreamException{
while (true) {
XMLEvent event = super.peek();
if(event == null)return null;
//if the filter accepts this event return this event.
if(fEventFilter.accept(event)){
return event;
}
//call super.next(), and then peek again.
super.next();
}
}
}//EventFilterSupport

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2005, 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;
import java.io.InputStream;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLResolver;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
/**
*
* @author Neeraj Bajaj
*/
public class StaxEntityResolverWrapper {
XMLResolver fStaxResolver ;
/** Creates a new instance of StaxEntityResolverWrapper */
public StaxEntityResolverWrapper(XMLResolver resolver) {
fStaxResolver = resolver ;
}
public void setStaxEntityResolver(XMLResolver resolver ){
fStaxResolver = resolver ;
}
public XMLResolver getStaxEntityResolver(){
return fStaxResolver ;
}
public StaxXMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier)
throws XNIException, java.io.IOException {
Object object = null ;
try{
object = fStaxResolver.resolveEntity(resourceIdentifier.getPublicId(), resourceIdentifier.getLiteralSystemId(),
resourceIdentifier.getBaseSystemId(), null);
return getStaxInputSource(object) ;
}catch(XMLStreamException streamException){
throw new XNIException(streamException) ;
}
}
StaxXMLInputSource getStaxInputSource(Object object){
if(object == null) return null ;
if(object instanceof java.io.InputStream){
return new StaxXMLInputSource(new XMLInputSource(null, null, null, (InputStream)object, null), true);
}
else if(object instanceof XMLStreamReader){
return new StaxXMLInputSource((XMLStreamReader)object, true) ;
}else if(object instanceof XMLEventReader){
return new StaxXMLInputSource((XMLEventReader)object, true) ;
}
return null ;
}
}//class StaxEntityResolverWrapper

View File

@@ -0,0 +1,187 @@
/*
* Copyright (c) 2005, 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;
import javax.xml.stream.Location;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLReporter;
import javax.xml.stream.XMLStreamException;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.MessageFormatter;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
/**
*
* @author neeraj
*/
public class StaxErrorReporter extends XMLErrorReporter {
protected XMLReporter fXMLReporter = null ;
/** Creates a new instance of StaxErrorReporter */
public StaxErrorReporter(PropertyManager propertyManager) {
super();
putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, new XMLMessageFormatter());
reset(propertyManager);
}
/** Creates a new instance of StaxErrorReporter
* If this constructor is used to create the object, one must invoke reset() on this object.
*/
public StaxErrorReporter() {
super();
putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, new XMLMessageFormatter());
}
/**
*One must call reset before using any of the function.
*/
public void reset(PropertyManager propertyManager){
fXMLReporter = (XMLReporter)propertyManager.getProperty(XMLInputFactory.REPORTER);
}
/**
* Reports an error at a specific location.
*
* @param location The error location.
* @param domain The error domain.
* @param key The key of the error message.
* @param arguments The replacement arguments for the error message,
* if needed.
* @param severity The severity of the error.
*
* @see #SEVERITY_WARNING
* @see #SEVERITY_ERROR
* @see #SEVERITY_FATAL_ERROR
*/
public String reportError(XMLLocator location,
String domain, String key, Object[] arguments,
short severity) throws XNIException {
// format error message and create parse exception
MessageFormatter messageFormatter = getMessageFormatter(domain);
String message;
if (messageFormatter != null) {
message = messageFormatter.formatMessage(fLocale, key, arguments);
}
else {
StringBuffer str = new StringBuffer();
str.append(domain);
str.append('#');
str.append(key);
int argCount = arguments != null ? arguments.length : 0;
if (argCount > 0) {
str.append('?');
for (int i = 0; i < argCount; i++) {
str.append(arguments[i]);
if (i < argCount -1) {
str.append('&');
}
}
}
message = str.toString();
}
//no reporter was specified
/**
* if (reporter == null) {
* reporter = new DefaultStaxErrorReporter();
* }
*/
// call error handler
switch (severity) {
case SEVERITY_WARNING: {
try{
if(fXMLReporter!= null){
fXMLReporter.report(message, "WARNING", null, convertToStaxLocation(location) );
}
}catch(XMLStreamException ex){
//what we should be doing ?? if the user throws XMLStreamException
//REVISIT:
throw new XNIException(ex);
}
break;
}
case SEVERITY_ERROR: {
try{
if(fXMLReporter!= null){
fXMLReporter.report(message, "ERROR", null, convertToStaxLocation(location) );
}
}catch(XMLStreamException ex){
//what we should be doing ?? if the user throws XMLStreamException
//REVISIT:
throw new XNIException(ex);
}
break;
}
case SEVERITY_FATAL_ERROR: {
if (!fContinueAfterFatalError) {
throw new XNIException(message);
}
break;
}
}
return message;
}
Location convertToStaxLocation(final XMLLocator location){
return new Location(){
public int getColumnNumber(){
return location.getColumnNumber();
}
public int getLineNumber(){
return location.getLineNumber();
}
public String getPublicId(){
return location.getPublicId();
}
public String getSystemId(){
return location.getLiteralSystemId();
}
public int getCharacterOffset(){
return location.getCharacterOffset();
}
public String getLocationURI(){
return "";
}
};
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamReader;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
/**
*
* @author Neeraj
*
* This class wraps XMLInputSource and is also capable of telling wether application
* returned XMLStreamReader or not when XMLResolver.resolveEnity
* was called.
*/
public class StaxXMLInputSource {
XMLStreamReader fStreamReader ;
XMLEventReader fEventReader ;
XMLInputSource fInputSource ;
//indicates if the source is created by a resolver
boolean fIsCreatedByResolver = false;
/** Creates a new instance of StaxXMLInputSource */
public StaxXMLInputSource(XMLStreamReader streamReader, boolean byResolver) {
fStreamReader = streamReader ;
}
/** Creates a new instance of StaxXMLInputSource */
public StaxXMLInputSource(XMLEventReader eventReader, boolean byResolver) {
fEventReader = eventReader ;
}
public StaxXMLInputSource(XMLInputSource inputSource, boolean byResolver){
fInputSource = inputSource ;
fIsCreatedByResolver = byResolver;
}
public XMLStreamReader getXMLStreamReader(){
return fStreamReader ;
}
public XMLEventReader getXMLEventReader(){
return fEventReader ;
}
public XMLInputSource getXMLInputSource(){
return fInputSource ;
}
public boolean hasXMLStreamOrXMLEventReader(){
return (fStreamReader == null) && (fEventReader == null) ? false : true ;
}
public boolean isCreatedByResolver() {
return fIsCreatedByResolver;
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright (c) 2005, 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;
/**
* XMLBufferListerner should be implemented by classes which wish to receive
* call backs from XMLEntityReader.
*
* @author k.venugopal@sun.com,
* @author Neeraj.bajaj@sun.com
*/
public interface XMLBufferListener {
/**
* Will be invoked by XMLEntityReader before it tries to resize,load new data
* into current ScannedEntities buffer.
*/
public void refresh();
/**
* receives callbacks from {@link XMLEntityReader } when buffer
* is being changed.
* @param refreshPosition
*/
public void refresh(int loadPosition);
}

View File

@@ -0,0 +1,303 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
import com.sun.org.apache.xerces.internal.xni.*;
/**
* This class allows various parser scanners to scan basic XML constructs
* from entities. This class works directly with the entity manager to
* provide this functionality.
* <p>
* There is only one entity scanner and entity manager per parser. The
* entity manager <em>could</em> implement the methods to perform entity
* scanning, but the entity scanner class allows a cleaner separation
* between entity management API and entity scanning.
*
* @author Andy Clark, IBM
* @author Neeraj Bajaj Sun Microsystems
* @author K.Venugopal Sun Microsystems
*
* @see XMLEntityHandler
* @see XMLEntityManager
*/
public abstract class XMLEntityReader implements XMLLocator {
//
// Public methods
//
/**
* Sets the encoding of the scanner. This method is used by the
* scanners if the XMLDecl or TextDecl line contains an encoding
* pseudo-attribute.
* <p>
* <strong>Note:</strong> The underlying character reader on the
* current entity will be changed to accomodate the new encoding.
* However, the new encoding is ignored if the current reader was
* not constructed from an input stream (e.g. an external entity
* that is resolved directly to the appropriate java.io.Reader
* object).
*
* @param encoding The IANA encoding name of the new encoding.
*
* @throws IOException Thrown if the new encoding is not supported.
*
* @see com.sun.org.apache.xerces.internal.util.EncodingMap
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isValidIANAEncoding
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isValidJavaEncoding
*/
public abstract void setEncoding(String encoding)
throws IOException;
public abstract String getEncoding() ;
public abstract int getCharacterOffset() ;
/** the version of the current entity being scanned or the version of the entity on which reader is operating */
public abstract void setVersion(String version) ;
/** get the version of the entity on which reader is operating */
public abstract String getVersion() ;
/** Returns true if the current entity being scanned is external. */
public abstract boolean isExternal();
/**
* Returns the next character on the input.
* <p>
* <strong>Note:</strong> The character is <em>not</em> consumed.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract int peekChar() throws IOException;
/**
* Returns the next character on the input.
* <p>
* <strong>Note:</strong> The character is consumed.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract int scanChar() throws IOException;
/**
* Returns a string matching the NMTOKEN production appearing immediately
* on the input as a symbol, or null if NMTOKEN Name string is present.
* <p>
* <strong>Note:</strong> The NMTOKEN characters are consumed.
* <p>
* <strong>Note:</strong> The string returned must be a symbol. The
* SymbolTable can be used for this purpose.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*
* @see com.sun.org.apache.xerces.internal.util.SymbolTable
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
*/
public abstract String scanNmtoken() throws IOException;
/**
* Returns a string matching the Name production appearing immediately
* on the input as a symbol, or null if no Name string is present.
* <p>
* <strong>Note:</strong> The Name characters are consumed.
* <p>
* <strong>Note:</strong> The string returned must be a symbol. The
* SymbolTable can be used for this purpose.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*
* @see com.sun.org.apache.xerces.internal.util.SymbolTable
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart
*/
public abstract String scanName() throws IOException;
/**
* Scans a qualified name from the input, setting the fields of the
* QName structure appropriately.
* <p>
* <strong>Note:</strong> The qualified name characters are consumed.
* <p>
* <strong>Note:</strong> The strings used to set the values of the
* QName structure must be symbols. The SymbolTable can be used for
* this purpose.
*
* @param qname The qualified name structure to fill.
*
* @return Returns true if a qualified name appeared immediately on
* the input and was scanned, false otherwise.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*
* @see com.sun.org.apache.xerces.internal.util.SymbolTable
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isName
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isNameStart
*/
public abstract boolean scanQName(QName qname) throws IOException;
/**
* CHANGED:
* Scans a range of parsed character data, This function appends the character data to
* the supplied buffer.
* <p>
* <strong>Note:</strong> The characters are consumed.
* <p>
* <strong>Note:</strong> This method does not guarantee to return
* the longest run of parsed character data. This method may return
* before markup due to reaching the end of the input buffer or any
* other reason.
* <p>
*
* @param content The content structure to fill.
*
* @return Returns the next character on the input, if known. This
* value may be -1 but this does <em>note</em> designate
* end of file.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract int scanContent(XMLString content) throws IOException;
/**
* Scans a range of attribute value data, setting the fields of the
* XMLString structure, appropriately.
* <p>
* <strong>Note:</strong> The characters are consumed.
* <p>
* <strong>Note:</strong> This method does not guarantee to return
* the longest run of attribute value data. This method may return
* before the quote character due to reaching the end of the input
* buffer or any other reason.
* <p>
* <strong>Note:</strong> The fields contained in the XMLString
* structure are not guaranteed to remain valid upon subsequent calls
* to the entity scanner. Therefore, the caller is responsible for
* immediately using the returned character data or making a copy of
* the character data.
*
* @param quote The quote character that signifies the end of the
* attribute value data.
* @param content The content structure to fill.
*
* @return Returns the next character on the input, if known. This
* value may be -1 but this does <em>note</em> designate
* end of file.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract int scanLiteral(int quote, XMLString content)
throws IOException;
/**
* Scans a range of character data up to the specicied delimiter,
* setting the fields of the XMLString structure, appropriately.
* <p>
* <strong>Note:</strong> The characters are consumed.
* <p>
* <strong>Note:</strong> This assumes that the internal buffer is
* at least the same size, or bigger, than the length of the delimiter
* and that the delimiter contains at least one character.
* <p>
* <strong>Note:</strong> This method does not guarantee to return
* the longest run of character data. This method may return before
* the delimiter due to reaching the end of the input buffer or any
* other reason.
* <p>
* <strong>Note:</strong> The fields contained in the XMLString
* structure are not guaranteed to remain valid upon subsequent calls
* to the entity scanner. Therefore, the caller is responsible for
* immediately using the returned character data or making a copy of
* the character data.
*
* @param delimiter The string that signifies the end of the character
* data to be scanned.
* @param data The data structure to fill.
*
* @return Returns true if there is more data to scan, false otherwise.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract boolean scanData(String delimiter, XMLStringBuffer data)
throws IOException;
/**
* Skips a character appearing immediately on the input.
* <p>
* <strong>Note:</strong> The character is consumed only if it matches
* the specified character.
*
* @param c The character to skip.
*
* @return Returns true if the character was skipped.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract boolean skipChar(int c) throws IOException;
/**
* Skips space characters appearing immediately on the input.
* <p>
* <strong>Note:</strong> The characters are consumed only if they are
* space characters.
*
* @return Returns true if at least one space character was skipped.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*
* @see com.sun.org.apache.xerces.internal.util.XMLChar#isSpace
*/
public abstract boolean skipSpaces() throws IOException;
/**
* Skips the specified string appearing immediately on the input.
* <p>
* <strong>Note:</strong> The characters are consumed only if they are
* space characters.
*
* @param s The string to skip.
*
* @return Returns true if the string was skipped.
*
* @throws IOException Thrown if i/o error occurs.
* @throws EOFException Thrown on end of file.
*/
public abstract boolean skipString(String s) throws IOException;
public abstract void registerListener(XMLBufferListener listener);
} // class XMLEntityScanner

View File

@@ -0,0 +1,625 @@
/*
* Copyright (c) 2005, 2015, 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;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
import com.sun.org.apache.xerces.internal.util.URI;
import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author K.Venugopal SUN Microsystems
* @author Neeraj Bajaj SUN Microsystems
* @author Andy Clark, IBM
*
*/
public class XMLEntityStorage {
/** Property identifier: error reporter. */
protected static final String ERROR_REPORTER =
Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
/** Feature identifier: warn on duplicate EntityDef */
protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
/** warn on duplicate Entity declaration.
* http://apache.org/xml/features/warn-on-duplicate-entitydef
*/
protected boolean fWarnDuplicateEntityDef;
/** Entities. */
protected Map<String, Entity> fEntities = new HashMap<>();
protected Entity.ScannedEntity fCurrentEntity ;
private XMLEntityManager fEntityManager;
/**
* Error reporter. This property identifier is:
* http://apache.org/xml/properties/internal/error-reporter
*/
protected XMLErrorReporter fErrorReporter;
protected PropertyManager fPropertyManager ;
/* To keep track whether an entity is declared in external or internal subset*/
protected boolean fInExternalSubset = false;
/** Creates a new instance of XMLEntityStorage */
public XMLEntityStorage(PropertyManager propertyManager) {
fPropertyManager = propertyManager ;
}
/** Creates a new instance of XMLEntityStorage */
/*public XMLEntityStorage(Entity.ScannedEntity currentEntity) {
fCurrentEntity = currentEntity ;*/
public XMLEntityStorage(XMLEntityManager entityManager) {
fEntityManager = entityManager;
}
public void reset(PropertyManager propertyManager){
fErrorReporter = (XMLErrorReporter)propertyManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY);
fEntities.clear();
fCurrentEntity = null;
}
public void reset(){
fEntities.clear();
fCurrentEntity = null;
}
/**
* Resets the component. The component can query the component manager
* about any features and properties that affect the operation of the
* component.
*
* @param componentManager The component manager.
*
* @throws SAXException Thrown by component on initialization error.
* For example, if a feature or property is
* required for the operation of the component, the
* component manager may throw a
* SAXNotRecognizedException or a
* SAXNotSupportedException.
*/
public void reset(XMLComponentManager componentManager)
throws XMLConfigurationException {
// xerces features
fWarnDuplicateEntityDef = componentManager.getFeature(WARN_ON_DUPLICATE_ENTITYDEF, false);
fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER);
fEntities.clear();
fCurrentEntity = null;
} // reset(XMLComponentManager)
/**
* Returns entity declaration.
*
* @param name The name of the entity.
*
* @see SymbolTable
*/
public Entity getEntity(String name) {
return fEntities.get(name);
} // getEntity(String)
public boolean hasEntities() {
return (fEntities!=null);
} // getEntity(String)
public int getEntitySize() {
return fEntities.size();
} // getEntity(String)
public Enumeration getEntityKeys() {
return Collections.enumeration(fEntities.keySet());
}
/**
* Adds an internal entity declaration.
* <p>
* <strong>Note:</strong> This method ignores subsequent entity
* declarations.
* <p>
* <strong>Note:</strong> The name should be a unique symbol. The
* SymbolTable can be used for this purpose.
*
* @param name The name of the entity.
* @param text The text of the entity.
*
* @see SymbolTable
*/
public void addInternalEntity(String name, String text) {
if (!fEntities.containsKey(name)) {
Entity entity = new Entity.InternalEntity(name, text, fInExternalSubset);
fEntities.put(name, entity);
}
else{
if(fWarnDuplicateEntityDef){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MSG_DUPLICATE_ENTITY_DEFINITION",
new Object[]{ name },
XMLErrorReporter.SEVERITY_WARNING );
}
}
} // addInternalEntity(String,String)
/**
* Adds an external entity declaration.
* <p>
* <strong>Note:</strong> This method ignores subsequent entity
* declarations.
* <p>
* <strong>Note:</strong> The name should be a unique symbol. The
* SymbolTable can be used for this purpose.
*
* @param name The name of the entity.
* @param publicId The public identifier of the entity.
* @param literalSystemId The system identifier of the entity.
* @param baseSystemId The base system identifier of the entity.
* This is the system identifier of the entity
* where <em>the entity being added</em> and
* is used to expand the system identifier when
* the system identifier is a relative URI.
* When null the system identifier of the first
* external entity on the stack is used instead.
*
* @see SymbolTable
*/
public void addExternalEntity(String name,
String publicId, String literalSystemId,
String baseSystemId) {
if (!fEntities.containsKey(name)) {
if (baseSystemId == null) {
// search for the first external entity on the stack
//xxx commenting the 'size' variable..
/**
* int size = fEntityStack.size();
* if (size == 0 && fCurrentEntity != null && fCurrentEntity.entityLocation != null) {
* baseSystemId = fCurrentEntity.entityLocation.getExpandedSystemId();
* }
*/
//xxx we need to have information about the current entity.
if (fCurrentEntity != null && fCurrentEntity.entityLocation != null) {
baseSystemId = fCurrentEntity.entityLocation.getExpandedSystemId();
}
/**
* for (int i = size - 1; i >= 0 ; i--) {
* ScannedEntity externalEntity =
* (ScannedEntity)fEntityStack.elementAt(i);
* if (externalEntity.entityLocation != null && externalEntity.entityLocation.getExpandedSystemId() != null) {
* baseSystemId = externalEntity.entityLocation.getExpandedSystemId();
* break;
* }
* }
*/
}
fCurrentEntity = fEntityManager.getCurrentEntity();
Entity entity = new Entity.ExternalEntity(name,
new XMLResourceIdentifierImpl(publicId, literalSystemId,
baseSystemId, expandSystemId(literalSystemId, baseSystemId)),
null, fInExternalSubset);
//TODO :: Forced to pass true above remove it.
//(fCurrentEntity == null) ? fasle : fCurrentEntity.isEntityDeclInExternalSubset());
// null, fCurrentEntity.isEntityDeclInExternalSubset());
fEntities.put(name, entity);
}
else{
if(fWarnDuplicateEntityDef){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MSG_DUPLICATE_ENTITY_DEFINITION",
new Object[]{ name },
XMLErrorReporter.SEVERITY_WARNING );
}
}
} // addExternalEntity(String,String,String,String)
/**
* Checks whether an entity given by name is external.
*
* @param entityName The name of the entity to check.
* @returns True if the entity is external, false otherwise
* (including when the entity is not declared).
*/
public boolean isExternalEntity(String entityName) {
Entity entity = fEntities.get(entityName);
if (entity == null) {
return false;
}
return entity.isExternal();
}
/**
* Checks whether the declaration of an entity given by name is
* // in the external subset.
*
* @param entityName The name of the entity to check.
* @returns True if the entity was declared in the external subset, false otherwise
* (including when the entity is not declared).
*/
public boolean isEntityDeclInExternalSubset(String entityName) {
Entity entity = fEntities.get(entityName);
if (entity == null) {
return false;
}
return entity.isEntityDeclInExternalSubset();
}
/**
* Adds an unparsed entity declaration.
* <p>
* <strong>Note:</strong> This method ignores subsequent entity
* declarations.
* <p>
* <strong>Note:</strong> The name should be a unique symbol. The
* SymbolTable can be used for this purpose.
*
* @param name The name of the entity.
* @param publicId The public identifier of the entity.
* @param systemId The system identifier of the entity.
* @param notation The name of the notation.
*
* @see SymbolTable
*/
public void addUnparsedEntity(String name,
String publicId, String systemId,
String baseSystemId, String notation) {
fCurrentEntity = fEntityManager.getCurrentEntity();
if (!fEntities.containsKey(name)) {
Entity entity = new Entity.ExternalEntity(name, new XMLResourceIdentifierImpl(publicId, systemId, baseSystemId, null), notation, fInExternalSubset);
// (fCurrentEntity == null) ? fasle : fCurrentEntity.isEntityDeclInExternalSubset());
// fCurrentEntity.isEntityDeclInExternalSubset());
fEntities.put(name, entity);
}
else{
if(fWarnDuplicateEntityDef){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"MSG_DUPLICATE_ENTITY_DEFINITION",
new Object[]{ name },
XMLErrorReporter.SEVERITY_WARNING );
}
}
} // addUnparsedEntity(String,String,String,String)
/**
* Checks whether an entity given by name is unparsed.
*
* @param entityName The name of the entity to check.
* @returns True if the entity is unparsed, false otherwise
* (including when the entity is not declared).
*/
public boolean isUnparsedEntity(String entityName) {
Entity entity = fEntities.get(entityName);
if (entity == null) {
return false;
}
return entity.isUnparsed();
}
/**
* Checks whether an entity given by name is declared.
*
* @param entityName The name of the entity to check.
* @returns True if the entity is declared, false otherwise.
*/
public boolean isDeclaredEntity(String entityName) {
Entity entity = fEntities.get(entityName);
return entity != null;
}
/**
* Expands a system id and returns the system id as a URI, if
* it can be expanded. A return value of null means that the
* identifier is already expanded. An exception thrown
* indicates a failure to expand the id.
*
* @param systemId The systemId to be expanded.
*
* @return Returns the URI string representing the expanded system
* identifier. A null value indicates that the given
* system identifier is already expanded.
*
*/
public static String expandSystemId(String systemId) {
return expandSystemId(systemId, null);
} // expandSystemId(String):String
// current value of the "user.dir" property
private static String gUserDir;
// escaped value of the current "user.dir" property
private static String gEscapedUserDir;
// which ASCII characters need to be escaped
private static boolean gNeedEscaping[] = new boolean[128];
// the first hex character if a character needs to be escaped
private static char gAfterEscaping1[] = new char[128];
// the second hex character if a character needs to be escaped
private static char gAfterEscaping2[] = new char[128];
private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
// initialize the above 3 arrays
static {
for (int i = 0; i <= 0x1f; i++) {
gNeedEscaping[i] = true;
gAfterEscaping1[i] = gHexChs[i >> 4];
gAfterEscaping2[i] = gHexChs[i & 0xf];
}
gNeedEscaping[0x7f] = true;
gAfterEscaping1[0x7f] = '7';
gAfterEscaping2[0x7f] = 'F';
char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}',
'|', '\\', '^', '~', '[', ']', '`'};
int len = escChs.length;
char ch;
for (int i = 0; i < len; i++) {
ch = escChs[i];
gNeedEscaping[ch] = true;
gAfterEscaping1[ch] = gHexChs[ch >> 4];
gAfterEscaping2[ch] = gHexChs[ch & 0xf];
}
}
// To escape the "user.dir" system property, by using %HH to represent
// special ASCII characters: 0x00~0x1F, 0x7F, ' ', '<', '>', '#', '%'
// and '"'. It's a static method, so needs to be synchronized.
// this method looks heavy, but since the system property isn't expected
// to change often, so in most cases, we only need to return the string
// that was escaped before.
// According to the URI spec, non-ASCII characters (whose value >= 128)
// need to be escaped too.
// REVISIT: don't know how to escape non-ASCII characters, especially
// which encoding to use. Leave them for now.
private static synchronized String getUserDir() {
// get the user.dir property
String userDir = "";
try {
userDir = SecuritySupport.getSystemProperty("user.dir");
}
catch (SecurityException se) {
}
// return empty string if property value is empty string.
if (userDir.length() == 0)
return "";
// compute the new escaped value if the new property value doesn't
// match the previous one
if (userDir.equals(gUserDir)) {
return gEscapedUserDir;
}
// record the new value as the global property value
gUserDir = userDir;
char separator = java.io.File.separatorChar;
userDir = userDir.replace(separator, '/');
int len = userDir.length(), ch;
StringBuffer buffer = new StringBuffer(len*3);
// change C:/blah to /C:/blah
if (len >= 2 && userDir.charAt(1) == ':') {
ch = Character.toUpperCase(userDir.charAt(0));
if (ch >= 'A' && ch <= 'Z') {
buffer.append('/');
}
}
// for each character in the path
int i = 0;
for (; i < len; i++) {
ch = userDir.charAt(i);
// if it's not an ASCII character, break here, and use UTF-8 encoding
if (ch >= 128)
break;
if (gNeedEscaping[ch]) {
buffer.append('%');
buffer.append(gAfterEscaping1[ch]);
buffer.append(gAfterEscaping2[ch]);
// record the fact that it's escaped
}
else {
buffer.append((char)ch);
}
}
// we saw some non-ascii character
if (i < len) {
// get UTF-8 bytes for the remaining sub-string
byte[] bytes = null;
byte b;
try {
bytes = userDir.substring(i).getBytes("UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
// should never happen
return userDir;
}
len = bytes.length;
// for each byte
for (i = 0; i < len; i++) {
b = bytes[i];
// for non-ascii character: make it positive, then escape
if (b < 0) {
ch = b + 256;
buffer.append('%');
buffer.append(gHexChs[ch >> 4]);
buffer.append(gHexChs[ch & 0xf]);
}
else if (gNeedEscaping[b]) {
buffer.append('%');
buffer.append(gAfterEscaping1[b]);
buffer.append(gAfterEscaping2[b]);
}
else {
buffer.append((char)b);
}
}
}
// change blah/blah to blah/blah/
if (!userDir.endsWith("/"))
buffer.append('/');
gEscapedUserDir = buffer.toString();
return gEscapedUserDir;
}
/**
* Expands a system id and returns the system id as a URI, if
* it can be expanded. A return value of null means that the
* identifier is already expanded. An exception thrown
* indicates a failure to expand the id.
*
* @param systemId The systemId to be expanded.
*
* @return Returns the URI string representing the expanded system
* identifier. A null value indicates that the given
* system identifier is already expanded.
*
*/
public static String expandSystemId(String systemId, String baseSystemId) {
// check for bad parameters id
if (systemId == null || systemId.length() == 0) {
return systemId;
}
// if id already expanded, return
try {
new URI(systemId);
return systemId;
} catch (URI.MalformedURIException e) {
// continue on...
}
// normalize id
String id = fixURI(systemId);
// normalize base
URI base = null;
URI uri = null;
try {
if (baseSystemId == null || baseSystemId.length() == 0 ||
baseSystemId.equals(systemId)) {
String dir = getUserDir();
base = new URI("file", "", dir, null, null);
}
else {
try {
base = new URI(fixURI(baseSystemId));
}
catch (URI.MalformedURIException e) {
if (baseSystemId.indexOf(':') != -1) {
// for xml schemas we might have baseURI with
// a specified drive
base = new URI("file", "", fixURI(baseSystemId), null, null);
}
else {
String dir = getUserDir();
dir = dir + fixURI(baseSystemId);
base = new URI("file", "", dir, null, null);
}
}
}
// expand id
uri = new URI(base, id);
}
catch (Exception e) {
// let it go through
}
if (uri == null) {
return systemId;
}
return uri.toString();
} // expandSystemId(String,String):String
//
// Protected static methods
//
/**
* Fixes a platform dependent filename to standard URI form.
*
* @param str The string to fix.
*
* @return Returns the fixed URI string.
*/
protected static String fixURI(String str) {
// handle platform dependent strings
str = str.replace(java.io.File.separatorChar, '/');
// Windows fix
if (str.length() >= 2) {
char ch1 = str.charAt(1);
// change "C:blah" to "/C:blah"
if (ch1 == ':') {
char ch0 = Character.toUpperCase(str.charAt(0));
if (ch0 >= 'A' && ch0 <= 'Z') {
str = "/" + str;
}
}
// change "//blah" to "file://blah"
else if (ch1 == '/' && str.charAt(0) == '/') {
str = "file:" + str;
}
}
// done
return str;
} // fixURI(String):String
// indicate start of external subset
public void startExternalSubset() {
fInExternalSubset = true;
}
public void endExternalSubset() {
fInExternalSubset = false;
}
}

View File

@@ -0,0 +1,287 @@
/*
* Copyright (c) 2005, 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;
import com.sun.xml.internal.stream.events.XMLEventAllocatorImpl;
import java.util.NoSuchElementException;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.util.XMLEventAllocator;
/**
* @author @author Neeraj Bajaj Sun Microsystems
*
*/
public class XMLEventReaderImpl implements javax.xml.stream.XMLEventReader{
protected XMLStreamReader fXMLReader ;
protected XMLEventAllocator fXMLEventAllocator;
//only constructor will do because we delegate everything to underlying XMLStreamReader
public XMLEventReaderImpl(XMLStreamReader reader) throws XMLStreamException {
fXMLReader = reader ;
fXMLEventAllocator = (XMLEventAllocator)reader.getProperty(XMLInputFactory.ALLOCATOR);
if(fXMLEventAllocator == null){
fXMLEventAllocator = new XMLEventAllocatorImpl();
}
fPeekedEvent = fXMLEventAllocator.allocate(fXMLReader);
}
public boolean hasNext() {
//if we have the peeked event return 'true'
if(fPeekedEvent != null)return true;
//this is strange XMLStreamReader throws XMLStreamException
//XMLEventReader doesn't throw XMLStreamException
boolean next = false ;
try{
next = fXMLReader.hasNext();
}catch(XMLStreamException ex){
return false;
}
return next ;
}
public XMLEvent nextEvent() throws XMLStreamException {
//if application peeked return the peeked event
if(fPeekedEvent != null){
fLastEvent = fPeekedEvent ;
fPeekedEvent = null;
return fLastEvent ;
}
else if(fXMLReader.hasNext()){
//advance the reader to next state.
fXMLReader.next();
return fLastEvent = fXMLEventAllocator.allocate(fXMLReader);
}
else{
fLastEvent = null;
throw new NoSuchElementException();
}
}
public void remove(){
//remove of the event is not supported.
throw new java.lang.UnsupportedOperationException();
}
public void close() throws XMLStreamException {
fXMLReader.close();
}
/** Reads the content of a text-only element. Precondition:
* the current event is START_ELEMENT. Postcondition:
* The current event is the corresponding END_ELEMENT.
* @throws XMLStreamException if the current event is not a START_ELEMENT
* or if a non text element is encountered
*/
public String getElementText() throws XMLStreamException {
//we have to keep reference to the 'last event' of the stream to be able
//to make this check - is there another way ? - nb.
if(fLastEvent.getEventType() != XMLEvent.START_ELEMENT){
throw new XMLStreamException(
"parser must be on START_ELEMENT to read next text", fLastEvent.getLocation());
}
// STag content ETag
//[43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)*
//<foo>....some long text say in KB and underlying parser reports multiple character
// but getElementText() events....</foo>
String data = null;
//having a peeked event makes things really worse -- we have to test the first event
if(fPeekedEvent != null){
XMLEvent event = fPeekedEvent ;
fPeekedEvent = null;
int type = event.getEventType();
if( type == XMLEvent.CHARACTERS || type == XMLEvent.SPACE ||
type == XMLEvent.CDATA){
data = event.asCharacters().getData();
}
else if(type == XMLEvent.ENTITY_REFERENCE){
data = ((EntityReference)event).getDeclaration().getReplacementText();
}
else if(type == XMLEvent.COMMENT || type == XMLEvent.PROCESSING_INSTRUCTION){
//ignore
} else if(type == XMLEvent.START_ELEMENT) {
throw new XMLStreamException(
"elementGetText() function expects text only elment but START_ELEMENT was encountered.", event.getLocation());
}else if(type == XMLEvent.END_ELEMENT){
return "";
}
//create the string buffer and add initial data
StringBuffer buffer = new StringBuffer();
if(data != null && data.length() > 0 ) {
buffer.append(data);
}
//get the next event -- we should stop at END_ELEMENT but it can be any thing
//things are worse when implementing this function in XMLEventReader because
//there isn't any function called getText() which can get values for
//space, cdata, characters and entity reference
//nextEvent() would also set the last event.
event = nextEvent();
while(event.getEventType() != XMLEvent.END_ELEMENT){
if( type == XMLEvent.CHARACTERS || type == XMLEvent.SPACE ||
type == XMLEvent.CDATA){
data = event.asCharacters().getData();
}
else if(type == XMLEvent.ENTITY_REFERENCE){
data = ((EntityReference)event).getDeclaration().getReplacementText();
}
else if(type == XMLEvent.COMMENT || type == XMLEvent.PROCESSING_INSTRUCTION){
//ignore
} else if(type == XMLEvent.END_DOCUMENT) {
throw new XMLStreamException("unexpected end of document when reading element text content");
} else if(type == XMLEvent.START_ELEMENT) {
throw new XMLStreamException(
"elementGetText() function expects text only elment but START_ELEMENT was encountered.", event.getLocation());
} else {
throw new XMLStreamException(
"Unexpected event type "+ type, event.getLocation());
}
//add the data to the buffer
if(data != null && data.length() > 0 ) {
buffer.append(data);
}
event = nextEvent();
}
return buffer.toString();
}//if (fPeekedEvent != null)
//if there was no peeked, delegate everything to fXMLReader
//update the last event before returning the text
data = fXMLReader.getElementText();
fLastEvent = fXMLEventAllocator.allocate(fXMLReader);
return data;
}
/** Get the value of a feature/property from the underlying implementation
* @param name The name of the property
* @return The value of the property
* @throws IllegalArgumentException if the property is not supported
*/
public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
return fXMLReader.getProperty(name) ;
}
/** Skips any insignificant space events until a START_ELEMENT or
* END_ELEMENT is reached. If anything other than space characters are
* encountered, an exception is thrown. This method should
* be used when processing element-only content because
* the parser is not able to recognize ignorable whitespace if
* the DTD is missing or not interpreted.
* @throws XMLStreamException if anything other than space characters are encountered
*/
public XMLEvent nextTag() throws XMLStreamException {
//its really a pain if there is peeked event before calling nextTag()
if(fPeekedEvent != null){
//check the peeked event first.
XMLEvent event = fPeekedEvent;
fPeekedEvent = null ;
int eventType = event.getEventType();
//if peeked event is whitespace move to the next event
//if peeked event is PI or COMMENT move to the next event
if( (event.isCharacters() && event.asCharacters().isWhiteSpace())
|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
|| eventType == XMLStreamConstants.COMMENT
|| eventType == XMLStreamConstants.START_DOCUMENT){
event = nextEvent();
eventType = event.getEventType();
}
//we have to have the while loop because there can be many PI or comment event in sucession
while((event.isCharacters() && event.asCharacters().isWhiteSpace())
|| eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
|| eventType == XMLStreamConstants.COMMENT){
event = nextEvent();
eventType = event.getEventType();
}
if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
throw new XMLStreamException("expected start or end tag", event.getLocation());
}
return event;
}
//if there is no peeked event -- delegate the work of getting next event to fXMLReader
fXMLReader.nextTag();
return (fLastEvent = fXMLEventAllocator.allocate(fXMLReader));
}
public Object next() {
Object object = null;
try{
object = nextEvent();
}catch(XMLStreamException streamException){
fLastEvent = null ;
//don't swallow the cause
NoSuchElementException e = new NoSuchElementException(streamException.getMessage());
e.initCause(streamException.getCause());
throw e;
}
return object;
}
public XMLEvent peek() throws XMLStreamException{
//if someone call peek() two times we should just return the peeked event
//this is reset if we call next() or nextEvent()
if(fPeekedEvent != null) return fPeekedEvent;
if(hasNext()){
//revisit: we can implement peek() by calling underlying reader to advance
// the stream and returning the event without the knowledge of the user
// that the stream was advanced but the point is we are advancing the stream
//here. -- nb.
// Is there any application that relies on this behavior ?
//Can it be an application knows that there is particularly very large 'comment' section
//or character data which it doesn't want to read or to be returned as event
//But as of now we are creating every event but it can be optimized not to create
// the event.
fXMLReader.next();
fPeekedEvent = fXMLEventAllocator.allocate(fXMLReader);
return fPeekedEvent;
}else{
return null;
}
}//peek()
private XMLEvent fPeekedEvent;
private XMLEvent fLastEvent;
}//XMLEventReaderImpl

View File

@@ -0,0 +1,305 @@
/*
* Copyright (c) 2005, 2006, 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;
import java.io.InputStream;
import java.io.Reader;
import javax.xml.stream.*;
import javax.xml.stream.util.XMLEventAllocator ;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
import com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl;
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
import com.sun.org.apache.xerces.internal.impl.XMLStreamFilterImpl;
import com.sun.org.apache.xerces.internal.impl.Constants;
/** Factory Implementation for XMLInputFactory.
* @author Neeraj Bajaj Sun Microsystems
* @author K.Venugopal Sun Microsystems
*/
//xxx: Should we be reusing the XMLInputSource object
public class XMLInputFactoryImpl extends javax.xml.stream.XMLInputFactory {
//List of supported properties and default values.
private PropertyManager fPropertyManager = new PropertyManager(PropertyManager.CONTEXT_READER) ;
private static final boolean DEBUG = false;
//Maintain a reference to last reader instantiated.
private XMLStreamReaderImpl fTempReader = null ;
boolean fPropertyChanged = false;
//no reader reuse by default
boolean fReuseInstance = false;
/** Creates a new instance of ZephryParserFactory */
public XMLInputFactoryImpl() {
}
void initEventReader(){
fPropertyChanged = true;
}
/**
* @param inputstream
* @throws XMLStreamException
* @return
*/
public XMLEventReader createXMLEventReader(InputStream inputstream) throws XMLStreamException {
initEventReader();
//delegate everything to XMLStreamReader
return new XMLEventReaderImpl(createXMLStreamReader(inputstream));
}
public XMLEventReader createXMLEventReader(Reader reader) throws XMLStreamException {
initEventReader();
//delegate everything to XMLStreamReader
return new XMLEventReaderImpl(createXMLStreamReader(reader));
}
public XMLEventReader createXMLEventReader(Source source) throws XMLStreamException {
initEventReader();
//delegate everything to XMLStreamReader
return new XMLEventReaderImpl(createXMLStreamReader(source));
}
public XMLEventReader createXMLEventReader(String systemId, InputStream inputstream) throws XMLStreamException {
initEventReader();
//delegate everything to XMLStreamReader
return new XMLEventReaderImpl(createXMLStreamReader(systemId, inputstream));
}
public XMLEventReader createXMLEventReader(java.io.InputStream stream, String encoding) throws XMLStreamException {
initEventReader();
//delegate everything to XMLStreamReader
return new XMLEventReaderImpl(createXMLStreamReader(stream, encoding));
}
public XMLEventReader createXMLEventReader(String systemId, Reader reader) throws XMLStreamException {
initEventReader();
//delegate everything to XMLStreamReader
return new XMLEventReaderImpl(createXMLStreamReader(systemId, reader));
}
/** Create a new XMLEventReader from an XMLStreamReader. After being used
* to construct the XMLEventReader instance returned from this method
* the XMLStreamReader must not be used.
* @param reader the XMLStreamReader to read from (may not be modified)
* @return a new XMLEventReader
* @throws XMLStreamException
*/
public XMLEventReader createXMLEventReader(XMLStreamReader reader) throws XMLStreamException {
//xxx: what do we do now -- instance is passed from the application
//probably we should check if the state is at the start document,
//eventreader call to next() should return START_DOCUMENT and
//then delegate every call to underlying streamReader
return new XMLEventReaderImpl(reader) ;
}
public XMLStreamReader createXMLStreamReader(InputStream inputstream) throws XMLStreamException {
XMLInputSource inputSource = new XMLInputSource(null, null, null, inputstream, null);
return getXMLStreamReaderImpl(inputSource);
}
public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException {
XMLInputSource inputSource = new XMLInputSource(null, null, null, reader, null);
return getXMLStreamReaderImpl(inputSource);
}
public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException {
XMLInputSource inputSource = new XMLInputSource(null,systemId,null,reader,null);
return getXMLStreamReaderImpl(inputSource);
}
public XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException {
return new XMLStreamReaderImpl(jaxpSourcetoXMLInputSource(source),
new PropertyManager(fPropertyManager));
}
public XMLStreamReader createXMLStreamReader(String systemId, InputStream inputstream) throws XMLStreamException {
XMLInputSource inputSource = new XMLInputSource(null,systemId,null,inputstream,null);
return getXMLStreamReaderImpl(inputSource);
}
public XMLStreamReader createXMLStreamReader(InputStream inputstream, String encoding) throws XMLStreamException {
XMLInputSource inputSource = new XMLInputSource(null,null,null,inputstream,encoding);
return getXMLStreamReaderImpl(inputSource);
}
public XMLEventAllocator getEventAllocator() {
return (XMLEventAllocator)getProperty(XMLInputFactory.ALLOCATOR);
}
public XMLReporter getXMLReporter() {
return (XMLReporter)fPropertyManager.getProperty(XMLInputFactory.REPORTER);
}
public XMLResolver getXMLResolver() {
Object object = fPropertyManager.getProperty(XMLInputFactory.RESOLVER);
return (XMLResolver)object;
//return (XMLResolver)fPropertyManager.getProperty(XMLInputFactory.RESOLVER);
}
public void setXMLReporter(XMLReporter xmlreporter) {
fPropertyManager.setProperty(XMLInputFactory.REPORTER, xmlreporter);
}
public void setXMLResolver(XMLResolver xmlresolver) {
fPropertyManager.setProperty(XMLInputFactory.RESOLVER, xmlresolver);
}
/** Create a filtered event reader that wraps the filter around the event reader
* @param reader the event reader to wrap
* @param filter the filter to apply to the event reader
* @throws XMLStreamException
*/
public XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter) throws XMLStreamException {
return new EventFilterSupport(reader, filter);
}
/** Create a filtered reader that wraps the filter around the reader
* @param reader the reader to filter
* @param filter the filter to apply to the reader
* @throws XMLStreamException
*/
public XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter) throws XMLStreamException {
if( reader != null && filter != null )
return new XMLStreamFilterImpl(reader,filter);
return null;
}
/** Get the value of a feature/property from the underlying implementation
* @param name The name of the property (may not be null)
* @return The value of the property
* @throws IllegalArgumentException if the property is not supported
*/
public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
if(name == null){
throw new IllegalArgumentException("Property not supported");
}
if(fPropertyManager.containsProperty(name))
return fPropertyManager.getProperty(name);
throw new IllegalArgumentException("Property not supported");
}
/** Query the set of fProperties that this factory supports.
*
* @param name The name of the property (may not be null)
* @return true if the property is supported and false otherwise
*/
public boolean isPropertySupported(String name) {
if(name == null)
return false ;
else
return fPropertyManager.containsProperty(name);
}
/** Set a user defined event allocator for events
* @param allocator the user defined allocator
*/
public void setEventAllocator(XMLEventAllocator allocator) {
fPropertyManager.setProperty(XMLInputFactory.ALLOCATOR, allocator);
}
/** Allows the user to set specific feature/property on the underlying implementation. The underlying implementation
* is not required to support every setting of every property in the specification and may use IllegalArgumentException
* to signal that an unsupported property may not be set with the specified value.
* @param name The name of the property (may not be null)
* @param value The value of the property
* @throws java.lang.IllegalArgumentException if the property is not supported
*/
public void setProperty(java.lang.String name, Object value) throws java.lang.IllegalArgumentException {
if(name == null || value == null || !fPropertyManager.containsProperty(name) ){
throw new IllegalArgumentException("Property "+name+" is not supported");
}
if(name == Constants.REUSE_INSTANCE || name.equals(Constants.REUSE_INSTANCE)){
fReuseInstance = ((Boolean)value).booleanValue();
if(DEBUG)System.out.println("fReuseInstance is set to " + fReuseInstance);
}else{//for any other property set the flag
//REVISIT: Even in this case instance can be reused, by passing PropertyManager
fPropertyChanged = true;
}
fPropertyManager.setProperty(name,value);
}
XMLStreamReader getXMLStreamReaderImpl(XMLInputSource inputSource) throws javax.xml.stream.XMLStreamException{
//1. if the temp reader is null -- create the instance and return
if(fTempReader == null){
fPropertyChanged = false;
return fTempReader = new XMLStreamReaderImpl(inputSource,
new PropertyManager(fPropertyManager));
}
//if factory is configured to reuse the instance & this instance can be reused
//& the setProperty() hasn't been called
if(fReuseInstance && fTempReader.canReuse() && !fPropertyChanged){
if(DEBUG)System.out.println("Reusing the instance");
//we can make setInputSource() call reset() and this way there wont be two function calls
fTempReader.reset();
fTempReader.setInputSource(inputSource);
fPropertyChanged = false;
return fTempReader;
}else{
fPropertyChanged = false;
//just return the new instance.. note that we are not setting fTempReader to the newly created instance
return fTempReader = new XMLStreamReaderImpl(inputSource,
new PropertyManager(fPropertyManager));
}
}
XMLInputSource jaxpSourcetoXMLInputSource(Source source){
if(source instanceof StreamSource){
StreamSource stSource = (StreamSource)source;
String systemId = stSource.getSystemId();
String publicId = stSource.getPublicId();
InputStream istream = stSource.getInputStream();
Reader reader = stSource.getReader();
if(istream != null){
return new XMLInputSource(publicId, systemId, null, istream, null);
}
else if(reader != null){
return new XMLInputSource(publicId, systemId,null, reader, null);
}else{
return new XMLInputSource(publicId, systemId, null);
}
}
throw new UnsupportedOperationException("Cannot create " +
"XMLStreamReader or XMLEventReader from a " +
source.getClass().getName());
}
}//XMLInputFactoryImpl

View File

@@ -0,0 +1,199 @@
/*
* Copyright (c) 2005, 2006, 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;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import javax.xml.stream.XMLOutputFactory ;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stax.StAXResult;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
import com.sun.xml.internal.stream.writers.XMLDOMWriterImpl;
import com.sun.xml.internal.stream.writers.XMLEventWriterImpl;
import com.sun.xml.internal.stream.writers.XMLStreamWriterImpl;
/**
* This class provides the implementation of XMLOutputFactory.
*
* @author Neeraj Bajaj,
* @author k.venugopal@sun.com
*/
public class XMLOutputFactoryImpl extends XMLOutputFactory {
//List of supported properties and default values.
private PropertyManager fPropertyManager = new PropertyManager(PropertyManager.CONTEXT_WRITER);
//cache the instance of XMLStreamWriterImpl
private XMLStreamWriterImpl fStreamWriter = null;
/**
* TODO: at the current time, XMLStreamWriters are not Thread safe.
*/
boolean fReuseInstance = false;
/** Creates a new instance of XMLOutputFactory */
public XMLOutputFactoryImpl() {
}
public javax.xml.stream.XMLEventWriter createXMLEventWriter(java.io.OutputStream outputStream) throws javax.xml.stream.XMLStreamException {
return createXMLEventWriter(outputStream, null);
}
public javax.xml.stream.XMLEventWriter createXMLEventWriter(java.io.OutputStream outputStream, String encoding) throws javax.xml.stream.XMLStreamException {
return new XMLEventWriterImpl(createXMLStreamWriter(outputStream, encoding));
}
public javax.xml.stream.XMLEventWriter createXMLEventWriter(javax.xml.transform.Result result) throws javax.xml.stream.XMLStreamException {
if (result instanceof StAXResult && ((StAXResult)result).getXMLEventWriter() != null)
return ((StAXResult)result).getXMLEventWriter();
return new XMLEventWriterImpl(createXMLStreamWriter(result));
}
public javax.xml.stream.XMLEventWriter createXMLEventWriter(java.io.Writer writer) throws javax.xml.stream.XMLStreamException {
return new XMLEventWriterImpl(createXMLStreamWriter(writer));
}
public javax.xml.stream.XMLStreamWriter createXMLStreamWriter(javax.xml.transform.Result result) throws javax.xml.stream.XMLStreamException {
if (result instanceof StreamResult) {
return createXMLStreamWriter((StreamResult) result, null);
} else if (result instanceof DOMResult) {
return new XMLDOMWriterImpl((DOMResult) result);
} else if (result instanceof StAXResult) {
if (((StAXResult) result).getXMLStreamWriter() != null) {
return ((StAXResult) result).getXMLStreamWriter();
} else {
throw new java.lang.UnsupportedOperationException("Result of type " + result + " is not supported");
}
} else {
if (result.getSystemId() !=null) {
//this is not correct impl of SAXResult. Keep it for now for compatibility
return createXMLStreamWriter(new StreamResult(result.getSystemId()));
} else {
throw new java.lang.UnsupportedOperationException("Result of type " + result + " is not supported. " +
"Supported result types are: DOMResult, StAXResult and StreamResult.");
}
}
}
public javax.xml.stream.XMLStreamWriter createXMLStreamWriter(java.io.Writer writer) throws javax.xml.stream.XMLStreamException {
return createXMLStreamWriter(toStreamResult(null, writer, null) , null);
}
public javax.xml.stream.XMLStreamWriter createXMLStreamWriter(java.io.OutputStream outputStream) throws javax.xml.stream.XMLStreamException {
return createXMLStreamWriter(outputStream, null);
}
public javax.xml.stream.XMLStreamWriter createXMLStreamWriter(java.io.OutputStream outputStream, String encoding) throws javax.xml.stream.XMLStreamException {
return createXMLStreamWriter(toStreamResult(outputStream, null, null) , encoding);
}
public Object getProperty(String name) throws java.lang.IllegalArgumentException {
if(name == null){
throw new IllegalArgumentException("Property not supported");
}
if(fPropertyManager.containsProperty(name))
return fPropertyManager.getProperty(name);
throw new IllegalArgumentException("Property not supported");
}
public boolean isPropertySupported(String name) {
if(name == null){
return false ;
}
else{
return fPropertyManager.containsProperty(name);
}
}
public void setProperty(String name, Object value) throws java.lang.IllegalArgumentException {
if(name == null || value == null || !fPropertyManager.containsProperty(name) ){
throw new IllegalArgumentException("Property "+name+"is not supported");
}
if(name == Constants.REUSE_INSTANCE || name.equals(Constants.REUSE_INSTANCE)){
fReuseInstance = ((Boolean)value).booleanValue();
if(DEBUG)System.out.println("fReuseInstance is set to " + fReuseInstance);
// TODO: XMLStreamWriters are not Thread safe,
// don't let application think it is optimizing
if (fReuseInstance) {
throw new IllegalArgumentException(
"Property "
+ name
+ " is not supported: XMLStreamWriters are not Thread safe");
}
}else{//for any other property set the flag
//REVISIT: Even in this case instance can be reused, by passing PropertyManager
fPropertyChanged = true;
}
fPropertyManager.setProperty(name,value);
}
/** StreamResult object is re-used and the values are set appropriately.
*/
StreamResult toStreamResult(OutputStream os, Writer writer, String systemId){
StreamResult sr = new StreamResult();
sr.setOutputStream(os);
sr.setWriter(writer);
sr.setSystemId(systemId);
return sr;
}
javax.xml.stream.XMLStreamWriter createXMLStreamWriter(javax.xml.transform.stream.StreamResult sr, String encoding) throws javax.xml.stream.XMLStreamException {
//if factory is configured to reuse the instance & this instance can be reused
//& the setProperty() hasn't been called
try{
if(fReuseInstance && fStreamWriter != null && fStreamWriter.canReuse() && !fPropertyChanged){
fStreamWriter.reset();
fStreamWriter.setOutput(sr, encoding);
if(DEBUG)System.out.println("reusing instance, object id : " + fStreamWriter);
return fStreamWriter;
}
return fStreamWriter = new XMLStreamWriterImpl(sr, encoding, new PropertyManager(fPropertyManager));
}catch(java.io.IOException io){
throw new XMLStreamException(io);
}
}//createXMLStreamWriter(StreamResult,String)
private static final boolean DEBUG = false;
/** This flag indicates the change of property. If true,
* <code>PropertyManager</code> should be passed when creating
* <code>XMLStreamWriterImpl</code> */
private boolean fPropertyChanged ;
}//XMLOutputFactory

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

@@ -0,0 +1,498 @@
/*
* Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream.dtd;
import com.sun.xml.internal.stream.dtd.nonvalidating.DTDGrammar;
import com.sun.xml.internal.stream.dtd.nonvalidating.XMLAttributeDecl;
import com.sun.xml.internal.stream.dtd.nonvalidating.XMLElementDecl;
import com.sun.xml.internal.stream.dtd.nonvalidating.XMLSimpleType;
import com.sun.org.apache.xerces.internal.impl.Constants;
import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
import javax.xml.XMLConstants;
/*
* @author Eric Ye, IBM
* @author Andy Clark, IBM
* @author Jeffrey Rodriguez IBM
* @author Neil Graham, IBM
* @author Sunitha Reddy, Sun Microsystems
*/
public class DTDGrammarUtil {
/** Property identifier: symbol table. */
protected static final String SYMBOL_TABLE =
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
protected static final String NAMESPACES =
Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
/** Compile to true to debug attributes. */
private static final boolean DEBUG_ATTRIBUTES = false;
/** Compile to true to debug element children. */
private static final boolean DEBUG_ELEMENT_CHILDREN = false;
protected DTDGrammar fDTDGrammar = null;
/** Namespaces. */
protected boolean fNamespaces;
/** Symbol table. */
protected SymbolTable fSymbolTable = null;
/** Current element index. */
private int fCurrentElementIndex = -1;
/** Current content spec type. */
private int fCurrentContentSpecType = -1;
/** Content spec type stack. */
private boolean[] fElementContentState = new boolean[8];
/** Element depth. */
private int fElementDepth = -1;
/** True if inside of element content. */
private boolean fInElementContent = false;
/** Temporary atribute declaration. */
private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl();
/** Temporary qualified name. */
private QName fTempQName = new QName();
/** Temporary string buffers. */
private StringBuffer fBuffer = new StringBuffer();
private NamespaceContext fNamespaceContext = null;
/** Default constructor. */
public DTDGrammarUtil(SymbolTable symbolTable) {
fSymbolTable = symbolTable;
}
public DTDGrammarUtil(DTDGrammar grammar, SymbolTable symbolTable) {
fDTDGrammar = grammar;
fSymbolTable = symbolTable;
}
public DTDGrammarUtil(DTDGrammar grammar, SymbolTable symbolTable,
NamespaceContext namespaceContext) {
fDTDGrammar = grammar;
fSymbolTable = symbolTable;
fNamespaceContext = namespaceContext;
}
/*
* Resets the component. The component can query the component manager
* about any features and properties that affect the operation of the
* component.
*
* @param componentManager The component manager.
*
* @throws SAXException Thrown by component on finitialization error.
* For example, if a feature or property is
* required for the operation of the component, the
* component manager may throw a
* SAXNotRecognizedException or a
* SAXNotSupportedException.
*/
public void reset(XMLComponentManager componentManager)
throws XMLConfigurationException {
fDTDGrammar = null;
fInElementContent = false;
fCurrentElementIndex = -1;
fCurrentContentSpecType = -1;
fNamespaces = componentManager.getFeature(NAMESPACES, true);
fSymbolTable = (SymbolTable) componentManager.getProperty(
Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY);
fElementDepth = -1;
}
/**
* The start of an element.
*
* @param element The name of the element.
* @param attributes The element attributes.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void startElement(QName element, XMLAttributes attributes) throws XNIException {
handleStartElement(element, attributes);
}
/**
* The end of an element.
*
* @param element The name of the element.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void endElement(QName element) throws XNIException {
handleEndElement(element);
}
/**
* The start of a CDATA section.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void startCDATA(Augmentations augs) throws XNIException {
}
/**
* The end of a CDATA section.
* @param augs Additional information that may include infoset augmentations
*
* @throws XNIException Thrown by handler to signal an error.
*/
public void endCDATA(Augmentations augs) throws XNIException {
}
/** Add default attributes and validate. */
public void addDTDDefaultAttrs(QName elementName, XMLAttributes attributes)
throws XNIException {
int elementIndex;
elementIndex = fDTDGrammar.getElementDeclIndex(elementName);
// is there anything to do?
if (elementIndex == -1 || fDTDGrammar == null) {
return;
}
//
// Check after all specified attrs are scanned
// (1) report error for REQUIRED attrs that are missing (V_TAGc)
// (2) add default attrs (FIXED and NOT_FIXED)
//
int attlistIndex = fDTDGrammar.getFirstAttributeDeclIndex(elementIndex);
while (attlistIndex != -1) {
fDTDGrammar.getAttributeDecl(attlistIndex, fTempAttDecl);
if (DEBUG_ATTRIBUTES) {
if (fTempAttDecl != null) {
XMLElementDecl elementDecl = new XMLElementDecl();
fDTDGrammar.getElementDecl(elementIndex, elementDecl);
System.out.println("element: " + (elementDecl.name.localpart));
System.out.println("attlistIndex " + attlistIndex + "\n" +
"attName : '" + (fTempAttDecl.name.localpart) + "'\n"
+ "attType : " + fTempAttDecl.simpleType.type + "\n"
+ "attDefaultType : " + fTempAttDecl.simpleType.defaultType + "\n"
+ "attDefaultValue : '" + fTempAttDecl.simpleType.defaultValue + "'\n"
+ attributes.getLength() + "\n"
);
}
}
String attPrefix = fTempAttDecl.name.prefix;
String attLocalpart = fTempAttDecl.name.localpart;
String attRawName = fTempAttDecl.name.rawname;
String attType = getAttributeTypeName(fTempAttDecl);
int attDefaultType = fTempAttDecl.simpleType.defaultType;
String attValue = null;
if (fTempAttDecl.simpleType.defaultValue != null) {
attValue = fTempAttDecl.simpleType.defaultValue;
}
boolean specified = false;
boolean required = attDefaultType == XMLSimpleType.DEFAULT_TYPE_REQUIRED;
boolean cdata = attType == XMLSymbols.fCDATASymbol;
if (!cdata || required || attValue != null) {
//check whether attribute is a namespace declaration
if (fNamespaceContext != null && attRawName.startsWith(XMLConstants.XMLNS_ATTRIBUTE)) {
String prefix = "";
int pos = attRawName.indexOf(':');
if (pos != -1) {
prefix = attRawName.substring(0, pos);
} else {
prefix = attRawName;
}
prefix = fSymbolTable.addSymbol(prefix);
if (!((com.sun.org.apache.xerces.internal.util.
NamespaceSupport) fNamespaceContext).
containsPrefixInCurrentContext(prefix)) {
fNamespaceContext.declarePrefix(prefix, attValue);
}
specified = true;
} else {
int attrCount = attributes.getLength();
for (int i = 0; i < attrCount; i++) {
if (attributes.getQName(i) == attRawName) {
specified = true;
break;
}
}
}
}
if (!specified) {
if (attValue != null) {
if (fNamespaces) {
int index = attRawName.indexOf(':');
if (index != -1) {
attPrefix = attRawName.substring(0, index);
attPrefix = fSymbolTable.addSymbol(attPrefix);
attLocalpart = attRawName.substring(index + 1);
attLocalpart = fSymbolTable.addSymbol(attLocalpart);
}
}
fTempQName.setValues(attPrefix, attLocalpart, attRawName,
fTempAttDecl.name.uri);
int newAttr = attributes.addAttribute(fTempQName, attType,
attValue);
}
}
attlistIndex = fDTDGrammar.getNextAttributeDeclIndex(attlistIndex);
}
// now iterate through the expanded attributes for
// 1. if every attribute seen is declared in the DTD
// 2. check if the VC: default_fixed holds
// 3. validate every attribute.
int attrCount = attributes.getLength();
for (int i = 0; i < attrCount; i++) {
String attrRawName = attributes.getQName(i);
boolean declared = false;
int position =
fDTDGrammar.getFirstAttributeDeclIndex(elementIndex);
while (position != -1) {
fDTDGrammar.getAttributeDecl(position, fTempAttDecl);
if (fTempAttDecl.name.rawname == attrRawName) {
// found the match att decl,
declared = true;
break;
}
position = fDTDGrammar.getNextAttributeDeclIndex(position);
}
if (!declared) {
continue;
}
String type = getAttributeTypeName(fTempAttDecl);
attributes.setType(i, type);
boolean changedByNormalization = false;
if (attributes.isSpecified(i) && type != XMLSymbols.fCDATASymbol) {
changedByNormalization = normalizeAttrValue(attributes, i);
}
} // for all attributes
} // addDTDDefaultAttrsAndValidate(int,XMLAttrList)
/**
* Normalize the attribute value of a non CDATA attributes collapsing
* sequences of space characters (x20)
*
* @param attributes The list of attributes
* @param index The index of the attribute to normalize
*/
private boolean normalizeAttrValue(XMLAttributes attributes, int index) {
// vars
boolean leadingSpace = true;
boolean spaceStart = false;
boolean readingNonSpace = false;
int count = 0;
int eaten = 0;
String attrValue = attributes.getValue(index);
char[] attValue = new char[attrValue.length()];
fBuffer.setLength(0);
attrValue.getChars(0, attrValue.length(), attValue, 0);
for (int i = 0; i < attValue.length; i++) {
if (attValue[i] == ' ') {
// now the tricky part
if (readingNonSpace) {
spaceStart = true;
readingNonSpace = false;
}
if (spaceStart && !leadingSpace) {
spaceStart = false;
fBuffer.append(attValue[i]);
count++;
} else {
if (leadingSpace || !spaceStart) {
eaten++;
}
}
} else {
readingNonSpace = true;
spaceStart = false;
leadingSpace = false;
fBuffer.append(attValue[i]);
count++;
}
}
// check if the last appended character is a space.
if (count > 0 && fBuffer.charAt(count - 1) == ' ') {
fBuffer.setLength(count - 1);
}
String newValue = fBuffer.toString();
attributes.setValue(index, newValue);
return !attrValue.equals(newValue);
}
/** convert attribute type from ints to strings */
private String getAttributeTypeName(XMLAttributeDecl attrDecl) {
switch (attrDecl.simpleType.type) {
case XMLSimpleType.TYPE_ENTITY: {
return attrDecl.simpleType.list ? XMLSymbols.fENTITIESSymbol :
XMLSymbols.fENTITYSymbol;
}
case XMLSimpleType.TYPE_ENUMERATION: {
StringBuffer buffer = new StringBuffer();
buffer.append('(');
for (int i = 0; i < attrDecl.simpleType.enumeration.length; i++) {
if (i > 0) {
buffer.append("|");
}
buffer.append(attrDecl.simpleType.enumeration[i]);
}
buffer.append(')');
return fSymbolTable.addSymbol(buffer.toString());
}
case XMLSimpleType.TYPE_ID: {
return XMLSymbols.fIDSymbol;
}
case XMLSimpleType.TYPE_IDREF: {
return attrDecl.simpleType.list ? XMLSymbols.fIDREFSSymbol :
XMLSymbols.fIDREFSymbol;
}
case XMLSimpleType.TYPE_NMTOKEN: {
return attrDecl.simpleType.list ? XMLSymbols.fNMTOKENSSymbol :
XMLSymbols.fNMTOKENSymbol;
}
case XMLSimpleType.TYPE_NOTATION: {
return XMLSymbols.fNOTATIONSymbol;
}
}
return XMLSymbols.fCDATASymbol;
}
/** ensure element stack capacity */
private void ensureStackCapacity(int newElementDepth) {
if (newElementDepth == fElementContentState.length) {
boolean[] newStack = new boolean[newElementDepth * 2];
System.arraycopy(this.fElementContentState, 0, newStack, 0,
newElementDepth);
fElementContentState = newStack;
}
}
/** Handle element
* @return true if validator is removed from the pipeline
*/
protected void handleStartElement(QName element, XMLAttributes attributes) throws XNIException {
if (fDTDGrammar == null) {
fCurrentElementIndex = -1;
fCurrentContentSpecType = -1;
fInElementContent = false;
return;
} else {
fCurrentElementIndex = fDTDGrammar.getElementDeclIndex(element);
fCurrentContentSpecType = fDTDGrammar.getContentSpecType(
fCurrentElementIndex);
//handleDTDDefaultAttrs(element,attributes);
addDTDDefaultAttrs(element, attributes);
}
fInElementContent = fCurrentContentSpecType == XMLElementDecl.TYPE_CHILDREN;
fElementDepth++;
ensureStackCapacity(fElementDepth);
fElementContentState[fElementDepth] = fInElementContent;
}
/** Handle end element. */
protected void handleEndElement(QName element) throws XNIException {
if (fDTDGrammar == null) return;
fElementDepth--;
if (fElementDepth < -1) {
throw new RuntimeException("FWK008 Element stack underflow");
}
if (fElementDepth < 0) {
fCurrentElementIndex = -1;
fCurrentContentSpecType = -1;
fInElementContent = false;
return;
}
fInElementContent = fElementContentState[fElementDepth];
}
public boolean isInElementContent() {
return fInElementContent;
}
public boolean isIgnorableWhiteSpace(XMLString text) {
if (isInElementContent()) {
for (int i = text.offset; i < text.offset + text.length; i++) {
if (!XMLChar.isSpace(text.ch[i])) {
return false;
}
}
return true;
}
return false;
}
}

View File

@@ -0,0 +1,878 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream.dtd.nonvalidating;
import com.sun.org.apache.xerces.internal.util.SymbolTable;
import com.sun.org.apache.xerces.internal.util.XMLSymbols;
import com.sun.org.apache.xerces.internal.xni.Augmentations;
import com.sun.org.apache.xerces.internal.xni.QName;
import com.sun.org.apache.xerces.internal.xni.XMLLocator;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import com.sun.org.apache.xerces.internal.xni.XMLString;
import com.sun.org.apache.xerces.internal.xni.XNIException;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDContentModelSource;
import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* A DTD grammar. This class implements the XNI handler interfaces
* for DTD information so that it can build the approprate validation
* structures automatically from the callbacks.
*
* @author Eric Ye, IBM
* @author Jeffrey Rodriguez, IBM
* @author Andy Clark, IBM
* @author Neil Graham, IBM
*
*/
public class DTDGrammar {
/** Top level scope (-1). */
public static final int TOP_LEVEL_SCOPE = -1;
// private
/** Chunk shift (8). */
private static final int CHUNK_SHIFT = 8; // 2^8 = 256
/** Chunk size (1 << CHUNK_SHIFT). */
private static final int CHUNK_SIZE = (1 << CHUNK_SHIFT);
/** Chunk mask (CHUNK_SIZE - 1). */
private static final int CHUNK_MASK = CHUNK_SIZE - 1;
/** Initial chunk count (1 << (10 - CHUNK_SHIFT)). */
private static final int INITIAL_CHUNK_COUNT = (1 << (10 - CHUNK_SHIFT)); // 2^10 = 1k
/** List flag (0x80). */
private static final short LIST_FLAG = 0x80;
/** List mask (~LIST_FLAG). */
private static final short LIST_MASK = ~LIST_FLAG;
// debugging
/** Debug DTDGrammar. */
private static final boolean DEBUG = false;
//
// Data
//
protected XMLDTDSource fDTDSource = null;
protected XMLDTDContentModelSource fDTDContentModelSource = null;
/** Current element index. */
protected int fCurrentElementIndex;
/** Current attribute index. */
protected int fCurrentAttributeIndex;
/** fReadingExternalDTD */
protected boolean fReadingExternalDTD = false;
/** Symbol table. */
private SymbolTable fSymbolTable;
private ArrayList notationDecls = new ArrayList();
// element declarations
/** Number of element declarations. */
private int fElementDeclCount = 0;
/** Element declaration name. */
private QName fElementDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
/**
* Element declaration type.
* @see XMLElementDecl
*/
private short fElementDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
/** First attribute declaration of an element declaration. */
private int fElementDeclFirstAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
/** Last attribute declaration of an element declaration. */
private int fElementDeclLastAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
// attribute declarations
/** Number of attribute declarations. */
private int fAttributeDeclCount = 0 ;
/** Attribute declaration name. */
private QName fAttributeDeclName[][] = new QName[INITIAL_CHUNK_COUNT][];
/**
* Attribute declaration type.
* @see XMLAttributeDecl
*/
private short fAttributeDeclType[][] = new short[INITIAL_CHUNK_COUNT][];
/** Attribute declaration enumeration values. */
private String[] fAttributeDeclEnumeration[][] = new String[INITIAL_CHUNK_COUNT][][];
private short fAttributeDeclDefaultType[][] = new short[INITIAL_CHUNK_COUNT][];
private String fAttributeDeclDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
private String fAttributeDeclNonNormalizedDefaultValue[][] = new String[INITIAL_CHUNK_COUNT][];
private int fAttributeDeclNextAttributeDeclIndex[][] = new int[INITIAL_CHUNK_COUNT][];
/** Element index mapping table. */
private final Map<String, Integer> fElementIndexMap = new HashMap<>();
/** Temporary qualified name. */
private final QName fQName = new QName();
/** Temporary Attribute decl. */
protected XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl();
/** Element declaration. */
private XMLElementDecl fElementDecl = new XMLElementDecl();
/** Simple type. */
private XMLSimpleType fSimpleType = new XMLSimpleType();
/** table of XMLElementDecl */
Map<String, XMLElementDecl> fElementDeclTab = new HashMap<>();
/** Default constructor. */
public DTDGrammar(SymbolTable symbolTable) {
fSymbolTable = symbolTable;
}
public int getAttributeDeclIndex(int elementDeclIndex, String attributeDeclName) {
if (elementDeclIndex == -1) {
return -1;
}
int attDefIndex = getFirstAttributeDeclIndex(elementDeclIndex);
while (attDefIndex != -1) {
getAttributeDecl(attDefIndex, fAttributeDecl);
if (fAttributeDecl.name.rawname == attributeDeclName
|| attributeDeclName.equals(fAttributeDecl.name.rawname) ) {
return attDefIndex;
}
attDefIndex = getNextAttributeDeclIndex(attDefIndex);
}
return -1;
}
/**
* The start of the DTD.
*
* @param locator The document locator, or null if the document
* location cannot be reported during the parsing of
* the document DTD. However, it is <em>strongly</em>
* recommended that a locator be supplied that can
* at least report the base system identifier of the
* DTD.
*
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*/
public void startDTD(XMLLocator locator, Augmentations augs) throws XNIException {
} // startDTD(XMLLocator)
// startExternalSubset(Augmentations)
// endExternalSubset(Augmentations)
/**
* An element declaration.
*
* @param name The name of the element.
* @param contentModel The element content model.
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*/
public void elementDecl(String name, String contentModel, Augmentations augs)
throws XNIException {
XMLElementDecl tmpElementDecl = fElementDeclTab.get(name) ;
if ( tmpElementDecl != null ) {
if (tmpElementDecl.type == -1) {
fCurrentElementIndex = getElementDeclIndex(name);
}
else {
// duplicate element, ignored.
return;
}
}
else {
fCurrentElementIndex = createElementDecl();//create element decl
}
XMLElementDecl elementDecl = new XMLElementDecl();
QName elementName = new QName(null, name, name, null);
elementDecl.name.setValues(elementName);
elementDecl.scope= -1;
if (contentModel.equals("EMPTY")) {
elementDecl.type = XMLElementDecl.TYPE_EMPTY;
}
else if (contentModel.equals("ANY")) {
elementDecl.type = XMLElementDecl.TYPE_ANY;
}
else if (contentModel.startsWith("(") ) {
if (contentModel.indexOf("#PCDATA") > 0 ) {
elementDecl.type = XMLElementDecl.TYPE_MIXED;
}
else {
elementDecl.type = XMLElementDecl.TYPE_CHILDREN;
}
}
//add(or set) this elementDecl to the local cache
this.fElementDeclTab.put(name, elementDecl );
fElementDecl = elementDecl;
if ( DEBUG ) {
System.out.println( "name = " + fElementDecl.name.localpart );
System.out.println( "Type = " + fElementDecl.type );
}
setElementDecl(fCurrentElementIndex, fElementDecl );//set internal structure
int chunk = fCurrentElementIndex >> CHUNK_SHIFT;
ensureElementDeclCapacity(chunk);
}
/**
* An attribute declaration.
*
* @param elementName The name of the element that this attribute
* is associated with.
* @param attributeName The name of the attribute.
* @param type The attribute type. This value will be one of
* the following: "CDATA", "ENTITY", "ENTITIES",
* "ENUMERATION", "ID", "IDREF", "IDREFS",
* "NMTOKEN", "NMTOKENS", or "NOTATION".
* @param enumeration If the type has the value "ENUMERATION", this
* array holds the allowed attribute values;
* otherwise, this array is null.
* @param defaultType The attribute default type. This value will be
* one of the following: "#FIXED", "#IMPLIED",
* "#REQUIRED", or null.
* @param defaultValue The attribute default value, or null if no
* default value is specified.
* @param nonNormalizedDefaultValue The attribute default value with no normalization
* performed, or null if no default value is specified.
*
* @param augs Additional information that may include infoset
* augmentations.
* @throws XNIException Thrown by handler to signal an error.
*/
public void attributeDecl(String elementName, String attributeName,
String type, String[] enumeration,
String defaultType, XMLString defaultValue,
XMLString nonNormalizedDefaultValue, Augmentations augs) throws XNIException {
if (type != XMLSymbols.fCDATASymbol && defaultValue != null) {
normalizeDefaultAttrValue(defaultValue);
}
if ( this.fElementDeclTab.containsKey(elementName)) {
//if ElementDecl has already being created in the Grammar then remove from table,
//this.fElementDeclTab.remove( (String) elementName );
}
// then it is forward reference to a element decl, create the elementDecl first.
else {
fCurrentElementIndex = createElementDecl();//create element decl
XMLElementDecl elementDecl = new XMLElementDecl();
elementDecl.name.setValues(null, elementName, elementName, null);
elementDecl.scope= -1;
//add(or set) this elementDecl to the local cache
this.fElementDeclTab.put(elementName, elementDecl );
//set internal structure
setElementDecl(fCurrentElementIndex, elementDecl );
}
//Get Grammar index to grammar array
int elementIndex = getElementDeclIndex(elementName);
//return, when more than one definition is provided for the same attribute of given element type
//only the first declaration is binding and later declarations are ignored
if (getAttributeDeclIndex(elementIndex, attributeName) != -1) {
return;
}
fCurrentAttributeIndex = createAttributeDecl();// Create current Attribute Decl
fSimpleType.clear();
if ( defaultType != null ) {
if ( defaultType.equals( "#FIXED") ) {
fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_FIXED;
} else if ( defaultType.equals( "#IMPLIED") ) {
fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_IMPLIED;
} else if ( defaultType.equals( "#REQUIRED") ) {
fSimpleType.defaultType = fSimpleType.DEFAULT_TYPE_REQUIRED;
}
}
if ( DEBUG ) {
System.out.println("defaultvalue = " + defaultValue.toString() );
}
fSimpleType.defaultValue = defaultValue!=null ? defaultValue.toString() : null;
fSimpleType.nonNormalizedDefaultValue = nonNormalizedDefaultValue!=null ? nonNormalizedDefaultValue.toString() : null;
fSimpleType.enumeration = enumeration;
if (type.equals("CDATA")) {
fSimpleType.type = XMLSimpleType.TYPE_CDATA;
}
else if ( type.equals("ID") ) {
fSimpleType.type = XMLSimpleType.TYPE_ID;
}
else if ( type.startsWith("IDREF") ) {
fSimpleType.type = XMLSimpleType.TYPE_IDREF;
if (type.indexOf("S") > 0) {
fSimpleType.list = true;
}
}
else if (type.equals("ENTITIES")) {
fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
fSimpleType.list = true;
}
else if (type.equals("ENTITY")) {
fSimpleType.type = XMLSimpleType.TYPE_ENTITY;
}
else if (type.equals("NMTOKENS")) {
fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
fSimpleType.list = true;
}
else if (type.equals("NMTOKEN")) {
fSimpleType.type = XMLSimpleType.TYPE_NMTOKEN;
}
else if (type.startsWith("NOTATION") ) {
fSimpleType.type = XMLSimpleType.TYPE_NOTATION;
}
else if (type.startsWith("ENUMERATION") ) {
fSimpleType.type = XMLSimpleType.TYPE_ENUMERATION;
}
else {
// REVISIT: Report error message. -Ac
System.err.println("!!! unknown attribute type "+type);
}
// REVISIT: The datatype should be stored with the attribute value
// and not special-cased in the XMLValidator. -Ac
//fSimpleType.datatypeValidator = fDatatypeValidatorFactory.createDatatypeValidator(type, null, facets, fSimpleType.list);
fQName.setValues(null, attributeName, attributeName, null);
fAttributeDecl.setValues( fQName, fSimpleType, false );
setAttributeDecl(elementIndex, fCurrentAttributeIndex, fAttributeDecl);
int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT;
ensureAttributeDeclCapacity(chunk);
} // attributeDecl(String,String,String,String[],String,XMLString,XMLString, Augmentations)
/** Returns the symbol table. */
public SymbolTable getSymbolTable() {
return fSymbolTable;
} // getSymbolTable():SymbolTable
/**
* Returns the index of the first element declaration. This index
* is then used to query more information about the element declaration.
*
* @see #getNextElementDeclIndex
* @see #getElementDecl
*/
public int getFirstElementDeclIndex() {
return fElementDeclCount >= 0 ? 0 : -1;
} // getFirstElementDeclIndex():int
/**
* Returns the next index of the element declaration following the
* specified element declaration.
*
* @param elementDeclIndex The element declaration index.
*/
public int getNextElementDeclIndex(int elementDeclIndex) {
return elementDeclIndex < fElementDeclCount - 1
? elementDeclIndex + 1 : -1;
} // getNextElementDeclIndex(int):int
/**
* getElementDeclIndex
*
* @param elementDeclName
*
* @return index of the elementDeclName in scope
*/
public int getElementDeclIndex(String elementDeclName) {
Integer mapping = fElementIndexMap.get(elementDeclName);
if (mapping == null) {
mapping = -1;
}
//System.out.println("getElementDeclIndex("+elementDeclName+") -> "+mapping);
return mapping;
} // getElementDeclIndex(String):int
/** Returns the element decl index.
* @param elementDeclQName qualilfied name of the element
*/
public int getElementDeclIndex(QName elementDeclQName) {
return getElementDeclIndex(elementDeclQName.rawname);
} // getElementDeclIndex(QName):int
/** make separate function for getting contentSpecType of element.
* we can avoid setting of the element values.
*/
public short getContentSpecType(int elementIndex){
if (elementIndex < 0 || elementIndex >= fElementDeclCount) {
return -1 ;
}
int chunk = elementIndex >> CHUNK_SHIFT;
int index = elementIndex & CHUNK_MASK;
if(fElementDeclType[chunk][index] == -1){
return -1 ;
}
else{
return (short) (fElementDeclType[chunk][index] & LIST_MASK);
}
}
/**
* getElementDecl
*
* @param elementDeclIndex
* @param elementDecl The values of this structure are set by this call.
*
* @return True if find the element, False otherwise.
*/
public boolean getElementDecl(int elementDeclIndex,
XMLElementDecl elementDecl) {
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
return false;
}
int chunk = elementDeclIndex >> CHUNK_SHIFT;
int index = elementDeclIndex & CHUNK_MASK;
elementDecl.name.setValues(fElementDeclName[chunk][index]);
if (fElementDeclType[chunk][index] == -1) {
elementDecl.type = -1;
elementDecl.simpleType.list = false;
} else {
elementDecl.type = (short) (fElementDeclType[chunk][index] & LIST_MASK);
elementDecl.simpleType.list = (fElementDeclType[chunk][index] & LIST_FLAG) != 0;
}
elementDecl.simpleType.defaultType = -1;
elementDecl.simpleType.defaultValue = null;
return true;
}
// REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac
/**
* getFirstAttributeDeclIndex
*
* @param elementDeclIndex
*
* @return index of the first attribute for element declaration elementDeclIndex
*/
public int getFirstAttributeDeclIndex(int elementDeclIndex) {
int chunk = elementDeclIndex >> CHUNK_SHIFT;
int index = elementDeclIndex & CHUNK_MASK;
return fElementDeclFirstAttributeDeclIndex[chunk][index];
} // getFirstAttributeDeclIndex
/**
* getNextAttributeDeclIndex
*
* @param attributeDeclIndex
*
* @return index of the next attribute of the attribute at attributeDeclIndex
*/
public int getNextAttributeDeclIndex(int attributeDeclIndex) {
int chunk = attributeDeclIndex >> CHUNK_SHIFT;
int index = attributeDeclIndex & CHUNK_MASK;
return fAttributeDeclNextAttributeDeclIndex[chunk][index];
}
/**
* getAttributeDecl
*
* @param attributeDeclIndex
* @param attributeDecl The values of this structure are set by this call.
*
* @return true if getAttributeDecl was able to fill in the value of attributeDecl
*/
public boolean getAttributeDecl(int attributeDeclIndex, XMLAttributeDecl attributeDecl) {
if (attributeDeclIndex < 0 || attributeDeclIndex >= fAttributeDeclCount) {
return false;
}
int chunk = attributeDeclIndex >> CHUNK_SHIFT;
int index = attributeDeclIndex & CHUNK_MASK;
attributeDecl.name.setValues(fAttributeDeclName[chunk][index]);
short attributeType;
boolean isList;
if (fAttributeDeclType[chunk][index] == -1) {
attributeType = -1;
isList = false;
} else {
attributeType = (short) (fAttributeDeclType[chunk][index] & LIST_MASK);
isList = (fAttributeDeclType[chunk][index] & LIST_FLAG) != 0;
}
attributeDecl.simpleType.setValues(attributeType,fAttributeDeclName[chunk][index].localpart,
fAttributeDeclEnumeration[chunk][index],
isList, fAttributeDeclDefaultType[chunk][index],
fAttributeDeclDefaultValue[chunk][index],
fAttributeDeclNonNormalizedDefaultValue[chunk][index]);
return true;
} // getAttributeDecl
/**
* Returns whether the given attribute is of type CDATA or not
*
* @param elName The element name.
* @param atName The attribute name.
*
* @return true if the attribute is of type CDATA
*/
public boolean isCDATAAttribute(QName elName, QName atName) {
int elDeclIdx = getElementDeclIndex(elName);
if (getAttributeDecl(elDeclIdx, fAttributeDecl)
&& fAttributeDecl.simpleType.type != XMLSimpleType.TYPE_CDATA){
return false;
}
return true;
}
public void printElements( ) {
int elementDeclIndex = 0;
XMLElementDecl elementDecl = new XMLElementDecl();
while (getElementDecl(elementDeclIndex++, elementDecl)) {
System.out.println("element decl: "+elementDecl.name+
", "+ elementDecl.name.rawname );
}
}
public void printAttributes(int elementDeclIndex) {
int attributeDeclIndex = getFirstAttributeDeclIndex(elementDeclIndex);
System.out.print(elementDeclIndex);
System.out.print(" [");
while (attributeDeclIndex != -1) {
System.out.print(' ');
System.out.print(attributeDeclIndex);
printAttribute(attributeDeclIndex);
attributeDeclIndex = getNextAttributeDeclIndex(attributeDeclIndex);
if (attributeDeclIndex != -1) {
System.out.print(",");
}
}
System.out.println(" ]");
}
protected int createElementDecl() {
int chunk = fElementDeclCount >> CHUNK_SHIFT;
int index = fElementDeclCount & CHUNK_MASK;
ensureElementDeclCapacity(chunk);
fElementDeclName[chunk][index] = new QName();
fElementDeclType[chunk][index] = -1;
fElementDeclFirstAttributeDeclIndex[chunk][index] = -1;
fElementDeclLastAttributeDeclIndex[chunk][index] = -1;
return fElementDeclCount++;
}
protected void setElementDecl(int elementDeclIndex, XMLElementDecl elementDecl) {
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
return;
}
int chunk = elementDeclIndex >> CHUNK_SHIFT;
int index = elementDeclIndex & CHUNK_MASK;
int scope = elementDecl.scope;
fElementDeclName[chunk][index].setValues(elementDecl.name);
fElementDeclType[chunk][index] = elementDecl.type;
if (elementDecl.simpleType.list == true ) {
fElementDeclType[chunk][index] |= LIST_FLAG;
}
fElementIndexMap.put(elementDecl.name.rawname, elementDeclIndex);
}
protected void setFirstAttributeDeclIndex(int elementDeclIndex, int newFirstAttrIndex){
if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) {
return;
}
int chunk = elementDeclIndex >> CHUNK_SHIFT;
int index = elementDeclIndex & CHUNK_MASK;
fElementDeclFirstAttributeDeclIndex[chunk][index] = newFirstAttrIndex;
}
protected int createAttributeDecl() {
int chunk = fAttributeDeclCount >> CHUNK_SHIFT;
int index = fAttributeDeclCount & CHUNK_MASK;
ensureAttributeDeclCapacity(chunk);
fAttributeDeclName[chunk][index] = new QName();
fAttributeDeclType[chunk][index] = -1;
fAttributeDeclEnumeration[chunk][index] = null;
fAttributeDeclDefaultType[chunk][index] = XMLSimpleType.DEFAULT_TYPE_IMPLIED;
fAttributeDeclDefaultValue[chunk][index] = null;
fAttributeDeclNonNormalizedDefaultValue[chunk][index] = null;
fAttributeDeclNextAttributeDeclIndex[chunk][index] = -1;
return fAttributeDeclCount++;
}
protected void setAttributeDecl(int elementDeclIndex, int attributeDeclIndex,
XMLAttributeDecl attributeDecl) {
int attrChunk = attributeDeclIndex >> CHUNK_SHIFT;
int attrIndex = attributeDeclIndex & CHUNK_MASK;
fAttributeDeclName[attrChunk][attrIndex].setValues(attributeDecl.name);
fAttributeDeclType[attrChunk][attrIndex] = attributeDecl.simpleType.type;
if (attributeDecl.simpleType.list) {
fAttributeDeclType[attrChunk][attrIndex] |= LIST_FLAG;
}
fAttributeDeclEnumeration[attrChunk][attrIndex] = attributeDecl.simpleType.enumeration;
fAttributeDeclDefaultType[attrChunk][attrIndex] = attributeDecl.simpleType.defaultType;
fAttributeDeclDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.defaultValue;
fAttributeDeclNonNormalizedDefaultValue[attrChunk][attrIndex] = attributeDecl.simpleType.nonNormalizedDefaultValue;
int elemChunk = elementDeclIndex >> CHUNK_SHIFT;
int elemIndex = elementDeclIndex & CHUNK_MASK;
int index = fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex];
while (index != -1) {
if (index == attributeDeclIndex) {
break;
}
attrChunk = index >> CHUNK_SHIFT;
attrIndex = index & CHUNK_MASK;
index = fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex];
}
if (index == -1) {
if (fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] == -1) {
fElementDeclFirstAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
} else {
index = fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex];
attrChunk = index >> CHUNK_SHIFT;
attrIndex = index & CHUNK_MASK;
fAttributeDeclNextAttributeDeclIndex[attrChunk][attrIndex] = attributeDeclIndex;
}
fElementDeclLastAttributeDeclIndex[elemChunk][elemIndex] = attributeDeclIndex;
}
}
public void notationDecl(String name, XMLResourceIdentifier identifier,
Augmentations augs) throws XNIException {
XMLNotationDecl notationDecl = new XMLNotationDecl();
notationDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(),
identifier.getBaseSystemId());
notationDecls.add(notationDecl);
}
public List getNotationDecls(){
return notationDecls;
}
//
// Private methods
//
private void printAttribute(int attributeDeclIndex) {
XMLAttributeDecl attributeDecl = new XMLAttributeDecl();
if (getAttributeDecl(attributeDeclIndex, attributeDecl)) {
System.out.print(" { ");
System.out.print(attributeDecl.name.localpart);
System.out.print(" }");
}
} // printAttribute(int)
private void ensureElementDeclCapacity(int chunk) {
if (chunk >= fElementDeclName.length) {
fElementDeclName = resize(fElementDeclName, fElementDeclName.length * 2);
fElementDeclType = resize(fElementDeclType, fElementDeclType.length * 2);
fElementDeclFirstAttributeDeclIndex = resize(fElementDeclFirstAttributeDeclIndex, fElementDeclFirstAttributeDeclIndex.length * 2);
fElementDeclLastAttributeDeclIndex = resize(fElementDeclLastAttributeDeclIndex, fElementDeclLastAttributeDeclIndex.length * 2);
}
else if (fElementDeclName[chunk] != null) {
return;
}
fElementDeclName[chunk] = new QName[CHUNK_SIZE];
fElementDeclType[chunk] = new short[CHUNK_SIZE];
fElementDeclFirstAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
fElementDeclLastAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
return;
}
private void ensureAttributeDeclCapacity(int chunk) {
if (chunk >= fAttributeDeclName.length) {
fAttributeDeclName = resize(fAttributeDeclName, fAttributeDeclName.length * 2);
fAttributeDeclType = resize(fAttributeDeclType, fAttributeDeclType.length * 2);
fAttributeDeclEnumeration = resize(fAttributeDeclEnumeration, fAttributeDeclEnumeration.length * 2);
fAttributeDeclDefaultType = resize(fAttributeDeclDefaultType, fAttributeDeclDefaultType.length * 2);
fAttributeDeclDefaultValue = resize(fAttributeDeclDefaultValue, fAttributeDeclDefaultValue.length * 2);
fAttributeDeclNonNormalizedDefaultValue = resize(fAttributeDeclNonNormalizedDefaultValue, fAttributeDeclNonNormalizedDefaultValue.length * 2);
fAttributeDeclNextAttributeDeclIndex = resize(fAttributeDeclNextAttributeDeclIndex, fAttributeDeclNextAttributeDeclIndex.length * 2);
}
else if (fAttributeDeclName[chunk] != null) {
return;
}
fAttributeDeclName[chunk] = new QName[CHUNK_SIZE];
fAttributeDeclType[chunk] = new short[CHUNK_SIZE];
fAttributeDeclEnumeration[chunk] = new String[CHUNK_SIZE][];
fAttributeDeclDefaultType[chunk] = new short[CHUNK_SIZE];
fAttributeDeclDefaultValue[chunk] = new String[CHUNK_SIZE];
fAttributeDeclNonNormalizedDefaultValue[chunk] = new String[CHUNK_SIZE];
fAttributeDeclNextAttributeDeclIndex[chunk] = new int[CHUNK_SIZE];
return;
}
// resize chunks
private static short[][] resize(short array[][], int newsize) {
short newarray[][] = new short[newsize][];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
private static int[][] resize(int array[][], int newsize) {
int newarray[][] = new int[newsize][];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
private static QName[][] resize(QName array[][], int newsize) {
QName newarray[][] = new QName[newsize][];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
private static String[][] resize(String array[][], int newsize) {
String newarray[][] = new String[newsize][];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
private static String[][][] resize(String array[][][], int newsize) {
String newarray[][][] = new String[newsize] [][];
System.arraycopy(array, 0, newarray, 0, array.length);
return newarray;
}
/**
* Normalize the attribute value of a non CDATA default attribute
* collapsing sequences of space characters (x20)
*
* @param value The value to normalize
* @return Whether the value was changed or not.
*/
private boolean normalizeDefaultAttrValue(XMLString value) {
int oldLength = value.length;
boolean skipSpace = true; // skip leading spaces
int current = value.offset;
int end = value.offset + value.length;
for (int i = value.offset; i < end; i++) {
if (value.ch[i] == ' ') {
if (!skipSpace) {
// take the first whitespace as a space and skip the others
value.ch[current++] = ' ';
skipSpace = true;
}
else {
// just skip it.
}
}
else {
// simply shift non space chars if needed
if (current != i) {
value.ch[current] = value.ch[i];
}
current++;
skipSpace = false;
}
}
if (current != end) {
if (skipSpace) {
// if we finished on a space trim it
current--;
}
// set the new value length
value.length = current - value.offset;
return true;
}
return false;
}
public void endDTD(Augmentations augs) throws XNIException {
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream.dtd.nonvalidating;
import com.sun.org.apache.xerces.internal.xni.QName;
/**
*/
public class XMLAttributeDecl {
/** name */
public final QName name = new QName();
/** simpleType */
public final XMLSimpleType simpleType = new XMLSimpleType();
/** optional */
public boolean optional;
/**
* setValues
*
* @param name
* @param simpleType
* @param optional
*/
public void setValues(QName name, XMLSimpleType simpleType, boolean optional) {
this.name.setValues(name);
this.simpleType.setValues(simpleType);
this.optional = optional;
}
/**
* clear
*/
public void clear() {
this.name.clear();
this.simpleType.clear();
this.optional = false;
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream.dtd.nonvalidating;
import com.sun.org.apache.xerces.internal.xni.QName;
/**
*/
public class XMLElementDecl {
/** TYPE_ANY */
public static final short TYPE_ANY = 0;
/** TYPE_EMPTY */
public static final short TYPE_EMPTY = 1;
/** TYPE_MIXED */
public static final short TYPE_MIXED = 2;
/** TYPE_CHILDREN */
public static final short TYPE_CHILDREN = 3;
/** TYPE_SIMPLE */
public static final short TYPE_SIMPLE = 4;
/** name */
public final QName name = new QName();
/** scope */
public int scope = -1;
/** type */
public short type = -1;
/** simpleType */
public final XMLSimpleType simpleType = new XMLSimpleType();
/**
* setValues
*
* @param name
* @param scope
* @param type
* @param contentModelValidator
* @param simpleType
*/
public void setValues(QName name, int scope, short type, XMLSimpleType simpleType) {
this.name.setValues(name);
this.scope = scope;
this.type = type;
this.simpleType.setValues(simpleType);
} // setValues
/**
* clear
*/
public void clear() {
this.name.clear();
this.type = -1;
this.scope = -1;
this.simpleType.clear();
} // clear
} // class XMLElementDecl

View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.xml.internal.stream.dtd.nonvalidating;
/**
*/
public class XMLNotationDecl {
//
// Data
//
/** name */
public String name;
/** publicId */
public String publicId;
/** systemId */
public String systemId;
/** base systemId */
public String baseSystemId;
//
// Methods
//
/**
* setValues
*
* @param name
* @param publicId
* @param systemId
*/
public void setValues(String name, String publicId, String systemId, String baseSystemId) {
this.name = name;
this.publicId = publicId;
this.systemId = systemId;
this.baseSystemId = baseSystemId;
} // setValues
/**
* clear
*/
public void clear() {
this.name = null;
this.publicId = null;
this.systemId = null;
this.baseSystemId = null;
} // clear
} // class XMLNotationDecl

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
* THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
*/
/*
* Copyright 2005 The Apache Software Foundation.
*/
package com.sun.xml.internal.stream.dtd.nonvalidating;
/**
*/
public class XMLSimpleType {
//
// Constants
//
/** TYPE_CDATA */
public static final short TYPE_CDATA = 0;
/** TYPE_ENTITY */
public static final short TYPE_ENTITY = 1;
/** TYPE_ENUMERATION */
public static final short TYPE_ENUMERATION = 2;
/** TYPE_ID */
public static final short TYPE_ID = 3;
/** TYPE_IDREF */
public static final short TYPE_IDREF = 4;
/** TYPE_NMTOKEN */
public static final short TYPE_NMTOKEN = 5;
/** TYPE_NOTATION */
public static final short TYPE_NOTATION = 6;
/** TYPE_NAMED */
public static final short TYPE_NAMED = 7;
/** DEFAULT_TYPE_DEFAULT */
public static final short DEFAULT_TYPE_DEFAULT = 3;
/** DEFAULT_TYPE_FIXED */
public static final short DEFAULT_TYPE_FIXED = 1;
/** DEFAULT_TYPE_IMPLIED */
public static final short DEFAULT_TYPE_IMPLIED = 0;
/** DEFAULT_TYPE_REQUIRED */
public static final short DEFAULT_TYPE_REQUIRED = 2;
//
// Data
//
/** type */
public short type;
/** name */
public String name;
/** enumeration */
public String[] enumeration;
/** list */
public boolean list;
/** defaultType */
public short defaultType;
/** defaultValue */
public String defaultValue;
/** non-normalized defaultValue */
public String nonNormalizedDefaultValue;
//
// Methods
//
/**
* setValues
*
* @param type
* @param name
* @param enumeration
* @param list
* @param defaultType
* @param defaultValue
* @param nonNormalizedDefaultValue
* @param datatypeValidator
*/
public void setValues(short type, String name, String[] enumeration,
boolean list, short defaultType,
String defaultValue, String nonNormalizedDefaultValue){
this.type = type;
this.name = name;
// REVISIT: Should this be a copy? -Ac
if (enumeration != null && enumeration.length > 0) {
this.enumeration = new String[enumeration.length];
System.arraycopy(enumeration, 0, this.enumeration, 0, this.enumeration.length);
}
else {
this.enumeration = null;
}
this.list = list;
this.defaultType = defaultType;
this.defaultValue = defaultValue;
this.nonNormalizedDefaultValue = nonNormalizedDefaultValue;
} // setValues(short,String,String[],boolean,short,String,String,DatatypeValidator)
/** Set values. */
public void setValues(XMLSimpleType simpleType) {
type = simpleType.type;
name = simpleType.name;
// REVISIT: Should this be a copy? -Ac
if (simpleType.enumeration != null && simpleType.enumeration.length > 0) {
enumeration = new String[simpleType.enumeration.length];
System.arraycopy(simpleType.enumeration, 0, enumeration, 0, enumeration.length);
}
else {
enumeration = null;
}
list = simpleType.list;
defaultType = simpleType.defaultType;
defaultValue = simpleType.defaultValue;
nonNormalizedDefaultValue = simpleType.nonNormalizedDefaultValue;
} // setValues(XMLSimpleType)
/**
* clear
*/
public void clear() {
this.type = -1;
this.name = null;
this.enumeration = null;
this.list = false;
this.defaultType = -1;
this.defaultValue = null;
this.nonNormalizedDefaultValue = null;
}
} // class XMLSimpleType

View File

@@ -0,0 +1,161 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.namespace.QName;
import javax.xml.stream.events.Attribute;
import java.io.Writer;
import javax.xml.stream.events.XMLEvent;
//xxx: AttributeEvent is not really a first order event. Should we be renaming the class to AttributeImpl for consistent
//naming convention.
/**
* Implementation of Attribute Event.
*
*@author Neeraj Bajaj, Sun Microsystems
*@author K.Venugopal, Sun Microsystems
*
*/
public class AttributeImpl extends DummyEvent implements Attribute
{
//attribute value
private String fValue;
private String fNonNormalizedvalue;
//name of the attribute
private QName fQName;
//attribute type
private String fAttributeType = "CDATA";
//A flag indicating whether this attribute was actually specified in the start-tag
//of its element or was defaulted from the schema.
private boolean fIsSpecified;
public AttributeImpl(){
init();
}
public AttributeImpl(String name, String value) {
init();
fQName = new QName(name);
fValue = value;
}
public AttributeImpl(String prefix, String name, String value) {
this(prefix, null,name, value, null,null,false );
}
public AttributeImpl(String prefix, String uri, String localPart, String value, String type) {
this(prefix, uri, localPart, value, null, type, false);
}
public AttributeImpl(String prefix, String uri, String localPart, String value, String nonNormalizedvalue, String type, boolean isSpecified) {
this(new QName(uri, localPart, prefix), value, nonNormalizedvalue, type, isSpecified);
}
public AttributeImpl(QName qname, String value, String nonNormalizedvalue, String type, boolean isSpecified) {
init();
fQName = qname ;
fValue = value ;
if(type != null && !type.equals(""))
fAttributeType = type;
fNonNormalizedvalue = nonNormalizedvalue;
fIsSpecified = isSpecified ;
}
public String toString() {
if( fQName.getPrefix() != null && fQName.getPrefix().length() > 0 )
return fQName.getPrefix() + ":" + fQName.getLocalPart() + "='" + fValue + "'";
else
return fQName.getLocalPart() + "='" + fValue + "'";
}
public void setName(QName name){
fQName = name ;
}
public QName getName() {
return fQName;
}
public void setValue(String value){
fValue = value;
}
public String getValue() {
return fValue;
}
public void setNonNormalizedValue(String nonNormalizedvalue){
fNonNormalizedvalue = nonNormalizedvalue;
}
public String getNonNormalizedValue(){
return fNonNormalizedvalue ;
}
public void setAttributeType(String attributeType){
fAttributeType = attributeType ;
}
/** Gets the type of this attribute, default is "CDATA */
// We dont need to take care of default value.. implementation takes care of it.
public String getDTDType() {
return fAttributeType;
}
/** is this attribute is specified in the instance document */
public void setSpecified(boolean isSpecified){
fIsSpecified = isSpecified ;
}
public boolean isSpecified() {
return fIsSpecified ;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write(toString());
}
protected void init(){
setEventType(XMLEvent.ATTRIBUTE);
}
}//AttributeImpl

View File

@@ -0,0 +1,196 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.Characters;
import java.io.Writer;
import java.io.IOException;
import javax.xml.stream.events.XMLEvent;
import com.sun.org.apache.xerces.internal.util.XMLChar;
/** Implementation of Character event.
*
*@author Neeraj Bajaj, Sun Microsystems
*@author K.Venugopal, Sun Microsystems
*
*/
public class CharacterEvent extends DummyEvent
implements Characters {
/* data */
private String fData;
/*true if fData is CData */
private boolean fIsCData;
/* true if fData is ignorableWhitespace*/
private boolean fIsIgnorableWhitespace;
/* true if fData contet is whitespace*/
private boolean fIsSpace = false;
/*used to prevent scanning of data multiple times */
private boolean fCheckIfSpaceNeeded = true;
public CharacterEvent() {
fIsCData = false;
init();
}
/**
*
* @param data Character Data.
*/
public CharacterEvent(String data) {
fIsCData = false;
init();
fData = data;
}
/**
*
* @param data Character Data.
* @param flag true if CData
*/
public CharacterEvent(String data, boolean flag) {
init();
fData = data;
fIsCData = flag;
}
/**
*
* @param data Character Data.
* @param flag true if CData
* @param isIgnorableWhiteSpace true if data is ignorable whitespace.
*/
public CharacterEvent(String data, boolean flag, boolean isIgnorableWhiteSpace) {
init();
fData = data;
fIsCData = flag;
fIsIgnorableWhitespace = isIgnorableWhiteSpace ;
}
protected void init() {
setEventType(XMLEvent.CHARACTERS);
}
/**
*
* @return return data.
*/
public String getData() {
return fData;
}
/**
*
* @param String data
*/
public void setData(String data){
fData = data;
fCheckIfSpaceNeeded = true;
}
/**
*
* @return boolean returns true if the data is CData
*/
public boolean isCData() {
return fIsCData;
}
/**
*
* @return String return the String representation of this event.
*/
public String toString() {
if(fIsCData)
return "<![CDATA[" + getData() + "]]>";
else
return fData;
}
/** This method will write the XMLEvent as per the XML 1.0 specification as Unicode characters.
* No indentation or whitespace should be outputted.
*
* Any user defined event type SHALL have this method
* called when being written to on an output stream.
* Built in Event types MUST implement this method,
* but implementations MAY choose not call these methods
* for optimizations reasons when writing out built in
* Events to an output stream.
* The output generated MUST be equivalent in terms of the
* infoset expressed.
*
* @param writer The writer that will output the data
* @throws XMLStreamException if there is a fatal error writing the event
*/
protected void writeAsEncodedUnicodeEx(Writer writer) throws IOException
{
if (fIsCData) {
writer.write("<![CDATA[" + getData() + "]]>");
} else {
charEncode(writer, fData);
}
}
/**
* Return true if this is ignorableWhiteSpace. If
* this event is ignorableWhiteSpace its event type will
* be SPACE.
* @return
*/
public boolean isIgnorableWhiteSpace() {
return fIsIgnorableWhitespace;
}
/**
* Returns true if this set of Characters
* is all whitespace. Whitspace inside a document
* is reported as CHARACTERS. This method allows
* checking of CHARACTERS events to see if they
* are composed of only whitespace characters
* @return
*/
public boolean isWhiteSpace() {
//no synchronization checks made.
if(fCheckIfSpaceNeeded){
checkWhiteSpace();
fCheckIfSpaceNeeded = false;
}
return fIsSpace;
}
private void checkWhiteSpace(){
//for now - remove dependancy of XMLChar
if(fData != null && fData.length() >0 ){
fIsSpace = true;
for(int i=0;i<fData.length();i++){
if(!XMLChar.isSpace(fData.charAt(i))){
fIsSpace = false;
break;
}
}
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.Comment;
import javax.xml.stream.events.XMLEvent;
/**
* This class contains information about Comment event.
*
* @author Neeraj Bajaj, Sun Microsystems.
*/
public class CommentEvent extends DummyEvent implements Comment {
/* String data for this event */
private String fText ;
public CommentEvent() {
init();
}
public CommentEvent(String text) {
init();
fText = text;
}
protected void init() {
setEventType(XMLEvent.COMMENT);
}
/**
* @return String String representation of this event
*/
public String toString() {
return "<!--" + getText() + "-->";
}
/** Return the string data of the comment, returns empty string if it
* does not exist
* @return String
*/
public String getText() {
return fText ;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write("<!--" + getText() + "-->");
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.DTD;
import javax.xml.stream.events.XMLEvent;
/**
*
* @author Neeraj Bajaj, Sun Microsystesm.
*
*/
public class DTDEvent extends DummyEvent implements DTD{
private String fDoctypeDeclaration;
private java.util.List fNotations;
private java.util.List fEntities;
/** Creates a new instance of DTDEvent */
public DTDEvent() {
init();
}
public DTDEvent(String doctypeDeclaration){
init();
fDoctypeDeclaration = doctypeDeclaration;
}
public void setDocumentTypeDeclaration(String doctypeDeclaration){
fDoctypeDeclaration = doctypeDeclaration;
}
public String getDocumentTypeDeclaration() {
return fDoctypeDeclaration;
}
//xxx: we can change the signature if the implementation doesn't store the entities in List Datatype.
//and then convert that DT to list format here. That way callee dont need to bother about conversion
public void setEntities(java.util.List entites){
fEntities = entites;
}
public java.util.List getEntities() {
return fEntities;
}
//xxx: we can change the signature if the implementation doesn't store the entities in List Datatype.
//and then convert that DT to list format here. That way callee dont need to bother about conversion
public void setNotations(java.util.List notations){
fNotations = notations;
}
public java.util.List getNotations() {
return fNotations;
}
/**
*Returns an implementation defined representation of the DTD.
* This method may return null if no representation is available.
*
*/
public Object getProcessedDTD() {
return null;
}
protected void init(){
setEventType(XMLEvent.DTD);
}
public String toString(){
return fDoctypeDeclaration ;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write(fDoctypeDeclaration);
}
}

View File

@@ -0,0 +1,258 @@
/*
* Copyright (c) 2005, 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.events;
import java.io.IOException;
import java.io.Writer;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
/** DummyEvent is an abstract class. It provides functionality for most of the
* function of XMLEvent.
*
* @author Neeraj Bajaj Sun Microsystems,Inc.
* @author K.Venugopal Sun Microsystems,Inc.
*
*/
public abstract class DummyEvent implements XMLEvent {
// Make sure that getLocation() never returns null. Instead, return this dummy location
// that indicates "nowhere" as effectively as possible.
private static DummyLocation nowhere = new DummyLocation();
/* Event type this event corresponds to */
private int fEventType;
protected Location fLocation = (Location) nowhere;
public DummyEvent() {
}
public DummyEvent(int i) {
fEventType = i;
}
public int getEventType() {
return fEventType;
}
protected void setEventType(int eventType){
fEventType = eventType;
}
public boolean isStartElement() {
return fEventType == XMLEvent.START_ELEMENT;
}
public boolean isEndElement() {
return fEventType == XMLEvent.END_ELEMENT;
}
public boolean isEntityReference() {
return fEventType == XMLEvent.ENTITY_REFERENCE;
}
public boolean isProcessingInstruction() {
return fEventType == XMLEvent.PROCESSING_INSTRUCTION;
}
public boolean isCharacterData() {
return fEventType == XMLEvent.CHARACTERS;
}
public boolean isStartDocument() {
return fEventType == XMLEvent.START_DOCUMENT;
}
public boolean isEndDocument() {
return fEventType == XMLEvent.END_DOCUMENT;
}
public Location getLocation(){
return fLocation;
}
void setLocation(Location loc){
if (loc == null) {
fLocation = nowhere;
} else {
fLocation = loc;
}
}
/** Returns this event as Characters, may result in
* a class cast exception if this event is not Characters.
*/
public Characters asCharacters() {
return (Characters)this;
}
/** Returns this event as an end element event, may result in
* a class cast exception if this event is not a end element.
*/
public EndElement asEndElement() {
return (EndElement)this;
}
/** Returns this event as a start element event, may result in
* a class cast exception if this event is not a start element.
*/
public StartElement asStartElement() {
return (StartElement)this;
}
/** This method is provided for implementations to provide
* optional type information about the associated event.
* It is optional and will return null if no information
* is available.
*/
public QName getSchemaType() {
//Base class will take care of providing extra information about this event.
return null;
}
/** A utility function to check if this event is an Attribute.
* @see Attribute
*/
public boolean isAttribute() {
return fEventType == XMLEvent.ATTRIBUTE;
}
/** A utility function to check if this event is Characters.
* @see Characters
*/
public boolean isCharacters() {
return fEventType == XMLEvent.CHARACTERS;
}
/** A utility function to check if this event is a Namespace.
* @see Namespace
*/
public boolean isNamespace() {
return fEventType == XMLEvent.NAMESPACE;
}
/** This method will write the XMLEvent as per the XML 1.0 specification as Unicode characters.
* No indentation or whitespace should be outputted.
*
* Any user defined event type SHALL have this method
* called when being written to on an output stream.
* Built in Event types MUST implement this method,
* but implementations MAY choose not call these methods
* for optimizations reasons when writing out built in
* Events to an output stream.
* The output generated MUST be equivalent in terms of the
* infoset expressed.
*
* @param writer The writer that will output the data
* @throws XMLStreamException if there is a fatal error writing the event
*/
public void writeAsEncodedUnicode(Writer writer) throws XMLStreamException {
try {
writeAsEncodedUnicodeEx(writer);
} catch (IOException e) {
throw new XMLStreamException(e);
}
}
/** Helper method in order to expose IOException.
* @param writer The writer that will output the data
* @throws XMLStreamException if there is a fatal error writing the event
* @throws IOException if there is an IO error
*/
protected abstract void writeAsEncodedUnicodeEx(Writer writer)
throws IOException, XMLStreamException;
/** Helper method to escape < > & for characters event and
* quotes, lt and amps for Entity
*/
protected void charEncode(Writer writer, String data)
throws IOException
{
if (data == null || data == "") return;
int i = 0, start = 0;
int len = data.length();
loop:
for (; i < len; ++i) {
switch (data.charAt(i)) {
case '<':
writer.write(data, start, i - start);
writer.write("&lt;");
start = i + 1;
break;
case '&':
writer.write(data, start, i - start);
writer.write("&amp;");
start = i + 1;
break;
case '>':
writer.write(data, start, i - start);
writer.write("&gt;");
start = i + 1;
break;
case '"':
writer.write(data, start, i - start);
writer.write("&quot;");
start = i + 1;
break;
}
}
// Write any pending data
writer.write(data, start, len - start);
}
static class DummyLocation implements Location {
public DummyLocation() {
}
public int getCharacterOffset() {
return -1;
}
public int getColumnNumber() {
return -1;
}
public int getLineNumber() {
return -1;
}
public String getPublicId() {
return null;
}
public String getSystemId() {
return null;
}
}
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.EndDocument;
import java.io.Writer;
import javax.xml.stream.XMLStreamConstants;
/**
* This class contains information about EndDocument event.
*
* @author Neeraj Bajaj, Sun Microsystems.
*/
public class EndDocumentEvent extends DummyEvent
implements EndDocument {
public EndDocumentEvent() {
init();
}
protected void init() {
setEventType(XMLStreamConstants.END_DOCUMENT);
}
public String toString() {
return "ENDDOCUMENT";
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
//end document
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (c) 2005, 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.events;
import java.util.List;
import java.util.ArrayList;
import javax.xml.namespace.QName;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.Namespace;
import java.io.Writer;
import java.util.Iterator;
import javax.xml.stream.events.XMLEvent;
import com.sun.xml.internal.stream.util.ReadOnlyIterator;
/** Implementation of EndElement event.
*
* @author Neeraj Bajaj Sun Microsystems,Inc.
* @author K.Venugopal Sun Microsystems,Inc.
*/
public class EndElementEvent extends DummyEvent
implements EndElement {
List fNamespaces = null;
QName fQName ;
public EndElementEvent() {
init();
}
protected void init() {
setEventType(XMLEvent.END_ELEMENT);
fNamespaces = new ArrayList();
}
public EndElementEvent(String prefix, String uri, String localpart) {
this(new QName(uri,localpart,prefix));
}
public EndElementEvent(QName qname) {
this.fQName = qname;
init();
}
public QName getName() {
return fQName;
}
public void setName(QName qname) {
this.fQName = qname;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write("</");
String prefix = fQName.getPrefix();
if (prefix != null && prefix.length() > 0) {
writer.write(prefix);
writer.write(':');
}
writer.write(fQName.getLocalPart());
writer.write('>');
}
/** Returns an Iterator of namespaces that have gone out
* of scope. Returns an empty iterator if no namespaces have gone
* out of scope.
* @return an Iterator over Namespace interfaces, or an
* empty iterator
*/
public Iterator getNamespaces() {
if(fNamespaces != null)
fNamespaces.iterator();
return new ReadOnlyIterator();
}
void addNamespace(Namespace attr){
if(attr != null){
fNamespaces.add(attr);
}
}
public String toString() {
String s = "</" + nameAsString();
s = s + ">";
return s;
}
public String nameAsString() {
if("".equals(fQName.getNamespaceURI()))
return fQName.getLocalPart();
if(fQName.getPrefix() != null)
return "['" + fQName.getNamespaceURI() + "']:" + fQName.getPrefix() + ":" + fQName.getLocalPart();
else
return "['" + fQName.getNamespaceURI() + "']:" + fQName.getLocalPart();
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2005, 2021, 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.events;
import javax.xml.stream.events.EntityDeclaration;
import javax.xml.stream.events.XMLEvent;
import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
import jdk.xml.internal.JdkXmlUtils;
/**
*
* This class store all the information for a particular EntityDeclaration. EntityDeclaration interface
* has various get* functiosn to retirve information about a particular EntityDeclaration.
*
* @author Neeraj Bajaj, Sun Microsystems.
*/
public class EntityDeclarationImpl extends DummyEvent implements EntityDeclaration {
private XMLResourceIdentifier fXMLResourceIdentifier ;
private String fEntityName;
private String fReplacementText;
private String fNotationName;
/** Creates a new instance of EntityDeclarationImpl */
public EntityDeclarationImpl() {
init();
}
public EntityDeclarationImpl(String entityName , String replacementText){
this(entityName,replacementText,null);
}
public EntityDeclarationImpl(String entityName, String replacementText, XMLResourceIdentifier resourceIdentifier){
init();
fEntityName = entityName;
fReplacementText = replacementText;
fXMLResourceIdentifier = resourceIdentifier;
}
public void setEntityName(String entityName){
fEntityName = entityName;
}
public String getEntityName(){
return fEntityName;
}
public void setEntityReplacementText(String replacementText){
fReplacementText = replacementText;
}
public void setXMLResourceIdentifier(XMLResourceIdentifier resourceIdentifier){
fXMLResourceIdentifier = resourceIdentifier ;
}
public XMLResourceIdentifier getXMLResourceIdentifier(){
return fXMLResourceIdentifier;
}
public String getSystemId(){
if(fXMLResourceIdentifier != null)
return fXMLResourceIdentifier.getLiteralSystemId();
return null;
}
public String getPublicId(){
if(fXMLResourceIdentifier != null)
return fXMLResourceIdentifier.getPublicId();
return null;
}
public String getBaseURI() {
if(fXMLResourceIdentifier != null)
return fXMLResourceIdentifier.getBaseSystemId();
return null;
}
public String getName(){
return fEntityName;
}
public String getNotationName() {
return fNotationName;
}
public void setNotationName(String notationName){
fNotationName = notationName;
}
public String getReplacementText() {
return fReplacementText;
}
protected void init(){
setEventType(XMLEvent.ENTITY_DECLARATION);
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write("<!ENTITY ");
writer.write(fEntityName);
if (fReplacementText != null) {
//internal entity
//escape quotes, lt and amps
writer.write(" \"");
charEncode(writer, fReplacementText);
writer.write("\"");
} else {
//external entity
writer.write(JdkXmlUtils.getDTDExternalDecl(getPublicId(), getSystemId()));
}
if (fNotationName != null) {
writer.write(" NDATA ");
writer.write(fNotationName);
}
writer.write(">");
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.EntityReference;
import java.io.Writer;
import javax.xml.stream.events.EntityDeclaration;
import javax.xml.stream.events.XMLEvent;
/** Implements EntityReference event.
*
*@author Neeraj Bajaj, Sun Microsystems,
*/
public class EntityReferenceEvent extends DummyEvent
implements EntityReference {
private EntityDeclaration fEntityDeclaration ;
private String fEntityName;
public EntityReferenceEvent() {
init();
}
public EntityReferenceEvent(String entityName , EntityDeclaration entityDeclaration) {
init();
fEntityName = entityName;
fEntityDeclaration = entityDeclaration ;
}
public String getName() {
return fEntityName;
}
public String toString() {
String text = fEntityDeclaration.getReplacementText();
if(text == null)
text = "";
return "&" + getName() + ";='" + text + "'";
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write('&');
writer.write(getName());
writer.write(';');
}
public EntityDeclaration getDeclaration(){
return fEntityDeclaration ;
}
protected void init() {
setEventType(XMLEvent.ENTITY_REFERENCE);
}
}

View File

@@ -0,0 +1,84 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.Location;
/**
*Implementation of Location interface to be used by
*event readers.
*@author Neeraj.bajaj@sun.com,k.venugopal@sun.com
*/
public class LocationImpl implements Location{
String systemId;
String publicId;
int colNo;
int lineNo;
int charOffset;
LocationImpl(Location loc){
systemId = loc.getSystemId();
publicId = loc.getPublicId();
lineNo = loc.getLineNumber();
colNo = loc.getColumnNumber();
charOffset = loc.getCharacterOffset();
}
public int getCharacterOffset(){
return charOffset;
}
public int getColumnNumber() {
return colNo;
}
public int getLineNumber(){
return lineNo;
}
public String getPublicId(){
return publicId;
}
public String getSystemId(){
return systemId;
}
public String toString(){
StringBuffer sbuffer = new StringBuffer() ;
sbuffer.append("Line number = " + getLineNumber());
sbuffer.append("\n") ;
sbuffer.append("Column number = " + getColumnNumber());
sbuffer.append("\n") ;
sbuffer.append("System Id = " + getSystemId());
sbuffer.append("\n") ;
sbuffer.append("Public Id = " + getPublicId());
sbuffer.append("\n") ;
sbuffer.append("CharacterOffset = " + getCharacterOffset());
sbuffer.append("\n") ;
return sbuffer.toString();
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.namespace.QName;
/**
*
*@author Neeraj Bajaj, Sun Microsystems
*
*/
public class NamedEvent extends DummyEvent {
private QName name;
public NamedEvent() {
}
public NamedEvent(QName qname) {
this.name = qname;
}
public NamedEvent(String prefix, String uri, String localpart) {
this.name = new QName(uri, localpart, prefix);
}
public String getPrefix() {
return this.name.getPrefix();
}
public QName getName() {
return name;
}
public void setName(QName qname) {
this.name = qname;
}
public String nameAsString() {
if("".equals(name.getNamespaceURI()))
return name.getLocalPart();
if(name.getPrefix() != null)
return "['" + name.getNamespaceURI() + "']:" + getPrefix() + ":" + name.getLocalPart();
else
return "['" + name.getNamespaceURI() + "']:" + name.getLocalPart();
}
public String getNamespace(){
return name.getNamespaceURI();
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write(nameAsString());
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.XMLEvent;
import javax.xml.namespace.QName;
import javax.xml.XMLConstants;
/**
*
* @author Neeraj Bajaj,K.Venugopal@sun.com Sun Microsystems.
*/
public class NamespaceImpl extends AttributeImpl implements Namespace{
public NamespaceImpl( ) {
init();
}
/** Creates a new instance of NamespaceImpl */
public NamespaceImpl(String namespaceURI) {
super(XMLConstants.XMLNS_ATTRIBUTE,XMLConstants.XMLNS_ATTRIBUTE_NS_URI,XMLConstants.DEFAULT_NS_PREFIX,namespaceURI,null);
init();
}
public NamespaceImpl(String prefix, String namespaceURI){
super(XMLConstants.XMLNS_ATTRIBUTE,XMLConstants.XMLNS_ATTRIBUTE_NS_URI,prefix,namespaceURI,null);
init();
}
public boolean isDefaultNamespaceDeclaration() {
QName name = this.getName();
if(name != null && (name.getLocalPart().equals(XMLConstants.DEFAULT_NS_PREFIX)))
return true;
return false;
}
void setPrefix(String prefix){
if(prefix == null)
setName(new QName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,XMLConstants.DEFAULT_NS_PREFIX,XMLConstants.XMLNS_ATTRIBUTE));
else// new QName(uri, localpart, prefix)
setName(new QName(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,prefix,XMLConstants.XMLNS_ATTRIBUTE));
}
public String getPrefix() {
//for a namespace declaration xmlns:prefix="uri" to get the prefix we have to get the
//local name if this declaration is stored as QName.
QName name = this.getName();
if(name != null)
return name.getLocalPart();
return null;
}
public String getNamespaceURI() {
//we are treating namespace declaration as attribute -- so URI is stored as value
//xmlns:prefix="Value"
return this.getValue();
}
void setNamespaceURI(String uri) {
//we are treating namespace declaration as attribute -- so URI is stored as value
//xmlns:prefix="Value"
this.setValue(uri);
}
protected void init(){
setEventType(XMLEvent.NAMESPACE);
}
public int getEventType(){
return XMLEvent.NAMESPACE;
}
public boolean isNamespace(){
return true;
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (c) 2005, 2021, 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.events;
import javax.xml.stream.events.NotationDeclaration;
import javax.xml.stream.events.XMLEvent;
import com.sun.xml.internal.stream.dtd.nonvalidating.XMLNotationDecl;
import jdk.xml.internal.JdkXmlUtils;
/**
* Implementation of NotationDeclaration event.
*
* @author k.venugopal@sun.com
*/
public class NotationDeclarationImpl extends DummyEvent implements NotationDeclaration {
String fName = null;
String fPublicId = null;
String fSystemId = null;
/** Creates a new instance of NotationDeclarationImpl */
public NotationDeclarationImpl() {
setEventType(XMLEvent.NOTATION_DECLARATION);
}
public NotationDeclarationImpl(String name,String publicId,String systemId){
this.fName = name;
this.fPublicId = publicId;
this.fSystemId = systemId;
setEventType(XMLEvent.NOTATION_DECLARATION);
}
public NotationDeclarationImpl(XMLNotationDecl notation){
this.fName = notation.name;
this.fPublicId = notation.publicId;
this.fSystemId = notation.systemId;
setEventType(XMLEvent.NOTATION_DECLARATION);
}
public String getName() {
return fName;
}
public String getPublicId() {
return fPublicId;
}
public String getSystemId() {
return fSystemId;
}
void setPublicId(String publicId){
this.fPublicId = publicId;
}
void setSystemId(String systemId){
this.fSystemId = systemId;
}
void setName(String name){
this.fName = name;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write("<!NOTATION ");
writer.write(getName());
writer.write(JdkXmlUtils.getDTDExternalDecl(fPublicId, fSystemId));
writer.write('>');
}
}

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2005, 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.events;
import java.io.Writer;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.ProcessingInstruction;
/** Implements Processing Instruction Event
*
*@author Neeraj Bajaj, Sun Microsystems.
*
*/
public class ProcessingInstructionEvent extends DummyEvent
implements ProcessingInstruction {
/** Processing Instruction Name */
private String fName;
/** Processsing instruction content */
private String fContent;
public ProcessingInstructionEvent() {
init();
}
public ProcessingInstructionEvent(String targetName, String data) {
this(targetName,data,null);
}
public ProcessingInstructionEvent(String targetName, String data,Location loc) {
init();
this.fName = targetName;
fContent = data;
setLocation(loc);
}
protected void init() {
setEventType(XMLStreamConstants.PROCESSING_INSTRUCTION);
}
public String getTarget() {
return fName;
}
public void setTarget(String targetName) {
fName = targetName;
}
public void setData(String data) {
fContent = data;
}
public String getData() {
return fContent;
}
public String toString() {
if(fContent != null && fName != null)
return "<?" + fName + " " + fContent + "?>";
if(fName != null)
return "<?" + fName + "?>";
if(fContent != null)
return "<?" + fContent + "?>";
else
return "<??>";
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write(toString());
}
}

View File

@@ -0,0 +1,173 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamConstants;
/** Implementation of StartDocumentEvent.
*
* @author Neeraj Bajaj Sun Microsystems,Inc.
* @author K.Venugopal Sun Microsystems,Inc.
*
*/
public class StartDocumentEvent extends DummyEvent
implements StartDocument {
protected String fSystemId;
protected String fEncodingScheam;
protected boolean fStandalone;
protected String fVersion;
private boolean fEncodingSchemeSet = false;
private boolean fStandaloneSet = false;
private boolean nestedCall = false;
public StartDocumentEvent() {
init("UTF-8","1.0",true,null);
}
public StartDocumentEvent(String encoding){
init(encoding,"1.0",true,null);
}
public StartDocumentEvent(String encoding, String version){
init(encoding,version,true,null);
}
public StartDocumentEvent(String encoding, String version, boolean standalone){
this.fStandaloneSet = true;
init(encoding,version,standalone,null);
}
public StartDocumentEvent(String encoding, String version, boolean standalone,Location loc){
this.fStandaloneSet = true;
init(encoding, version, standalone, loc);
}
protected void init(String encoding, String version, boolean standalone,Location loc) {
setEventType(XMLStreamConstants.START_DOCUMENT);
this.fEncodingScheam = encoding;
this.fVersion = version;
this.fStandalone = standalone;
if (encoding != null && !encoding.equals(""))
this.fEncodingSchemeSet = true;
else {
this.fEncodingSchemeSet = false;
this.fEncodingScheam = "UTF-8";
}
this.fLocation = loc;
}
public String getSystemId() {
if(fLocation == null )
return "";
else
return fLocation.getSystemId();
}
public String getCharacterEncodingScheme() {
return fEncodingScheam;
}
public boolean isStandalone() {
return fStandalone;
}
public String getVersion() {
return fVersion;
}
public void setStandalone(boolean flag) {
fStandaloneSet = true;
fStandalone = flag;
}
public void setStandalone(String s) {
fStandaloneSet = true;
if(s == null) {
fStandalone = true;
return;
}
if(s.equals("yes"))
fStandalone = true;
else
fStandalone = false;
}
public boolean encodingSet() {
return fEncodingSchemeSet;
}
public boolean standaloneSet() {
return fStandaloneSet;
}
public void setEncoding(String encoding) {
fEncodingScheam = encoding;
}
void setDeclaredEncoding(boolean value){
fEncodingSchemeSet = value;
}
public void setVersion(String s) {
fVersion = s;
}
void clear() {
fEncodingScheam = "UTF-8";
fStandalone = true;
fVersion = "1.0";
fEncodingSchemeSet = false;
fStandaloneSet = false;
}
public String toString() {
String s = "<?xml version=\"" + fVersion + "\"";
s = s + " encoding='" + fEncodingScheam + "'";
if(fStandaloneSet) {
if(fStandalone)
s = s + " standalone='yes'?>";
else
s = s + " standalone='no'?>";
} else {
s = s + "?>";
}
return s;
}
public boolean isStartDocument() {
return true;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write(toString());
}
}

View File

@@ -0,0 +1,231 @@
/*
* Copyright (c) 2005, 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.events;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.namespace.QName;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.Attribute;
import javax.xml.namespace.NamespaceContext;
import java.io.Writer;
import com.sun.xml.internal.stream.util.ReadOnlyIterator;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.Namespace;
/** Implementation of StartElementEvent.
*
* @author Neeraj Bajaj Sun Microsystems,Inc.
* @author K.Venugopal Sun Microsystems,Inc.
*/
public class StartElementEvent extends DummyEvent
implements StartElement {
private Map fAttributes;
private List fNamespaces;
private NamespaceContext fNamespaceContext = null;
private QName fQName;
public StartElementEvent(String prefix, String uri, String localpart) {
this(new QName(uri, localpart, prefix));
}
public StartElementEvent(QName qname) {
fQName = qname;
init();
}
public StartElementEvent(StartElement startelement) {
this(startelement.getName());
addAttributes(startelement.getAttributes());
addNamespaceAttributes(startelement.getNamespaces());
}
protected void init() {
setEventType(XMLStreamConstants.START_ELEMENT);
fAttributes = new HashMap();
fNamespaces = new ArrayList();
}
public QName getName() {
return fQName;
}
public void setName(QName qname) {
this.fQName = qname;
}
public Iterator getAttributes() {
if(fAttributes != null){
Collection coll = fAttributes.values();
return new ReadOnlyIterator(coll.iterator());
}
return new ReadOnlyIterator();
}
public Iterator getNamespaces() {
if(fNamespaces != null){
return new ReadOnlyIterator(fNamespaces.iterator());
}
return new ReadOnlyIterator();
}
public Attribute getAttributeByName(QName qname) {
if(qname == null)
return null;
return (Attribute)fAttributes.get(qname);
}
public String getNamespace(){
return fQName.getNamespaceURI();
}
public String getNamespaceURI(String prefix) {
//check that URI was supplied when creating this startElement event and prefix matches
if( getNamespace() != null && fQName.getPrefix().equals(prefix)) return getNamespace();
//else check the namespace context
if(fNamespaceContext != null)
return fNamespaceContext.getNamespaceURI(prefix);
return null;
}
/**
* <p>Return a <code>String</code> representation of this
* <code>StartElement</code> formatted as XML.</p>
*
* @return <code>String</code> representation of this
* <code>StartElement</code> formatted as XML.
*/
public String toString() {
StringBuffer startElement = new StringBuffer();
// open element
startElement.append("<");
startElement.append(nameAsString());
// add any attributes
if (fAttributes != null) {
Iterator it = this.getAttributes();
Attribute attr = null;
while (it.hasNext()) {
attr = (Attribute) it.next();
startElement.append(" ");
startElement.append(attr.toString());
}
}
// add any namespaces
if (fNamespaces != null) {
Iterator it = fNamespaces.iterator();
Namespace attr = null;
while (it.hasNext()) {
attr = (Namespace) it.next();
startElement.append(" ");
startElement.append(attr.toString());
}
}
// close start tag
startElement.append(">");
// return StartElement as a String
return startElement.toString();
}
/** Return this event as String
* @return String Event returned as string.
*/
public String nameAsString() {
if("".equals(fQName.getNamespaceURI()))
return fQName.getLocalPart();
if(fQName.getPrefix() != null)
return "['" + fQName.getNamespaceURI() + "']:" + fQName.getPrefix() + ":" + fQName.getLocalPart();
else
return "['" + fQName.getNamespaceURI() + "']:" + fQName.getLocalPart();
}
/** Gets a read-only namespace context. If no context is
* available this method will return an empty namespace context.
* The NamespaceContext contains information about all namespaces
* in scope for this StartElement.
*
* @return the current namespace context
*/
public NamespaceContext getNamespaceContext() {
return fNamespaceContext;
}
public void setNamespaceContext(NamespaceContext nc) {
fNamespaceContext = nc;
}
protected void writeAsEncodedUnicodeEx(java.io.Writer writer)
throws java.io.IOException
{
writer.write(toString());
}
void addAttribute(Attribute attr){
if(attr.isNamespace()){
fNamespaces.add(attr);
}else{
fAttributes.put(attr.getName(),attr);
}
}
void addAttributes(Iterator attrs){
if(attrs == null)
return;
while(attrs.hasNext()){
Attribute attr = (Attribute)attrs.next();
fAttributes.put(attr.getName(),attr);
}
}
void addNamespaceAttribute(Namespace attr){
if(attr == null)
return;
fNamespaces.add(attr);
}
void addNamespaceAttributes(Iterator attrs){
if(attrs == null)
return;
while(attrs.hasNext()){
Namespace attr = (Namespace)attrs.next();
fNamespaces.add(attr);
}
}
}

View File

@@ -0,0 +1,257 @@
/*
* Copyright (c) 2005, 2006, 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.events;
import com.sun.org.apache.xerces.internal.impl.PropertyManager;
import java.util.List;
import javax.xml.stream.util.XMLEventAllocator;
import javax.xml.stream.*;
import javax.xml.stream.events.*;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import com.sun.org.apache.xerces.internal.util.NamespaceContextWrapper;
import com.sun.org.apache.xerces.internal.util.NamespaceSupport;
/**
* Implementation of XMLEvent Allocator.
* @author Neeraj.bajaj@sun.com, k.venugopal@sun.com
*/
public class XMLEventAllocatorImpl implements XMLEventAllocator {
/** Creates a new instance of XMLEventAllocator */
public XMLEventAllocatorImpl() {
}
public javax.xml.stream.events.XMLEvent allocate(javax.xml.stream.XMLStreamReader xMLStreamReader) throws javax.xml.stream.XMLStreamException {
if(xMLStreamReader == null )
throw new XMLStreamException("Reader cannot be null");
// allocate is not supposed to change the state of the reader so we shouldn't be calling next.
// return getNextEvent(xMLStreamReader);
return getXMLEvent(xMLStreamReader);
}
public void allocate(javax.xml.stream.XMLStreamReader xMLStreamReader, javax.xml.stream.util.XMLEventConsumer xMLEventConsumer) throws javax.xml.stream.XMLStreamException {
XMLEvent currentEvent = getXMLEvent(xMLStreamReader);
if(currentEvent != null )
xMLEventConsumer.add(currentEvent);
return;
}
public javax.xml.stream.util.XMLEventAllocator newInstance() {
return new XMLEventAllocatorImpl();
}
//REVISIT: shouldn't we be using XMLEventFactory to create events.
XMLEvent getXMLEvent(XMLStreamReader streamReader){
XMLEvent event = null;
//returns the current event
int eventType = streamReader.getEventType();
switch(eventType){
case XMLEvent.START_ELEMENT:{
StartElementEvent startElementEvent = new StartElementEvent(getQName(streamReader));
fillAttributes(startElementEvent,streamReader);
//we might have different XMLStreamReader so check every time for the namespace aware property
//we should be setting namespace related values only when isNamespaceAware is 'true'
if( ((Boolean)streamReader.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE)).booleanValue() ){
fillNamespaceAttributes(startElementEvent, streamReader);
setNamespaceContext(startElementEvent,streamReader);
}
startElementEvent.setLocation(streamReader.getLocation());
event = startElementEvent ;
break;
}
case XMLEvent.END_ELEMENT:{
EndElementEvent endElementEvent = new EndElementEvent(getQName(streamReader));
endElementEvent.setLocation(streamReader.getLocation());
if( ((Boolean)streamReader.getProperty(XMLInputFactory.IS_NAMESPACE_AWARE)).booleanValue() ){
fillNamespaceAttributes(endElementEvent,streamReader);
}
event = endElementEvent ;
break;
}
case XMLEvent.PROCESSING_INSTRUCTION:{
ProcessingInstructionEvent piEvent = new ProcessingInstructionEvent(streamReader.getPITarget(),streamReader.getPIData());
piEvent.setLocation(streamReader.getLocation());
event = piEvent ;
break;
}
case XMLEvent.CHARACTERS:{
CharacterEvent cDataEvent = new CharacterEvent(streamReader.getText());
cDataEvent.setLocation(streamReader.getLocation());
event = cDataEvent ;
break;
}
case XMLEvent.COMMENT:{
CommentEvent commentEvent = new CommentEvent(streamReader.getText());
commentEvent.setLocation(streamReader.getLocation());
event = commentEvent ;
break;
}
case XMLEvent.START_DOCUMENT:{
StartDocumentEvent sdEvent = new StartDocumentEvent();
sdEvent.setVersion(streamReader.getVersion());
sdEvent.setEncoding(streamReader.getEncoding());
if(streamReader.getCharacterEncodingScheme() != null){
sdEvent.setDeclaredEncoding(true);
}else{
sdEvent.setDeclaredEncoding(false);
}
sdEvent.setStandalone(streamReader.isStandalone());
sdEvent.setLocation(streamReader.getLocation());
event = sdEvent ;
break;
}
case XMLEvent.END_DOCUMENT:{
EndDocumentEvent endDocumentEvent = new EndDocumentEvent() ;
endDocumentEvent.setLocation(streamReader.getLocation());
event = endDocumentEvent ;
break;
}
case XMLEvent.ENTITY_REFERENCE:{
EntityReferenceEvent entityEvent = new EntityReferenceEvent(streamReader.getLocalName(), new EntityDeclarationImpl(streamReader.getLocalName(),streamReader.getText()));
entityEvent.setLocation(streamReader.getLocation());
event = entityEvent;
break;
}
case XMLEvent.ATTRIBUTE:{
event = null ;
break;
}
case XMLEvent.DTD:{
DTDEvent dtdEvent = new DTDEvent(streamReader.getText());
dtdEvent.setLocation(streamReader.getLocation());
List entities = (List)streamReader.getProperty(PropertyManager.STAX_ENTITIES);
if (entities != null && entities.size() != 0) dtdEvent.setEntities(entities);
List notations = (List)streamReader.getProperty(PropertyManager.STAX_NOTATIONS);
if (notations != null && notations.size() != 0) dtdEvent.setNotations(notations);
event = dtdEvent;
break;
}
case XMLEvent.CDATA:{
CharacterEvent cDataEvent = new CharacterEvent(streamReader.getText(),true);
cDataEvent.setLocation(streamReader.getLocation());
event = cDataEvent ;
break;
}
case XMLEvent.SPACE:{
CharacterEvent spaceEvent = new CharacterEvent(streamReader.getText(),false,true);
spaceEvent.setLocation(streamReader.getLocation());
event = spaceEvent ;
break;
}
}
return event ;
}
//this function is not used..
protected XMLEvent getNextEvent(XMLStreamReader streamReader) throws XMLStreamException{
//advance the reader to next event.
streamReader.next();
return getXMLEvent(streamReader);
}
protected void fillAttributes(StartElementEvent event,XMLStreamReader xmlr){
int len = xmlr.getAttributeCount();
QName qname = null;
AttributeImpl attr = null;
NamespaceImpl nattr = null;
for(int i=0; i<len ;i++){
qname = xmlr.getAttributeName(i);
//this method doesn't include namespace declarations
//so we can be sure that there wont be any namespace declaration as part of this function call
//we can avoid this check - nb.
/**
* prefix = qname.getPrefix();
* localpart = qname.getLocalPart();
* if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) ) {
* attr = new NamespaceImpl(localpart,xmlr.getAttributeValue(i));
* }else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)){
* attr = new NamespaceImpl(xmlr.getAttributeValue(i));
* }else{
* attr = new AttributeImpl();
* attr.setName(qname);
* }
**/
attr = new AttributeImpl();
attr.setName(qname);
attr.setAttributeType(xmlr.getAttributeType(i));
attr.setSpecified(xmlr.isAttributeSpecified(i));
attr.setValue(xmlr.getAttributeValue(i));
event.addAttribute(attr);
}
}
protected void fillNamespaceAttributes(StartElementEvent event,XMLStreamReader xmlr){
int count = xmlr.getNamespaceCount();
String uri = null;
String prefix = null;
NamespaceImpl attr = null;
for(int i=0;i< count;i++){
uri = xmlr.getNamespaceURI(i);
prefix = xmlr.getNamespacePrefix(i);
if(prefix == null){
prefix = XMLConstants.DEFAULT_NS_PREFIX;
}
attr = new NamespaceImpl(prefix,uri);
event.addNamespaceAttribute(attr);
}
}
protected void fillNamespaceAttributes(EndElementEvent event,XMLStreamReader xmlr){
int count = xmlr.getNamespaceCount();
String uri = null;
String prefix = null;
NamespaceImpl attr = null;
for(int i=0;i< count;i++){
uri = xmlr.getNamespaceURI(i);
prefix = xmlr.getNamespacePrefix(i);
if(prefix == null){
prefix = XMLConstants.DEFAULT_NS_PREFIX;
}
attr = new NamespaceImpl(prefix,uri);
event.addNamespace(attr);
}
}
//Revisit : Creating a new Namespacecontext for now.
//see if we can do better job.
private void setNamespaceContext(StartElementEvent event , XMLStreamReader xmlr){
NamespaceContextWrapper contextWrapper =(NamespaceContextWrapper) xmlr.getNamespaceContext();
NamespaceSupport ns = new NamespaceSupport(contextWrapper.getNamespaceContext());
event.setNamespaceContext(new NamespaceContextWrapper(ns));
}
private QName getQName(XMLStreamReader xmlr) {
return new QName(xmlr.getNamespaceURI(), xmlr.getLocalName(),
xmlr.getPrefix());
}
}

View File

@@ -0,0 +1,201 @@
/*
* Copyright (c) 2005, 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.events;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.Location;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.EntityDeclaration;
/**
*
* @author Neeraj Bajaj, k.venugopal@sun.com
*/
public class XMLEventFactoryImpl extends XMLEventFactory {
Location location = null;
/** Creates a new instance of XMLEventFactory */
public XMLEventFactoryImpl() {
}
public javax.xml.stream.events.Attribute createAttribute(String localName, String value) {
AttributeImpl attr = new AttributeImpl(localName, value);
if(location != null)attr.setLocation(location);
return attr;
}
public javax.xml.stream.events.Attribute createAttribute(javax.xml.namespace.QName name, String value) {
return createAttribute(name.getPrefix(), name.getNamespaceURI(), name.getLocalPart(), value);
}
public javax.xml.stream.events.Attribute createAttribute(String prefix, String namespaceURI, String localName, String value) {
AttributeImpl attr = new AttributeImpl(prefix, namespaceURI, localName, value, null);
if(location != null)attr.setLocation(location);
return attr;
}
public javax.xml.stream.events.Characters createCData(String content) {
//stax doesn't have separate CDATA event. This is taken care by
//CHRACTERS event setting the cdata flag to true.
CharacterEvent charEvent = new CharacterEvent(content, true);
if(location != null)charEvent.setLocation(location);
return charEvent;
}
public javax.xml.stream.events.Characters createCharacters(String content) {
CharacterEvent charEvent = new CharacterEvent(content);
if(location != null)charEvent.setLocation(location);
return charEvent;
}
public javax.xml.stream.events.Comment createComment(String text) {
CommentEvent charEvent = new CommentEvent(text);
if(location != null)charEvent.setLocation(location);
return charEvent;
}
public javax.xml.stream.events.DTD createDTD(String dtd) {
DTDEvent dtdEvent = new DTDEvent(dtd);
if(location != null)dtdEvent.setLocation(location);
return dtdEvent;
}
public javax.xml.stream.events.EndDocument createEndDocument() {
EndDocumentEvent event =new EndDocumentEvent();
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.EndElement createEndElement(javax.xml.namespace.QName name, java.util.Iterator namespaces) {
return createEndElement(name.getPrefix(), name.getNamespaceURI(), name.getLocalPart());
}
public javax.xml.stream.events.EndElement createEndElement(String prefix, String namespaceUri, String localName) {
EndElementEvent event = new EndElementEvent(prefix, namespaceUri, localName);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.EndElement createEndElement(String prefix, String namespaceUri, String localName, java.util.Iterator namespaces) {
EndElementEvent event = new EndElementEvent(prefix, namespaceUri, localName);
if(namespaces!=null){
while(namespaces.hasNext())
event.addNamespace((Namespace)namespaces.next());
}
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.EntityReference createEntityReference(String name, EntityDeclaration entityDeclaration) {
EntityReferenceEvent event = new EntityReferenceEvent(name, entityDeclaration);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.Characters createIgnorableSpace(String content) {
CharacterEvent event = new CharacterEvent(content, false, true);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.Namespace createNamespace(String namespaceURI) {
NamespaceImpl event = new NamespaceImpl(namespaceURI);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.Namespace createNamespace(String prefix, String namespaceURI) {
NamespaceImpl event = new NamespaceImpl(prefix, namespaceURI);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.ProcessingInstruction createProcessingInstruction(String target, String data) {
ProcessingInstructionEvent event = new ProcessingInstructionEvent(target, data);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.Characters createSpace(String content) {
CharacterEvent event = new CharacterEvent(content);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.StartDocument createStartDocument() {
StartDocumentEvent event = new StartDocumentEvent();
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.StartDocument createStartDocument(String encoding) {
StartDocumentEvent event = new StartDocumentEvent(encoding);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.StartDocument createStartDocument(String encoding, String version) {
StartDocumentEvent event = new StartDocumentEvent(encoding, version);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.StartDocument createStartDocument(String encoding, String version, boolean standalone) {
StartDocumentEvent event = new StartDocumentEvent(encoding, version, standalone);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.StartElement createStartElement(javax.xml.namespace.QName name, java.util.Iterator attributes, java.util.Iterator namespaces) {
return createStartElement(name.getPrefix(), name.getNamespaceURI(), name.getLocalPart(), attributes, namespaces);
}
public javax.xml.stream.events.StartElement createStartElement(String prefix, String namespaceUri, String localName) {
StartElementEvent event = new StartElementEvent(prefix, namespaceUri, localName);
if(location != null)event.setLocation(location);
return event;
}
public javax.xml.stream.events.StartElement createStartElement(String prefix, String namespaceUri, String localName, java.util.Iterator attributes, java.util.Iterator namespaces) {
return createStartElement(prefix, namespaceUri, localName, attributes, namespaces, null);
}
public javax.xml.stream.events.StartElement createStartElement(String prefix, String namespaceUri, String localName, java.util.Iterator attributes, java.util.Iterator namespaces, javax.xml.namespace.NamespaceContext context) {
StartElementEvent elem = new StartElementEvent(prefix, namespaceUri, localName);
elem.addAttributes(attributes);
elem.addNamespaceAttributes(namespaces);
elem.setNamespaceContext(context);
if(location != null)elem.setLocation(location);
return elem;
}
public void setLocation(javax.xml.stream.Location location) {
this.location = location;
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright (c) 2005, 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.util;
import java.lang.ref.*;
/**
* Buffer allocator for buffers of sizes 128 B, 2 KB and 8 KB. Includes
* methods for allocating and freeing buffers.
*
* @author Binu.John@sun.com
* @author Santiago.PericasGeertsen@sun.com
*/
public class BufferAllocator {
public static int SMALL_SIZE_LIMIT = 128;
public static int MEDIUM_SIZE_LIMIT = 2048;
public static int LARGE_SIZE_LIMIT = 8192;
char[] smallCharBuffer;
char[] mediumCharBuffer;
char[] largeCharBuffer;
byte[] smallByteBuffer;
byte[] mediumByteBuffer;
byte[] largeByteBuffer;
public BufferAllocator() {
}
public char[] getCharBuffer(int size) {
if (size <= SMALL_SIZE_LIMIT) {
char[] buffer = smallCharBuffer;
smallCharBuffer = null;
return buffer;
}
else if (size <= MEDIUM_SIZE_LIMIT) {
char[] buffer = mediumCharBuffer;
mediumCharBuffer = null;
return buffer;
}
else if (size <= LARGE_SIZE_LIMIT) {
char[] buffer = largeCharBuffer;
largeCharBuffer = null;
return buffer;
}
return null;
}
public void returnCharBuffer(char[] c) {
if (c == null) {
return;
}
if (c.length <= SMALL_SIZE_LIMIT) {
smallCharBuffer = c;
}
else if (c.length <= MEDIUM_SIZE_LIMIT) {
mediumCharBuffer = c;
}
else if (c.length <= LARGE_SIZE_LIMIT) {
largeCharBuffer = c;
}
}
public byte[] getByteBuffer(int size) {
if (size <= SMALL_SIZE_LIMIT) {
byte[] buffer = smallByteBuffer;
smallByteBuffer = null;
return buffer;
}
else if (size <= MEDIUM_SIZE_LIMIT) {
byte[] buffer = mediumByteBuffer;
mediumByteBuffer = null;
return buffer;
}
else if (size <= LARGE_SIZE_LIMIT) {
byte[] buffer = largeByteBuffer;
largeByteBuffer = null;
return buffer;
}
return null;
}
public void returnByteBuffer(byte[] b) {
if (b == null) {
return;
}
if (b.length <= SMALL_SIZE_LIMIT) {
smallByteBuffer = b;
}
else if (b.length <= MEDIUM_SIZE_LIMIT) {
mediumByteBuffer = b;
}
else if (b.length <= LARGE_SIZE_LIMIT) {
largeByteBuffer = b;
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2005, 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.util;
/**
*
* @author K.Venugopal ,Neeraj Bajaj Sun Microsystems.
*/
import java.util.Iterator;
public class ReadOnlyIterator implements Iterator {
Iterator iterator = null;
public ReadOnlyIterator(){
}
public ReadOnlyIterator(Iterator itr){
iterator = itr;
}
/**
* @return
*/
public boolean hasNext() {
if(iterator != null)
return iterator.hasNext();
return false;
}
/**
* @return
*/
public Object next() {
if(iterator != null)
return iterator.next();
return null;
}
public void remove() {
throw new UnsupportedOperationException("Remove operation is not supported");
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (c) 2005, 2018, 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.util;
import java.lang.ref.*;
/**
* This is a Singleton class that allows you to allocate buffer that
* are stored in ThreadLocal. This class stores 3 types of char
* buffers - small (< 128 bytes), medium (<2K) and large (> 2K) as
* well as three byte buffers - small, medium and large.
* The local storage is activated on the return of the buffer.
* The buffer returns null if it is already allocated.
*
* @author Binu.John@sun.com
* @author Santiago.PericasGeertsen@sun.com
*/
public class ThreadLocalBufferAllocator {
private static final ThreadLocal<SoftReference<BufferAllocator>> TL = new ThreadLocal<>();
public static BufferAllocator getBufferAllocator() {
BufferAllocator ba = null;
SoftReference<BufferAllocator> sr = TL.get();
if (sr != null) {
ba = sr.get();
}
if (ba == null) {
ba = new BufferAllocator();
sr = new SoftReference<>(ba);
TL.set(sr);
}
return ba;
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (c) 2006, 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.writers;
import java.io.Writer;
import java.io.OutputStream;
import java.io.IOException;
import com.sun.org.apache.xerces.internal.util.XMLChar;
/**
* <p>This class is used to write a stream of chars as a stream of
* bytes using the UTF8 encoding. It assumes that the underlying
* output stream is buffered or does not need additional buffering.</p>
*
* <p>It is more efficient than using a <code>java.io.OutputStreamWriter</code>
* because it does not need to be wrapped in a
* <code>java.io.BufferedWriter</code>. Creating multiple instances
* of <code>java.io.BufferedWriter</code> has been shown to be very
* expensive in JAX-WS.</p>
*
* @author Santiago.PericasGeertsen@sun.com
*/
public final class UTF8OutputStreamWriter extends Writer {
/**
* Undelying output stream. This class assumes that this
* output stream does not need buffering.
*/
OutputStream out;
/**
* Java represents chars that are not in the Basic Multilingual
* Plane (BMP) in UTF-16. This int stores the first code unit
* for a code point encoded in two UTF-16 code units.
*/
int lastUTF16CodePoint = 0;
public UTF8OutputStreamWriter(OutputStream out) {
this.out = out;
}
public String getEncoding() {
return "UTF-8";
}
public void write(int c) throws IOException {
// Check in we are encoding at high and low surrogates
if (lastUTF16CodePoint != 0) {
final int uc =
(((lastUTF16CodePoint & 0x3ff) << 10) | (c & 0x3ff)) + 0x10000;
if (uc < 0 || uc >= 0x200000) {
throw new IOException("Atttempting to write invalid Unicode code point '" + uc + "'");
}
out.write(0xF0 | (uc >> 18));
out.write(0x80 | ((uc >> 12) & 0x3F));
out.write(0x80 | ((uc >> 6) & 0x3F));
out.write(0x80 | (uc & 0x3F));
lastUTF16CodePoint = 0;
return;
}
// Otherwise, encode char as defined in UTF-8
if (c < 0x80) {
// 1 byte, 7 bits
out.write((int) c);
}
else if (c < 0x800) {
// 2 bytes, 11 bits
out.write(0xC0 | (c >> 6)); // first 5
out.write(0x80 | (c & 0x3F)); // second 6
}
else if (c <= '\uFFFF') {
if (!XMLChar.isHighSurrogate(c) && !XMLChar.isLowSurrogate(c)) {
// 3 bytes, 16 bits
out.write(0xE0 | (c >> 12)); // first 4
out.write(0x80 | ((c >> 6) & 0x3F)); // second 6
out.write(0x80 | (c & 0x3F)); // third 6
}
else {
lastUTF16CodePoint = c;
}
}
}
public void write(char cbuf[]) throws IOException {
for (int i = 0; i < cbuf.length; i++) {
write(cbuf[i]);
}
}
public void write(char cbuf[], int off, int len) throws IOException {
for (int i = 0; i < len; i++) {
write(cbuf[off + i]);
}
}
public void write(String str) throws IOException {
final int len = str.length();
for (int i = 0; i < len; i++) {
write(str.charAt(i));
}
}
public void write(String str, int off, int len) throws IOException {
for (int i = 0; i < len; i++) {
write(str.charAt(off + i));
}
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
if (lastUTF16CodePoint != 0) {
throw new IllegalStateException("Attempting to close a UTF8OutputStreamWriter"
+ " while awaiting for a UTF-16 code unit");
}
out.close();
}
}

View File

@@ -0,0 +1,254 @@
/*
* 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.writers;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import com.sun.org.apache.xerces.internal.util.XMLChar;
import com.sun.org.apache.xerces.internal.utils.SecuritySupport;
/**
* Implements common xml writer functions.
*
* @author Neeraj Bajaj,K.Venugopal Sun Microsystems.
*/
public class WriterUtility {
public static final String START_COMMENT = "<!--";
public static final String END_COMMENT = "-->";
public static final String DEFAULT_ENCODING = " encoding=\"utf-8\"";
public static final String DEFAULT_XMLDECL ="<?xml version=\"1.0\" ?>";
public static final String DEFAULT_XML_VERSION ="1.0";
public static final char CLOSE_START_TAG = '>';
public static final char OPEN_START_TAG = '<';
public static final String OPEN_END_TAG ="</";
public static final char CLOSE_END_TAG = '>';
public static final String START_CDATA = "<![CDATA[";
public static final String END_CDATA = "]]>";
public static final String CLOSE_EMPTY_ELEMENT = "/>";
public static final String SPACE = " ";
public static final String UTF_8 = "utf-8";
static final boolean DEBUG_XML_CONTENT = false;
/**XXX: This feature is only used when writing element content values.
* default value is 'true' however, if the feature is set to false
* characters wont be escaped.
* This feature has no effect when writing Attribute values, character would still be escaped.
* I can't think of any reason why this would be useful when writing attribute values.
* However, this can be reconsidered if there is any usecase.
*/
boolean fEscapeCharacters = true ;
/** Writer object*/
Writer fWriter = null;
//CharsetEncoder
CharsetEncoder fEncoder ;
public WriterUtility(){
fEncoder = getDefaultEncoder();
}
/** Creates a new instance of WriterUtility */
public WriterUtility(Writer writer) {
fWriter = writer;
if(writer instanceof OutputStreamWriter){
String charset = ((OutputStreamWriter)writer).getEncoding();
if(charset != null){
fEncoder = Charset.forName(charset).newEncoder();
}
}else if(writer instanceof FileWriter){
String charset = ((FileWriter)writer).getEncoding();
if(charset != null){
fEncoder = Charset.forName(charset).newEncoder();
}
}
else{
//attempt to retreive default fEncoderoder
fEncoder = getDefaultEncoder();
}
}
/**
* sets the writer object
* @param writer file to write into
*/
public void setWriter(Writer writer){
fWriter = writer;
}
public void setEscapeCharacters(boolean escape){
fEscapeCharacters = escape ;
}
public boolean getEscapeCharacters(){
return fEscapeCharacters;
}
/**
* writes xml content (characters and element content
* @param content
*/
public void writeXMLContent(char[] content, int start, int length) throws IOException{
writeXMLContent(content, start, length, getEscapeCharacters());
}
/**
* writes xml content (characters and element content
* @param content
*/
private void writeXMLContent(char[] content, int start, int length, boolean escapeCharacter) throws IOException{
if(DEBUG_XML_CONTENT){
System.out.println("content to write is " + new String(content, start, length));
}
int index;
char ch;
int sc;
final int end = start + length ;
//define startWritePos to track the position from where the character array data needs to be written
//initialize this variable to start pos. indicating that no data has been written
int startWritePos = start;
for ( index = start ; index < end ; index++ ) {
ch = content[ index ];
if(fEncoder != null && !fEncoder.canEncode(ch)){
//- write the data to the point we get this character
fWriter.write(content, startWritePos, index - startWritePos );
//escape this character
fWriter.write( "&#x" );
fWriter.write(Integer.toHexString(ch));
fWriter.write( ';' );
//increase the startWritePos by 1 indicating that next write should start from
//one position ahead
startWritePos = index + 1;
}
if(DEBUG_XML_CONTENT){
System.out.println("startWritePos = " + startWritePos);
System.out.println("index = " + index);
System.out.println("start = " + start);
System.out.println("end = " + end);
}
switch(ch){
case '<' :{
if(escapeCharacter){
//this character needs to be escaped, write the data from the last write pos
fWriter.write(content, startWritePos, index - startWritePos);
fWriter.write("&lt;");
if(DEBUG_XML_CONTENT){
System.out.print(new String(content, startWritePos, index - startWritePos));
System.out.println("&lt;");
}
//increase the startWritePos by 1 indicating that next write should start from
//one position ahead
startWritePos = index + 1;
}
break;
}
case '&' :{
if(escapeCharacter){
//this character needs to be escaped, write the data from the last write pos
fWriter.write(content, startWritePos, index - startWritePos);
fWriter.write("&amp;");
if(DEBUG_XML_CONTENT){
System.out.print(new String(content,startWritePos, index - startWritePos));
System.out.println("&amp;");
}
//increase the startWritePos by 1 indicating that next write should start from
//one position ahead
startWritePos = index + 1;
}
break;
}
case '>': {
if(escapeCharacter){
//this character needs to be escaped, write the data from the last write pos
fWriter.write(content, startWritePos, index - startWritePos);
fWriter.write("&gt;");
if(DEBUG_XML_CONTENT){
System.out.print(new String(content,startWritePos, index - startWritePos));
System.out.println("&gt;");
}
//increase the startWritePos by 1 indicating that next write should start from
//one position ahead
startWritePos = index + 1;
}
break;
}
}
}
if(DEBUG_XML_CONTENT){
System.out.println("out of the loop, writing " + new String(content, startWritePos, end - startWritePos));
}
//write any pending data
fWriter.write(content, startWritePos, end - startWritePos);
}
/**
* writes xml content (characters and element content
* @param content
*/
public void writeXMLContent(String content) throws IOException{
if(content == null || content.length() == 0) return ;
writeXMLContent(content.toCharArray(), 0, content.length());
}
/**
* Write Attribute value to the underlying stream.
*
* @param value
*/
public void writeXMLAttributeValue(String value)throws IOException{
writeXMLContent(value.toCharArray(), 0, value.length(), true);
}
private CharsetEncoder getDefaultEncoder(){
try{
String encoding = SecuritySupport.getSystemProperty("file.encoding");
if(encoding != null){
return Charset.forName(encoding).newEncoder();
}
}
catch(Exception ex){
//for any exception thrown , catch and continue
}
return null;
}
}

View File

@@ -0,0 +1,742 @@
/*
* Copyright (c) 2005, 2006, 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.writers;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.dom.DOMResult;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;
import org.xml.sax.helpers.NamespaceSupport;
/**
* This class provides support to build a DOM tree using XMLStreamWriter API's.
* @author K.Venugopal@sun.com
*/
/*
* TODO : -Venu
* Internal NamespaceManagement
* setPrefix
* support for isRepairNamespace property.
* Some Unsupported Methods.
* Change StringBuffer to StringBuilder, when JDK 1.5 will be minimum requirement for SJSXP.
*/
public class XMLDOMWriterImpl implements XMLStreamWriter {
private Document ownerDoc = null;
private Node currentNode = null;
private Node node = null;
private NamespaceSupport namespaceContext = null;
private Method mXmlVersion = null;
private boolean [] needContextPop = null;
private StringBuffer stringBuffer = null;
private int resizeValue = 20;
private int depth = 0;
/**
* Creates a new instance of XMLDOMwriterImpl
* @param result DOMResult object @javax.xml.transform.dom.DOMResult
*/
public XMLDOMWriterImpl(DOMResult result) {
node = result.getNode();
if( node.getNodeType() == Node.DOCUMENT_NODE){
ownerDoc = (Document)node;
currentNode = ownerDoc;
}else{
ownerDoc = node.getOwnerDocument();
currentNode = node;
}
getDLThreeMethods();
stringBuffer = new StringBuffer();
needContextPop = new boolean[resizeValue];
namespaceContext = new NamespaceSupport();
}
private void getDLThreeMethods(){
try{
mXmlVersion = ownerDoc.getClass().getMethod("setXmlVersion",new Class[] {String.class});
}catch(NoSuchMethodException mex){
//log these errors at fine level.
mXmlVersion = null;
}catch(SecurityException se){
//log these errors at fine level.
mXmlVersion = null;
}
}
/**
* This method has no effect when called.
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void close() throws XMLStreamException {
//no-op
}
/**
* This method has no effect when called.
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void flush() throws XMLStreamException {
//no-op
}
/**
* {@inheritDoc}
* @return {@inheritDoc}
*/
public javax.xml.namespace.NamespaceContext getNamespaceContext() {
return null;
}
/**
* {@inheritDoc}
* @param namespaceURI {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
* @return {@inheritDoc}
*/
public String getPrefix(String namespaceURI) throws XMLStreamException {
String prefix = null;
if(this.namespaceContext != null){
prefix = namespaceContext.getPrefix(namespaceURI);
}
return prefix;
}
/**
* Is not supported in this implementation.
* @param str {@inheritDoc}
* @throws java.lang.IllegalArgumentException {@inheritDoc}
* @return {@inheritDoc}
*/
public Object getProperty(String str) throws IllegalArgumentException {
throw new UnsupportedOperationException();
}
/**
* Is not supported in this version of the implementation.
* @param uri {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void setDefaultNamespace(String uri) throws XMLStreamException {
namespaceContext.declarePrefix(XMLConstants.DEFAULT_NS_PREFIX, uri);
if(!needContextPop[depth]){
needContextPop[depth] = true;
}
}
/**
* {@inheritDoc}
* @param namespaceContext {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void setNamespaceContext(javax.xml.namespace.NamespaceContext namespaceContext) throws XMLStreamException {
throw new UnsupportedOperationException();
}
/**
* Is not supported in this version of the implementation.
* @param prefix {@inheritDoc}
* @param uri {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void setPrefix(String prefix, String uri) throws XMLStreamException {
if(prefix == null){
throw new XMLStreamException("Prefix cannot be null");
}
namespaceContext.declarePrefix(prefix, uri);
if(!needContextPop[depth]){
needContextPop[depth] = true;
}
}
/**
* Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node.
* @param localName {@inheritDoc}
* @param value {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeAttribute(String localName, String value) throws XMLStreamException {
if(currentNode.getNodeType() == Node.ELEMENT_NODE){
Attr attr = ownerDoc.createAttribute(localName);
attr.setValue(value);
((Element)currentNode).setAttributeNode(attr);
}else{
//Convert node type to String
throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +
"and does not allow attributes to be set ");
}
}
/**
* Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node.
* @param namespaceURI {@inheritDoc}
* @param localName {@inheritDoc}
* @param value {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeAttribute(String namespaceURI,String localName,String value)throws XMLStreamException {
if(currentNode.getNodeType() == Node.ELEMENT_NODE){
String prefix = null;
if(namespaceURI == null ){
throw new XMLStreamException("NamespaceURI cannot be null");
}
if(localName == null){
throw new XMLStreamException("Local name cannot be null");
}
if(namespaceContext != null){
prefix = namespaceContext.getPrefix(namespaceURI);
}
if(prefix == null){
throw new XMLStreamException("Namespace URI "+namespaceURI +
"is not bound to any prefix" );
}
String qualifiedName = null;
if(prefix.equals("")){
qualifiedName = localName;
}else{
qualifiedName = getQName(prefix,localName);
}
Attr attr = ownerDoc.createAttributeNS(namespaceURI, qualifiedName);
attr.setValue(value);
((Element)currentNode).setAttributeNode(attr);
}else{
//Convert node type to String
throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +
"and does not allow attributes to be set ");
}
}
/**
* Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node.
* @param prefix {@inheritDoc}
* @param namespaceURI {@inheritDoc}
* @param localName {@inheritDoc}
* @param value {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeAttribute(String prefix,String namespaceURI,String localName,String value)throws XMLStreamException {
if(currentNode.getNodeType() == Node.ELEMENT_NODE){
if(namespaceURI == null ){
throw new XMLStreamException("NamespaceURI cannot be null");
}
if(localName == null){
throw new XMLStreamException("Local name cannot be null");
}
if(prefix == null){
throw new XMLStreamException("prefix cannot be null");
}
String qualifiedName = null;
if(prefix.equals("")){
qualifiedName = localName;
}else{
qualifiedName = getQName(prefix,localName);
}
Attr attr = ownerDoc.createAttributeNS(namespaceURI, qualifiedName);
attr.setValue(value);
((Element)currentNode).setAttributeNodeNS(attr);
}else{
//Convert node type to String
throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +
"and does not allow attributes to be set ");
}
}
/**
* Creates a CDATA object @see org.w3c.dom.CDATASection.
* @param data {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeCData(String data) throws XMLStreamException {
if(data == null){
throw new XMLStreamException("CDATA cannot be null");
}
CDATASection cdata = ownerDoc.createCDATASection(data);
getNode().appendChild(cdata);
}
/**
* Creates a character object @see org.w3c.dom.Text and appends it to the current
* element in the DOM tree.
* @param charData {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeCharacters(String charData) throws XMLStreamException {
Text text = ownerDoc.createTextNode(charData);
currentNode.appendChild(text);
}
/**
* Creates a character object @see org.w3c.dom.Text and appends it to the current
* element in the DOM tree.
* @param values {@inheritDoc}
* @param param {@inheritDoc}
* @param param2 {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeCharacters(char[] values, int param, int param2) throws XMLStreamException {
Text text = ownerDoc.createTextNode(new String(values,param,param2));
currentNode.appendChild(text);
}
/**
* Creates a Comment object @see org.w3c.dom.Comment and appends it to the current
* element in the DOM tree.
* @param str {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeComment(String str) throws XMLStreamException {
Comment comment = ownerDoc.createComment(str);
getNode().appendChild(comment);
}
/**
* This method is not supported in this implementation.
* @param str {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeDTD(String str) throws XMLStreamException {
throw new UnsupportedOperationException();
}
/**
* Creates a DOM attribute and adds it to the current element in the DOM tree.
* @param namespaceURI {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeDefaultNamespace(String namespaceURI) throws XMLStreamException {
if(currentNode.getNodeType() == Node.ELEMENT_NODE){
String qname = XMLConstants.XMLNS_ATTRIBUTE;
((Element)currentNode).setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,qname, namespaceURI);
}else{
//Convert node type to String
throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() +
"and does not allow attributes to be set ");
}
}
/**
* creates a DOM Element and appends it to the current element in the tree.
* @param localName {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeEmptyElement(String localName) throws XMLStreamException {
if(ownerDoc != null){
Element element = ownerDoc.createElement(localName);
if(currentNode!=null){
currentNode.appendChild(element);
}else{
ownerDoc.appendChild(element);
}
}
}
/**
* creates a DOM Element and appends it to the current element in the tree.
* @param namespaceURI {@inheritDoc}
* @param localName {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeEmptyElement(String namespaceURI, String localName) throws XMLStreamException {
if(ownerDoc != null){
String qualifiedName = null;
String prefix = null;
if(namespaceURI == null ){
throw new XMLStreamException("NamespaceURI cannot be null");
}
if(localName == null){
throw new XMLStreamException("Local name cannot be null");
}
if(namespaceContext != null){
prefix = namespaceContext.getPrefix(namespaceURI);
}
if(prefix == null){
throw new XMLStreamException("Namespace URI "+namespaceURI +
"is not bound to any prefix" );
}
if("".equals(prefix)){
qualifiedName = localName;
}else{
qualifiedName = getQName(prefix,localName);
}
Element element = ownerDoc.createElementNS(namespaceURI, qualifiedName);
if(currentNode!=null){
currentNode.appendChild(element);
}else{
ownerDoc.appendChild(element);
}
//currentNode = element;
}
}
/**
* creates a DOM Element and appends it to the current element in the tree.
* @param prefix {@inheritDoc}
* @param localName {@inheritDoc}
* @param namespaceURI {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeEmptyElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
if(ownerDoc != null){
if(namespaceURI == null ){
throw new XMLStreamException("NamespaceURI cannot be null");
}
if(localName == null){
throw new XMLStreamException("Local name cannot be null");
}
if(prefix == null){
throw new XMLStreamException("Prefix cannot be null");
}
String qualifiedName = null;
if("".equals(prefix)){
qualifiedName = localName;
}else{
qualifiedName = getQName(prefix,localName);
}
Element el = ownerDoc.createElementNS(namespaceURI,qualifiedName);
if(currentNode!=null){
currentNode.appendChild(el);
}else{
ownerDoc.appendChild(el);
}
}
}
/**
* Will reset current Node pointer maintained by the implementation.
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeEndDocument() throws XMLStreamException {
//What do you want me to do eh! :)
currentNode = null;
for(int i=0; i< depth;i++){
if(needContextPop[depth]){
needContextPop[depth] = false;
namespaceContext.popContext();
}
depth--;
}
depth =0;
}
/**
* Internal current Node pointer will point to the parent of the current Node.
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeEndElement() throws XMLStreamException {
Node node= currentNode.getParentNode();
if(currentNode.getNodeType() == Node.DOCUMENT_NODE){
currentNode = null;
}else{
currentNode = node;
}
if(needContextPop[depth]){
needContextPop[depth] = false;
namespaceContext.popContext();
}
depth--;
}
/**
* Is not supported in this implementation.
* @param name {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeEntityRef(String name) throws XMLStreamException {
EntityReference er = ownerDoc.createEntityReference(name);
currentNode.appendChild(er);
}
/**
* creates a namespace attribute and will associate it with the current element in
* the DOM tree.
* @param prefix {@inheritDoc}
* @param namespaceURI {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
if (prefix == null) {
throw new XMLStreamException("prefix cannot be null");
}
if (namespaceURI == null) {
throw new XMLStreamException("NamespaceURI cannot be null");
}
String qname = null;
if (prefix.equals("")) {
qname = XMLConstants.XMLNS_ATTRIBUTE;
} else {
qname = getQName(XMLConstants.XMLNS_ATTRIBUTE,prefix);
}
((Element)currentNode).setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,qname, namespaceURI);
}
/**
* is not supported in this release.
* @param target {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeProcessingInstruction(String target) throws XMLStreamException {
if(target == null){
throw new XMLStreamException("Target cannot be null");
}
ProcessingInstruction pi = ownerDoc.createProcessingInstruction(target, "");
currentNode.appendChild(pi);
}
/**
* is not supported in this release.
* @param target {@inheritDoc}
* @param data {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeProcessingInstruction(String target, String data) throws XMLStreamException {
if(target == null){
throw new XMLStreamException("Target cannot be null");
}
ProcessingInstruction pi = ownerDoc.createProcessingInstruction(target, data);
currentNode.appendChild(pi);
}
/**
* will set version on the Document object when the DOM Node passed to this implementation
* supports DOM Level3 API's.
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeStartDocument() throws XMLStreamException {
try{
if(mXmlVersion != null){
mXmlVersion.invoke(ownerDoc, new Object[] {"1.0"});
}
}catch(IllegalAccessException iae){
throw new XMLStreamException(iae);
}catch(InvocationTargetException ite){
throw new XMLStreamException(ite);
}
}
/**
* will set version on the Document object when the DOM Node passed to this implementation
* supports DOM Level3 API's.
* @param version {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeStartDocument(String version) throws XMLStreamException {
try{
if(mXmlVersion != null){
mXmlVersion.invoke(ownerDoc, new Object[] {version});
}
}catch(IllegalAccessException iae){
throw new XMLStreamException(iae);
}catch(InvocationTargetException ite){
throw new XMLStreamException(ite);
}
}
/**
* will set version on the Document object when the DOM Node passed to this implementation
* supports DOM Level3 API's.
* @param encoding {@inheritDoc}
* @param version {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeStartDocument(String encoding, String version) throws XMLStreamException {
try{
if(mXmlVersion != null){
mXmlVersion.invoke(ownerDoc, new Object[] {version});
}
}catch(IllegalAccessException iae){
throw new XMLStreamException(iae);
}catch(InvocationTargetException ite){
throw new XMLStreamException(ite);
}
//TODO: What to do with encoding.-Venu
}
/**
* creates a DOM Element and appends it to the current element in the tree.
* @param localName {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeStartElement(String localName) throws XMLStreamException {
if(ownerDoc != null){
Element element = ownerDoc.createElement(localName);
if(currentNode!=null){
currentNode.appendChild(element);
}else{
ownerDoc.appendChild(element);
}
currentNode = element;
}
if(needContextPop[depth]){
namespaceContext.pushContext();
}
incDepth();
}
/**
* creates a DOM Element and appends it to the current element in the tree.
* @param namespaceURI {@inheritDoc}
* @param localName {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeStartElement(String namespaceURI, String localName) throws XMLStreamException {
if(ownerDoc != null){
String qualifiedName = null;
String prefix = null;
if(namespaceURI == null ){
throw new XMLStreamException("NamespaceURI cannot be null");
}
if(localName == null){
throw new XMLStreamException("Local name cannot be null");
}
if(namespaceContext != null){
prefix = namespaceContext.getPrefix(namespaceURI);
}
if(prefix == null){
throw new XMLStreamException("Namespace URI "+namespaceURI +
"is not bound to any prefix" );
}
if("".equals(prefix)){
qualifiedName = localName;
}else{
qualifiedName = getQName(prefix,localName);
}
Element element = ownerDoc.createElementNS(namespaceURI, qualifiedName);
if(currentNode!=null){
currentNode.appendChild(element);
}else{
ownerDoc.appendChild(element);
}
currentNode = element;
}
if(needContextPop[depth]){
namespaceContext.pushContext();
}
incDepth();
}
/**
* creates a DOM Element and appends it to the current element in the tree.
* @param prefix {@inheritDoc}
* @param localName {@inheritDoc}
* @param namespaceURI {@inheritDoc}
* @throws javax.xml.stream.XMLStreamException {@inheritDoc}
*/
public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
if(ownerDoc != null){
String qname = null;
if(namespaceURI == null ){
throw new XMLStreamException("NamespaceURI cannot be null");
}
if(localName == null){
throw new XMLStreamException("Local name cannot be null");
}
if(prefix == null){
throw new XMLStreamException("Prefix cannot be null");
}
if(prefix.equals("")){
qname = localName;
}else{
qname = getQName(prefix,localName);
}
Element el = ownerDoc.createElementNS(namespaceURI,qname);
if(currentNode!=null){
currentNode.appendChild(el);
}else{
ownerDoc.appendChild(el);
}
currentNode = el;
if(needContextPop[depth]){
namespaceContext.pushContext();
}
incDepth();
}
}
private String getQName(String prefix , String localName){
stringBuffer.setLength(0);
stringBuffer.append(prefix);
stringBuffer.append(":");
stringBuffer.append(localName);
return stringBuffer.toString();
}
private Node getNode(){
if(currentNode == null){
return ownerDoc;
} else{
return currentNode;
}
}
private void incDepth() {
depth++;
if (depth == needContextPop.length) {
boolean[] array = new boolean[depth + resizeValue];
System.arraycopy(needContextPop, 0, array, 0, depth);
needContextPop = array;
}
}
}

View File

@@ -0,0 +1,261 @@
/*
* Copyright (c) 2005, 2006, 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.writers;
import java.util.Iterator;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.Comment;
import javax.xml.stream.events.DTD;
import javax.xml.stream.events.EntityReference;
import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.ProcessingInstruction;
import javax.xml.stream.events.StartDocument;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import javax.xml.stream.XMLStreamWriter;
/**
*
* @author Neeraj Bajaj, Sun Microsystems.
*
*/
public class XMLEventWriterImpl implements XMLEventWriter{
//delegate everything to XMLStreamWriter..
private XMLStreamWriter fStreamWriter ;
private static final boolean DEBUG = false;
/**
*
* @param streamWriter
*/
public XMLEventWriterImpl(XMLStreamWriter streamWriter){
fStreamWriter = streamWriter;
}
/**
*
* @param xMLEventReader
* @throws XMLStreamException
*/
public void add(javax.xml.stream.XMLEventReader xMLEventReader) throws javax.xml.stream.XMLStreamException {
if(xMLEventReader == null) throw new XMLStreamException("Event reader shouldn't be null");
while(xMLEventReader.hasNext()){
add(xMLEventReader.nextEvent());
}
}
/**
*
* @param xMLEvent
* @throws XMLStreamException
*/
public void add(javax.xml.stream.events.XMLEvent xMLEvent) throws javax.xml.stream.XMLStreamException {
int type = xMLEvent.getEventType();
switch(type){
case XMLEvent.DTD:{
DTD dtd = (DTD)xMLEvent ;
if (DEBUG)System.out.println("Adding DTD = " + dtd.toString());
fStreamWriter.writeDTD(dtd.getDocumentTypeDeclaration());
break;
}
case XMLEvent.START_DOCUMENT :{
StartDocument startDocument = (StartDocument)xMLEvent ;
if (DEBUG)System.out.println("Adding StartDocument = " + startDocument.toString());
try {
fStreamWriter.writeStartDocument(startDocument.getCharacterEncodingScheme(), startDocument.getVersion());
}catch(XMLStreamException e) {
fStreamWriter.writeStartDocument(startDocument.getVersion());
}
break;
}
case XMLEvent.START_ELEMENT :{
StartElement startElement = xMLEvent.asStartElement() ;
if (DEBUG)System.out.println("Adding startelement = " + startElement.toString());
QName qname = startElement.getName();
fStreamWriter.writeStartElement(qname.getPrefix(), qname.getLocalPart(), qname.getNamespaceURI());
//getNamespaces() Returns an Iterator of namespaces declared on this element. This Iterator does not contain
//previously declared namespaces unless they appear on the current START_ELEMENT. Therefore
//this list may contain redeclared namespaces and duplicate namespace declarations. Use the
//getNamespaceContext() method to get the current context of namespace declarations.
//so we should be using getNamespaces() to write namespace declarations for this START_ELEMENT
Iterator iterator = startElement.getNamespaces();
while(iterator.hasNext()){
Namespace namespace = (Namespace)iterator.next();
fStreamWriter.writeNamespace(namespace.getPrefix(), namespace.getNamespaceURI());
}
//REVISIT: What about writing attributes ?
Iterator attributes = startElement.getAttributes();
while(attributes.hasNext()){
Attribute attribute = (Attribute)attributes.next();
QName aqname = attribute.getName();
fStreamWriter.writeAttribute(aqname.getPrefix(), aqname.getNamespaceURI(), aqname.getLocalPart(),attribute.getValue());
}
break;
}
case XMLEvent.NAMESPACE:{
Namespace namespace = (Namespace)xMLEvent;
if (DEBUG)System.out.println("Adding namespace = " + namespace.toString());
fStreamWriter.writeNamespace(namespace.getPrefix(), namespace.getNamespaceURI());
break ;
}
case XMLEvent.COMMENT: {
Comment comment = (Comment)xMLEvent ;
if (DEBUG)System.out.println("Adding comment = " + comment.toString());
fStreamWriter.writeComment(comment.getText());
break;
}
case XMLEvent.PROCESSING_INSTRUCTION:{
ProcessingInstruction processingInstruction = (ProcessingInstruction)xMLEvent ;
if (DEBUG)System.out.println("Adding processing instruction = " + processingInstruction.toString());
fStreamWriter.writeProcessingInstruction(processingInstruction.getTarget(), processingInstruction.getData());
break;
}
case XMLEvent.CHARACTERS:{
Characters characters = xMLEvent.asCharacters();
if (DEBUG)System.out.println("Adding characters = " + characters.toString());
//check if the CHARACTERS are CDATA
if(characters.isCData()){
fStreamWriter.writeCData(characters.getData());
}
else{
fStreamWriter.writeCharacters(characters.getData());
}
break;
}
case XMLEvent.ENTITY_REFERENCE:{
EntityReference entityReference = (EntityReference)xMLEvent ;
if (DEBUG)System.out.println("Adding Entity Reference = "+ entityReference.toString());
fStreamWriter.writeEntityRef(entityReference.getName());
break;
}
case XMLEvent.ATTRIBUTE:{
Attribute attribute = (Attribute)xMLEvent;
if (DEBUG)System.out.println("Adding Attribute = " + attribute.toString());
QName qname = attribute.getName();
fStreamWriter.writeAttribute(qname.getPrefix(), qname.getNamespaceURI(), qname.getLocalPart(),attribute.getValue());
break;
}
case XMLEvent.CDATA:{
//there is no separate CDATA datatype but CDATA event can be reported
//by using vendor specific CDATA property.
Characters characters = (Characters)xMLEvent;
if (DEBUG)System.out.println("Adding characters = " + characters.toString());
if(characters.isCData()){
fStreamWriter.writeCData(characters.getData());
}
break;
}
//xxx: Why there isn't any event called Notation.
//case XMLEvent.NOTATION_DECLARATION:{
//}
case XMLEvent.END_ELEMENT:{
//we dont need to typecast it.. just call writeEndElement() and fStreamWriter will take care of it.
//EndElement endElement = (EndElement)xMLEvent;
fStreamWriter.writeEndElement();
break;
}
case XMLEvent.END_DOCUMENT:{
//we dont need to typecast just call writeEndDocument() and fStreamWriter will take care rest.
//EndDocument endDocument = (EndDocument)xMLEvent;
fStreamWriter.writeEndDocument();
break;
}
//throw new XMLStreamException("Unknown Event type = " + type);
};
}
/**
*
* @throws XMLStreamException
*/
public void close() throws javax.xml.stream.XMLStreamException {
fStreamWriter.close();
}
/**
*
* @throws XMLStreamException will inturn call flush on the stream to which data is being
* written.
*/
public void flush() throws javax.xml.stream.XMLStreamException {
fStreamWriter.flush();
}
/**
*
* @return
*/
public javax.xml.namespace.NamespaceContext getNamespaceContext() {
return fStreamWriter.getNamespaceContext();
}
/**
*
* @param namespaceURI Namespace URI
* @throws XMLStreamException
* @return prefix associated with the URI.
*/
public String getPrefix(String namespaceURI) throws javax.xml.stream.XMLStreamException {
return fStreamWriter.getPrefix(namespaceURI);
}
/**
*
* @param uri Namespace URI
* @throws XMLStreamException
*/
public void setDefaultNamespace(String uri) throws javax.xml.stream.XMLStreamException {
fStreamWriter.setDefaultNamespace(uri);
}
/**
*
* @param namespaceContext Namespace Context
* @throws XMLStreamException
*/
public void setNamespaceContext(javax.xml.namespace.NamespaceContext namespaceContext) throws javax.xml.stream.XMLStreamException {
fStreamWriter.setNamespaceContext(namespaceContext);
}
/**
*
* @param prefix namespace prefix associated with the uri.
* @param uri Namespace URI
* @throws XMLStreamException
*/
public void setPrefix(String prefix, String uri) throws javax.xml.stream.XMLStreamException {
fStreamWriter.setPrefix(prefix, uri);
}
}//XMLEventWriterImpl

View File

@@ -0,0 +1,45 @@
/*
* Copyright (c) 2006, 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.writers;
import java.io.OutputStream;
import java.io.Writer;
/**
* XMLOutputSource.
*
* Encapuslates the information about the source where
* XML output needs to be written.
*
* @author Neeraj Bajaj
*/
public class XMLOutputSource {
/** Creates a new instance of XMLOutputSource */
public XMLOutputSource() {
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,260 @@
/*
* Copyright (c) 2006, 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.writers;
import java.io.IOException;
import java.io.Writer;
import com.sun.org.apache.xerces.internal.util.XMLStringBuffer;
/**
* XMLWriter
*
* <code>XMLWriter</code> is not thread safe.
*
* For efficiency this writer buffers the input. Use <code>flush()</code> function
* to explicitly write the data to underlying stream.
*
* This writer is designed in such a way that it atleast buffers the input to the
* <code>size</code> specified. Unless <code>flush</code> is called, it guarantees that
* data in chunks of size equal to or more than <code>size</code> specified will be written.
*
*
* <code>XMLWriter</code> instance can be reused. <code>setWriter()</code> internally clears the
* buffer and stores the reference to newly supplied <code>Writer</code> instance.
*
* @author Neeraj Bajaj Sun Microsystems, inc.
*/
public class XMLWriter extends Writer {
private Writer writer ;
private int size ;
//keep the size of internal buffer more than 'size' required to avoid resizing
private XMLStringBuffer buffer = new XMLStringBuffer(6 * (1 << 11) ); // 6 KB
private static final int THRESHHOLD_LENGTH = 1 << 12 ; // 4 KB
private static final boolean DEBUG = false;
/** Creates the instance of <code>XMLWriter</code>
*/
public XMLWriter(Writer writer){
this(writer, THRESHHOLD_LENGTH);
}
/**
* Creates the instnace of <code>XMLWriter</code>.
*
* atleast buffers the input to the
* <code>size</code> specified.
*/
public XMLWriter(Writer writer, int size){
this.writer = writer ;
this.size = size;
}
/**
* Write a single character. The character to be written is contained in
* the 16 low-order bits of the given integer value; the 16 high-order bits
* are ignored.
*
* <p> Subclasses that intend to support efficient single-character output
* should override this method.
*
* @param c int specifying a character to be written.
* @exception IOException If an I/O error occurs
*/
public void write(int c) throws IOException {
ensureOpen();
buffer.append((char)c);
conditionalWrite();
}
/**
* Write an array of characters.
*
* @param cbuf Array of characters to be written
*
* @exception IOException If an I/O error occurs
*/
public void write(char cbuf[]) throws IOException {
write(cbuf, 0, cbuf.length);
}
/**
* Write a portion of an array of characters.
*
* @param cbuf Array of characters
* @param off Offset from which to start writing characters
* @param len Number of characters to write
*
* @exception IOException If an I/O error occurs
*/
public void write(char cbuf[], int off, int len) throws IOException{
ensureOpen();
//optimization: if data size to be written is more than the 'size' specified,
//do not buffer the data but write the data straight to the underlying stream
if(len > size){
//first write the data that may be present in the buffer
writeBufferedData();
//write directly to stream
writer.write(cbuf, off, len);
}else{
buffer.append(cbuf, off, len);
conditionalWrite();
}
}
/**
* Write a portion of a string.
*
* @param str A String
* @param off Offset from which to start writing characters
* @param len Number of characters to write
*
* @exception IOException If an I/O error occurs
*/
public void write(String str, int off, int len) throws IOException {
write(str.toCharArray(), off, len);
}
/**
* Write a string.
*
* @param str String to be written
*
* @exception IOException If an I/O error occurs
*/
public void write(String str) throws IOException {
//optimization: if data size to be written is more than the 'size' specified,
//do not buffer the data but write the data straight to the underlying stream - nb.
if(str.length() > size){
//first write the data that may be present in the buffer
writeBufferedData();
//write directly to stream
writer.write(str);
}else{
buffer.append(str);
conditionalWrite();
}
}
/**
* Close the stream, flushing it first. Once a stream has been closed,
* further write() or flush() invocations will cause an IOException to be
* thrown. Closing a previously-closed stream, however, has no effect.
*
* @exception IOException If an I/O error occurs
*/
public void close() throws IOException {
if(writer == null) return;
//flush it first
flush();
writer.close();
writer = null ;
}
/**
* Flush the stream. If the stream has saved any characters from the
* various write() methods in a buffer, write them immediately to their
* intended destination. Then, if that destination is another character or
* byte stream, flush it. Thus one flush() invocation will flush all the
* buffers in a chain of Writers and OutputStreams.
*
* @exception IOException If an I/O error occurs
*/
public void flush() throws IOException {
ensureOpen();
//write current data present in the buffer
writeBufferedData();
writer.flush();
}
/** Reset this Writer.
*
* see @setWriter()
*/
public void reset(){
this.writer = null;
buffer.clear();
this.size = THRESHHOLD_LENGTH;
}
/**
* Set the given <code>Writer</code>.
*
* @param Writer Writer.
*/
public void setWriter(Writer writer){
this.writer = writer;
buffer.clear();
this.size = THRESHHOLD_LENGTH;
}
/** Set the given <code>Writer</code>
*
* @param Writer Writer.
* @param int Writer will buffer the character data size, after that data is written to stream.
*/
public void setWriter(Writer writer, int size){
this.writer = writer;
this.size = size;
}
/**
* Returns underlying <code>Writer</code>
*/
protected Writer getWriter() {
return writer;
}
/** write the buffer data, if the buffer size has increased the size specified
*/
private void conditionalWrite() throws IOException {
if(buffer.length > size){
if(DEBUG){
System.out.println("internal buffer length " + buffer.length + " increased size limit : " + size);
System.out.println("Data: ('" + new String(buffer.ch, buffer.offset, buffer.length) + "')");
}
writeBufferedData();
}
}
/** Write the data present in the buffer to the writer.
* buffer is cleared after write operation.
*/
private void writeBufferedData() throws IOException {
writer.write(buffer.ch, buffer.offset, buffer.length);
buffer.clear();
}
/** Check to make sure that the stream has not been closed */
private void ensureOpen() throws IOException {
if (writer == null)throw new IOException("Stream closed");
}
}