Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » jaxp » validation » [javadoc | source]
    1   /*
    2    * reserved comment block
    3    * DO NOT REMOVE OR ALTER!
    4    */
    5   /*
    6    * Copyright 2005 The Apache Software Foundation.
    7    *
    8    * Licensed under the Apache License, Version 2.0 (the "License");
    9    * you may not use this file except in compliance with the License.
   10    * You may obtain a copy of the License at
   11    *
   12    *      http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing, software
   15    * distributed under the License is distributed on an "AS IS" BASIS,
   16    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   17    * See the License for the specific language governing permissions and
   18    * limitations under the License.
   19    */
   20   
   21   package com.sun.org.apache.xerces.internal.jaxp.validation;
   22   
   23   import java.io.IOException;
   24   import java.io.InputStream;
   25   import java.io.Reader;
   26   import java.io.StringReader;
   27   import java.util.HashMap;
   28   import java.util.Locale;
   29   
   30   import javax.xml.parsers.FactoryConfigurationError;
   31   import javax.xml.parsers.SAXParserFactory;
   32   import javax.xml.transform.Result;
   33   import javax.xml.transform.Source;
   34   import javax.xml.transform.sax.SAXResult;
   35   import javax.xml.transform.sax.SAXSource;
   36   import javax.xml.validation.TypeInfoProvider;
   37   import javax.xml.validation.ValidatorHandler;
   38   
   39   import com.sun.org.apache.xerces.internal.impl.Constants;
   40   import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
   41   import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
   42   import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType;
   43   import com.sun.org.apache.xerces.internal.impl.validation.EntityState;
   44   import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
   45   import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator;
   46   import com.sun.org.apache.xerces.internal.util.AttributesProxy;
   47   import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper;
   48   import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
   49   import com.sun.org.apache.xerces.internal.util.SymbolTable;
   50   import com.sun.org.apache.xerces.internal.util.URI;
   51   import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl;
   52   import com.sun.org.apache.xerces.internal.util.XMLSymbols;
   53   import com.sun.org.apache.xerces.internal.xni.Augmentations;
   54   import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
   55   import com.sun.org.apache.xerces.internal.xni.QName;
   56   import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
   57   import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
   58   import com.sun.org.apache.xerces.internal.xni.XMLLocator;
   59   import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
   60   import com.sun.org.apache.xerces.internal.xni.XMLString;
   61   import com.sun.org.apache.xerces.internal.xni.XNIException;
   62   import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
   63   import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
   64   import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
   65   import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
   66   import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
   67   import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
   68   import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
   69   import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition;
   70   import org.w3c.dom.TypeInfo;
   71   import org.w3c.dom.ls.LSInput;
   72   import org.w3c.dom.ls.LSResourceResolver;
   73   import org.xml.sax.Attributes;
   74   import org.xml.sax.ContentHandler;
   75   import org.xml.sax.DTDHandler;
   76   import org.xml.sax.ErrorHandler;
   77   import org.xml.sax.InputSource;
   78   import org.xml.sax.Locator;
   79   import org.xml.sax.SAXException;
   80   import org.xml.sax.SAXNotRecognizedException;
   81   import org.xml.sax.SAXNotSupportedException;
   82   import org.xml.sax.XMLReader;
   83   import org.xml.sax.ext.Attributes2;
   84   import org.xml.sax.ext.EntityResolver2;
   85   
   86   /**
   87    * <p>Implementation of ValidatorHandler for W3C XML Schemas and
   88    * also a validator helper for <code>SAXSource</code>s.</p>
   89    *
   90    * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
   91    * @author Michael Glavassevich, IBM
   92    *
   93    */
   94   final class ValidatorHandlerImpl extends ValidatorHandler implements
   95       DTDHandler, EntityState, PSVIProvider, ValidatorHelper, XMLDocumentHandler {
   96   
   97       // feature identifiers
   98   
   99       /** Feature identifier: namespace prefixes. */
  100       private static final String NAMESPACE_PREFIXES =
  101           Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE;
  102   
  103       /** Feature identifier: string interning. */
  104       protected static final String STRING_INTERNING =
  105           Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE;
  106   
  107       // property identifiers
  108   
  109       /** Property identifier: error reporter. */
  110       private static final String ERROR_REPORTER =
  111           Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  112   
  113       /** Property identifier: namespace context. */
  114       private static final String NAMESPACE_CONTEXT =
  115           Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY;
  116   
  117       /** Property identifier: XML Schema validator. */
  118       private static final String SCHEMA_VALIDATOR =
  119           Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY;
  120   
  121       /** Property identifier: security manager. */
  122       private static final String SECURITY_MANAGER =
  123           Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  124   
  125       /** Property identifier: symbol table. */
  126       private static final String SYMBOL_TABLE =
  127           Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  128   
  129       /** Property identifier: validation manager. */
  130       private static final String VALIDATION_MANAGER =
  131           Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
  132   
  133       //
  134       // Data
  135       //
  136   
  137       /** Error reporter. */
  138       private XMLErrorReporter fErrorReporter;
  139   
  140       /** The namespace context of this document: stores namespaces in scope */
  141       private NamespaceContext fNamespaceContext;
  142   
  143       /** Schema validator. **/
  144       private XMLSchemaValidator fSchemaValidator;
  145   
  146       /** Symbol table **/
  147       private SymbolTable fSymbolTable;
  148   
  149       /** Validation manager. */
  150       private ValidationManager fValidationManager;
  151   
  152       /** Component manager. **/
  153       private XMLSchemaValidatorComponentManager fComponentManager;
  154   
  155       /** XML Locator wrapper for SAX. **/
  156       private final SAXLocatorWrapper fSAXLocatorWrapper = new SAXLocatorWrapper();
  157   
  158       /** Flag used to track whether the namespace context needs to be pushed. */
  159       private boolean fNeedPushNSContext = true;
  160   
  161       /** Map for tracking unparsed entities. */
  162       private HashMap fUnparsedEntities = null;
  163   
  164       /** Flag used to track whether XML names and Namespace URIs have been internalized. */
  165       private boolean fStringsInternalized = false;
  166   
  167       /** Fields for start element, end element and characters. */
  168       private final QName fElementQName = new QName();
  169       private final QName fAttributeQName = new QName();
  170       private final XMLAttributesImpl fAttributes = new XMLAttributesImpl();
  171       private final AttributesProxy fAttrAdapter = new AttributesProxy(fAttributes);
  172       private final XMLString fTempString = new XMLString();
  173   
  174       //
  175       // User Objects
  176       //
  177   
  178       private ContentHandler fContentHandler = null;
  179   
  180       /*
  181        * Constructors
  182        */
  183   
  184       public ValidatorHandlerImpl(XSGrammarPoolContainer grammarContainer) {
  185           this(new XMLSchemaValidatorComponentManager(grammarContainer));
  186           fComponentManager.addRecognizedFeatures(new String [] {NAMESPACE_PREFIXES});
  187           fComponentManager.setFeature(NAMESPACE_PREFIXES, false);
  188           setErrorHandler(null);
  189           setResourceResolver(null);
  190       }
  191   
  192       public ValidatorHandlerImpl(XMLSchemaValidatorComponentManager componentManager) {
  193           fComponentManager = componentManager;
  194           fErrorReporter = (XMLErrorReporter) fComponentManager.getProperty(ERROR_REPORTER);
  195           fNamespaceContext = (NamespaceContext) fComponentManager.getProperty(NAMESPACE_CONTEXT);
  196           fSchemaValidator = (XMLSchemaValidator) fComponentManager.getProperty(SCHEMA_VALIDATOR);
  197           fSymbolTable = (SymbolTable) fComponentManager.getProperty(SYMBOL_TABLE);
  198           fValidationManager = (ValidationManager) fComponentManager.getProperty(VALIDATION_MANAGER);
  199       }
  200   
  201       /*
  202        * ValidatorHandler methods
  203        */
  204   
  205       public void setContentHandler(ContentHandler receiver) {
  206           fContentHandler = receiver;
  207       }
  208   
  209       public ContentHandler getContentHandler() {
  210           return fContentHandler;
  211       }
  212   
  213       public void setErrorHandler(ErrorHandler errorHandler) {
  214           fComponentManager.setErrorHandler(errorHandler);
  215       }
  216   
  217       public ErrorHandler getErrorHandler() {
  218           return fComponentManager.getErrorHandler();
  219       }
  220   
  221       public void setResourceResolver(LSResourceResolver resourceResolver) {
  222           fComponentManager.setResourceResolver(resourceResolver);
  223       }
  224   
  225       public LSResourceResolver getResourceResolver() {
  226           return fComponentManager.getResourceResolver();
  227       }
  228   
  229       public TypeInfoProvider getTypeInfoProvider() {
  230           return fTypeInfoProvider;
  231       }
  232   
  233       public boolean getFeature(String name)
  234           throws SAXNotRecognizedException, SAXNotSupportedException {
  235           if (name == null) {
  236               throw new NullPointerException();
  237           }
  238           try {
  239               return fComponentManager.getFeature(name);
  240           }
  241           catch (XMLConfigurationException e) {
  242               final String identifier = e.getIdentifier();
  243               final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
  244                       "feature-not-recognized" : "feature-not-supported";
  245               throw new SAXNotRecognizedException(
  246                       SAXMessageFormatter.formatMessage(Locale.getDefault(),
  247                       key, new Object [] {identifier}));
  248           }
  249       }
  250   
  251       public void setFeature(String name, boolean value)
  252           throws SAXNotRecognizedException, SAXNotSupportedException {
  253           if (name == null) {
  254               throw new NullPointerException();
  255           }
  256           try {
  257               fComponentManager.setFeature(name, value);
  258           }
  259           catch (XMLConfigurationException e) {
  260               final String identifier = e.getIdentifier();
  261               final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
  262                       "feature-not-recognized" : "feature-not-supported";
  263               throw new SAXNotRecognizedException(
  264                       SAXMessageFormatter.formatMessage(Locale.getDefault(),
  265                       key, new Object [] {identifier}));
  266           }
  267       }
  268   
  269       public Object getProperty(String name)
  270           throws SAXNotRecognizedException, SAXNotSupportedException {
  271           if (name == null) {
  272               throw new NullPointerException();
  273           }
  274           try {
  275               return fComponentManager.getProperty(name);
  276           }
  277           catch (XMLConfigurationException e) {
  278               final String identifier = e.getIdentifier();
  279               final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
  280                       "property-not-recognized" : "property-not-supported";
  281               throw new SAXNotRecognizedException(
  282                       SAXMessageFormatter.formatMessage(Locale.getDefault(),
  283                       key, new Object [] {identifier}));
  284           }
  285       }
  286   
  287       public void setProperty(String name, Object object)
  288           throws SAXNotRecognizedException, SAXNotSupportedException {
  289           if (name == null) {
  290               throw new NullPointerException();
  291           }
  292           try {
  293               fComponentManager.setProperty(name, object);
  294           }
  295           catch (XMLConfigurationException e) {
  296               final String identifier = e.getIdentifier();
  297               final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ?
  298                       "property-not-recognized" : "property-not-supported";
  299               throw new SAXNotRecognizedException(
  300                       SAXMessageFormatter.formatMessage(Locale.getDefault(),
  301                       key, new Object [] {identifier}));
  302           }
  303       }
  304   
  305       /*
  306        * EntityState methods
  307        */
  308   
  309       public boolean isEntityDeclared(String name) {
  310           return false;
  311       }
  312   
  313       public boolean isEntityUnparsed(String name) {
  314           if (fUnparsedEntities != null) {
  315               return fUnparsedEntities.containsKey(name);
  316           }
  317           return false;
  318       }
  319   
  320       /*
  321        * XMLDocumentHandler methods
  322        */
  323   
  324       public void startDocument(XMLLocator locator, String encoding,
  325               NamespaceContext namespaceContext, Augmentations augs)
  326               throws XNIException {
  327           if (fContentHandler != null) {
  328               try {
  329                   fContentHandler.startDocument();
  330               }
  331               catch (SAXException e) {
  332                   throw new XNIException(e);
  333               }
  334           }
  335       }
  336   
  337       public void xmlDecl(String version, String encoding, String standalone,
  338               Augmentations augs) throws XNIException {}
  339   
  340       public void doctypeDecl(String rootElement, String publicId,
  341               String systemId, Augmentations augs) throws XNIException {}
  342   
  343       public void comment(XMLString text, Augmentations augs) throws XNIException {}
  344   
  345       public void processingInstruction(String target, XMLString data,
  346               Augmentations augs) throws XNIException {
  347           if (fContentHandler != null) {
  348               try {
  349                   fContentHandler.processingInstruction(target, data.toString());
  350               }
  351               catch (SAXException e) {
  352                   throw new XNIException(e);
  353               }
  354           }
  355       }
  356   
  357       public void startElement(QName element, XMLAttributes attributes,
  358               Augmentations augs) throws XNIException {
  359           if (fContentHandler != null) {
  360               try {
  361                   fTypeInfoProvider.beginStartElement(augs, attributes);
  362                   fContentHandler.startElement((element.uri != null) ? element.uri : XMLSymbols.EMPTY_STRING,
  363                           element.localpart, element.rawname, fAttrAdapter);
  364               }
  365               catch (SAXException e) {
  366                   throw new XNIException(e);
  367               }
  368               finally {
  369                   fTypeInfoProvider.finishStartElement();
  370               }
  371           }
  372       }
  373   
  374       public void emptyElement(QName element, XMLAttributes attributes,
  375               Augmentations augs) throws XNIException {
  376           /** Split empty element event. **/
  377           startElement(element, attributes, augs);
  378           endElement(element, augs);
  379       }
  380   
  381       public void startGeneralEntity(String name,
  382               XMLResourceIdentifier identifier, String encoding,
  383               Augmentations augs) throws XNIException {}
  384   
  385       public void textDecl(String version, String encoding, Augmentations augs)
  386               throws XNIException {}
  387   
  388       public void endGeneralEntity(String name, Augmentations augs)
  389               throws XNIException {}
  390   
  391       public void characters(XMLString text, Augmentations augs)
  392               throws XNIException {
  393           if (fContentHandler != null) {
  394               // if the type is union it is possible that we receive
  395               // a character call with empty data
  396               if (text.length == 0) {
  397                   return;
  398               }
  399               try {
  400                   fContentHandler.characters(text.ch, text.offset, text.length);
  401               }
  402               catch (SAXException e) {
  403                   throw new XNIException(e);
  404               }
  405           }
  406       }
  407   
  408       public void ignorableWhitespace(XMLString text, Augmentations augs)
  409               throws XNIException {
  410           if (fContentHandler != null) {
  411               try {
  412                   fContentHandler.ignorableWhitespace(text.ch, text.offset, text.length);
  413               }
  414               catch (SAXException e) {
  415                   throw new XNIException(e);
  416               }
  417           }
  418       }
  419   
  420       public void endElement(QName element, Augmentations augs)
  421               throws XNIException {
  422           if (fContentHandler != null) {
  423               try {
  424                   fTypeInfoProvider.beginEndElement(augs);
  425                   fContentHandler.endElement((element.uri != null) ? element.uri : XMLSymbols.EMPTY_STRING,
  426                           element.localpart, element.rawname);
  427               }
  428               catch (SAXException e) {
  429                   throw new XNIException(e);
  430               }
  431               finally {
  432                   fTypeInfoProvider.finishEndElement();
  433               }
  434           }
  435       }
  436   
  437       public void startCDATA(Augmentations augs) throws XNIException {}
  438   
  439       public void endCDATA(Augmentations augs) throws XNIException {}
  440   
  441       public void endDocument(Augmentations augs) throws XNIException {
  442           if (fContentHandler != null) {
  443               try {
  444                   fContentHandler.endDocument();
  445               }
  446               catch (SAXException e) {
  447                   throw new XNIException(e);
  448               }
  449           }
  450       }
  451   
  452       // NO-OP
  453       public void setDocumentSource(XMLDocumentSource source) {}
  454   
  455       public XMLDocumentSource getDocumentSource() {
  456           return fSchemaValidator;
  457       }
  458   
  459       /*
  460        * ContentHandler methods
  461        */
  462   
  463       public void setDocumentLocator(Locator locator) {
  464           fSAXLocatorWrapper.setLocator(locator);
  465           if (fContentHandler != null) {
  466               fContentHandler.setDocumentLocator(locator);
  467           }
  468       }
  469   
  470       public void startDocument() throws SAXException {
  471           fComponentManager.reset();
  472           fSchemaValidator.setDocumentHandler(this);
  473           fValidationManager.setEntityState(this);
  474           fTypeInfoProvider.finishStartElement(); // cleans up TypeInfoProvider
  475           fNeedPushNSContext = true;
  476           if (fUnparsedEntities != null && !fUnparsedEntities.isEmpty()) {
  477               // should only clear this if the last document contained unparsed entities
  478               fUnparsedEntities.clear();
  479           }
  480           fErrorReporter.setDocumentLocator(fSAXLocatorWrapper);
  481           try {
  482               fSchemaValidator.startDocument(fSAXLocatorWrapper, fSAXLocatorWrapper.getEncoding(), fNamespaceContext, null);
  483           }
  484           catch (XMLParseException e) {
  485               throw Util.toSAXParseException(e);
  486           }
  487           catch (XNIException e) {
  488               throw Util.toSAXException(e);
  489           }
  490       }
  491   
  492       public void endDocument() throws SAXException {
  493           fSAXLocatorWrapper.setLocator(null);
  494           try {
  495               fSchemaValidator.endDocument(null);
  496           }
  497           catch (XMLParseException e) {
  498               throw Util.toSAXParseException(e);
  499           }
  500           catch (XNIException e) {
  501               throw Util.toSAXException(e);
  502           }
  503       }
  504   
  505       public void startPrefixMapping(String prefix, String uri)
  506               throws SAXException {
  507           String prefixSymbol;
  508           String uriSymbol;
  509           if (!fStringsInternalized) {
  510               prefixSymbol = (prefix != null) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING;
  511               uriSymbol = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
  512           }
  513           else {
  514               prefixSymbol = (prefix != null) ? prefix : XMLSymbols.EMPTY_STRING;
  515               uriSymbol = (uri != null && uri.length() > 0) ? uri : null;
  516           }
  517           if (fNeedPushNSContext) {
  518               fNeedPushNSContext = false;
  519               fNamespaceContext.pushContext();
  520           }
  521           fNamespaceContext.declarePrefix(prefixSymbol, uriSymbol);
  522           if (fContentHandler != null) {
  523               fContentHandler.startPrefixMapping(prefix, uri);
  524           }
  525       }
  526   
  527       public void endPrefixMapping(String prefix) throws SAXException {
  528           if (fContentHandler != null) {
  529               fContentHandler.endPrefixMapping(prefix);
  530           }
  531       }
  532   
  533       public void startElement(String uri, String localName, String qName,
  534               Attributes atts) throws SAXException {
  535           if (fNeedPushNSContext) {
  536               fNamespaceContext.pushContext();
  537           }
  538           fNeedPushNSContext = true;
  539   
  540           // Fill element QName
  541           fillQName(fElementQName, uri, localName, qName);
  542   
  543           // Fill XMLAttributes
  544           if (atts instanceof Attributes2) {
  545               fillXMLAttributes2((Attributes2) atts);
  546           }
  547           else {
  548               fillXMLAttributes(atts);
  549           }
  550   
  551           try {
  552               fSchemaValidator.startElement(fElementQName, fAttributes, null);
  553           }
  554           catch (XMLParseException e) {
  555               throw Util.toSAXParseException(e);
  556           }
  557           catch (XNIException e) {
  558               throw Util.toSAXException(e);
  559           }
  560       }
  561   
  562       public void endElement(String uri, String localName, String qName)
  563               throws SAXException {
  564           fillQName(fElementQName, uri, localName, qName);
  565           try {
  566               fSchemaValidator.endElement(fElementQName, null);
  567           }
  568           catch (XMLParseException e) {
  569               throw Util.toSAXParseException(e);
  570           }
  571           catch (XNIException e) {
  572               throw Util.toSAXException(e);
  573           }
  574           finally {
  575               fNamespaceContext.popContext();
  576           }
  577       }
  578   
  579       public void characters(char[] ch, int start, int length)
  580               throws SAXException {
  581           try {
  582               fTempString.setValues(ch, start, length);
  583               fSchemaValidator.characters(fTempString, null);
  584           }
  585           catch (XMLParseException e) {
  586               throw Util.toSAXParseException(e);
  587           }
  588           catch (XNIException e) {
  589               throw Util.toSAXException(e);
  590           }
  591       }
  592   
  593       public void ignorableWhitespace(char[] ch, int start, int length)
  594               throws SAXException {
  595           try {
  596               fTempString.setValues(ch, start, length);
  597               fSchemaValidator.ignorableWhitespace(fTempString, null);
  598           }
  599           catch (XMLParseException e) {
  600               throw Util.toSAXParseException(e);
  601           }
  602           catch (XNIException e) {
  603               throw Util.toSAXException(e);
  604           }
  605       }
  606   
  607       public void processingInstruction(String target, String data)
  608               throws SAXException {
  609           /**
  610            * Processing instructions do not participate in schema validation,
  611            * so just forward the event to the application's content
  612            * handler.
  613            */
  614           if (fContentHandler != null) {
  615               fContentHandler.processingInstruction(target, data);
  616           }
  617       }
  618   
  619       public void skippedEntity(String name) throws SAXException {
  620           // there seems to be no corresponding method on XMLDocumentFilter.
  621           // just pass it down to the output, if any.
  622           if (fContentHandler != null) {
  623               fContentHandler.skippedEntity(name);
  624           }
  625       }
  626   
  627       /*
  628        * DTDHandler methods
  629        */
  630   
  631       public void notationDecl(String name, String publicId,
  632               String systemId) throws SAXException {}
  633   
  634       public void unparsedEntityDecl(String name, String publicId,
  635               String systemId, String notationName) throws SAXException {
  636           if (fUnparsedEntities == null) {
  637               fUnparsedEntities = new HashMap();
  638           }
  639           fUnparsedEntities.put(name, name);
  640       }
  641   
  642       /*
  643        * ValidatorHelper methods
  644        */
  645   
  646       public void validate(Source source, Result result)
  647           throws SAXException, IOException {
  648           if (result instanceof SAXResult || result == null) {
  649               final SAXSource saxSource = (SAXSource) source;
  650               final SAXResult saxResult = (SAXResult) result;
  651   
  652               if (result != null) {
  653                   setContentHandler(saxResult.getHandler());
  654               }
  655   
  656               try {
  657                   XMLReader reader = saxSource.getXMLReader();
  658                   if( reader==null ) {
  659                       // create one now
  660                       SAXParserFactory spf = SAXParserFactory.newInstance();
  661                       spf.setNamespaceAware(true);
  662                       try {
  663                           reader = spf.newSAXParser().getXMLReader();
  664                           // If this is a Xerces SAX parser, set the security manager if there is one
  665                           if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) {
  666                              SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER);
  667                              if (securityManager != null) {
  668                                  try {
  669                                      reader.setProperty(SECURITY_MANAGER, securityManager);
  670                                  }
  671                                  // Ignore the exception if the security manager cannot be set.
  672                                  catch (SAXException exc) {}
  673                              }
  674                           }
  675                       } catch( Exception e ) {
  676                           // this is impossible, but better safe than sorry
  677                           throw new FactoryConfigurationError(e);
  678                       }
  679                   }
  680   
  681                   // If XML names and Namespace URIs are already internalized we
  682                   // can avoid running them through the SymbolTable.
  683                   try {
  684                       fStringsInternalized = reader.getFeature(STRING_INTERNING);
  685                   }
  686                   catch (SAXException exc) {
  687                       // The feature isn't recognized or getting it is not supported.
  688                       // In either case, assume that strings are not internalized.
  689                       fStringsInternalized = false;
  690                   }
  691   
  692                   ErrorHandler errorHandler = fComponentManager.getErrorHandler();
  693                   reader.setErrorHandler(errorHandler != null ? errorHandler : DraconianErrorHandler.getInstance());
  694                   reader.setEntityResolver(fResolutionForwarder);
  695                   fResolutionForwarder.setEntityResolver(fComponentManager.getResourceResolver());
  696                   reader.setContentHandler(this);
  697                   reader.setDTDHandler(this);
  698   
  699                   InputSource is = saxSource.getInputSource();
  700                   reader.parse(is);
  701               }
  702               finally {
  703                   // release the reference to user's handler ASAP
  704                   setContentHandler(null);
  705               }
  706               return;
  707           }
  708           throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(),
  709                   "SourceResultMismatch",
  710                   new Object [] {source.getClass().getName(), result.getClass().getName()}));
  711       }
  712   
  713       /*
  714        * PSVIProvider methods
  715        */
  716   
  717       public ElementPSVI getElementPSVI() {
  718           return fTypeInfoProvider.getElementPSVI();
  719       }
  720   
  721       public AttributePSVI getAttributePSVI(int index) {
  722           return fTypeInfoProvider.getAttributePSVI(index);
  723       }
  724   
  725       public AttributePSVI getAttributePSVIByName(String uri, String localname) {
  726           return fTypeInfoProvider.getAttributePSVIByName(uri, localname);
  727       }
  728   
  729       //
  730       //
  731       // helper methods
  732       //
  733       //
  734   
  735       /** Fills in a QName object. */
  736       private void fillQName(QName toFill, String uri, String localpart, String raw) {
  737           if (!fStringsInternalized) {
  738               uri = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null;
  739               localpart = (localpart != null) ? fSymbolTable.addSymbol(localpart) : XMLSymbols.EMPTY_STRING;
  740               raw = (raw != null) ? fSymbolTable.addSymbol(raw) : XMLSymbols.EMPTY_STRING;
  741           }
  742           else {
  743               if (uri != null && uri.length() == 0) {
  744                   uri = null;
  745               }
  746               if (localpart == null) {
  747                   localpart = XMLSymbols.EMPTY_STRING;
  748               }
  749               if (raw == null) {
  750                   raw = XMLSymbols.EMPTY_STRING;
  751               }
  752           }
  753           String prefix = XMLSymbols.EMPTY_STRING;
  754           int prefixIdx = raw.indexOf(':');
  755           if (prefixIdx != -1) {
  756               prefix = fSymbolTable.addSymbol(raw.substring(0, prefixIdx));
  757           }
  758           toFill.setValues(prefix, localpart, raw, uri);
  759       }
  760   
  761       /** Fills in the XMLAttributes object. */
  762       private void fillXMLAttributes(Attributes att) {
  763           fAttributes.removeAllAttributes();
  764           final int len = att.getLength();
  765           for (int i = 0; i < len; ++i) {
  766               fillXMLAttribute(att, i);
  767               fAttributes.setSpecified(i, true);
  768           }
  769       }
  770   
  771       /** Fills in the XMLAttributes object. */
  772       private void fillXMLAttributes2(Attributes2 att) {
  773           fAttributes.removeAllAttributes();
  774           final int len = att.getLength();
  775           for (int i = 0; i < len; ++i) {
  776               fillXMLAttribute(att, i);
  777               fAttributes.setSpecified(i, att.isSpecified(i));
  778               if (att.isDeclared(i)) {
  779                   fAttributes.getAugmentations(i).putItem(Constants.ATTRIBUTE_DECLARED, Boolean.TRUE);
  780               }
  781           }
  782       }
  783   
  784       /** Adds an attribute to the XMLAttributes object. */
  785       private void fillXMLAttribute(Attributes att, int index) {
  786           fillQName(fAttributeQName, att.getURI(index), att.getLocalName(index), att.getQName(index));
  787           String type = att.getType(index);
  788           fAttributes.addAttributeNS(fAttributeQName, (type != null) ? type : XMLSymbols.fCDATASymbol, att.getValue(index));
  789       }
  790   
  791       /**
  792        * {@link TypeInfoProvider} implementation.
  793        *
  794        * REVISIT: I'm not sure if this code should belong here.
  795        */
  796       private final XMLSchemaTypeInfoProvider fTypeInfoProvider = new XMLSchemaTypeInfoProvider();
  797       private static class XMLSchemaTypeInfoProvider extends TypeInfoProvider {
  798   
  799           /** Element augmentations: contains ElementPSVI. **/
  800           private Augmentations fElementAugs;
  801   
  802           /** Attributes: augmentations for each attribute contain AttributePSVI. **/
  803           private XMLAttributes fAttributes;
  804   
  805           /** In start element. **/
  806           private boolean fInStartElement = false;
  807   
  808           /** In end element. **/
  809           private boolean fInEndElement = false;
  810   
  811           /** Initializes the TypeInfoProvider with type information for the current element. **/
  812           void beginStartElement(Augmentations elementAugs, XMLAttributes attributes) {
  813               fInStartElement = true;
  814               fElementAugs = elementAugs;
  815               fAttributes = attributes;
  816           }
  817   
  818           /** Cleanup at the end of start element. **/
  819           void finishStartElement() {
  820               fInStartElement = false;
  821               fElementAugs = null;
  822               fAttributes = null;
  823           }
  824   
  825           /** Initializes the TypeInfoProvider with type information for the current element. **/
  826           void beginEndElement(Augmentations elementAugs) {
  827               fInEndElement = true;
  828               fElementAugs = elementAugs;
  829           }
  830   
  831           /** Cleanup at the end of end element. **/
  832           void finishEndElement() {
  833               fInEndElement = false;
  834               fElementAugs = null;
  835           }
  836   
  837           /**
  838            * Throws a {@link IllegalStateException} if we are not in
  839            * the startElement callback. the JAXP API requires this
  840            * for most of the public methods.
  841            */
  842           private void checkState(boolean forElementInfo) {
  843               if (! (fInStartElement || (fInEndElement && forElementInfo))) {
  844                   throw new IllegalStateException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(),
  845                           "TypeInfoProviderIllegalState", null));
  846               }
  847           }
  848   
  849           public TypeInfo getAttributeTypeInfo(int index) {
  850               checkState(false);
  851               return getAttributeType(index);
  852           }
  853   
  854           private TypeInfo getAttributeType( int index ) {
  855               checkState(false);
  856               if( index<0 || fAttributes.getLength()<=index )
  857                   throw new IndexOutOfBoundsException(Integer.toString(index));
  858               Augmentations augs = fAttributes.getAugmentations(index);
  859               if (augs == null) return null;
  860               AttributePSVI psvi = (AttributePSVI)augs.getItem(Constants.ATTRIBUTE_PSVI);
  861               return getTypeInfoFromPSVI(psvi);
  862           }
  863   
  864           public TypeInfo getAttributeTypeInfo(String attributeUri, String attributeLocalName) {
  865               checkState(false);
  866               return getAttributeTypeInfo(fAttributes.getIndex(attributeUri,attributeLocalName));
  867           }
  868   
  869           public TypeInfo getAttributeTypeInfo(String attributeQName) {
  870               checkState(false);
  871               return getAttributeTypeInfo(fAttributes.getIndex(attributeQName));
  872           }
  873   
  874           public TypeInfo getElementTypeInfo() {
  875               checkState(true);
  876               if (fElementAugs == null) return null;
  877               ElementPSVI psvi = (ElementPSVI)fElementAugs.getItem(Constants.ELEMENT_PSVI);
  878               return getTypeInfoFromPSVI(psvi);
  879           }
  880   
  881           private TypeInfo getTypeInfoFromPSVI( ItemPSVI psvi ) {
  882               if(psvi==null)  return null;
  883   
  884               // TODO: make sure if this is correct.
  885               // TODO: since the number of types in a schema is quite limited,
  886               // TypeInfoImpl should be pooled. Even better, it should be a part
  887               // of the element decl.
  888               if( psvi.getValidity()== ElementPSVI.VALIDITY_VALID ) {
  889                   XSTypeDefinition t = psvi.getMemberTypeDefinition();
  890                   if (t != null) {
  891                       return (t instanceof TypeInfo) ? (TypeInfo) t : null;
  892                   }
  893               }
  894   
  895               XSTypeDefinition t = psvi.getTypeDefinition();
  896               // TODO: can t be null?
  897               if (t != null) {
  898                   return (t instanceof TypeInfo) ? (TypeInfo) t : null;
  899               }
  900               return null;
  901           }
  902   
  903           public boolean isIdAttribute(int index) {
  904               checkState(false);
  905               XSSimpleType type = (XSSimpleType)getAttributeType(index);
  906               if(type==null)  return false;
  907               return type.isIDType();
  908           }
  909   
  910           public boolean isSpecified(int index) {
  911               checkState(false);
  912               return fAttributes.isSpecified(index);
  913           }
  914   
  915           /*
  916            * Other methods
  917            */
  918   
  919           // PSVIProvider support
  920           ElementPSVI getElementPSVI() {
  921               return (fElementAugs != null) ? (ElementPSVI) fElementAugs.getItem(Constants.ELEMENT_PSVI) : null;
  922           }
  923   
  924           AttributePSVI getAttributePSVI(int index) {
  925               if (fAttributes != null) {
  926                   Augmentations augs = fAttributes.getAugmentations(index);
  927                   if (augs != null) {
  928                       return (AttributePSVI) augs.getItem(Constants.ATTRIBUTE_PSVI);
  929                   }
  930               }
  931               return null;
  932           }
  933   
  934           AttributePSVI getAttributePSVIByName(String uri, String localname) {
  935               if (fAttributes != null) {
  936                   Augmentations augs = fAttributes.getAugmentations(uri, localname);
  937                   if (augs != null) {
  938                       return (AttributePSVI) augs.getItem(Constants.ATTRIBUTE_PSVI);
  939                   }
  940               }
  941               return null;
  942           }
  943       }
  944   
  945       /** SAX adapter for an LSResourceResolver. */
  946       private final ResolutionForwarder fResolutionForwarder = new ResolutionForwarder(null);
  947       static final class ResolutionForwarder
  948           implements EntityResolver2 {
  949   
  950           //
  951           // Data
  952           //
  953   
  954           /** XML 1.0 type constant according to DOM L3 LS REC spec "http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/" */
  955           private static final String XML_TYPE = "http://www.w3.org/TR/REC-xml";
  956   
  957           /** The DOM entity resolver. */
  958           protected LSResourceResolver fEntityResolver;
  959   
  960           //
  961           // Constructors
  962           //
  963   
  964           /** Default constructor. */
  965           public ResolutionForwarder() {}
  966   
  967           /** Wraps the specified DOM entity resolver. */
  968           public ResolutionForwarder(LSResourceResolver entityResolver) {
  969               setEntityResolver(entityResolver);
  970           }
  971   
  972           //
  973           // Public methods
  974           //
  975   
  976           /** Sets the DOM entity resolver. */
  977           public void setEntityResolver(LSResourceResolver entityResolver) {
  978               fEntityResolver = entityResolver;
  979           } // setEntityResolver(LSResourceResolver)
  980   
  981           /** Returns the DOM entity resolver. */
  982           public LSResourceResolver getEntityResolver() {
  983               return fEntityResolver;
  984           } // getEntityResolver():LSResourceResolver
  985   
  986           /**
  987            * Always returns <code>null</code>. An LSResourceResolver has no corresponding method.
  988            */
  989           public InputSource getExternalSubset(String name, String baseURI)
  990                   throws SAXException, IOException {
  991               return null;
  992           }
  993   
  994           /**
  995            * Resolves the given resource and adapts the <code>LSInput</code>
  996            * returned into an <code>InputSource</code>.
  997            */
  998           public InputSource resolveEntity(String name, String publicId,
  999                   String baseURI, String systemId) throws SAXException, IOException {
 1000               if (fEntityResolver != null) {
 1001                   LSInput lsInput = fEntityResolver.resolveResource(XML_TYPE, null, publicId, systemId, baseURI);
 1002                   if (lsInput != null) {
 1003                       final String pubId = lsInput.getPublicId();
 1004                       final String sysId = lsInput.getSystemId();
 1005                       final String baseSystemId = lsInput.getBaseURI();
 1006                       final Reader charStream = lsInput.getCharacterStream();
 1007                       final InputStream byteStream = lsInput.getByteStream();
 1008                       final String data = lsInput.getStringData();
 1009                       final String encoding = lsInput.getEncoding();
 1010   
 1011                       /**
 1012                        * An LSParser looks at inputs specified in LSInput in
 1013                        * the following order: characterStream, byteStream,
 1014                        * stringData, systemId, publicId. For consistency
 1015                        * with the DOM Level 3 Load and Save Recommendation
 1016                        * use the same lookup order here.
 1017                        */
 1018                       InputSource inputSource = new InputSource();
 1019                       inputSource.setPublicId(pubId);
 1020                       inputSource.setSystemId((baseSystemId != null) ? resolveSystemId(systemId, baseSystemId) : systemId);
 1021   
 1022                       if (charStream != null) {
 1023                           inputSource.setCharacterStream(charStream);
 1024                       }
 1025                       else if (byteStream != null) {
 1026                           inputSource.setByteStream(byteStream);
 1027                       }
 1028                       else if (data != null && data.length() != 0) {
 1029                           inputSource.setCharacterStream(new StringReader(data));
 1030                       }
 1031                       inputSource.setEncoding(encoding);
 1032                       return inputSource;
 1033                   }
 1034               }
 1035               return null;
 1036           }
 1037   
 1038           /** Delegates to EntityResolver2.resolveEntity(String, String, String, String). */
 1039           public InputSource resolveEntity(String publicId, String systemId)
 1040                   throws SAXException, IOException {
 1041               return resolveEntity(null, publicId, null, systemId);
 1042           }
 1043   
 1044           /** Resolves a system identifier against a base URI. */
 1045           private String resolveSystemId(String systemId, String baseURI) {
 1046               try {
 1047                   return XMLEntityManager.expandSystemId(systemId, baseURI, false);
 1048               }
 1049               // In the event that resolution failed against the
 1050               // base URI, just return the system id as is. There's not
 1051               // much else we can do.
 1052               catch (URI.MalformedURIException ex) {
 1053                   return systemId;
 1054               }
 1055           }
 1056       }
 1057   }

Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » jaxp » validation » [javadoc | source]