KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > jaxp > validation > ValidatorHandlerImpl


1 /*
2  * Copyright 2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.jaxp.validation;
18
19 import java.io.IOException JavaDoc;
20 import java.io.InputStream JavaDoc;
21 import java.io.Reader JavaDoc;
22 import java.io.StringReader JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.Locale JavaDoc;
25
26 import javax.xml.parsers.FactoryConfigurationError JavaDoc;
27 import javax.xml.parsers.SAXParserFactory JavaDoc;
28 import javax.xml.transform.Result JavaDoc;
29 import javax.xml.transform.Source JavaDoc;
30 import javax.xml.transform.sax.SAXResult JavaDoc;
31 import javax.xml.transform.sax.SAXSource JavaDoc;
32 import javax.xml.validation.TypeInfoProvider JavaDoc;
33 import javax.xml.validation.ValidatorHandler JavaDoc;
34
35 import org.apache.xerces.impl.Constants;
36 import org.apache.xerces.impl.XMLEntityManager;
37 import org.apache.xerces.impl.XMLErrorReporter;
38 import org.apache.xerces.impl.dv.XSSimpleType;
39 import org.apache.xerces.impl.validation.EntityState;
40 import org.apache.xerces.impl.validation.ValidationManager;
41 import org.apache.xerces.impl.xs.XMLSchemaValidator;
42 import org.apache.xerces.util.AttributesProxy;
43 import org.apache.xerces.util.SAXLocatorWrapper;
44 import org.apache.xerces.util.SAXMessageFormatter;
45 import org.apache.xerces.util.SymbolTable;
46 import org.apache.xerces.util.URI;
47 import org.apache.xerces.util.XMLAttributesImpl;
48 import org.apache.xerces.util.XMLSymbols;
49 import org.apache.xerces.xni.Augmentations;
50 import org.apache.xerces.xni.NamespaceContext;
51 import org.apache.xerces.xni.QName;
52 import org.apache.xerces.xni.XMLAttributes;
53 import org.apache.xerces.xni.XMLDocumentHandler;
54 import org.apache.xerces.xni.XMLLocator;
55 import org.apache.xerces.xni.XMLResourceIdentifier;
56 import org.apache.xerces.xni.XMLString;
57 import org.apache.xerces.xni.XNIException;
58 import org.apache.xerces.xni.parser.XMLConfigurationException;
59 import org.apache.xerces.xni.parser.XMLDocumentSource;
60 import org.apache.xerces.xni.parser.XMLParseException;
61 import org.apache.xerces.xs.AttributePSVI;
62 import org.apache.xerces.xs.ElementPSVI;
63 import org.apache.xerces.xs.ItemPSVI;
64 import org.apache.xerces.xs.PSVIProvider;
65 import org.apache.xerces.xs.XSTypeDefinition;
66 import org.w3c.dom.TypeInfo JavaDoc;
67 import org.w3c.dom.ls.LSInput JavaDoc;
68 import org.w3c.dom.ls.LSResourceResolver JavaDoc;
69 import org.xml.sax.Attributes JavaDoc;
70 import org.xml.sax.ContentHandler JavaDoc;
71 import org.xml.sax.DTDHandler JavaDoc;
72 import org.xml.sax.ErrorHandler JavaDoc;
73 import org.xml.sax.InputSource JavaDoc;
74 import org.xml.sax.Locator JavaDoc;
75 import org.xml.sax.SAXException JavaDoc;
76 import org.xml.sax.SAXNotRecognizedException JavaDoc;
77 import org.xml.sax.SAXNotSupportedException JavaDoc;
78 import org.xml.sax.XMLReader JavaDoc;
79 import org.xml.sax.ext.Attributes2 JavaDoc;
80 import org.xml.sax.ext.EntityResolver2 JavaDoc;
81
82 /**
83  * <p>Implementation of ValidatorHandler for W3C XML Schemas and
84  * also a validator helper for <code>SAXSource</code>s.</p>
85  *
86  * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
87  * @author Michael Glavassevich, IBM
88  *
89  * @version $Id: ValidatorHandlerImpl.java,v 1.2 2005/06/13 21:57:00 mrglavas Exp $
90  */

