src/share/jaxws_classes/com/sun/xml/internal/xsom/parser/JAXPParser.java

Thu, 31 Aug 2017 15:18:52 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:18:52 +0800
changeset 637
9c07ef4934dd
parent 397
b99d7e355d4b
parent 0
373ffda63c9a
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.xml.internal.xsom.parser;
    28 import java.io.IOException;
    29 import java.net.URL;
    30 import java.util.logging.Level;
    31 import java.util.logging.Logger;
    33 import javax.xml.parsers.ParserConfigurationException;
    34 import javax.xml.parsers.SAXParser;
    35 import javax.xml.parsers.SAXParserFactory;
    37 import org.xml.sax.*;
    38 import org.xml.sax.helpers.XMLFilterImpl;
    40 import com.sun.xml.internal.xsom.impl.parser.Messages;
    42 /**
    43  * Standard XMLParser implemented by using JAXP.
    44  *
    45  * @author
    46  *     Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
    47  */
    48 public class JAXPParser implements XMLParser {
    50     // not in older JDK, so must be duplicated here, otherwise javax.xml.XMLConstants should be used
    51     private static final String ACCESS_EXTERNAL_SCHEMA = "http://javax.xml.XMLConstants/property/accessExternalSchema";
    53     private static final Logger LOGGER = Logger.getLogger(JAXPParser.class.getName());
    55     private final SAXParserFactory factory;
    57     public JAXPParser( SAXParserFactory factory ) {
    58         factory.setNamespaceAware(true);    // just in case
    59         this.factory = factory;
    60     }
    62     /**
    63      * @deprecated Unsafe, use JAXPParser(factory) instead with
    64      * security features initialized by setting
    65      * XMLConstants.FEATURE_SECURE_PROCESSING feature.
    66      */
    67     public JAXPParser() {
    68         this( SAXParserFactory.newInstance());
    69     }
    71     public void parse( InputSource source, ContentHandler handler,
    72         ErrorHandler errorHandler, EntityResolver entityResolver )
    74         throws SAXException, IOException {
    76         try {
    77             SAXParser saxParser = allowFileAccess(factory.newSAXParser(), false);
    78             XMLReader reader = new XMLReaderEx(saxParser.getXMLReader());
    80             reader.setContentHandler(handler);
    81             if(errorHandler!=null)
    82                 reader.setErrorHandler(errorHandler);
    83             if(entityResolver!=null)
    84                 reader.setEntityResolver(entityResolver);
    85             reader.parse(source);
    86         } catch( ParserConfigurationException e ) {
    87             // in practice this won't happen
    88             SAXParseException spe = new SAXParseException(e.getMessage(),null,e);
    89             errorHandler.fatalError(spe);
    90             throw spe;
    91         }
    92     }
    94     private static SAXParser allowFileAccess(SAXParser saxParser, boolean disableSecureProcessing) throws SAXException {
    96         // if feature secure processing enabled, nothing to do, file is allowed,
    97         // or user is able to control access by standard JAXP mechanisms
    98         if (disableSecureProcessing) {
    99             return saxParser;
   100         }
   102         try {
   103             saxParser.setProperty(ACCESS_EXTERNAL_SCHEMA, "file");
   104             LOGGER.log(Level.FINE, Messages.format(Messages.JAXP_SUPPORTED_PROPERTY, ACCESS_EXTERNAL_SCHEMA));
   105         } catch (SAXException ignored) {
   106             // nothing to do; support depends on version JDK or SAX implementation
   107             LOGGER.log(Level.CONFIG, Messages.format(Messages.JAXP_UNSUPPORTED_PROPERTY, ACCESS_EXTERNAL_SCHEMA), ignored);
   108         }
   109         return saxParser;
   110     }
   112     /**
   113      * XMLReader with improved error message for entity resolution failure.
   114      *
   115      * TODO: this class is completely stand-alone, so it shouldn't be
   116      * an inner class.
   117      */
   118     private static class XMLReaderEx extends XMLFilterImpl {
   120         private Locator locator;
   122         XMLReaderEx( XMLReader parent ) {
   123             this.setParent(parent);
   124         }
   126         /**
   127          * Resolves entities and reports user-friendly error messages.
   128          *
   129          * <p>
   130          * Some XML parser (at least Xerces) does not report much information
   131          * when it fails to resolve an entity, which is often quite
   132          * frustrating. For example, if you are behind a firewall and the
   133          * schema contains a reference to www.w3.org, and there is no
   134          * entity resolver, the parser will just throw an IOException
   135          * that doesn't contain any information about where that reference
   136          * occurs nor what it is accessing.
   137          *
   138          * <p>
   139          * By implementing an EntityResolver and resolving the reference
   140          * by ourselves, we can report an error message with all the
   141          * necessary information to fix the problem.
   142          *
   143          * <p>
   144          * Note that we still need to the client-specified entity resolver
   145          * to let the application handle entity resolution. Here we just catch
   146          * an IOException and add more information.
   147          */
   148         @Override
   149         public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
   150             try {
   151                 InputSource is=null;
   153                 // ask the client-specified entity resolver first
   154                 if( this.getEntityResolver()!=null)
   155                     is = this.getEntityResolver().resolveEntity(publicId,systemId);
   156                 if( is!=null )  return is;  // if that succeeds, fine.
   158                 // rather than returning null, resolve it now
   159                 // so that we can detect errors.
   160                 is = new InputSource( new URL(systemId).openStream() );
   161                 is.setSystemId(systemId);
   162                 is.setPublicId(publicId);
   163                 return is;
   164             } catch( IOException e ) {
   165                 // catch this error and provide a nice error message, rather than
   166                 // just throwing this IOException.
   167                 SAXParseException spe = new SAXParseException(
   168                     Messages.format(Messages.ERR_ENTITY_RESOLUTION_FAILURE,
   169                         systemId, e.toString()),    // use the toString method to get the class name
   170                     locator, e );
   171                 if(this.getErrorHandler()!=null)
   172                     this.getErrorHandler().fatalError(spe);
   173                 throw spe;
   174             }
   175         }
   177         @Override
   178         public void setDocumentLocator(Locator locator) {
   179             super.setDocumentLocator(locator);
   180             this.locator = locator;
   181         }
   182     }
   183 }

mercurial