1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 
  22 package com.sun.org.apache.xerces.internal.parsers;
  23 
  24 import java.io.IOException;
  25 
  26 import com.sun.org.apache.xerces.internal.impl.Constants;
  27 import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar;
  28 import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader;
  29 import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
  30 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader;
  31 import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
  32 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  33 import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;
  34 import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
  35 import com.sun.org.apache.xerces.internal.xni.XNIException;
  36 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  37 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  38 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  39 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  40 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  41 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  42 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  43 
  44 /**
  45  * <p> This configuration provides a generic way of using
  46  * Xerces's grammar caching facilities.  It extends the
  47  * XIncludeAwareParserConfiguration and thus may validate documents
  48  * according to XML schemas or DTD's.  It also allows the user to
  49  * preparse a grammar, and to lock the grammar pool
  50  * implementation such that no more grammars will be added.</p>
  51  * <p> Using the com.sun.org.apache.xerces.internal.xni.parser property, an
  52  * application may instantiate a Xerces SAX or DOM parser with
  53  * this configuration.  When invoked in this manner, the default
  54  * behaviour will be elicited; to use this configuration's
  55  * specific facilities, the user will need to reference it
  56  * directly.</p>
  57  * <p>
  58  * In addition to the features and properties recognized by the base
  59  * parser configuration, this class recognizes these additional
  60  * features and properties:
  61  * <ul>
  62  * </ul>
  63  *
  64  * @author Neil Graham, IBM
  65  *
  66  * @version $Id: XMLGrammarCachingConfiguration.java,v 1.6 2010-11-01 04:40:10 joehw Exp $
  67  */
  68 public class XMLGrammarCachingConfiguration
  69     extends XIncludeAwareParserConfiguration {
  70 
  71     //
  72     // Constants
  73     //
  74 
  75     // a larg(ish) prime to use for a symbol table to be shared
  76     // among
  77     // potentially man parsers.  Start one as close to 2K (20
  78     // times larger than normal) and see what happens...
  79     public static final int BIG_PRIME = 2039;
  80 
  81     // the static symbol table to be shared amongst parsers
  82     protected static final SynchronizedSymbolTable fStaticSymbolTable =
  83             new SynchronizedSymbolTable(BIG_PRIME);
  84 
  85     // the Grammar Pool to be shared similarly
  86     protected static final XMLGrammarPoolImpl fStaticGrammarPool =
  87             new XMLGrammarPoolImpl();
  88 
  89     // schema full checking constant
  90     protected static final String SCHEMA_FULL_CHECKING =
  91             Constants.XERCES_FEATURE_PREFIX+Constants.SCHEMA_FULL_CHECKING;
  92 
  93     // Data
  94 
  95     // variables needed for caching schema grammars.
  96     protected XMLSchemaLoader fSchemaLoader;
  97 
  98     // the DTD grammar loader
  99     protected XMLDTDLoader fDTDLoader;
 100 
 101     //
 102     // Constructors
 103     //
 104 
 105     /** Default constructor. */
 106     public XMLGrammarCachingConfiguration() {
 107         this(fStaticSymbolTable, fStaticGrammarPool, null);
 108     } // <init>()
 109 
 110     /**
 111      * Constructs a parser configuration using the specified symbol table.
 112      *
 113      * @param symbolTable The symbol table to use.
 114      */
 115     public XMLGrammarCachingConfiguration(SymbolTable symbolTable) {
 116         this(symbolTable, fStaticGrammarPool, null);
 117     } // <init>(SymbolTable)
 118 
 119     /**
 120      * Constructs a parser configuration using the specified symbol table and
 121      * grammar pool.
 122      * <p>
 123      * <strong>REVISIT:</strong>
 124      * Grammar pool will be updated when the new validation engine is
 125      * implemented.
 126      *
 127      * @param symbolTable The symbol table to use.
 128      * @param grammarPool The grammar pool to use.
 129      */
 130     public XMLGrammarCachingConfiguration(SymbolTable symbolTable,
 131                                        XMLGrammarPool grammarPool) {
 132         this(symbolTable, grammarPool, null);
 133     } // <init>(SymbolTable,XMLGrammarPool)
 134 
 135     /**
 136      * Constructs a parser configuration using the specified symbol table,
 137      * grammar pool, and parent settings.
 138      * <p>
 139      * <strong>REVISIT:</strong>
 140      * Grammar pool will be updated when the new validation engine is
 141      * implemented.
 142      *
 143      * @param symbolTable    The symbol table to use.
 144      * @param grammarPool    The grammar pool to use.
 145      * @param parentSettings The parent settings.
 146      */
 147     public XMLGrammarCachingConfiguration(SymbolTable symbolTable,
 148                                        XMLGrammarPool grammarPool,
 149                                        XMLComponentManager parentSettings) {
 150         super(symbolTable, grammarPool, parentSettings);
 151 
 152         // REVISIT:  may need to add some features/properties
 153         // specific to this configuration at some point...
 154 
 155         // add default recognized features
 156         // set state for default features
 157         // add default recognized properties
 158         // create and register missing components
 159         fSchemaLoader = new XMLSchemaLoader(fSymbolTable);
 160         fSchemaLoader.setProperty(XMLGRAMMAR_POOL, fGrammarPool);
 161 
 162         // and set up the DTD loader too:
 163         fDTDLoader = new XMLDTDLoader(fSymbolTable, fGrammarPool);
 164     } // <init>(SymbolTable,XMLGrammarPool, XMLComponentManager)
 165 
 166     //
 167     // Public methods
 168     //
 169 
 170     /*
 171      * lock the XMLGrammarPoolImpl object so that it does not
 172      * accept any more grammars from the validators.
 173      */
 174     public void lockGrammarPool() {
 175         fGrammarPool.lockPool();
 176     } // lockGrammarPool()
 177 
 178     /*
 179      * clear the XMLGrammarPoolImpl object so that it does not
 180      * contain any more grammars.
 181      */
 182     public void clearGrammarPool() {
 183         fGrammarPool.clear();
 184     } // clearGrammarPool()
 185 
 186     /*
 187      * unlock the XMLGrammarPoolImpl object so that it
 188      * accepts more grammars from the validators.
 189      */
 190     public void unlockGrammarPool() {
 191         fGrammarPool.unlockPool();
 192     } // unlockGrammarPool()
 193 
 194     /**
 195      * Parse a grammar from a location identified by an URI.
 196      * This method also adds this grammar to the XMLGrammarPool
 197      *
 198      * @param type The type of the grammar to be constructed
 199      * @param uri The location of the grammar to be constructed.
 200      * <strong>The parser will not expand this URI or make it
 201      * available to the EntityResolver</strong>
 202      * @return The newly created <code>Grammar</code>.
 203      * @exception XNIException thrown on an error in grammar
 204      * construction
 205      * @exception IOException thrown if an error is encountered
 206      * in reading the file
 207      */
 208     public Grammar parseGrammar(String type, String uri)
 209                               throws XNIException, IOException {
 210         XMLInputSource source = new XMLInputSource(null, uri, null);
 211         return parseGrammar(type, source);
 212 
 213     }
 214 
 215     /**
 216      * Parse a grammar from a location identified by an
 217      * XMLInputSource.
 218      * This method also adds this grammar to the XMLGrammarPool
 219      *
 220      * @param type The type of the grammar to be constructed
 221      * @param is The XMLInputSource containing this grammar's
 222      * information
 223      * <strong>If a URI is included in the systemId field, the parser will not expand this URI or make it
 224      * available to the EntityResolver</strong>
 225      * @return The newly created <code>Grammar</code>.
 226      * @exception XNIException thrown on an error in grammar
 227      * construction
 228      * @exception IOException thrown if an error is encountered
 229      * in reading the file
 230      */
 231     public Grammar parseGrammar(String type, XMLInputSource
 232                 is) throws XNIException, IOException {
 233         if(type.equals(XMLGrammarDescription.XML_SCHEMA)) {
 234             // by default, make all XMLGrammarPoolImpl's schema grammars available to fSchemaHandler
 235             return parseXMLSchema(is);
 236         } else if(type.equals(XMLGrammarDescription.XML_DTD)) {
 237             return parseDTD(is);
 238         }
 239         // don't know this grammar...
 240         return null;
 241     } // parseGrammar(String, XMLInputSource):  Grammar
 242 
 243     //
 244     // Protected methods
 245     //
 246 
 247     // package-protected methods
 248 
 249     /* This method parses an XML Schema document.
 250      * It requires a GrammarBucket parameter so that DOMASBuilder can
 251      * extract the info it needs.
 252      * Therefore, bucket must not be null!
 253      */
 254     SchemaGrammar parseXMLSchema(XMLInputSource is)
 255                 throws IOException {
 256         XMLEntityResolver resolver = getEntityResolver();
 257         if(resolver != null) {
 258             fSchemaLoader.setEntityResolver(resolver);
 259         }
 260         if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
 261             fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
 262         }
 263         fSchemaLoader.setProperty(ERROR_REPORTER, fErrorReporter);
 264 
 265         String propPrefix = Constants.XERCES_PROPERTY_PREFIX;
 266         String propName = propPrefix + Constants.SCHEMA_LOCATION;
 267         fSchemaLoader.setProperty(propName, getProperty(propName));
 268         propName = propPrefix + Constants.SCHEMA_NONS_LOCATION;
 269         fSchemaLoader.setProperty(propName, getProperty(propName));
 270         propName = Constants.JAXP_PROPERTY_PREFIX+Constants.SCHEMA_SOURCE;
 271         fSchemaLoader.setProperty(propName, getProperty(propName));
 272         fSchemaLoader.setFeature(SCHEMA_FULL_CHECKING, getFeature(SCHEMA_FULL_CHECKING));
 273 
 274         // Should check whether the grammar with this namespace is already in
 275         // the grammar resolver. But since we don't know the target namespace
 276         // of the document here, we leave such check to XSDHandler
 277         SchemaGrammar grammar = (SchemaGrammar)fSchemaLoader.loadGrammar(is);
 278         // by default, hand it off to the grammar pool
 279         if (grammar != null) {
 280             fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA,
 281                                       new Grammar[]{grammar});
 282         }
 283 
 284         return grammar;
 285 
 286     } // parseXMLSchema(XMLInputSource) :  SchemaGrammar
 287 
 288     /* This method parses an external DTD entity.
 289      */
 290     DTDGrammar parseDTD(XMLInputSource is)
 291                 throws IOException {
 292         XMLEntityResolver resolver = getEntityResolver();
 293         if(resolver != null) {
 294             fDTDLoader.setEntityResolver(resolver);
 295         }
 296         fDTDLoader.setProperty(ERROR_REPORTER, fErrorReporter);
 297 
 298         // Should check whether the grammar with this namespace is already in
 299         // the grammar resolver. But since we don't know the target namespace
 300         // of the document here, we leave such check to the application...
 301         DTDGrammar grammar = (DTDGrammar)fDTDLoader.loadGrammar(is);
 302         // by default, hand it off to the grammar pool
 303         if (grammar != null) {
 304             fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_DTD,
 305                                       new Grammar[]{grammar});
 306         }
 307 
 308         return grammar;
 309 
 310     } // parseXMLDTD(XMLInputSource) :  DTDGrammar
 311 
 312 
 313 } // class XMLGrammarCachingConfiguration