Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » impl » [javadoc | source]
    1   /*
    2    * reserved comment block
    3    * DO NOT REMOVE OR ALTER!
    4    */
    5   /*
    6    * The Apache Software License, Version 1.1
    7    *
    8    *
    9    * Copyright (c) 1999-2004 The Apache Software Foundation.
   10    * All rights reserved.
   11    *
   12    * Redistribution and use in source and binary forms, with or without
   13    * modification, are permitted provided that the following conditions
   14    * are met:
   15    *
   16    * 1. Redistributions of source code must retain the above copyright
   17    *    notice, this list of conditions and the following disclaimer.
   18    *
   19    * 2. Redistributions in binary form must reproduce the above copyright
   20    *    notice, this list of conditions and the following disclaimer in
   21    *    the documentation and/or other materials provided with the
   22    *    distribution.
   23    *
   24    * 3. The end-user documentation included with the redistribution,
   25    *    if any, must include the following acknowledgment:
   26    *       "This product includes software developed by the
   27    *        Apache Software Foundation (http://www.apache.org/)."
   28    *    Alternately, this acknowledgment may appear in the software itself,
   29    *    if and wherever such third-party acknowledgments normally appear.
   30    *
   31    * 4. The names "Xerces" and "Apache Software Foundation" must
   32    *    not be used to endorse or promote products derived from this
   33    *    software without prior written permission. For written
   34    *    permission, please contact apache@apache.org.
   35    *
   36    * 5. Products derived from this software may not be called "Apache",
   37    *    nor may "Apache" appear in their name, without prior written
   38    *    permission of the Apache Software Foundation.
   39    *
   40    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   41    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   42    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   43    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   44    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   45    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   46    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   47    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   48    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   49    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   50    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   51    * SUCH DAMAGE.
   52    * ====================================================================
   53    *
   54    * This software consists of voluntary contributions made by many
   55    * individuals on behalf of the Apache Software Foundation and was
   56    * originally based on software copyright (c) 1999, International
   57    * Business Machines, Inc., http://www.apache.org.  For more
   58    * information on the Apache Software Foundation, please see
   59    * <http://www.apache.org/>.
   60    */
   61   
   62   package com.sun.org.apache.xerces.internal.impl;
   63   
   64   import java.util.Hashtable;
   65   import java.util.Locale;
   66   
   67   import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
   68   import com.sun.org.apache.xerces.internal.util.ErrorHandlerProxy;
   69   import com.sun.org.apache.xerces.internal.util.MessageFormatter;
   70   import com.sun.org.apache.xerces.internal.xni.XMLLocator;
   71   import com.sun.org.apache.xerces.internal.xni.XNIException;
   72   import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
   73   import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
   74   import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
   75   import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
   76   import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
   77   import org.xml.sax.ErrorHandler;
   78   
   79   /**
   80    * This class is a common element of all parser configurations and is
   81    * used to report errors that occur. This component can be queried by
   82    * parser components from the component manager using the following
   83    * property ID:
   84    * <pre>
   85    *   http://apache.org/xml/properties/internal/error-reporter
   86    * </pre>
   87    * <p>
   88    * Errors are separated into domains that categorize a class of errors.
   89    * In a parser configuration, the parser would register a
   90    * <code>MessageFormatter</code> for each domain that is capable of
   91    * localizing error messages and formatting them based on information
   92    * about the error. Any parser component can invent new error domains
   93    * and register additional message formatters to localize messages in
   94    * those domains.
   95    * <p>
   96    * This component requires the following features and properties from the
   97    * component manager that uses it:
   98    * <ul>
   99    *  <li>http://apache.org/xml/properties/internal/error-handler</li>
  100    * </ul>
  101    * <p>
  102    * This component can use the following features and properties but they
  103    * are not required:
  104    * <ul>
  105    *  <li>http://apache.org/xml/features/continue-after-fatal-error</li>
  106    * </ul>
  107    *
  108    * @xerces.internal
  109    *
  110    * @see MessageFormatter
  111    *
  112    * @author Eric Ye, IBM
  113    * @author Andy Clark, IBM
  114    *
  115    */
  116   public class XMLErrorReporter
  117       implements XMLComponent {
  118   
  119       //
  120       // Constants
  121       //
  122   
  123       // severity
  124   
  125       /**
  126        * Severity: warning. Warnings represent informational messages only
  127        * that should not be considered serious enough to stop parsing or
  128        * indicate an error in the document's validity.
  129        */
  130       public static final short SEVERITY_WARNING = 0;
  131   
  132       /**
  133        * Severity: error. Common causes of errors are document structure and/or
  134        * content that that does not conform to the grammar rules specified for
  135        * the document. These are typically validation errors.
  136        */
  137       public static final short SEVERITY_ERROR = 1;
  138   
  139       /**
  140        * Severity: fatal error. Fatal errors are errors in the syntax of the
  141        * XML document or invalid byte sequences for a given encoding. The
  142        * XML 1.0 Specification mandates that errors of this type are not
  143        * recoverable.
  144        * <p>
  145        * <strong>Note:</strong> The parser does have a "continue after fatal
  146        * error" feature but it should be used with extreme caution and care.
  147        */
  148       public static final short SEVERITY_FATAL_ERROR = 2;
  149   
  150       // feature identifiers
  151   
  152       /** Feature identifier: continue after fatal error. */
  153       protected static final String CONTINUE_AFTER_FATAL_ERROR =
  154           Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
  155   
  156       // property identifiers
  157   
  158       /** Property identifier: error handler. */
  159       protected static final String ERROR_HANDLER =
  160           Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
  161   
  162       // recognized features and properties
  163   
  164       /** Recognized features. */
  165       private static final String[] RECOGNIZED_FEATURES = {
  166           CONTINUE_AFTER_FATAL_ERROR,
  167       };
  168   
  169       /** Feature defaults. */
  170       private static final Boolean[] FEATURE_DEFAULTS = {
  171           null,
  172       };
  173   
  174       /** Recognized properties. */
  175       private static final String[] RECOGNIZED_PROPERTIES = {
  176           ERROR_HANDLER,
  177       };
  178   
  179       /** Property defaults. */
  180       private static final Object[] PROPERTY_DEFAULTS = {
  181           null,
  182       };
  183   
  184       //
  185       // Data
  186       //
  187   
  188       /** The locale to be used to format error messages. */
  189       protected Locale fLocale;
  190   
  191       /** Mapping of Message formatters for domains. */
  192       protected Hashtable fMessageFormatters;
  193   
  194       /** Error handler. */
  195       protected XMLErrorHandler fErrorHandler;
  196   
  197       /** Document locator. */
  198       protected XMLLocator fLocator;
  199   
  200       /** Continue after fatal error feature. */
  201       protected boolean fContinueAfterFatalError;
  202   
  203       /**
  204        * Default error handler. This error handler is only used in the
  205        * absence of a registered error handler so that errors are not
  206        * "swallowed" silently. This is one of the most common "problems"
  207        * reported by users of the parser.
  208        */
  209       protected XMLErrorHandler fDefaultErrorHandler;
  210   
  211       //
  212       // Constructors
  213       //
  214   
  215       /** Constructs an error reporter with a locator. */
  216       public XMLErrorReporter() {
  217   
  218           // REVISIT: [Q] Should the locator be passed to the reportError
  219           //              method? Otherwise, there is no way for a parser
  220           //              component to store information about where an
  221           //              error occurred so as to report it later.
  222           //
  223           //              An example would be to record the location of
  224           //              IDREFs so that, at the end of the document, if
  225           //              there is no associated ID declared, the error
  226           //              could report the location information of the
  227           //              reference. -Ac
  228           //
  229           // NOTE: I added another reportError method that allows the
  230           //       caller to specify the location of the error being
  231           //       reported. -Ac
  232   
  233           fMessageFormatters = new Hashtable();
  234   
  235       } // <init>()
  236   
  237       //
  238       // Methods
  239       //
  240   
  241       /**
  242        * Sets the current locale.
  243        *
  244        * @param locale The new locale.
  245        */
  246       public void setLocale(Locale locale) {
  247           fLocale = locale;
  248       } // setLocale(Locale)
  249   
  250       /**
  251        * Gets the current locale.
  252        *
  253        * @return the current Locale
  254        */
  255       public Locale getLocale() {
  256           return fLocale ;
  257       } // getLocale():  Locale
  258   
  259       /**
  260        * Sets the document locator.
  261        *
  262        * @param locator The locator.
  263        */
  264       public void setDocumentLocator(XMLLocator locator) {
  265           fLocator = locator;
  266       } // setDocumentLocator(XMLLocator)
  267   
  268       /**
  269        * Registers a message formatter for the specified domain.
  270        * <p>
  271        * <strong>Note:</strong> Registering a message formatter for a domain
  272        * when there is already a formatter registered will cause the previous
  273        * formatter to be lost. This method replaces any previously registered
  274        * message formatter for the specified domain.
  275        *
  276        * @param domain
  277        * @param messageFormatter
  278        */
  279       public void putMessageFormatter(String domain,
  280                                       MessageFormatter messageFormatter) {
  281           fMessageFormatters.put(domain, messageFormatter);
  282       } // putMessageFormatter(String,MessageFormatter)
  283   
  284       /**
  285        * Returns the message formatter associated with the specified domain,
  286        * or null if no message formatter is registered for that domain.
  287        *
  288        * @param domain The domain of the message formatter.
  289        */
  290       public MessageFormatter getMessageFormatter(String domain) {
  291           return (MessageFormatter)fMessageFormatters.get(domain);
  292       } // getMessageFormatter(String):MessageFormatter
  293   
  294       /**
  295        * Removes the message formatter for the specified domain and
  296        * returns the removed message formatter.
  297        *
  298        * @param domain The domain of the message formatter.
  299        */
  300       public MessageFormatter removeMessageFormatter(String domain) {
  301           return (MessageFormatter) fMessageFormatters.remove(domain);
  302       } // removeMessageFormatter(String):MessageFormatter
  303   
  304       /**
  305        * Reports an error. The error message passed to the error handler
  306        * is formatted for the locale by the message formatter installed
  307        * for the specified error domain.
  308        *
  309        * @param domain    The error domain.
  310        * @param key       The key of the error message.
  311        * @param arguments The replacement arguments for the error message,
  312        *                  if needed.
  313        * @param severity  The severity of the error.
  314        *
  315        * @see #SEVERITY_WARNING
  316        * @see #SEVERITY_ERROR
  317        * @see #SEVERITY_FATAL_ERROR
  318        */
  319       public void reportError(String domain, String key, Object[] arguments,
  320                               short severity) throws XNIException {
  321           reportError(fLocator, domain, key, arguments, severity);
  322       } // reportError(String,String,Object[],short)
  323   
  324       /**
  325        * Reports an error at a specific location.
  326        *
  327        * @param location  The error location.
  328        * @param domain    The error domain.
  329        * @param key       The key of the error message.
  330        * @param arguments The replacement arguments for the error message,
  331        *                  if needed.
  332        * @param severity  The severity of the error.
  333        *
  334        * @see #SEVERITY_WARNING
  335        * @see #SEVERITY_ERROR
  336        * @see #SEVERITY_FATAL_ERROR
  337        */
  338       public void reportError(XMLLocator location,
  339                               String domain, String key, Object[] arguments,
  340                               short severity) throws XNIException {
  341   
  342           // REVISIT: [Q] Should we do anything about invalid severity
  343           //              parameter? -Ac
  344   
  345           // format error message and create parse exception
  346           MessageFormatter messageFormatter = getMessageFormatter(domain);
  347           String message;
  348           if (messageFormatter != null) {
  349               message = messageFormatter.formatMessage(fLocale, key, arguments);
  350           }
  351           else {
  352               StringBuffer str = new StringBuffer();
  353               str.append(domain);
  354               str.append('#');
  355               str.append(key);
  356               int argCount = arguments != null ? arguments.length : 0;
  357               if (argCount > 0) {
  358                   str.append('?');
  359                   for (int i = 0; i < argCount; i++) {
  360                       str.append(arguments[i]);
  361                       if (i < argCount -1) {
  362                           str.append('&');
  363                       }
  364                   }
  365               }
  366               message = str.toString();
  367           }
  368           XMLParseException parseException =
  369               new XMLParseException(location, message);
  370   
  371           // get error handler
  372           XMLErrorHandler errorHandler = fErrorHandler;
  373           if (errorHandler == null) {
  374               if (fDefaultErrorHandler == null) {
  375                   fDefaultErrorHandler = new DefaultErrorHandler();
  376               }
  377               errorHandler = fDefaultErrorHandler;
  378           }
  379   
  380           // call error handler
  381           switch (severity) {
  382               case SEVERITY_WARNING: {
  383                   errorHandler.warning(domain, key, parseException);
  384                   break;
  385               }
  386               case SEVERITY_ERROR: {
  387                   errorHandler.error(domain, key, parseException);
  388                   break;
  389               }
  390               case SEVERITY_FATAL_ERROR: {
  391                   errorHandler.fatalError(domain, key, parseException);
  392                   if (!fContinueAfterFatalError) {
  393                       throw parseException;
  394                   }
  395                   break;
  396               }
  397           }
  398   
  399       } // reportError(XMLLocator,String,String,Object[],short)
  400   
  401       //
  402       // XMLComponent methods
  403       //
  404   
  405       /**
  406        * Resets the component. The component can query the component manager
  407        * about any features and properties that affect the operation of the
  408        * component.
  409        *
  410        * @param componentManager The component manager.
  411        *
  412        * @throws SAXException Thrown by component on initialization error.
  413        *                      For example, if a feature or property is
  414        *                      required for the operation of the component, the
  415        *                      component manager may throw a
  416        *                      SAXNotRecognizedException or a
  417        *                      SAXNotSupportedException.
  418        */
  419       public void reset(XMLComponentManager componentManager)
  420           throws XNIException {
  421   
  422           // features
  423           try {
  424               fContinueAfterFatalError = componentManager.getFeature(CONTINUE_AFTER_FATAL_ERROR);
  425           }
  426           catch (XNIException e) {
  427               fContinueAfterFatalError = false;
  428           }
  429   
  430           // properties
  431           fErrorHandler = (XMLErrorHandler)componentManager.getProperty(ERROR_HANDLER);
  432   
  433       } // reset(XMLComponentManager)
  434   
  435       /**
  436        * Returns a list of feature identifiers that are recognized by
  437        * this component. This method may return null if no features
  438        * are recognized by this component.
  439        */
  440       public String[] getRecognizedFeatures() {
  441           return (String[])(RECOGNIZED_FEATURES.clone());
  442       } // getRecognizedFeatures():String[]
  443   
  444       /**
  445        * Sets the state of a feature. This method is called by the component
  446        * manager any time after reset when a feature changes state.
  447        * <p>
  448        * <strong>Note:</strong> Components should silently ignore features
  449        * that do not affect the operation of the component.
  450        *
  451        * @param featureId The feature identifier.
  452        * @param state     The state of the feature.
  453        *
  454        * @throws SAXNotRecognizedException The component should not throw
  455        *                                   this exception.
  456        * @throws SAXNotSupportedException The component should not throw
  457        *                                  this exception.
  458        */
  459       public void setFeature(String featureId, boolean state)
  460           throws XMLConfigurationException {
  461   
  462           //
  463           // Xerces features
  464           //
  465   
  466           if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
  467               final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
  468   
  469               //
  470               // http://apache.org/xml/features/continue-after-fatal-error
  471               //   Allows the parser to continue after a fatal error.
  472               //   Normally, a fatal error would stop the parse.
  473               //
  474               if (suffixLength == Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE.length() &&
  475                   featureId.endsWith(Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE)) {
  476                   fContinueAfterFatalError = state;
  477               }
  478           }
  479   
  480       } // setFeature(String,boolean)
  481   
  482       // return state of given feature or false if unsupported.
  483       public boolean getFeature(String featureId)
  484           throws XMLConfigurationException {
  485   
  486           //
  487           // Xerces features
  488           //
  489   
  490           if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
  491                   final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
  492   
  493               //
  494               // http://apache.org/xml/features/continue-after-fatal-error
  495               //   Allows the parser to continue after a fatal error.
  496               //   Normally, a fatal error would stop the parse.
  497               //
  498               if (suffixLength == Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE.length() &&
  499                   featureId.endsWith(Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE)) {
  500                   return fContinueAfterFatalError ;
  501               }
  502           }
  503           return false;
  504   
  505       } // setFeature(String,boolean)
  506   
  507       /**
  508        * Returns a list of property identifiers that are recognized by
  509        * this component. This method may return null if no properties
  510        * are recognized by this component.
  511        */
  512       public String[] getRecognizedProperties() {
  513           return (String[])(RECOGNIZED_PROPERTIES.clone());
  514       } // getRecognizedProperties():String[]
  515   
  516       /**
  517        * Sets the value of a property. This method is called by the component
  518        * manager any time after reset when a property changes value.
  519        * <p>
  520        * <strong>Note:</strong> Components should silently ignore properties
  521        * that do not affect the operation of the component.
  522        *
  523        * @param propertyId The property identifier.
  524        * @param value      The value of the property.
  525        *
  526        * @throws SAXNotRecognizedException The component should not throw
  527        *                                   this exception.
  528        * @throws SAXNotSupportedException The component should not throw
  529        *                                  this exception.
  530        */
  531       public void setProperty(String propertyId, Object value)
  532           throws XMLConfigurationException {
  533   
  534           //
  535           // Xerces properties
  536           //
  537   
  538           if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
  539               final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
  540   
  541               if (suffixLength == Constants.ERROR_HANDLER_PROPERTY.length() &&
  542                   propertyId.endsWith(Constants.ERROR_HANDLER_PROPERTY)) {
  543                   fErrorHandler = (XMLErrorHandler)value;
  544               }
  545           }
  546   
  547       } // setProperty(String,Object)
  548   
  549       /**
  550        * Returns the default state for a feature, or null if this
  551        * component does not want to report a default value for this
  552        * feature.
  553        *
  554        * @param featureId The feature identifier.
  555        *
  556        * @since Xerces 2.2.0
  557        */
  558       public Boolean getFeatureDefault(String featureId) {
  559           for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
  560               if (RECOGNIZED_FEATURES[i].equals(featureId)) {
  561                   return FEATURE_DEFAULTS[i];
  562               }
  563           }
  564           return null;
  565       } // getFeatureDefault(String):Boolean
  566   
  567       /**
  568        * Returns the default state for a property, or null if this
  569        * component does not want to report a default value for this
  570        * property.
  571        *
  572        * @param propertyId The property identifier.
  573        *
  574        * @since Xerces 2.2.0
  575        */
  576       public Object getPropertyDefault(String propertyId) {
  577           for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
  578               if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
  579                   return PROPERTY_DEFAULTS[i];
  580               }
  581           }
  582           return null;
  583       } // getPropertyDefault(String):Object
  584   
  585       /**
  586        * Get the internal XMLErrrorHandler.
  587        */
  588       public XMLErrorHandler getErrorHandler() {
  589           return fErrorHandler;
  590       }
  591   
  592   
  593       private ErrorHandler fSaxProxy = null;
  594   
  595       /**
  596        * Gets the internal XMLErrorHandler
  597        * as SAX ErrorHandler.
  598        */
  599       public ErrorHandler getSAXErrorHandler() {
  600           if( fSaxProxy==null )
  601               fSaxProxy = new ErrorHandlerProxy() {
  602                   protected XMLErrorHandler getErrorHandler() {
  603                       return fErrorHandler;
  604                   }
  605               };
  606           return fSaxProxy;
  607       }
  608   } // class XMLErrorReporter

Save This Page
Home » openjdk-7 » com.sun.org.apache.xerces.internal » impl » [javadoc | source]