blob: 797d44d14ec9c78843a89a2d17f13a827273e6b1 [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache
* XMLBeans", nor may "Apache" appear in their name, without prior
* written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 2000-2003 BEA Systems
* Inc., <http://www.bea.com/>. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
package org.apache.xmlbeans;
import java.net.URI;
import java.net.URISyntaxException;
import java.io.File;
/**
* Represents a message at a specific XML location.
* <p>
* The message can be an error, warning, or simple information, and
* it may optionally be associated with a specific location in
* an XML document. The class includes methods for extracting
* the location as a line number, XmlCursor, or XmlObject, as
* well as for obtaining and message and severity of the
* error.
*
* @see XmlOptions#setErrorListener
* @see XmlException
*/
public class XmlError implements java.io.Serializable
{
private static final long serialVersionUID = 1L;
private String _message;
private String _source;
private int _severity = SEVERITY_ERROR;
private int _line = -1;
private int _column = -1;
private int _offset = -1;
private transient XmlCursor _cursor;
/**
* Copy constructor.
* @param src The original XmlError to copy.
*/
public XmlError(XmlError src)
{
_message = src.getMessage();
_severity = src.getSeverity();
_source = src.getSourceName();
_line = src.getLine();
_column = src.getColumn();
_offset = src.getOffset();
_cursor = src.getCursorLocation();
}
/**
* The static factory methods should be used instead of
* this constructor.
*/
private XmlError(String message, int severity, String source, int line, int column, int offset, XmlCursor cursor)
{
_message = message;
_severity = severity;
_source = source;
_line = line;
_column = column;
_offset = offset;
_cursor = cursor;
}
/**
* Returns an XmlError for the given message, with no location and {@link #SEVERITY_ERROR}.
* @param message the error message
*/
public static XmlError forMessage(String message)
{
return forMessage(message, SEVERITY_ERROR);
}
/**
* Returns an XmlError for the given message, with no location and the given severity.
* @param message the error message
* @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
*/
public static XmlError forMessage(String message, int severity)
{
return forSource(message, severity, null);
}
/**
* Returns an XmlError for the given message, located in the given file and {@link #SEVERITY_ERROR}.
* @param message the error message
* @param sourceName the URL or other name for the file
*/
public static XmlError forSource(String message, String sourceName)
{
return forLocation(message, SEVERITY_ERROR, sourceName, -1, -1, -1);
}
/**
* Returns an XmlError for the given message, with the given severity, located in the given file.
* @param message the error message
* @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
* @param sourceName the URL or other name for the file
*/
public static XmlError forSource(String message, int severity, String sourceName)
{
return forLocation(message, severity, sourceName, -1, -1, -1);
}
/**
* Returns an XmlError for the given message, located at a specific point in the given file and {@link #SEVERITY_ERROR}.
* @param message the error message
* @param sourceName the URL or other name for the file
* @param line the 1-based line number, or -1 if not known
* @param column the 1-based column number, or -1 if not known
* @param offset the 0-base file character offset, or -1 if not known
*/
public static XmlError forLocation(String message, String sourceName, int line, int column, int offset)
{
return new XmlError(message, SEVERITY_ERROR, sourceName, line, column, offset, null);
}
/**
* Returns an XmlError for the given message, with the given severity, located at a specific point in the given file.
* @param message the error message
* @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
* @param sourceName the URL or other name for the file
* @param line the 1-based line number, or -1 if not known
* @param column the 1-based column number, or -1 if not known
* @param offset the 0-base file character offset, or -1 if not known
*/
public static XmlError forLocation(String message, int severity, String sourceName, int line, int column, int offset)
{
return new XmlError(message, severity, sourceName, line, column, offset, null);
}
/**
* Returns an XmlError for the given message, with the given severity, located at the given physcial location and XmlCursor.
* @param message the error message
* @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
* @param sourceName the URL or other name for the file
* @param line the 1-based line number, or -1 if not known
* @param column the 1-based column number, or -1 if not known
* @param offset the 0-base file character offset, or -1 if not known
* @param cursor the XmlCursor representing the location of the error
*/
public static XmlError forLocationAndCursor(String message, int severity, String sourceName, int line, int column, int offset, XmlCursor cursor)
{
return new XmlError(message, severity, sourceName, line, column, offset, cursor);
}
/**
* Returns an XmlError for the given message, located at the XmlObject, with {@link #SEVERITY_ERROR}.
* @param message the error message
* @param xobj the XmlObject representing the location of the error
*/
public static XmlError forObject(String message, XmlObject xobj)
{
return forObject(message, SEVERITY_ERROR, xobj);
}
/**
* Returns an XmlError for the given message, with the given severity, located at the XmlObject.
* @param message the error message
* @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
* @param xobj the XmlObject representing the location of the error
*/
public static XmlError forObject(String message, int severity, XmlObject xobj)
{
if (xobj == null)
return forMessage(message, severity);
XmlCursor cur = xobj.newCursor();
XmlError result = forCursor(message, severity, cur);
if (cur != null)
cur.dispose();
return result;
}
/**
* Returns an XmlError for the given message, located at the XmlCursor, with {@link #SEVERITY_ERROR}.
* @param message the error message
* @param cursor the XmlCursor representing the location of the error
*/
public static XmlError forCursor(String message, XmlCursor cursor)
{
return forCursor(message, SEVERITY_ERROR, cursor);
}
/**
* Returns an XmlError for the given message, with the given severity, located at the XmlCursor.
* @param message the error message
* @param severity the severity ({@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO})
* @param cursor the XmlCursor representing the location of the error
*/
public static XmlError forCursor(String message, int severity, XmlCursor cursor)
{
if (cursor == null)
return forMessage(message, severity);
// Hunt down the line/column/offset
int line = -1;
int column = -1;
int offset = -1;
String source = null;
source = cursor.documentProperties().getSourceName();
XmlCursor c = cursor.newCursor();
XmlLineNumber ln =
(XmlLineNumber) c.getBookmark( XmlLineNumber.class );
if (ln == null)
ln = (XmlLineNumber) c.toPrevBookmark( XmlLineNumber.class );
if (ln != null)
{
line = ln.getLine();
column = ln.getColumn();
offset = ln.getOffset();
}
c.dispose();
return new XmlError(message, severity, source, line, column, offset, cursor);
}
/**
* Tries to produce a nicely formatted filename from the given string.
*/
protected static String formattedFileName(String rawString, URI base)
{
if (rawString == null)
return null;
URI uri = null;
try
{
// if it looks like an absolute URI, treat it as such
uri = new URI(rawString);
// otherwise, treat it like a filename
if (!uri.isAbsolute())
uri = null;
}
catch (URISyntaxException e)
{
uri = null;
}
// looks like a filename; convert it to uri for relativization
if (uri == null)
uri = new File(rawString).toURI();
if (base != null)
uri = base.relativize(uri);
// filenames get their file: stripped off and their /'s turned into \'s (MSDOS)
if (uri.isAbsolute() ? uri.getScheme().compareToIgnoreCase("file") == 0 :
base != null && base.isAbsolute() && base.getScheme().compareToIgnoreCase("file") == 0)
{
try
{
return (new File(uri)).toString();
}
catch (Exception e) {};
}
return uri.toString();
}
/**
* An error. See {@link #getSeverity}.
*/
public static final int SEVERITY_ERROR = 0;
/**
* A warning. See {@link #getSeverity}.
*/
public static final int SEVERITY_WARNING = 1;
/**
* An informational message. See {@link #getSeverity}.
*/
public static final int SEVERITY_INFO = 2;
/**
* Returns the severity. Either {@link #SEVERITY_ERROR}, {@link #SEVERITY_WARNING}, or {@link #SEVERITY_INFO}.
*/
public int getSeverity ( ) { return _severity; }
/**
* Returns the error message without location information.
*/
public String getMessage ( ) { return _message; }
/**
* Returns the URL (or other name) of the file with the error, if available.
*/
public String getSourceName ( ) { return _source; }
/**
* Returns the line number of the error, if available, -1 if not.
*/
public int getLine ( ) { return _line; }
/**
* Returns the column number of the error, if available, -1 if not.
*/
public int getColumn ( ) { return _column; }
/**
* Returns the file character offset of the error, if available, -1 if not.
*/
public int getOffset ( ) { return _offset; }
/**
* Returns a location object of the given type. XmlCursor.class and
* XmlObject.class can be passed, for example. Null if not available.
*/
public Object getLocation ( Object type )
{
if (type == XmlCursor.class)
return _cursor;
if (type == XmlObject.class && _cursor != null)
return _cursor.getObject();
return null;
}
/**
* Returns a location of the error as an {@link XmlCursor}, null if
* not available.
*/
public XmlCursor getCursorLocation ( )
{
return (XmlCursor) getLocation( XmlCursor.class );
}
/**
* Returns a location of the error as an {@link XmlObject}, null if
* not available.
*/
public XmlObject getObjectLocation ( )
{
return (XmlObject) getLocation( XmlObject.class );
}
/**
* Produces a standard string for the error message, complete with
* filename and location offsets if available.
*/
public String toString ( )
{
return toString( null );
}
/**
* Produces a standard string with the error message. If a non-null
* URI is supplied, source names are relativized against the given
* URI.
*/
public String toString ( URI base )
{
// modified to carefully match the IDE's
// workshop.workspace.ant.AntLogger regex
// which also matches javac (davidbau)
StringBuffer sb = new StringBuffer();
String source = formattedFileName(getSourceName(), base);
if ( source != null )
{
sb.append( source );
int line = getLine();
if ( line < 0 )
line = 0;
sb.append( ':' );
sb.append( line );
sb.append( ':' );
if (getColumn() > 0)
{
sb.append( getColumn() );
sb.append( ':' );
}
sb.append(" ");
}
switch ( getSeverity() )
{
case SEVERITY_ERROR : sb.append( "error: " ); break;
case SEVERITY_WARNING : sb.append( "warning: " ); break;
case SEVERITY_INFO : break;
}
String msg = getMessage();
sb.append( msg == null ? "<Unspecified message>" : msg );
return sb.toString();
}
}