91 final class ValidatorHandlerImpl extends ValidatorHandler JavaDoc implements
92     DTDHandler JavaDoc, EntityState, PSVIProvider, ValidatorHelper, XMLDocumentHandler {
93     
94     // feature identifiers
95

96     /** Feature identifier: namespace prefixes. */
97     private static final String JavaDoc NAMESPACE_PREFIXES =
98         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
99     
100     /** Feature identifier: string interning. */
101     protected static final String JavaDoc STRING_INTERNING =
102         Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE;
103     
104     // property identifiers
105

106     /** Property identifier: error reporter. */
107     private static final String JavaDoc ERROR_REPORTER =
108         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
109     
110     /** Property identifier: namespace context. */
111     private static final String JavaDoc NAMESPACE_CONTEXT =
112         Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
113     
114     /** Property identifier: XML Schema validator. */
115     private static final String JavaDoc SCHEMA_VALIDATOR =
116         Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
117     
118     /** Property identifier: security manager. */
119     private static final String JavaDoc SECURITY_MANAGER =
120         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
121     
122     /** Property identifier: symbol table. */
123     private static final String JavaDoc SYMBOL_TABLE =
124         Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
125
126     /** Property identifier: validation manager. */
127     private static final String JavaDoc VALIDATION_MANAGER =
128         Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
129  
130     //
131
// Data
132
//
133

134     /** Error reporter. */
135     private XMLErrorReporter fErrorReporter;
136     
137     /** The namespace context of this document: stores namespaces in scope */
138     private NamespaceContext fNamespaceContext;
139     
140     /** Schema validator. **/
141     private XMLSchemaValidator fSchemaValidator;
142     
143     /** Symbol table **/
144     private SymbolTable fSymbolTable;
145     
146     /** Validation manager. */
147     private ValidationManager fValidationManager;
148     
149     /** Component manager. **/
150     private XMLSchemaValidatorComponentManager fComponentManager;
151
152     /** XML Locator wrapper for SAX. **/
153     private final SAXLocatorWrapper fSAXLocatorWrapper = new SAXLocatorWrapper();
154     
155     /** Flag used to track whether the namespace context needs to be pushed. */
156     private boolean fNeedPushNSContext = true;
157     
158     /** Map for tracking unparsed entities. */
159     private HashMap JavaDoc fUnparsedEntities = null;
160     
161     /** Flag used to track whether XML names and Namespace URIs have been internalized. */
162     private boolean fStringsInternalized = false;
163     
164     /** Fields for start element, end element and characters. */
165     private final QName fElementQName = new QName();
166     private final QName fAttributeQName = new QName();
167     private final XMLAttributesImpl fAttributes = new XMLAttributesImpl();
168     private final AttributesProxy fAttrAdapter = new AttributesProxy(fAttributes);
169     private final XMLString fTempString = new XMLString();
170     
171     //
172
// User Objects
173
//
174

175     private ContentHandler JavaDoc fContentHandler = null;
176     
177     /*
178      * Constructors
179      */

180     
181     public ValidatorHandlerImpl(XSGrammarPoolContainer grammarContainer) {
182         this(new XMLSchemaValidatorComponentManager(grammarContainer));
183         fComponentManager.addRecognizedFeatures(new String JavaDoc [] {NAMESPACE_PREFIXES});
184         fComponentManager.setFeature(NAMESPACE_PREFIXES, false);
185         setErrorHandler(null);
186         setResourceResolver(null);
187     }
188     
189     public ValidatorHandlerImpl(XMLSchemaValidatorComponentManager componentManager) {
190         fComponentManager = componentManager;
191         fErrorReporter = (XMLErrorReporter) fComponentManager.getProperty(ERROR_REPORTER);
192         fNamespaceContext = (NamespaceContext) fComponentManager.getProperty(NAMESPACE_CONTEXT);
193         fSchemaValidator = (XMLSchemaValidator) fComponentManager.getProperty(SCHEMA_VALIDATOR);
194         fSymbolTable = (SymbolTable) fComponentManager.getProperty(SYMBOL_TABLE);
195         fValidationManager = (ValidationManager) fComponentManager.getProperty(VALIDATION_MANAGER);
196     }
197
198     /*
199      * ValidatorHandler methods
200      */

201     
202     public void setContentHandler(ContentHandler JavaDoc receiver) {
203         fContentHandler = receiver;
204     }
205     
206     public ContentHandler JavaDoc getContentHandler() {
207         return fContentHandler;
208     }
209
210     public void setErrorHandler(ErrorHandler JavaDoc errorHandler) {
211         fComponentManager.setErrorHandler(errorHandler);
212     }
213
214     public ErrorHandler JavaDoc getErrorHandler() {
215         return fComponentManager.getErrorHandler();
216     }
217
218     public void setResourceResolver(LSResourceResolver JavaDoc resourceResolver) {
219         fComponentManager.setResourceResolver(resourceResolver);
220     }
221
222     public LSResourceResolver JavaDoc getResourceResolver() {
223         return fComponentManager.getResourceResolver();
224     }
225
226     public TypeInfoProvider JavaDoc getTypeInfoProvider() {
227         return fTypeInfoProvider;
228     }
229     
230     public boolean getFeature(String JavaDoc name)
231         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
232         if (name == null) {
233             throw new NullPointerException JavaDoc();
234         }
235         try {
236             return fComponentManager.getFeature(name);
237         }
238         catch (XMLConfigurationException e) {
239             final String JavaDoc identifier = e.getIdentifier();
240             final String JavaDoc key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
241                     "feature-not-recognized" : "feature-not-supported";
242             throw new SAXNotRecognizedException JavaDoc(
243                     SAXMessageFormatter.formatMessage(Locale.getDefault(),
244                     key, new Object JavaDoc [] {identifier}));
245         }
246     }
247     
248     public void setFeature(String JavaDoc name, boolean value)
249         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
250         if (name == null) {
251             throw new NullPointerException JavaDoc();
252         }
253         try {
254             fComponentManager.setFeature(name, value);
255         }
256         catch (XMLConfigurationException e) {
257             final String JavaDoc identifier = e.getIdentifier();
258             final String JavaDoc key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
259                     "feature-not-recognized" : "feature-not-supported";
260             throw new SAXNotRecognizedException JavaDoc(
261                     SAXMessageFormatter.formatMessage(Locale.getDefault(),
262                     key, new Object JavaDoc [] {identifier}));
263         }
264     }
265     
266     public Object JavaDoc getProperty(String JavaDoc name)
267         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
268         if (name == null) {
269             throw new NullPointerException JavaDoc();
270         }
271         try {
272             return fComponentManager.getProperty(name);
273         }
274         catch (XMLConfigurationException e) {
275             final String JavaDoc identifier = e.getIdentifier();
276             final String JavaDoc key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
277                     "property-not-recognized" : "property-not-supported";
278             throw new SAXNotRecognizedException JavaDoc(
279                     SAXMessageFormatter.formatMessage(Locale.getDefault(),
280                     key, new Object JavaDoc [] {identifier}));
281         }
282     }
283     
284     public void setProperty(String JavaDoc name, Object JavaDoc object)
285         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
286         if (name == null) {
287             throw new NullPointerException JavaDoc();
288         }
289         try {
290             fComponentManager.setProperty(name, object);
291         }
292         catch (XMLConfigurationException e) {
293             final String JavaDoc identifier = e.getIdentifier();
294             final String JavaDoc key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
295                     "property-not-recognized" : "property-not-supported";
296             throw new SAXNotRecognizedException JavaDoc(
297                     SAXMessageFormatter.formatMessage(Locale.getDefault(),
298                     key, new Object JavaDoc [] {identifier}));
299         }
300     }
301     
302     /*
303      * EntityState methods
304      */

