How to use

Configuration of Exception Context

You install your context via the service provider facility.

To use your custom implementation of the ExceptionContext specify the name of your class in

META-INF/services/de.smartics.exceptions.ExceptionContext

Specifying Error and Exception Codes

To specify your codes you should implement enumerations that implement the interface Code or any one of its sub interfaces. Currently only codes implemented by enumerations are supported (although only the reporting feature will not work if you use plain Java classes - so implementing codes by enumerations is highly recommended).

This is what it looks like:

public enum ParseExceptionCode implements NumberCode
{
  /**
   * The generic parsing error.
   */
  GENERIC(2000),

  /**
   * Parsing an OGNL path expression failed.
   */
  OGNL(2000, 1),

  /**
   * Parsing the value for a parent attribute failed because the <code>=</code>-sign
   * is missing. The <code>=</code>-sign separates the attribute name from
   * the index information.
   */
  MISSING_PARENT_PROPERTY_SEPARATOR(2000, 2),

  /**
   * Parsing the value for a parent attribute failed because the attribute in
   * front of the <code>=</code>-sign is missing.
   */
  MISSING_PARENT_PROPERTY_ATTRIBUTE(2000, 3),

  /**
   * Parsing the value for a parent attribute failed because the index after the
   * <code>=</code>-sign is missing.
   */
  MISSING_PARENT_PROPERTY_INDEX(2000, 4);

  /**
   * The code information.
   */
  private final NumberCodeInfo info;

  /**
   * Default constructor.
   *
   * @param majorNumber the major part of the error code.
   * @param minorNumber the minor part of the error code.
   */
  private ParseExceptionCode(
      final Integer majorNumber, final Integer minorNumber)
  {
    this.info = new NumberCodeInfo(readComponentId(), majorNumber, minorNumber);
  }

  private static String readComponentId()
  {
    return Constant.COMPONENT_ID;
  }

  @Override
  public String getCode()
  {
    return info.getCode();
  }

  @Override
  public String getComponentId()
  {
    return info.getComponentId();
  }

  @Override
  public Integer getMajorNumber()
  {
    return info.getMajorNumber();
  }

  @Override
  public Integer getMinorNumber()
  {
    return info.getMinorNumber();
  }

  @Override
  public String toString()
  {
    return info.toString();
  }
}
        

You group codes semantically by the use of enumerations. Normally a certain exception type uses all codes of an enumeration.

public class ParseException extends
    AbstractLocalizedRuntimeException
{
  private static final long serialVersionUID = 1L;

  /**
   * The input that cannot be parsed.
   *
   * @serial
   */
  @MessageParam("0")
  protected final String input;

  /**
   * The index within the input string where the parsing error occurred.
   *
   * @serial
   */
  @MessageParam("1")
  protected final int index;

  /**
   * Constructor.
   *
   * @param code the error or exception code of the exception.
   * @param bundleBaseName the fully qualified name of the bundle to use.
   * @param input the input that cannot be parsed.
   * @param index the index within the input string where the parsing error
   *        occurred.
   */
  public ParseException(final ParseExceptionCode code,
      final String bundleBaseName, final String input, final int index)
  {
    this(null, code, bundleBaseName, input, index);
  }

  /**
   * Constructor.
   *
   * @param code the error or exception code of the exception.
   * @param input the input that cannot be parsed.
   * @param index the index within the input string where the parsing error
   *        occurred.
   */
  public ParseException(final ParseExceptionCode code, final String input,
      final int index)
  {
    this(code, null, input, index);
  }

  /**
   * Constructor.
   *
   * @param cause the cause (which is saved for later retrieval by the
   *        {@link #getCause()} method). (A <tt>null</tt> value is permitted,
   *        and indicates that the cause is nonexistent or unknown.)
   * @param code the error or exception code of the exception.
   * @param bundleBaseName the fully qualified name of the bundle to use.
   * @param input the input that cannot be parsed.
   * @param index the index within the input string where the parsing error
   *        occurred.
   */
  protected ParseException(final Throwable cause,
      final ParseExceptionCode code, final String bundleBaseName,
      final String input, final int index)
  {
    super(cause, code, bundleBaseName != null ? bundleBaseName
        : "de.smartics.exceptions.i18n.message.ParseExceptionBundle");
    this.input = input;
    this.index = index;
  }

  /**
   * Constructor.
   *
   * @param cause the cause (which is saved for later retrieval by the
   *        {@link #getCause()} method). (A <tt>null</tt> value is permitted,
   *        and indicates that the cause is nonexistent or unknown.)
   * @param code the error or exception code of the exception.
   * @param input the input that cannot be parsed.
   * @param index the index within the input string where the parsing error
   *        occurred.
   */
  protected ParseException(final Throwable cause,
      final ParseExceptionCode code, final String input, final int index)
  {
    this(cause, code, null, input, index);
  }

  public String getInput()
  {
    return input;
  }

  public int getIndex()
  {
    return index;
  }
}
        

What you can see in this example is the use of the ParseExceptionCode in the constructors.

Note: Please do not bother with the MessageParam annotation and the resource bundle stuff. They use the I18N library that is provided in an add-on project. If you are interested in this support please refer to smart-exceptions-i18n.