001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.xml.internal.bind.v2.runtime.unmarshaller;
027:
028: import javax.xml.namespace.NamespaceContext;
029: import javax.xml.validation.Schema;
030: import javax.xml.validation.ValidatorHandler;
031:
032: import com.sun.xml.internal.bind.v2.util.FatalAdapter;
033:
034: import org.xml.sax.SAXException;
035:
036: /**
037: * {@link XmlVisitor} decorator that validates the events by using JAXP validation API.
038: *
039: * @author Kohsuke Kawaguchi
040: */
041: final class ValidatingUnmarshaller implements XmlVisitor,
042: XmlVisitor.TextPredictor {
043:
044: private final XmlVisitor next;
045: private final ValidatorHandler validator;
046:
047: /**
048: * {@link TextPredictor} of the next {@link XmlVisitor}.
049: */
050: private final TextPredictor predictor;
051:
052: private char[] buf = new char[256];
053:
054: /**
055: * Creates a new instance of ValidatingUnmarshaller.
056: */
057: public ValidatingUnmarshaller(Schema schema, XmlVisitor next) {
058: this .validator = schema.newValidatorHandler();
059: this .next = next;
060: this .predictor = next.getPredictor();
061: // if the user bothers to use a validator, make validation errors fatal
062: // so that it will abort unmarshalling.
063: validator.setErrorHandler(new FatalAdapter(getContext()));
064: }
065:
066: public void startDocument(LocatorEx locator,
067: NamespaceContext nsContext) throws SAXException {
068: // when nsContext is non-null, validator won't probably work correctly.
069: // should we warn?
070: validator.setDocumentLocator(locator);
071: validator.startDocument();
072: next.startDocument(locator, nsContext);
073: }
074:
075: public void endDocument() throws SAXException {
076: validator.endDocument();
077: next.endDocument();
078: }
079:
080: public void startElement(TagName tagName) throws SAXException {
081: validator.startElement(tagName.uri, tagName.local, tagName
082: .getQname(), tagName.atts);
083: next.startElement(tagName);
084: }
085:
086: public void endElement(TagName tagName) throws SAXException {
087: validator.endElement(tagName.uri, tagName.local, tagName
088: .getQname());
089: next.endElement(tagName);
090: }
091:
092: public void startPrefixMapping(String prefix, String nsUri)
093: throws SAXException {
094: validator.startPrefixMapping(prefix, nsUri);
095: next.startPrefixMapping(prefix, nsUri);
096: }
097:
098: public void endPrefixMapping(String prefix) throws SAXException {
099: validator.endPrefixMapping(prefix);
100: next.endPrefixMapping(prefix);
101: }
102:
103: public void text(CharSequence pcdata) throws SAXException {
104: int len = pcdata.length();
105: if (buf.length < len) {
106: buf = new char[len];
107: }
108: for (int i = 0; i < len; i++)
109: buf[i] = pcdata.charAt(i); // isn't this kinda slow?
110:
111: validator.characters(buf, 0, len);
112: if (predictor.expectText())
113: next.text(pcdata);
114: }
115:
116: public UnmarshallingContext getContext() {
117: return next.getContext();
118: }
119:
120: public TextPredictor getPredictor() {
121: return this ;
122: }
123:
124: // should be always invoked through TextPredictor
125: @Deprecated
126: public boolean expectText() {
127: // validator needs to make sure that there's no text
128: // even when it's not expected. So always have them
129: // send text, ignoring optimization hints from the unmarshaller
130: return true;
131: }
132: }
|