305     
306     public boolean isEntityDeclared(String JavaDoc name) {
307         return false;
308     }
309
310     public boolean isEntityUnparsed(String JavaDoc name) {
311         if (fUnparsedEntities != null) {
312             return fUnparsedEntities.containsKey(name);
313         }
314         return false;
315     }
316     
317     /*
318      * XMLDocumentHandler methods
319      */

320
321     public void startDocument(XMLLocator locator, String JavaDoc encoding,
322             NamespaceContext namespaceContext, Augmentations augs)
323             throws XNIException {
324         if (fContentHandler != null) {
325             try {
326                 fContentHandler.startDocument();
327             }
328             catch (SAXException JavaDoc e) {
329                 throw new XNIException(e);
330             }
331         }
332     }
333
334     public void xmlDecl(String JavaDoc version, String JavaDoc encoding, String JavaDoc standalone,
335             Augmentations augs) throws XNIException {}
336
337     public void doctypeDecl(String JavaDoc rootElement, String JavaDoc publicId,
338             String JavaDoc systemId, Augmentations augs) throws XNIException {}
339
340     public void comment(XMLString text, Augmentations augs) throws XNIException {}
341
342     public void processingInstruction(String JavaDoc target, XMLString data,
343             Augmentations augs) throws XNIException {
344         if (fContentHandler != null) {
345             try {
346                 fContentHandler.processingInstruction(target, data.toString());
347             }
348             catch (SAXException JavaDoc e) {
349                 throw new XNIException(e);
350             }
351         }
352     }
353
354     public void startElement(QName element, XMLAttributes attributes,
355             Augmentations augs) throws XNIException {
356         if (fContentHandler != null) {
357             try {
358                 fTypeInfoProvider.beginStartElement(augs, attributes);
359                 fContentHandler.startElement((element.uri != null) ? element.uri : XMLSymbols.EMPTY_STRING,
360                         element.localpart, element.rawname, fAttrAdapter);
361             }
362             catch (SAXException JavaDoc e) {
363                 throw new XNIException(e);
364             }
365             finally {
366                 fTypeInfoProvider.finishStartElement();
367             }
368         }
369     }
370
371     public void emptyElement(QName element, XMLAttributes attributes,
372             Augmentations augs) throws XNIException {
373         /** Split empty element event. **/
374         startElement(element, attributes, augs);
375         endElement(element, augs);
376     }
377
378     public void startGeneralEntity(String JavaDoc name,
379             XMLResourceIdentifier identifier, String JavaDoc encoding,
380             Augmentations augs) throws XNIException {}
381
382     public void textDecl(String JavaDoc version, String JavaDoc encoding, Augmentations augs)
383             throws XNIException {}
384
385     public void endGeneralEntity(String JavaDoc name, Augmentations augs)
386             throws XNIException {}
387
388     public void characters(XMLString text, Augmentations augs)
389             throws XNIException {
390         if (fContentHandler != null) {
391             // if the type is union it is possible that we receive
392
// a character call with empty data
393
if (text.length == 0) {
394                 return;
395             }
396             try {
397                 fContentHandler.characters(text.ch, text.offset, text.length);
398             }
399             catch (SAXException JavaDoc e) {
400                 throw new XNIException(e);
401             }
402         }
403     }
404
405     public void ignorableWhitespace(XMLString text, Augmentations augs)
406             throws XNIException {
407         if (fContentHandler != null) {
408             try {
409                 fContentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
410             }
411             catch (SAXException JavaDoc e) {
412                 throw new XNIException(e);
413             }
414         }
415     }
416
417     public void endElement(QName element, Augmentations augs)
418             throws XNIException {
419         if (fContentHandler != null) {
420             try {
421                 fTypeInfoProvider.beginEndElement(augs);
422                 fContentHandler.endElement((element.uri != null) ? element.uri : XMLSymbols.EMPTY_STRING,
423                         element.localpart, element.rawname);
424             }
425             catch (SAXException JavaDoc e) {
426                 throw new XNIException(e);
427             }
428             finally {
429                 fTypeInfoProvider.finishEndElement();
430             }
431         }
432     }
433
434     public void startCDATA(Augmentations augs) throws XNIException {}
435
436     public void endCDATA(Augmentations augs) throws XNIException {}
437
438     public void endDocument(Augmentations augs) throws XNIException {
439         if (fContentHandler != null) {
440             try {
441                 fContentHandler.endDocument();
442             }
443             catch (SAXException JavaDoc e) {
444                 throw new XNIException(e);
445             }
446         }
447     }
448
449     // NO-OP
450
public void setDocumentSource(XMLDocumentSource source) {}
451
452     public XMLDocumentSource getDocumentSource() {
453         return fSchemaValidator;
454     }
455     
456     /*
457      * ContentHandler methods
458      */

