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