Home » xmlbeans-2.5.0-src » org.apache » xmlbeans » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package org.apache.xmlbeans;
   17   
   18   import java.net.URI;
   19   import java.net.URISyntaxException;
   20   import java.io.File;
   21   import java.util.ResourceBundle;
   22   import java.util.PropertyResourceBundle;
   23   import java.text.MessageFormat;
   24   import javax.xml.stream.Location;
   25   
   26   /**
   27    * Represents a message at a specific XML location.
   28    * <p>
   29    * The message can be an error, warning, or simple information, and
   30    * it may optionally be associated with a specific location in
   31    * an XML document.  The class includes methods for extracting
   32    * the location as a line number, XmlCursor, or XmlObject, as
   33    * well as for obtaining and message and severity of the
   34    * error.
   35    *
   36    * @see XmlOptions#setErrorListener
   37    * @see XmlException
   38    */
   39   public class XmlError implements java.io.Serializable
   40   {
   41       private static final long serialVersionUID = 1L;
   42   
   43       private static final ResourceBundle _bundle = PropertyResourceBundle.getBundle("org.apache.xmlbeans.message");
   44   
   45       private String _message;
   46       private String _code;
   47       private String _source;
   48       private int    _severity = SEVERITY_ERROR;
   49       private int    _line = -1;
   50       private int    _column = -1;
   51       private int    _offset = -1;
   52   
   53       private transient XmlCursor _cursor;
   54   
   55       /**
   56        * Copy constructor.
   57        * @param src The original XmlError to copy.
   58        */
   59       public XmlError(XmlError src)
   60       {
   61           _message = src.getMessage();
   62           _code = src.getErrorCode();
   63           _severity = src.getSeverity();
   64           _source = src.getSourceName();
   65           _line = src.getLine();
   66           _column = src.getColumn();
   67           _offset = src.getOffset();
   68           _cursor = src.getCursorLocation();
   69       }
   70   
   71       /**
   72        * The static factory methods should be used instead of
   73        * this constructor.
   74        */
   75       private XmlError(String message, String code, int severity,
   76                        String source, int line, int column, int offset, XmlCursor cursor)
   77       {
   78           _message = message;
   79           _code = code;
   80           _severity = severity;
   81           _source = source;
   82           _line = line;
   83           _column = column;
   84           _offset = offset;
   85           _cursor = cursor;
   86       }
   87   
   88       private XmlError(String code, Object[] args, int severity,
   89                        String source, int line, int column, int offset, XmlCursor cursor)
   90       {
   91           this(XmlError.formattedMessage(code, args), code, severity,  source, line, column, offset, cursor);
   92       }
   93   
   94       /**
   95        * The static factory methods should be used instead of
   96        * this constructor.
   97        */
   98       protected XmlError(String message, String code, int severity, XmlCursor cursor)
   99       {
  100           String source = null;
  101           int line = -1;
  102           int column = -1;
  103           int offset = -1;
  104   
  105           if (cursor != null)
  106           {
  107               // Hunt down the line/column/offset
  108               source = cursor.documentProperties().getSourceName();
  109   
  110               XmlCursor c = cursor.newCursor();
  111   
  112               XmlLineNumber ln =
  113                   (XmlLineNumber) c.getBookmark( XmlLineNumber.class );
  114   
  115               if (ln == null)
  116                   ln = (XmlLineNumber) c.toPrevBookmark( XmlLineNumber.class );
  117   
  118               if (ln != null)
  119               {
  120                   line = ln.getLine();
  121                   column = ln.getColumn();
  122                   offset = ln.getOffset();
  123               }
  124   
  125               c.dispose();
  126           }
  127   
  128           _message = message;
  129           _code = code;
  130           _severity = severity;
  131           _source = source;
  132           _line = line;
  133           _column = column;
  134           _offset = offset;
  135           _cursor = cursor;
  136       }
  137   
  138       protected XmlError(String code, Object[] args, int severity, XmlCursor cursor)
  139       {
  140           this(XmlError.formattedMessage(code, args), code, severity, cursor);
  141       }
  142   
  143       /**
  144        * The static factory methods should be used instead of
  145        * this constructor.
  146        */
  147       protected XmlError(String message, String code, int severity, Location loc)
  148       {
  149           String source = null;
  150           int line = -1;
  151           int column = -1;
  152   
  153           if (loc != null)
  154           {
  155               line = loc.getLineNumber();
  156               column = loc.getColumnNumber();
  157               source = loc.getPublicId();
  158               if (source==null)
  159                   source = loc.getSystemId();
  160           }
  161   
  162           _message = message;
  163           _code = code;
  164           _severity = severity;
  165           _source = source;
  166           _line = line;
  167           _column = column;
  168       }
  169   
  170       protected XmlError(String code, Object[] args, int severity, Location loc)
  171       {
  172           this(XmlError.formattedMessage(code, args), code, severity, loc);
  173       }
  174   
  175       /**
  176        * Returns an XmlError for the given message, with no location and {@link #SEVERITY_ERROR}.
  177        * @param message the error message
  178        */
  179       public static XmlError forMessage(String message)
  180       {
  181           return forMessage(message, SEVERITY_ERROR);
  182       }
  183   
  184       /**
  185        * Returns an XmlError for the given message, with no location and the given severity.
  186        * @param message the error message
  187        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  188        */
  189       public static XmlError forMessage(String message, int severity)
  190       {
  191           return forSource(message, severity, null);
  192       }
  193   
  194       /**
  195        * Returns an XmlError for the given message, with no location and the given severity.
  196        * @param code the error code
  197        * @param args the arguments to use in formatting the error message
  198        */
  199       public static XmlError forMessage(String code, Object[] args)
  200       {
  201           return forSource(code, args, SEVERITY_ERROR, null);
  202       }
  203   
  204       /**
  205        * Returns an XmlError for the given message, with no location and the given severity.
  206        * @param code the error code
  207        * @param args the arguments to use in formatting the error message
  208        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  209        */
  210       public static XmlError forMessage(String code, Object[] args, int severity)
  211       {
  212           return forSource(code, args, severity, null);
  213       }
  214   
  215       /**
  216        * Returns an XmlError for the given message, located in the given file and {@link #SEVERITY_ERROR}.
  217        * @param message the error message
  218        * @param sourceName the URL or other name for the file
  219        */
  220       public static XmlError forSource(String message, String sourceName)
  221       {
  222           return forLocation(message, SEVERITY_ERROR, sourceName, -1, -1, -1);
  223       }
  224   
  225       /**
  226        * Returns an XmlError for the given message, with the given severity, located in the given file.
  227        * @param message the error message
  228        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  229        * @param sourceName the URL or other name for the file
  230        */
  231       public static XmlError forSource(String message, int severity, String sourceName)
  232       {
  233           return forLocation(message, severity, sourceName, -1, -1, -1);
  234       }
  235   
  236       /**
  237        * Returns an XmlError for the given message, with the given severity, located in the given file.
  238        * @param code the error code
  239        * @param args the arguments to use in formatting the error message
  240        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  241        * @param sourceName the URL or other name for the file
  242        */
  243       public static XmlError forSource(String code, Object[] args, int severity, String sourceName)
  244       {
  245           return forLocation(code, args, severity, sourceName, -1, -1, -1);
  246       }
  247   
  248       /**
  249        * Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}.
  250        * @param message the error message
  251        * @param sourceName the URL or other name for the file
  252        * @param location the location from an xml stream
  253        */
  254       public static XmlError forLocation(String message, String sourceName, Location location)
  255       {
  256           return new XmlError(message, (String)null, SEVERITY_ERROR, sourceName,
  257               location.getLineNumber(), location.getColumnNumber(), -1, null);
  258       }
  259   
  260       /**
  261        * Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}.
  262        * @param message the error message
  263        * @param sourceName the URL or other name for the file
  264        * @param line the 1-based line number, or -1 if not known
  265        * @param column the 1-based column number, or -1 if not known
  266        * @param offset the 0-base file character offset, or -1 if not known
  267        */
  268       public static XmlError forLocation(String message, String sourceName, int line, int column, int offset)
  269       {
  270           return new XmlError(message, (String)null, SEVERITY_ERROR, sourceName, line, column, offset, null);
  271       }
  272   
  273       /**
  274        * Returns an XmlError for the given message, with the given severity, located at a specific point in the given file.
  275        * @param code the error code
  276        * @param args the arguments to use in formatting the error message
  277        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  278        * @param sourceName the URL or other name for the file
  279        * @param line the 1-based line number, or -1 if not known
  280        * @param column the 1-based column number, or -1 if not known
  281        * @param offset the 0-base file character offset, or -1 if not known
  282        */
  283       public static XmlError forLocation(String code, Object[] args, int severity, String sourceName, int line, int column, int offset)
  284       {
  285           return new XmlError(code, args, severity, sourceName, line, column, offset, null);
  286       }
  287   
  288       /**
  289        * Returns an XmlError for the given message, with the given severity, located at a specific point in the given file.
  290        * @param message the error message
  291        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  292        * @param sourceName the URL or other name for the file
  293        * @param line the 1-based line number, or -1 if not known
  294        * @param column the 1-based column number, or -1 if not known
  295        * @param offset the 0-base file character offset, or -1 if not known
  296        */
  297       public static XmlError forLocation(String message, int severity, String sourceName, int line, int column, int offset)
  298       {
  299           return new XmlError(message, (String)null, severity, sourceName, line, column, offset, null);
  300       }
  301   
  302       /**
  303        * Returns an XmlError for the given message, with the given severity, located at the given physcial location and XmlCursor.
  304        * @param message the error message
  305        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  306        * @param sourceName the URL or other name for the file
  307        * @param line the 1-based line number, or -1 if not known
  308        * @param column the 1-based column number, or -1 if not known
  309        * @param offset the 0-base file character offset, or -1 if not known
  310        * @param cursor the XmlCursor representing the location of the error
  311        */
  312       public static XmlError forLocationAndCursor(String message, int severity, String sourceName, int line, int column, int offset, XmlCursor cursor)
  313       {
  314           return new XmlError(message, (String)null, severity, sourceName, line, column, offset, cursor);
  315       }
  316   
  317       /**
  318        * Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}.
  319        * @param message the error message
  320        * @param xobj the XmlObject representing the location of the error
  321        */
  322       public static XmlError forObject(String message, XmlObject xobj)
  323       {
  324           return forObject(message, SEVERITY_ERROR, xobj);
  325       }
  326   
  327       /**
  328        * Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}.
  329        * @param code the error code
  330        * @param args the arguments to use in formatting the error message
  331        * @param xobj the XmlObject representing the location of the error
  332        */
  333       public static XmlError forObject(String code, Object[] args, XmlObject xobj)
  334       {
  335           return forObject(code, args, SEVERITY_ERROR, xobj);
  336       }
  337   
  338       /**
  339        * Returns an XmlError for the given message, with the given severity, located at the XmlObject.
  340        * @param message the error message
  341        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  342        * @param xobj the XmlObject representing the location of the error
  343        */
  344       public static XmlError forObject(String message, int severity, XmlObject xobj)
  345       {
  346           if (xobj == null)
  347               return forMessage(message, severity);
  348   
  349           XmlCursor cur = xobj.newCursor();
  350           XmlError result = forCursor(message, severity, cur);
  351           return result;
  352       }
  353   
  354       /**
  355        * Returns an XmlError for the given message, with the given severity, located at the XmlObject.
  356        * @param code the error code
  357        * @param args the arguments to use in formatting the error message
  358        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  359        * @param xobj the XmlObject representing the location of the error
  360        */
  361       public static XmlError forObject(String code, Object[] args, int severity, XmlObject xobj)
  362       {
  363           if (xobj == null)
  364               return forMessage(code, args, severity);
  365   
  366           XmlCursor cur = xobj.newCursor();
  367           XmlError result = forCursor(code, args, severity, cur);
  368           return result;
  369       }
  370   
  371       /**
  372        * Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}.
  373        * @param message the error message
  374        * @param cursor the XmlCursor representing the location of the error
  375        */
  376       public static XmlError forCursor(String message, XmlCursor cursor)
  377       {
  378           return forCursor(message, SEVERITY_ERROR, cursor);
  379       }
  380   
  381       /**
  382        * Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}.
  383        * @param code the error code
  384        * @param args the arguments to use in formatting the error message
  385        * @param cursor the XmlCursor representing the location of the error
  386        */
  387       public static XmlError forCursor(String code, Object[] args, XmlCursor cursor)
  388       {
  389           return forCursor(code, args, SEVERITY_ERROR, cursor);
  390       }
  391   
  392       /**
  393        * Returns an XmlError for the given message, with the given severity, located at the XmlCursor.
  394        * @param message the error message
  395        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  396        * @param cursor the XmlCursor representing the location of the error
  397        */
  398       public static XmlError forCursor(String message, int severity, XmlCursor cursor)
  399       {
  400           return new XmlError(message, (String)null, severity, cursor);
  401       }
  402   
  403       /**
  404        * Returns an XmlError for the given message, with the given severity, located at the XmlCursor.
  405        * @param code the error code
  406        * @param args the arguments to use in formatting the error message
  407        * @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
  408        * @param cursor the XmlCursor representing the location of the error
  409        */
  410       public static XmlError forCursor(String code, Object[] args, int severity, XmlCursor cursor)
  411       {
  412           return new XmlError(code, args, severity, cursor);
  413       }
  414   
  415       /**
  416        * Tries to produce a nicely formatted filename from the given string.
  417        */
  418       protected static String formattedFileName(String rawString, URI base)
  419       {
  420           if (rawString == null)
  421               return null;
  422   
  423           URI uri = null;
  424   
  425           try
  426           {
  427               // if it looks like an absolute URI, treat it as such
  428               uri = new URI(rawString);
  429   
  430               // otherwise, treat it like a filename
  431               if (!uri.isAbsolute())
  432                   uri = null;
  433           }
  434           catch (URISyntaxException e)
  435           {
  436               uri = null;
  437           }
  438   
  439           // looks like a filename; convert it to uri for relativization
  440           if (uri == null)
  441               uri = new File(rawString).toURI();
  442   
  443           if (base != null)
  444               uri = base.relativize(uri);
  445   
  446           // filenames get their file: stripped off and their /'s turned into \'s (MSDOS)
  447           if (uri.isAbsolute() ? uri.getScheme().compareToIgnoreCase("file") == 0 :
  448               base != null && base.isAbsolute() && base.getScheme().compareToIgnoreCase("file") == 0)
  449           {
  450               try
  451               {
  452                   return (new File(uri)).toString();
  453               }
  454               catch (Exception e) {};
  455           }
  456   
  457           return uri.toString();
  458       }
  459   
  460       /**
  461        * Tries to format a message using the error code.
  462        */
  463       public static String formattedMessage(String code, Object[] args)
  464       {
  465           if (code == null)
  466               return null;
  467   
  468           String message;
  469   
  470           try
  471           {
  472               message = MessageFormat.format(_bundle.getString(code), args);
  473           }
  474           catch (java.util.MissingResourceException e)
  475           {
  476               return MessageFormat.format(_bundle.getString("message.missing.resource"),
  477                   new Object[] { e.getMessage() });
  478           }
  479           catch (IllegalArgumentException e)
  480           {
  481               return MessageFormat.format(_bundle.getString("message.pattern.invalid"),
  482                   new Object[] { e.getMessage() });
  483           }
  484   
  485           return message;
  486       }
  487   
  488       /**
  489        * An error. See {@link #getSeverity}.
  490        */
  491       public static final int SEVERITY_ERROR   = 0;
  492       /**
  493        * A warning. See {@link #getSeverity}.
  494        */
  495       public static final int SEVERITY_WARNING = 1;
  496       /**
  497        * An informational message. See {@link #getSeverity}.
  498        */
  499       public static final int SEVERITY_INFO    = 2;
  500   
  501       /**
  502        * Returns the severity.  Either {@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}.
  503        */
  504       public int    getSeverity   ( ) { return _severity; }
  505   
  506       /**
  507        * Returns the error message without location information.
  508        */
  509       public String getMessage    ( ) { return _message; }
  510   
  511       /**
  512        * Returns the error code or null. See {@link XmlErrorCodes}.
  513        */
  514       public String getErrorCode  ( ) { return _code; }
  515   
  516       /**
  517        * Returns the URL (or other name) of the file with the error, if available.
  518        */
  519       public String getSourceName ( ) { return _source; }
  520   
  521       /**
  522        * Returns the line number of the error, if available, -1 if not.
  523        */
  524       public int    getLine       ( ) { return _line; }
  525   
  526       /**
  527        * Returns the column number of the error, if available, -1 if not.
  528        */
  529       public int    getColumn     ( ) { return _column; }
  530   
  531       /**
  532        * Returns the file character offset of the error, if available, -1 if not.
  533        */
  534       public int    getOffset     ( ) { return _offset; }
  535   
  536       /**
  537        * Returns a location object of the given type.  XmlCursor.class and
  538        * XmlObject.class can be passed, for example.  Null if not available.
  539        */
  540       public Object getLocation ( Object type )
  541       {
  542           if (type == XmlCursor.class)
  543               return _cursor;
  544           if (type == XmlObject.class && _cursor != null)
  545               return _cursor.getObject();
  546           return null;
  547       }
  548   
  549       /**
  550        * Returns a location of the error as an {@link XmlCursor}, null if
  551        * not available.
  552        */
  553       public XmlCursor getCursorLocation ( )
  554       {
  555           return (XmlCursor) getLocation( XmlCursor.class );
  556       }
  557   
  558       /**
  559        * Returns a location of the error as an {@link XmlObject}, null if
  560        * not available.
  561        */
  562       public XmlObject getObjectLocation ( )
  563       {
  564           return (XmlObject) getLocation( XmlObject.class );
  565       }
  566   
  567       /**
  568        * Produces a standard string for the error message, complete with
  569        * filename and location offsets if available.
  570        */
  571       public String toString ( )
  572       {
  573           return toString( null );
  574       }
  575   
  576       /**
  577        * Produces a standard string with the error message.  If a non-null
  578        * URI is supplied, source names are relativized against the given
  579        * URI.
  580        */
  581       public String toString ( URI base )
  582       {
  583           // modified to carefully match the IDE's
  584           // workshop.workspace.ant.AntLogger regex
  585           // which also matches javac (davidbau)
  586   
  587           StringBuffer sb = new StringBuffer();
  588   
  589           String source = formattedFileName(getSourceName(), base);
  590   
  591           if ( source != null )
  592           {
  593               sb.append( source );
  594               int line = getLine();
  595               if ( line < 0 )
  596                   line = 0;
  597   
  598               sb.append( ':' );
  599               sb.append( line );
  600               sb.append( ':' );
  601               if (getColumn() > 0)
  602               {
  603                   sb.append( getColumn() );
  604                   sb.append( ':' );
  605               }
  606               sb.append(" ");
  607           }
  608   
  609           switch ( getSeverity() )
  610           {
  611               case SEVERITY_ERROR   : sb.append( "error: " );   break;
  612               case SEVERITY_WARNING : sb.append( "warning: " ); break;
  613               case SEVERITY_INFO : break;
  614           }
  615   
  616           if (getErrorCode() != null)
  617           {
  618               sb.append(getErrorCode()).append(": ");
  619           }
  620   
  621           String msg = getMessage();
  622   
  623           sb.append( msg == null ? "<Unspecified message>" : msg );
  624   
  625           return sb.toString();
  626       }
  627   
  628       public static String severityAsString(int severity)
  629       {
  630           switch (severity) {
  631               case SEVERITY_ERROR:
  632                   return ("error");
  633               case SEVERITY_WARNING:
  634                   return ("warning");
  635               case SEVERITY_INFO:
  636                   return "info";
  637               default:
  638                   throw new IllegalArgumentException("unknown severity");
  639           }
  640       }
  641   }

Home » xmlbeans-2.5.0-src » org.apache » xmlbeans » [javadoc | source]