459
460     public void setDocumentLocator(Locator locator) {
461         fSAXLocatorWrapper.setLocator(locator);
462         if (fContentHandler != null) {
463             fContentHandler.setDocumentLocator(locator);
464         }
465     }
466
467     public void startDocument() throws SAXException JavaDoc {
468         fComponentManager.reset();
469         fSchemaValidator.setDocumentHandler(this);
470         fValidationManager.setEntityState(this);
471         fTypeInfoProvider.finishStartElement(); // cleans up TypeInfoProvider
472
fNeedPushNSContext = true;
473         if (fUnparsedEntities != null && !fUnparsedEntities.isEmpty()) {
474             // should only clear this if the last document contained unparsed entities
475
fUnparsedEntities.clear();
476         }
477         fErrorReporter.setDocumentLocator(fSAXLocatorWrapper);
478         try {
479             fSchemaValidator.startDocument(fSAXLocatorWrapper, fSAXLocatorWrapper.getEncoding(), fNamespaceContext, null);
480         }
481         catch (XMLParseException e) {
482             throw Util.toSAXParseException(e);
483         }
484         catch (XNIException e) {
485             throw Util.toSAXException(e);
486         }
487     }
488
489     public void endDocument() throws SAXException JavaDoc {
490         fSAXLocatorWrapper.setLocator(null);
491         try {
492             fSchemaValidator.endDocument(null);
493         }
494         catch (XMLParseException e) {
495             throw Util.toSAXParseException(e);
496         }
497         catch (XNIException e) {
498             throw Util.toSAXException(e);
499         }
500     }
501
502     public void startPrefixMapping(String JavaDoc prefix, String JavaDoc uri)
503             throws SAXException JavaDoc {
504         String JavaDoc prefixSymbol;
505         String JavaDoc uriSymbol;
506         if (!fStringsInternalized) {
507             prefixSymbol = (prefix != null) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING;
508             uriSymbol = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
509         }
510         else {
511             prefixSymbol = (prefix != null) ? prefix : XMLSymbols.EMPTY_STRING;
512             uriSymbol = (uri != null && uri.length() > 0) ? uri : null;
513         }
514         if (fNeedPushNSContext) {
515             fNeedPushNSContext = false;
516             fNamespaceContext.pushContext();
517         }
518         fNamespaceContext.declarePrefix(prefixSymbol, uriSymbol);
519         if (fContentHandler != null) {
520             fContentHandler.startPrefixMapping(prefix, uri);
521         }
522     }
523
524     public void endPrefixMapping(String JavaDoc prefix) throws SAXException JavaDoc {
525         if (fContentHandler != null) {
526             fContentHandler.endPrefixMapping(prefix);
527         }
528     }
529
530     public void startElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName,
531             Attributes atts) throws SAXException JavaDoc {
532         if (fNeedPushNSContext) {
533             fNamespaceContext.pushContext();
534         }
535         fNeedPushNSContext = true;
536         
537         // Fill element QName
538
fillQName(fElementQName, uri, localName, qName);
539         
540         // Fill XMLAttributes
541
if (atts instanceof Attributes2 JavaDoc) {
542             fillXMLAttributes2((Attributes2 JavaDoc) atts);
543         }
544         else {
545             fillXMLAttributes(atts);
546         }
547         
548         try {
549             fSchemaValidator.startElement(fElementQName, fAttributes, null);
550         }
551         catch (XMLParseException e) {
552             throw Util.toSAXParseException(e);
553         }
554         catch (XNIException e) {
555             throw Util.toSAXException(e);
556         }
557     }
558
559     public void endElement(String JavaDoc uri, String JavaDoc localName, String JavaDoc qName)
560             throws SAXException JavaDoc {
561         fillQName(fElementQName, uri, localName, qName);
562         try {
563             fSchemaValidator.endElement(fElementQName, null);
564         }
565         catch (XMLParseException e) {
566             throw Util.toSAXParseException(e);
567         }
568         catch (XNIException e) {
569             throw Util.toSAXException(e);
570         }
571         finally {
572             fNamespaceContext.popContext();
573         }
574     }
575
576     public void characters(char[] ch, int start, int length)
577             throws SAXException JavaDoc {
578         try {
579             fTempString.setValues(ch, start, length);
580             fSchemaValidator.characters(fTempString, null);
581         }
582         catch (XMLParseException e) {
583             throw Util.toSAXParseException(e);
584         }
585         catch (XNIException e) {
586             throw Util.toSAXException(e);
587         }
588     }
589
590     public void ignorableWhitespace(char[] ch, int start, int length)
591             throws SAXException JavaDoc {
592         try {
593             fTempString.setValues(ch, start, length);
594             fSchemaValidator.ignorableWhitespace(fTempString, null);
595         }
596         catch (XMLParseException e) {
597             throw Util.toSAXParseException(e);
598         }
599         catch (XNIException e) {
600             throw Util.toSAXException(e);
601         }
602     }
603
604     public void processingInstruction(String JavaDoc target, String JavaDoc data)
605             throws SAXException JavaDoc {
606         /**
607          * Processing instructions do not participate in schema validation,
608          * so just forward the event to the application's content
609          * handler.
610          */

611         if (fContentHandler != null) {
612             fContentHandler.processingInstruction(target, data);
613         }
614     }
615
616     public void skippedEntity(String JavaDoc name) throws SAXException JavaDoc {
617         // there seems to be no corresponding method on XMLDocumentFilter.
618
// just pass it down to the output, if any.
619
if (fContentHandler != null) {
620             fContentHandler.skippedEntity(name);
621         }
622     }
623     
624     /*
625      * DTDHandler methods
626      */

