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 package com.sun.org.apache.xerces.internal.jaxp.validation; 21 22 import com.sun.org.apache.xerces.internal.impl.Constants; 23 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; 24 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 25 import com.sun.org.apache.xerces.internal.parsers.XML11Configuration; 26 import com.sun.org.apache.xerces.internal.utils.XMLSecurityManager; 27 import com.sun.org.apache.xerces.internal.xni.XNIException; 28 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 29 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; 30 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; 31 import java.io.IOException; 32 import java.lang.ref.SoftReference; 33 import javax.xml.XMLConstants; 34 import javax.xml.catalog.CatalogFeatures; 35 import javax.xml.transform.Result; 36 import javax.xml.transform.Source; 37 import javax.xml.transform.TransformerConfigurationException; 38 import javax.xml.transform.TransformerFactory; 39 import javax.xml.transform.TransformerFactoryConfigurationError; 40 import javax.xml.transform.sax.SAXTransformerFactory; 41 import javax.xml.transform.sax.TransformerHandler; 42 import javax.xml.transform.stream.StreamResult; 43 import javax.xml.transform.stream.StreamSource; 44 import jdk.xml.internal.JdkXmlFeatures; 45 import jdk.xml.internal.JdkXmlUtils; 46 import org.xml.sax.SAXException; 47 48 /** 49 * <p> 50 * A validator helper for <code>StreamSource</code>s.</p> 51 * 52 * @author Michael Glavassevich, IBM 53 * @author Sunitha Reddy 54 */ 55 final class StreamValidatorHelper implements ValidatorHelper { 56 57 // feature identifiers 58 /** 59 * Feature identifier: parser settings. 60 */ 61 private static final String PARSER_SETTINGS 62 = Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; 63 64 // property identifiers 65 /** 66 * Property identifier: entity resolver. 67 */ 68 private static final String ENTITY_RESOLVER 69 = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; 70 71 /** 72 * Property identifier: error handler. 73 */ 74 private static final String ERROR_HANDLER 75 = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY; 76 77 /** 78 * Property identifier: error reporter. 79 */ 80 private static final String ERROR_REPORTER 81 = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 82 83 /** 84 * Property identifier: XML Schema validator. 85 */ 86 private static final String SCHEMA_VALIDATOR 87 = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY; 88 89 /** 90 * Property identifier: symbol table. 91 */ 92 private static final String SYMBOL_TABLE 93 = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 94 95 /** 96 * Property identifier: validation manager. 97 */ 98 private static final String VALIDATION_MANAGER 99 = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 100 101 private static final String DEFAULT_TRANSFORMER_IMPL 102 = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"; 103 104 /** 105 * Property id: security manager. 106 */ 107 private static final String SECURITY_MANAGER 108 = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; 109 110 // 111 // Data 112 // 113 /** 114 * SoftReference to parser configuration. * 115 */ 116 private SoftReference<XMLParserConfiguration> fConfiguration = new SoftReference<>(null); 117 118 /** 119 * Schema validator. * 120 */ 121 private com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator fSchemaValidator; 122 123 /** 124 * Component manager. * 125 */ 126 private XMLSchemaValidatorComponentManager fComponentManager; 127 128 private ValidatorHandlerImpl handler = null; 129 130 public StreamValidatorHelper(XMLSchemaValidatorComponentManager componentManager) { 131 fComponentManager = componentManager; 132 fSchemaValidator = (com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator) 133 fComponentManager.getProperty(SCHEMA_VALIDATOR); 134 } 135 136 public void validate(Source source, Result result) 137 throws SAXException, IOException { 138 if (result == null || result instanceof StreamResult) { 139 final StreamSource streamSource = (StreamSource) source; 140 TransformerHandler identityTransformerHandler; 141 142 if (result != null) { 143 try { 144 SAXTransformerFactory tf = fComponentManager.getFeature( 145 Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? 146 (SAXTransformerFactory) SAXTransformerFactory.newInstance() : 147 (SAXTransformerFactory) TransformerFactory.newInstance( 148 DEFAULT_TRANSFORMER_IMPL, 149 StreamValidatorHelper.class.getClassLoader()); 150 identityTransformerHandler = tf.newTransformerHandler(); 151 } catch (TransformerConfigurationException e) { 152 throw new TransformerFactoryConfigurationError(e); 153 } 154 155 handler = new ValidatorHandlerImpl(fComponentManager); 156 handler.setContentHandler(identityTransformerHandler); 157 identityTransformerHandler.setResult(result); 158 } 159 160 XMLInputSource input = new XMLInputSource(streamSource.getPublicId(), 161 streamSource.getSystemId(), null, false); 162 input.setByteStream(streamSource.getInputStream()); 163 input.setCharacterStream(streamSource.getReader()); 164 165 // Gets the parser configuration. We'll create and initialize a new one, if we 166 // haven't created one before or if the previous one was garbage collected. 167 XMLParserConfiguration config = fConfiguration.get(); 168 if (config == null) { 169 config = initialize(); 170 } 171 // If settings have changed on the component manager, refresh the error handler and entity resolver. 172 else if (fComponentManager.getFeature(PARSER_SETTINGS)) { 173 config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); 174 config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); 175 } 176 177 // prepare for parse 178 fComponentManager.reset(); 179 fSchemaValidator.setDocumentHandler(handler); 180 181 try { 182 config.parse(input); 183 } catch (XMLParseException e) { 184 throw Util.toSAXParseException(e); 185 } catch (XNIException e) { 186 throw Util.toSAXException(e); 187 } 188 return; 189 } 190 throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage( 191 fComponentManager.getLocale(), 192 "SourceResultMismatch", 193 new Object[]{source.getClass().getName(), result.getClass().getName()})); 194 } 195 196 private XMLParserConfiguration initialize() { 197 XML11Configuration config = new XML11Configuration(); 198 if (fComponentManager.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) { 199 config.setProperty(SECURITY_MANAGER, new XMLSecurityManager()); 200 } 201 config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); 202 config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); 203 XMLErrorReporter errorReporter = (XMLErrorReporter) fComponentManager.getProperty(ERROR_REPORTER); 204 config.setProperty(ERROR_REPORTER, errorReporter); 205 // add message formatters 206 if (errorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { 207 XMLMessageFormatter xmft = new XMLMessageFormatter(); 208 errorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); 209 errorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); 210 } 211 config.setProperty(SYMBOL_TABLE, fComponentManager.getProperty(SYMBOL_TABLE)); 212 config.setProperty(VALIDATION_MANAGER, fComponentManager.getProperty(VALIDATION_MANAGER)); 213 config.setDocumentHandler(fSchemaValidator); 214 config.setDTDHandler(null); 215 config.setDTDContentModelHandler(null); 216 config.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, 217 fComponentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER)); 218 config.setProperty(Constants.SECURITY_MANAGER, 219 fComponentManager.getProperty(Constants.SECURITY_MANAGER)); 220 221 // Passing on the CatalogFeatures settings 222 JdkXmlUtils.catalogFeaturesConfig2Config(fComponentManager, config); 223 224 config.setProperty(JdkXmlUtils.CDATA_CHUNK_SIZE, 225 fComponentManager.getProperty(JdkXmlUtils.CDATA_CHUNK_SIZE)); 226 227 fConfiguration = new SoftReference<>(config); 228 return config; 229 } 230 231 } // StreamValidatorHelper