* Note: The QName values are copied into the
* stack. In other words, the caller does not orphan
* the element to the stack. Also, the QName object returned
* is not orphaned to the caller. It should be
* considered read-only.
*
* @param element The element to push onto the stack.
*
* @return Returns the actual QName object that stores the
*/
public ElementState push(ElementState element) {
if (fDepth == fElements.length) {
ElementState[] array = new ElementState[fElements.length * 2];
System.arraycopy(fElements, 0, array, 0, fDepth);
fElements = array;
for (int i = fDepth; i < fElements.length; i++) {
fElements[i] = new ElementState();
}
}
fElements[fDepth].setValues(element);
return fElements[fDepth++];
}
/**
*
* @param prefix
* @param localpart
* @param rawname
* @param uri
* @param isEmpty
* @return
*/
public ElementState push(String prefix, String localpart,
String rawname, String uri, boolean isEmpty) {
if (fDepth == fElements.length) {
ElementState[] array = new ElementState[fElements.length * 2];
System.arraycopy(fElements, 0, array, 0, fDepth);
fElements = array;
for (int i = fDepth; i < fElements.length; i++) {
fElements[i] = new ElementState();
}
}
fElements[fDepth].setValues(prefix, localpart, rawname, uri, isEmpty);
return fElements[fDepth++];
}
/**
* Pops an element off of the stack by setting the values of
* the specified QName.
*
* Note: The object returned is not
* orphaned to the caller. Therefore, the caller should consider
* the object to be read-only.
*/
public ElementState pop() {
return fElements[--fDepth];
}
/** Clears the stack without throwing away existing QName objects. */
public void clear() {
fDepth = 0;
}
/**
* This function is as a result of optimization done for endElement --
* we dont need to set the value for every end element we encouter.
* For Well formedness checks we can have the same QName object that was pushed.
* the values will be set only if application need to know about the endElement
*/
public ElementState peek() {
return fElements[fDepth - 1];
}
/**
*
* @return
*/
public boolean empty() {
return (fDepth > 0) ? false : true;
}
}
/**
* Maintains element state . localName for now.
*/
class ElementState extends QName {
public boolean isEmpty = false;
public ElementState() {}
public ElementState(String prefix, String localpart, String rawname,
String uri) {
super(prefix, localpart, rawname, uri);
}
public void setValues(String prefix, String localpart, String rawname,
String uri, boolean isEmpty) {
super.setValues(prefix, localpart, rawname, uri);
this.isEmpty = isEmpty;
}
}
/**
* Attributes
*/
class Attribute extends QName {
String value;
Attribute(String value) {
super();
this.value = value;
}
}
/**
* Implementation of NamespaceContext .
*
*/
class NamespaceContextImpl implements NamespaceContext {
//root namespace context set by user.
NamespaceContext userContext = null;
//context built by the writer.
NamespaceSupport internalContext = null;
public String getNamespaceURI(String prefix) {
String uri = null;
if (prefix != null) {
prefix = fSymbolTable.addSymbol(prefix);
}
if (internalContext != null) {
uri = internalContext.getURI(prefix);
if (uri != null) {
return uri;
}
}
if (userContext != null) {
uri = userContext.getNamespaceURI(prefix);
return uri;
}
return null;
}
public String getPrefix(String uri) {
String prefix = null;
if (uri != null) {
uri = fSymbolTable.addSymbol(uri);
}
if (internalContext != null) {
prefix = internalContext.getPrefix(uri);
if (prefix != null) {
return prefix;
}
}
if (userContext != null) {
return userContext.getPrefix(uri);
}
return null;
}
//Cleanup note: leaving these warnings to a xerces.internal.util cleanup
public Iterator getPrefixes(String uri) {
List prefixes = null;
Iterator itr = null;
if (uri != null) {
uri = fSymbolTable.addSymbol(uri);
}
if (userContext != null) {
itr = userContext.getPrefixes(uri);
}
if (internalContext != null) {
prefixes = internalContext.getPrefixes(uri);
}
if ((prefixes == null) && (itr != null)) {
return itr;
} else if ((prefixes != null) && (itr == null)) {
return new ReadOnlyIterator<>(prefixes.iterator());
} else if ((prefixes != null) && (itr != null)) {
String ob = null;
while (itr.hasNext()) {
ob = itr.next();
if (ob != null) {
ob = fSymbolTable.addSymbol(ob);
}
if (!prefixes.contains(ob)) {
prefixes.add(ob);
}
}
return new ReadOnlyIterator<>(prefixes.iterator());
}
return fReadOnlyIterator;
}
}
// -- Map Interface --------------------------------------------------
@Override
public int size() {
return 1;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean containsKey(Object key) {
return key.equals(OUTPUTSTREAM_PROPERTY);
}
/**
* Returns the value associated to an implementation-specific
* property.
*/
@Override
public Object get(Object key) {
if (key.equals(OUTPUTSTREAM_PROPERTY)) {
return fOutputStream;
}
return null;
}
@Override
public Set> entrySet() {
throw new UnsupportedOperationException();
}
/**
* Overrides the method defined in AbstractMap which is
* not completely implemented. Calling toString() in
* AbstractMap would cause an unsupported exection to
* be thrown.
*/
@Override
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* Overrides the method defined in AbstractMap
* This is required by the toString() method
*/
@Override
public int hashCode() {
return fElementStack.hashCode();
}
/**
* Overrides the method defined in AbstractMap
* This is required to satisfy the contract for hashCode.
*/
@Override
public boolean equals(Object obj) {
return (this == obj);
}
}