627     
628     public void notationDecl(String JavaDoc name, String JavaDoc publicId,
629             String JavaDoc systemId) throws SAXException JavaDoc {}
630
631     public void unparsedEntityDecl(String JavaDoc name, String JavaDoc publicId,
632             String JavaDoc systemId, String JavaDoc notationName) throws SAXException JavaDoc {
633         if (fUnparsedEntities == null) {
634             fUnparsedEntities = new HashMap JavaDoc();
635         }
636         fUnparsedEntities.put(name, name);
637     }
638     
639     /*
640      * ValidatorHelper methods
641      */

642     
643     public void validate(Source JavaDoc source, Result JavaDoc result)
644         throws SAXException JavaDoc, IOException JavaDoc {
645         if (result instanceof SAXResult JavaDoc || result == null) {
646             final SAXSource JavaDoc saxSource = (SAXSource JavaDoc) source;
647             final SAXResult JavaDoc saxResult = (SAXResult JavaDoc) result;
648             
649             if (result != null) {
650                 setContentHandler(saxResult.getHandler());
651             }
652             
653             try {
654                 XMLReader JavaDoc reader = saxSource.getXMLReader();
655                 if( reader==null ) {
656                     // create one now
657
SAXParserFactory JavaDoc spf = SAXParserFactory.newInstance();
658                     spf.setNamespaceAware(true);
659                     try {
660                         reader = spf.newSAXParser().getXMLReader();
661                         // If this is a Xerces SAX parser, set the security manager if there is one
662
if (reader instanceof org.apache.xerces.parsers.SAXParser) {
663                            SecurityManager JavaDoc securityManager = (SecurityManager JavaDoc) fComponentManager.getProperty(SECURITY_MANAGER);
664                            if (securityManager != null) {
665                                try {
666                                    reader.setProperty(SECURITY_MANAGER, securityManager);
667                                }
668                                // Ignore the exception if the security manager cannot be set.
669
catch (SAXException JavaDoc exc) {}
670                            }
671                         }
672                     } catch( Exception JavaDoc e ) {
673                         // this is impossible, but better safe than sorry
674
throw new FactoryConfigurationError JavaDoc(e);
675                     }
676                 }
677                 
678                 // If XML names and Namespace URIs are already internalized we
679
// can avoid running them through the SymbolTable.
680
try {
681                     fStringsInternalized = reader.getFeature(STRING_INTERNING);
682                 }
683                 catch (SAXException JavaDoc exc) {
684                     // The feature isn't recognized or getting it is not supported.
685
// In either case, assume that strings are not internalized.
686
fStringsInternalized = false;
687                 }
688                 
689                 ErrorHandler JavaDoc errorHandler = fComponentManager.getErrorHandler();
690                 reader.setErrorHandler(errorHandler != null ? errorHandler : DraconianErrorHandler.getInstance());
691                 reader.setEntityResolver(fResolutionForwarder);
692                 fResolutionForwarder.setEntityResolver(fComponentManager.getResourceResolver());
693                 reader.setContentHandler(this);
694                 reader.setDTDHandler(this);
695                 
696                 InputSource JavaDoc is = saxSource.getInputSource();
697                 reader.parse(is);
698             }
699             finally {
700                 // release the reference to user's handler ASAP
701
setContentHandler(null);
702             }
703             return;
704         }
705         throw new IllegalArgumentException JavaDoc(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(),
706                 "SourceResultMismatch",
707                 new Object JavaDoc [] {source.getClass().getName(), result.getClass().getName()}));
708     }
709     
710     /*
711      * PSVIProvider methods
712      */

