Save This Page
Home » commons-digester-1.8-src » org.apache.commons » digester » parser » [javadoc | source]
    1   /* $Id: XercesParser.java 471661 2006-11-06 08:09:25Z skitching $
    2    *
    3    * Licensed to the Apache Software Foundation (ASF) under one or more
    4    * contributor license agreements.  See the NOTICE file distributed with
    5    * this work for additional information regarding copyright ownership.
    6    * The ASF licenses this file to You under the Apache License, Version 2.0
    7    * (the "License"); you may not use this file except in compliance with
    8    * the License.  You may obtain a copy of the License at
    9    * 
   10    *      http://www.apache.org/licenses/LICENSE-2.0
   11    * 
   12    * Unless required by applicable law or agreed to in writing, software
   13    * distributed under the License is distributed on an "AS IS" BASIS,
   14    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15    * See the License for the specific language governing permissions and
   16    * limitations under the License.
   17    */ 
   18   
   19   
   20   package org.apache.commons.digester.parser;
   21   
   22   import java.lang.reflect.Method;
   23   import java.util.Properties;
   24   
   25   import javax.xml.parsers.ParserConfigurationException;
   26   import javax.xml.parsers.SAXParser;
   27   import javax.xml.parsers.SAXParserFactory;
   28   
   29   import org.apache.commons.logging.Log;
   30   import org.apache.commons.logging.LogFactory;
   31   import org.xml.sax.SAXException;
   32   import org.xml.sax.SAXNotRecognizedException;
   33   import org.xml.sax.SAXNotSupportedException;
   34   
   35   /**
   36    * Create a <code>SAXParser</code> based on the underlying Xerces version.
   37    * Currently, Xerces 2.3 and up doesn't implement schema validation the same way
   38    * 2.1 was. In other to support schema validation in a portable way between 
   39    * parser, some features/properties need to be set.
   40    *
   41    * @since 1.6
   42    */
   43   
   44   public class XercesParser{
   45   
   46       /**
   47        * The Log to which all SAX event related logging calls will be made.
   48        */
   49       protected static Log log =
   50           LogFactory.getLog("org.apache.commons.digester.Digester.sax");
   51   
   52   
   53       /**
   54        * The JAXP 1.2 property required to set up the schema location.
   55        */
   56       private static final String JAXP_SCHEMA_SOURCE =
   57           "http://java.sun.com/xml/jaxp/properties/schemaSource";
   58   
   59   
   60       /**
   61        * The JAXP 1.2 property to set up the schemaLanguage used.
   62        */
   63       protected static String JAXP_SCHEMA_LANGUAGE =
   64           "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
   65   
   66   
   67       /**
   68        * Xerces dynamic validation property
   69        */
   70       protected static String XERCES_DYNAMIC = 
   71           "http://apache.org/xml/features/validation/dynamic";
   72   
   73   
   74       /**
   75        * Xerces schema validation property
   76        */
   77       protected static String XERCES_SCHEMA =
   78           "http://apache.org/xml/features/validation/schema";
   79   
   80   
   81       /**
   82        * A <code>float</code> representing the underlying Xerces version
   83        */
   84       protected static float version;
   85   
   86   
   87       /**
   88        * The current Xerces version.
   89        */
   90       protected static String versionNumber = null;
   91   
   92   
   93       /**
   94        * Return the current Xerces version.
   95        * @return the current Xerces version.
   96        */
   97       private static String getXercesVersion() {
   98           // If for some reason we can't get the version, set it to 1.0.
   99           String versionNumber = "1.0";
  100           try{
  101               // Use reflection to avoid a build dependency with Xerces.
  102               Class versionClass = 
  103                               Class.forName("org.apache.xerces.impl.Version");
  104               // Will return Xerces-J 2.x.0
  105               Method method = 
  106                   versionClass.getMethod("getVersion", (Class[])null); 
  107               String version = (String)method.invoke(null, (Object[])null);
  108               versionNumber = version.substring( "Xerces-J".length() , 
  109                                                  version.lastIndexOf(".") ); 
  110           } catch (Exception ex){
  111               // Do nothing.
  112           }
  113           return versionNumber;
  114       }
  115   
  116   
  117       /**
  118        * Create a <code>SAXParser</code> based on the underlying
  119        * <code>Xerces</code> version.
  120        * @param properties parser specific properties/features
  121        * @return an XML Schema/DTD enabled <code>SAXParser</code>
  122        */
  123       public static SAXParser newSAXParser(Properties properties) 
  124               throws ParserConfigurationException, 
  125                      SAXException,
  126                      SAXNotSupportedException {
  127   
  128           SAXParserFactory factory =  
  129                           (SAXParserFactory)properties.get("SAXParserFactory");
  130   
  131           if (versionNumber == null){
  132               versionNumber = getXercesVersion();
  133               version = new Float( versionNumber ).floatValue();
  134           }
  135   
  136           // Note: 2.2 is completely broken (with XML Schema). 
  137           if (version > 2.1) {
  138   
  139               configureXerces(factory);
  140               return factory.newSAXParser();
  141           } else {
  142               SAXParser parser = factory.newSAXParser();
  143               configureOldXerces(parser,properties);
  144               return parser;
  145           }
  146       }
  147   
  148   
  149       /**
  150        * Configure schema validation as recommended by the JAXP 1.2 spec.
  151        * The <code>properties</code> object may contains information about
  152        * the schema local and language. 
  153        * @param properties parser optional info
  154        */
  155       private static void configureOldXerces(SAXParser parser, 
  156                                              Properties properties) 
  157               throws ParserConfigurationException, 
  158                      SAXNotSupportedException {
  159   
  160           String schemaLocation = (String)properties.get("schemaLocation");
  161           String schemaLanguage = (String)properties.get("schemaLanguage");
  162   
  163           try{
  164               if (schemaLocation != null) {
  165                   parser.setProperty(JAXP_SCHEMA_LANGUAGE, schemaLanguage);
  166                   parser.setProperty(JAXP_SCHEMA_SOURCE, schemaLocation);
  167               }
  168           } catch (SAXNotRecognizedException e){
  169               log.info(parser.getClass().getName() + ": " 
  170                                           + e.getMessage() + " not supported."); 
  171           }
  172   
  173       }
  174   
  175   
  176       /**
  177        * Configure schema validation as recommended by the Xerces spec. 
  178        * Both DTD and Schema validation will be enabled simultaneously.
  179        * <p>
  180        * NOTE: This method is broken. It is supposed to set up validation
  181        * against the schema specified in property "schemaLocation", but
  182        * it doesn't.
  183        *
  184        * @param factory SAXParserFactory to be configured
  185        */
  186       private static void configureXerces(SAXParserFactory factory)
  187               throws ParserConfigurationException, 
  188                      SAXNotRecognizedException, 
  189                      SAXNotSupportedException {
  190   
  191           factory.setFeature(XERCES_DYNAMIC, true);
  192           factory.setFeature(XERCES_SCHEMA, true);
  193   
  194       }
  195   }

Save This Page
Home » commons-digester-1.8-src » org.apache.commons » digester » parser » [javadoc | source]