1 /*
   2  * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  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 
  25 import javax.xml.transform.Result;
  26 import javax.xml.transform.Source;
  27 import javax.xml.transform.dom.DOMSource;
  28 import javax.xml.transform.sax.SAXSource;
  29 import javax.xml.transform.stax.StAXSource;
  30 import javax.xml.transform.stream.StreamSource;
  31 import javax.xml.validation.Validator;
  32 
  33 import com.sun.org.apache.xerces.internal.impl.Constants;
  34 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter;
  35 import com.sun.org.apache.xerces.internal.util.Status;
  36 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  37 import com.sun.org.apache.xerces.internal.xs.AttributePSVI;
  38 import com.sun.org.apache.xerces.internal.xs.ElementPSVI;
  39 import com.sun.org.apache.xerces.internal.xs.PSVIProvider;
  40 import org.w3c.dom.ls.LSResourceResolver;
  41 import org.xml.sax.ErrorHandler;
  42 import org.xml.sax.SAXException;
  43 import org.xml.sax.SAXNotRecognizedException;
  44 import org.xml.sax.SAXNotSupportedException;
  45 
  46 /**
  47  * <p>Implementation of Validator for W3C XML Schemas.</p>
  48  *
  49  * @author Kohsuke Kawaguchi
  50  * @author Michael Glavassevich, IBM
  51  * @author Sunitha Reddy
  52  */
  53 final class ValidatorImpl extends Validator implements PSVIProvider {
  54 
  55     //
  56     // Data
  57     //
  58 
  59     /** Component manager. **/
  60     private XMLSchemaValidatorComponentManager fComponentManager;
  61 
  62     /** SAX validator helper. **/
  63     private ValidatorHandlerImpl fSAXValidatorHelper;
  64 
  65     /** DOM validator helper. **/
  66     private DOMValidatorHelper fDOMValidatorHelper;
  67 
  68     /** Stream validator helper. **/
  69     private StreamValidatorHelper fStreamValidatorHelper;
  70 
  71     /** StAX validator helper. **/
  72     private StAXValidatorHelper fStaxValidatorHelper;
  73 
  74     /** Flag for tracking whether features/properties changed since last reset. */
  75     private boolean fConfigurationChanged = false;
  76 
  77     /** Flag for tracking whether the error handler changed since last reset. */
  78     private boolean fErrorHandlerChanged = false;
  79 
  80     /** Flag for tracking whether the resource resolver changed since last reset. */
  81     private boolean fResourceResolverChanged = false;
  82 
  83     /** Support current-element-node property */
  84     private static final String CURRENT_ELEMENT_NODE =
  85             Constants.XERCES_PROPERTY_PREFIX + Constants.CURRENT_ELEMENT_NODE_PROPERTY;
  86 
  87     public ValidatorImpl(XSGrammarPoolContainer grammarContainer) {
  88         fComponentManager = new XMLSchemaValidatorComponentManager(grammarContainer);
  89         setErrorHandler(null);
  90         setResourceResolver(null);
  91     }
  92 
  93     @Override
  94     public void validate(Source source, Result result)
  95         throws SAXException, IOException {
  96         if (source instanceof SAXSource) {
  97             // Hand off to SAX validator helper.
  98             if (fSAXValidatorHelper == null) {
  99                 fSAXValidatorHelper = new ValidatorHandlerImpl(fComponentManager);
 100             }
 101             fSAXValidatorHelper.validate(source, result);
 102         }
 103         else if (source instanceof DOMSource) {
 104             // Hand off to DOM validator helper.
 105             if (fDOMValidatorHelper == null) {
 106                 fDOMValidatorHelper = new DOMValidatorHelper(fComponentManager);
 107             }
 108             fDOMValidatorHelper.validate(source, result);
 109         }
 110         else if (source instanceof StreamSource) {
 111             // Hand off to stream validator helper.
 112             if (fStreamValidatorHelper == null) {
 113                 fStreamValidatorHelper = new StreamValidatorHelper(fComponentManager);
 114             }
 115             fStreamValidatorHelper.validate(source, result);
 116         }
 117         else if (source instanceof StAXSource) {
 118             // Hand off to stax validator helper.
 119             if (fStaxValidatorHelper == null) {
 120                 fStaxValidatorHelper = new StAXValidatorHelper(fComponentManager);
 121             }
 122             fStaxValidatorHelper.validate(source, result);
 123         }
 124         // Source parameter cannot be null.
 125         else if (source == null) {
 126             throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(),
 127                     "SourceParameterNull", null));
 128         }
 129         // Source parameter must be a SAXSource, DOMSource or StreamSource
 130         else {
 131             throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(),
 132                     "SourceNotAccepted", new Object [] {source.getClass().getName()}));
 133         }
 134     }
 135 
 136     @Override
 137     public void setErrorHandler(ErrorHandler errorHandler) {
 138         fErrorHandlerChanged = (errorHandler != null);
 139         fComponentManager.setErrorHandler(errorHandler);
 140     }
 141 
 142     @Override
 143     public ErrorHandler getErrorHandler() {
 144         return fComponentManager.getErrorHandler();
 145     }
 146 
 147     @Override
 148     public void setResourceResolver(LSResourceResolver resourceResolver) {
 149         fResourceResolverChanged = (resourceResolver != null);
 150         fComponentManager.setResourceResolver(resourceResolver);
 151     }
 152 
 153     @Override
 154     public LSResourceResolver getResourceResolver() {
 155         return fComponentManager.getResourceResolver();
 156     }
 157 
 158     @Override
 159     public boolean getFeature(String name)
 160         throws SAXNotRecognizedException, SAXNotSupportedException {
 161         if (name == null) {
 162             throw new NullPointerException();
 163         }
 164         try {
 165             return fComponentManager.getFeature(name);
 166         }
 167         catch (XMLConfigurationException e) {
 168             final String identifier = e.getIdentifier();
 169             final String key = e.getType() == Status.NOT_RECOGNIZED ?
 170                     "feature-not-recognized" : "feature-not-supported";
 171             throw new SAXNotRecognizedException(
 172                     SAXMessageFormatter.formatMessage(fComponentManager.getLocale(),
 173                     key, new Object [] {identifier}));
 174         }
 175     }
 176 
 177     @Override
 178     public void setFeature(String name, boolean value)
 179         throws SAXNotRecognizedException, SAXNotSupportedException {
 180         if (name == null) {
 181             throw new NullPointerException();
 182         }
 183         try {
 184             fComponentManager.setFeature(name, value);
 185         }
 186         catch (XMLConfigurationException e) {
 187             final String identifier = e.getIdentifier();
 188             final String key;
 189             if (e.getType() == Status.NOT_ALLOWED) {
 190                 //for now, the identifier can only be (XMLConstants.FEATURE_SECURE_PROCESSING)
 191                 throw new SAXNotSupportedException(
 192                     SAXMessageFormatter.formatMessage(fComponentManager.getLocale(),
 193                     "jaxp-secureprocessing-feature", null));
 194             } else if (e.getType() == Status.NOT_RECOGNIZED) {
 195                 key = "feature-not-recognized";
 196             } else {
 197                 key = "feature-not-supported";
 198             }
 199             throw new SAXNotRecognizedException(
 200                     SAXMessageFormatter.formatMessage(fComponentManager.getLocale(),
 201                     key, new Object [] {identifier}));
 202         }
 203         fConfigurationChanged = true;
 204     }
 205 
 206     @Override
 207     public Object getProperty(String name)
 208         throws SAXNotRecognizedException, SAXNotSupportedException {
 209         if (name == null) {
 210             throw new NullPointerException();
 211         }
 212         //Support current-element-node; return current node if DOMSource is used.
 213         if (CURRENT_ELEMENT_NODE.equals(name)) {
 214             return (fDOMValidatorHelper != null) ? fDOMValidatorHelper.getCurrentElement() : null;
 215         }
 216         try {
 217             return fComponentManager.getProperty(name);
 218         }
 219         catch (XMLConfigurationException e) {
 220             final String identifier = e.getIdentifier();
 221             final String key = e.getType() == Status.NOT_RECOGNIZED ?
 222                     "property-not-recognized" : "property-not-supported";
 223             throw new SAXNotRecognizedException(
 224                     SAXMessageFormatter.formatMessage(fComponentManager.getLocale(),
 225                     key, new Object [] {identifier}));
 226         }
 227     }
 228 
 229     @Override
 230     public void setProperty(String name, Object object)
 231         throws SAXNotRecognizedException, SAXNotSupportedException {
 232         if (name == null) {
 233             throw new NullPointerException();
 234         }
 235         try {
 236             fComponentManager.setProperty(name, object);
 237         }
 238         catch (XMLConfigurationException e) {
 239             final String identifier = e.getIdentifier();
 240             final String key = e.getType() == Status.NOT_RECOGNIZED ?
 241                     "property-not-recognized" : "property-not-supported";
 242             throw new SAXNotRecognizedException(
 243                     SAXMessageFormatter.formatMessage(fComponentManager.getLocale(),
 244                     key, new Object [] {identifier}));
 245         }
 246         fConfigurationChanged = true;
 247     }
 248 
 249     @Override
 250     public void reset() {
 251         // avoid resetting features and properties if the state the validator
 252         // is currently in, is the same as it will be after reset.
 253         if (fConfigurationChanged) {
 254             fComponentManager.restoreInitialState();
 255             setErrorHandler(null);
 256             setResourceResolver(null);
 257             fConfigurationChanged = false;
 258             fErrorHandlerChanged = false;
 259             fResourceResolverChanged = false;
 260         }
 261         else {
 262             if (fErrorHandlerChanged) {
 263                 setErrorHandler(null);
 264                 fErrorHandlerChanged = false;
 265             }
 266             if (fResourceResolverChanged) {
 267                 setResourceResolver(null);
 268                 fResourceResolverChanged = false;
 269             }
 270         }
 271     }
 272 
 273     /*
 274      * PSVIProvider methods
 275      */
 276 
 277     @Override
 278     public ElementPSVI getElementPSVI() {
 279         return (fSAXValidatorHelper != null) ? fSAXValidatorHelper.getElementPSVI() : null;
 280     }
 281 
 282     @Override
 283     public AttributePSVI getAttributePSVI(int index) {
 284         return (fSAXValidatorHelper != null) ? fSAXValidatorHelper.getAttributePSVI(index) : null;
 285     }
 286 
 287     @Override
 288     public AttributePSVI getAttributePSVIByName(String uri, String localname) {
 289         return (fSAXValidatorHelper != null) ? fSAXValidatorHelper.getAttributePSVIByName(uri, localname) : null;
 290     }
 291 
 292 } // ValidatorImpl