713     
714     public ElementPSVI getElementPSVI() {
715         return fTypeInfoProvider.getElementPSVI();
716     }
717     
718     public AttributePSVI getAttributePSVI(int index) {
719         return fTypeInfoProvider.getAttributePSVI(index);
720     }
721     
722     public AttributePSVI getAttributePSVIByName(String JavaDoc uri, String JavaDoc localname) {
723         return fTypeInfoProvider.getAttributePSVIByName(uri, localname);
724     }
725  
726     //
727
//
728
// helper methods
729
//
730
//
731

732     /** Fills in a QName object. */
733     private void fillQName(QName toFill, String JavaDoc uri, String JavaDoc localpart, String JavaDoc raw) {
734         if (!fStringsInternalized) {
735             uri = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
736             localpart = (localpart != null) ? fSymbolTable.addSymbol(localpart) : XMLSymbols.EMPTY_STRING;
737             raw = (raw != null) ? fSymbolTable.addSymbol(raw) : XMLSymbols.EMPTY_STRING;
738         }
739         else {
740             if (uri != null && uri.length() == 0) {
741                 uri = null;
742             }
743             if (localpart == null) {
744                 localpart = XMLSymbols.EMPTY_STRING;
745             }
746             if (raw == null) {
747                 raw = XMLSymbols.EMPTY_STRING;
748             }
749         }
750         String JavaDoc prefix = XMLSymbols.EMPTY_STRING;
751         int prefixIdx = raw.indexOf(':');
752         if (prefixIdx != -1) {
753             prefix = fSymbolTable.addSymbol(raw.substring(0, prefixIdx));
754         }
755         toFill.setValues(prefix, localpart, raw, uri);
756     }
757     
758     /** Fills in the XMLAttributes object. */
759     private void fillXMLAttributes(Attributes att) {
760         fAttributes.removeAllAttributes();
761         final int len = att.getLength();
762         for (int i = 0; i < len; ++i) {
763             fillXMLAttribute(att, i);
764             fAttributes.setSpecified(i, true);
765         }
766     }
767     
768     /** Fills in the XMLAttributes object. */
769     private void fillXMLAttributes2(Attributes2 JavaDoc att) {
770         fAttributes.removeAllAttributes();
771         final int len = att.getLength();
772         for (int i = 0; i < len; ++i) {
773             fillXMLAttribute(att, i);
774             fAttributes.setSpecified(i, att.isSpecified(i));
775             if (att.isDeclared(i)) {
776                 fAttributes.getAugmentations(i).putItem(Constants.ATTRIBUTE_DECLARED, Boolean.TRUE);
777             }
778         }
779     }
780     
781     /** Adds an attribute to the XMLAttributes object. */
782     private void fillXMLAttribute(Attributes att, int index) {
783         fillQName(fAttributeQName, att.getURI(index), att.getLocalName(index), att.getQName(index));
784         String JavaDoc type = att.getType(index);
785         fAttributes.addAttributeNS(fAttributeQName, (type != null) ? type : XMLSymbols.fCDATASymbol, att.getValue(index));
786     }
787     
788     /**
789      * {@link TypeInfoProvider} implementation.
790      *
791      * REVISIT: I'm not sure if this code should belong here.
792      */

