blob: 3f5cc672c1ee067cd353075d6b22caa7a249ec4a [file] [log] [blame]
/* Copyright 2004 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 org.apache.xmlbeans.impl.validator;
import org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.common.GenericXmlInputStream;
import org.apache.xmlbeans.impl.common.ValidatorListener;
import org.apache.xmlbeans.impl.common.ValidatorListener.Event;
import org.apache.xmlbeans.impl.common.XMLNameHelper;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
import org.apache.xmlbeans.impl.schema.BuiltinSchemaTypeSystem;
import org.apache.xmlbeans.xml.stream.CharacterData;
import org.apache.xmlbeans.xml.stream.*;
import javax.xml.namespace.QName;
import java.util.AbstractCollection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Map;
/**
* @deprecated XMLInputStream was deprecated by XMLStreamReader from STaX - jsr173 API.
*/
public final class ValidatingXMLInputStream
extends GenericXmlInputStream implements Event {
public ValidatingXMLInputStream(
XMLInputStream xis,
SchemaTypeLoader typeLoader, SchemaType sType, XmlOptions options)
throws XMLStreamException {
_source = xis;
// Figure out the root type
options = XmlOptions.maskNull(options);
SchemaType type = options.getDocumentType();
if (type == null) {
type = sType;
}
if (type == null) {
type = BuiltinSchemaTypeSystem.ST_ANY_TYPE;
xis = xis.getSubStream();
if (xis.skip(XMLEvent.START_ELEMENT)) {
SchemaType docType =
typeLoader.findDocumentType(
XMLNameHelper.getQName(xis.next().getName()));
if (docType != null) {
type = docType;
}
}
xis.close();
}
// Create the validator
_validator =
new Validator(
type, null, typeLoader, options, new ExceptionXmlErrorListener());
nextEvent(ValidatorListener.BEGIN);
}
// TODO - this is the quick and dirty impl of streaming validation,
// may objects are created (like strings) which can be optimized
protected XMLEvent nextEvent() throws XMLStreamException {
XMLEvent e = _source.next();
if (e == null) {
if (!_finished) {
flushText();
nextEvent(ValidatorListener.END);
_finished = true;
}
} else {
switch (e.getType()) {
case XMLEvent.CHARACTER_DATA:
case XMLEvent.SPACE: {
CharacterData cd = (CharacterData) e;
if (cd.hasContent()) {
_text.append(cd.getContent());
}
break;
}
case XMLEvent.START_ELEMENT: {
StartElement se = (StartElement) e;
flushText();
// Used for prefix to namespace mapping
_startElement = se;
// Prepare the xsi:* values
AttributeIterator attrs = se.getAttributes();
while (attrs.hasNext()) {
Attribute attr = attrs.next();
XMLName attrName = attr.getName();
if ("http://www.w3.org/2001/XMLSchema-instance".equals(
attrName.getNamespaceUri())) {
String local = attrName.getLocalName();
if (local.equals("type")) {
_xsiType = attr.getValue();
} else if (local.equals("nil")) {
_xsiNil = attr.getValue();
} else if (local.equals("schemaLocation")) {
_xsiLoc = attr.getValue();
} else if (local.equals("noNamespaceSchemaLocation")) {
_xsiNoLoc = attr.getValue();
}
}
}
// Emit the START
// TODO - should delay the aquisition of the name
_name = e.getName();
nextEvent(ValidatorListener.BEGIN);
// Emit the attrs
attrs = se.getAttributes();
while (attrs.hasNext()) {
Attribute attr = attrs.next();
XMLName attrName = attr.getName();
if ("http://www.w3.org/2001/XMLSchema-instance".equals(
attrName.getNamespaceUri())) {
String local = attrName.getLocalName();
if (local.equals("type")) {
continue;
} else if (local.equals("nil")) {
continue;
} else if (local.equals("schemaLocation")) {
continue;
} else if (local.equals("noNamespaceSchemaLocation")) {
continue;
}
}
// TODO - God, this is lame :-)
_text.append(attr.getValue());
_name = attr.getName();
nextEvent(ValidatorListener.ATTR);
}
clearText();
_startElement = null;
break;
}
case XMLEvent.END_ELEMENT: {
flushText();
nextEvent(ValidatorListener.END);
break;
}
}
}
return e;
}
private void clearText() {
_text.delete(0, _text.length());
}
private void flushText() throws XMLStreamException {
if (_text.length() > 0) {
nextEvent(ValidatorListener.TEXT);
clearText();
}
}
public String getNamespaceForPrefix(String prefix) {
if (_startElement == null) {
return null;
}
Map map = _startElement.getNamespaceMap();
if (map == null) {
return null;
}
return (String) map.get(prefix);
}
public XmlCursor getLocationAsCursor() {
return null;
}
public javax.xml.stream.Location getLocation() {
try {
final org.apache.xmlbeans.xml.stream.Location xeLoc = _source.peek().getLocation();
if (xeLoc == null) {
return null;
}
javax.xml.stream.Location loc = new javax.xml.stream.Location() {
public int getLineNumber() {
return xeLoc.getLineNumber();
}
public int getColumnNumber() {
return xeLoc.getColumnNumber();
}
public int getCharacterOffset() {
return -1;
}
public String getPublicId() {
return xeLoc.getPublicId();
}
public String getSystemId() {
return xeLoc.getSystemId();
}
};
return loc;
} catch (XMLStreamException e) {
return null;
}
}
public String getXsiType() {
return _xsiType;
}
public String getXsiNil() {
return _xsiNil;
}
public String getXsiLoc() {
return _xsiLoc;
}
public String getXsiNoLoc() {
return _xsiNoLoc;
}
public QName getName() {
return XMLNameHelper.getQName(_name);
}
public String getText() {
return _text.toString();
}
public String getText(int wsr) {
return XmlWhitespace.collapse(_text.toString(), wsr);
}
public boolean textIsWhitespace() {
for (int i = 0; i < _text.length(); i++) {
switch (_text.charAt(i)) {
case ' ':
case '\n':
case '\r':
case '\t':
break;
default:
return false;
}
}
return true;
}
private final class ExceptionXmlErrorListener extends AbstractCollection {
public boolean add(Object o) {
assert ValidatingXMLInputStream.this._exception == null;
ValidatingXMLInputStream.this._exception =
new XMLStreamValidationException((XmlError) o);
return false;
}
public Iterator iterator() {
return Collections.EMPTY_LIST.iterator();
}
public int size() {
return 0;
}
}
private void nextEvent(int kind)
throws XMLStreamException {
assert _exception == null;
_validator.nextEvent(kind, this);
if (_exception != null) {
throw _exception;
}
}
private XMLStreamValidationException _exception;
private XMLInputStream _source;
private Validator _validator;
private StringBuilder _text = new StringBuilder();
private boolean _finished;
private String _xsiType;
private String _xsiNil;
private String _xsiLoc;
private String _xsiNoLoc;
private XMLName _name;
private StartElement _startElement;
}