793     private final XMLSchemaTypeInfoProvider fTypeInfoProvider = new XMLSchemaTypeInfoProvider();
794     private static class XMLSchemaTypeInfoProvider extends TypeInfoProvider JavaDoc {
795         
796         /** Element augmentations: contains ElementPSVI. **/
797         private Augmentations fElementAugs;
798         
799         /** Attributes: augmentations for each attribute contain AttributePSVI. **/
800         private XMLAttributes fAttributes;
801         
802         /** In start element. **/
803         private boolean fInStartElement = false;
804         
805         /** Initializes the TypeInfoProvider with type information for the current element. **/
806         void beginStartElement(Augmentations elementAugs, XMLAttributes attributes) {
807             fInStartElement = true;
808             fElementAugs = elementAugs;
809             fAttributes = attributes;
810         }
811         
812         /** Cleanup at the end of start element. **/
813         void finishStartElement() {
814             fInStartElement = false;
815             fElementAugs = null;
816             fAttributes = null;
817         }
818         
819         /** Initializes the TypeInfoProvider with type information for the current element. **/
820         void beginEndElement(Augmentations elementAugs) {
821             fElementAugs = elementAugs;
822         }
823         
824         /** Cleanup at the end of end element. **/
825         void finishEndElement() {
826             fElementAugs = null;
827         }
828         
829         /**
830          * Throws a {@link IllegalStateException} if we are not in
831          * the startElement callback. the JAXP API requires this
832          * for most of the public methods.
833          */

834         private void checkState() {
835             if( !fInStartElement ) {
836                 throw new IllegalStateException JavaDoc(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(),
837                         "TypeInfoProviderIllegalState", null));
838             }
839         }
840         
841         public TypeInfo JavaDoc getAttributeTypeInfo(int index) {
842             checkState();
843             return getAttributeType(index);
844         }
845         
846         private TypeInfo JavaDoc getAttributeType( int index ) {
847             checkState();
848             if( index<0 || fAttributes.getLength()<=index )
849                 throw new IndexOutOfBoundsException JavaDoc(Integer.toString(index));
850             Augmentations augs = fAttributes.getAugmentations(index);
851             if (augs == null) return null;
852             AttributePSVI psvi = (AttributePSVI)augs.getItem(Constants.ATTRIBUTE_PSVI);
853             return getTypeInfoFromPSVI(psvi);
854         }
855         
856         public TypeInfo JavaDoc getAttributeTypeInfo(String JavaDoc attributeUri, String JavaDoc attributeLocalName) {
857             checkState();
858             return getAttributeTypeInfo(fAttributes.getIndex(attributeUri,attributeLocalName));
859         }
860         
861         public TypeInfo JavaDoc getAttributeTypeInfo(String JavaDoc attributeQName) {
862             checkState();
863             return getAttributeTypeInfo(fAttributes.getIndex(attributeQName));
864         }
865         
866         public TypeInfo JavaDoc getElementTypeInfo() {
867             checkState();
868             if (fElementAugs == null) return null;
869             ElementPSVI psvi = (ElementPSVI)fElementAugs.getItem(Constants.ELEMENT_PSVI);
870             return getTypeInfoFromPSVI(psvi);
871         }
872         
873         private TypeInfo JavaDoc getTypeInfoFromPSVI( ItemPSVI psvi ) {
874             if(psvi==null) return null;
875             
876             // TODO: make sure if this is correct.
877
// TODO: since the number of types in a schema is quite limited,
878
// TypeInfoImpl should be pooled. Even better, it should be a part
879
// of the element decl.
880
if( psvi.getValidity()== ElementPSVI.VALIDITY_VALID ) {
881                 XSTypeDefinition t = psvi.getMemberTypeDefinition();
882                 if (t != null) {
883                     return (t instanceof TypeInfo JavaDoc) ? (TypeInfo JavaDoc) t : null;
884                 }
885             }
886             
887             XSTypeDefinition t = psvi.getTypeDefinition();
888             // TODO: can t be null?
889
if (t != null) {
890                 return (t instanceof TypeInfo JavaDoc) ? (TypeInfo JavaDoc) t : null;
891             }
892             return null;
893         }
894         
895         public boolean isIdAttribute(int index) {
896             checkState();
897             XSSimpleType type = (XSSimpleType)getAttributeType(index);
898             if(type==null) return false;
899             return type.isIDType();
900         }
901         
902         public boolean isSpecified(int index) {
903             checkState();
904             return fAttributes.isSpecified(index);
905         }
906         
907         /*
908          * Other methods
909          */

910         
911         // PSVIProvider support
912
ElementPSVI getElementPSVI() {
913             return (fElementAugs != null) ? (ElementPSVI) fElementAugs.getItem(Constants.ELEMENT_PSVI) : null;
914         }
915         
916         AttributePSVI getAttributePSVI(int index) {
917             if (fAttributes != null) {
918                 Augmentations augs = fAttributes.getAugmentations(index);
919                 if (augs != null) {
920                     return (AttributePSVI) augs.getItem(Constants.ATTRIBUTE_PSVI);
921                 }
922             }
923             return null;
924         }
925         
926         AttributePSVI getAttributePSVIByName(String JavaDoc uri, String JavaDoc localname) {
927             if (fAttributes != null) {
928                 Augmentations augs = fAttributes.getAugmentations(uri, localname);
929                 if (augs != null) {
930                     return (AttributePSVI) augs.getItem(Constants.ATTRIBUTE_PSVI);
931                 }
932             }
933             return null;
934         }
935     }
936     
937     /** SAX adapter for an LSResourceResolver. */
938     private final ResolutionForwarder fResolutionForwarder = new ResolutionForwarder(null);
939     static final class ResolutionForwarder
940         implements EntityResolver2 JavaDoc {
941         
942         //
943
// Data
944
//
945

946         /** XML 1.0 type constant according to DOM L3 LS REC spec "http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/" */
947         private static final String JavaDoc XML_TYPE = "http://www.w3.org/TR/REC-xml";
948
949         /** The DOM entity resolver. */
950         protected LSResourceResolver JavaDoc fEntityResolver;
951
952         //
953
// Constructors
954
//
955

956         /** Default constructor. */
957         public ResolutionForwarder() {}
958
959         /** Wraps the specified DOM entity resolver. */
960         public ResolutionForwarder(LSResourceResolver JavaDoc entityResolver) {
961             setEntityResolver(entityResolver);
962         }
963         
964         //
965
// Public methods
966
//
967

968         /** Sets the DOM entity resolver. */
969         public void setEntityResolver(LSResourceResolver JavaDoc entityResolver) {
970             fEntityResolver = entityResolver;
971         } // setEntityResolver(LSResourceResolver)
972

973         /** Returns the DOM entity resolver. */
974         public LSResourceResolver JavaDoc getEntityResolver() {
975             return fEntityResolver;
976         } // getEntityResolver():LSResourceResolver
977

978         /**
979          * Always returns <code>null</code>. An LSResourceResolver has no corresponding method.
980          */

981         public InputSource JavaDoc getExternalSubset(String JavaDoc name, String JavaDoc baseURI)
982                 throws SAXException JavaDoc, IOException JavaDoc {
983             return null;
984         }
985
986         /**
987          * Resolves the given resource and adapts the <code>LSInput</code>
988          * returned into an <code>InputSource</code>.
989          */

990         public InputSource JavaDoc resolveEntity(String JavaDoc name, String JavaDoc publicId,
991                 String JavaDoc baseURI, String JavaDoc systemId) throws SAXException JavaDoc, IOException JavaDoc {
992             if (fEntityResolver != null) {
993                 LSInput JavaDoc lsInput = fEntityResolver.resolveResource(XML_TYPE, null, publicId, systemId, baseURI);
994                 if (lsInput != null) {
995                     final String JavaDoc pubId = lsInput.getPublicId();
996                     final String JavaDoc sysId = lsInput.getSystemId();
997                     final String JavaDoc baseSystemId = lsInput.getBaseURI();
998                     final Reader JavaDoc charStream = lsInput.getCharacterStream();
999                     final InputStream JavaDoc byteStream = lsInput.getByteStream();
1000                    final String JavaDoc data = lsInput.getStringData();
1001                    final String JavaDoc encoding = lsInput.getEncoding();
1002
1003                    /**
1004                     * An LSParser looks at inputs specified in LSInput in
1005                     * the following order: characterStream, byteStream,
1006                     * stringData, systemId, publicId. For consistency
1007                     * with the DOM Level 3 Load and Save Recommendation
1008                     * use the same lookup order here.
1009                     */

1010                    InputSource JavaDoc inputSource = new InputSource JavaDoc();
1011                    inputSource.setPublicId(pubId);
1012                    inputSource.setSystemId((baseSystemId != null) ? resolveSystemId(systemId, baseSystemId) : systemId);
1013                    
1014                    if (charStream != null) {
1015                        inputSource.setCharacterStream(charStream);
1016                    }
1017                    else if (byteStream != null) {
1018                        inputSource.setByteStream(byteStream);
1019                    }
1020                    else if (data != null && data.length() != 0) {
1021                        inputSource.setCharacterStream(new StringReader JavaDoc(data));
1022                    }
1023                    inputSource.setEncoding(encoding);
1024                    return inputSource;
1025                }
1026            }
1027            return null;
1028        }
1029        
1030        /** Delegates to EntityResolver2.resolveEntity(String, String, String, String). */
1031        public InputSource JavaDoc resolveEntity(String JavaDoc publicId, String JavaDoc systemId)
1032                throws SAXException JavaDoc, IOException JavaDoc {
1033            return resolveEntity(null, publicId, null, systemId);
1034        }
1035        
1036        /** Resolves a system identifier against a base URI. */
1037        private String JavaDoc resolveSystemId(String JavaDoc systemId, String JavaDoc baseURI) {
1038            try {
1039                return XMLEntityManager.expandSystemId(systemId, baseURI, false);
1040            }
1041            // In the event that resolution failed against the
1042
// base URI, just return the system id as is. There's not
1043
// much else we can do.
1044
catch (URI.MalformedURIException ex) {
1045                return systemId;
1046            }
1047        }
1048    }
1049}
1050
Popular Tags