Customization Options for Libraries

Library developers may want control over the layout of their exception codes. This is currently the only customization option for libraries provided by smartics-exceptions.

This configuration is not implemented by customizing the ExceptionContext, since these options are - as we have explained in Customize Apps - to be used by application developers only. The option shown here can be used for libraries and applications alike.

The Code Interface

The design of the exception codes is defined by the implementation of the de.smartics.exceptions.core.Code interface.

If you want to change this, simply provide your own implementation and use this in your code enumerations. Since there is hardly ever any need to change implementations, you may not want to add a factory pattern here to make changing the layout more comfortable. Usually, if one decides to alter the layout of the codes, the code implementation is simply changed. Also note that the number code identifies the message template in the messages bundle.

NumberCodeInfo

It is easier to extend de.smartics.exceptions.code.NumberCodeInfo. In this case there are only two methods to consider:

  1. String getCode() - defines the formatting of the number code.
  2. String getDisplayId() - defines the formatting of the number code and component identifier.

The NumberCodeInfo has three parts of information of a code, as defined in de.smartics.exceptions.code.NumberCode. These are:

Part Description
Component ID The (optional) identifier of the component, e.g. Security. This is a name for a logical component. We recommend to use it. There may be problems if usability constraints dictates that there is no unlocalized information.
Major Number The mandatory major code. This makes it easier to define code ranges and separate them to individual enumeration types. Each type has its own major number assigned (e.g. 1000).
Minor Number The (optional) minor code. This is the running number within the major code (e.g. 23).

The layouts provided by smartics-exceptions render the input

Part Value
Component ID Security
Major Number 1000
Minor Number 23

like this:

Implementation Rendering
de.smartics.exceptions.code.NumberCodeInfo (default) Security-1023
de.smartics.exceptions.code.TwoNumberCodeInfo Security-1000-23
de.smartics.exceptions.code.RunningZerosNumberCodeInfo Security-001023

A Sample Implementation

Here is a sample implementation that extends NumberCodeInfo:

public class RunningZeros7DigitsNumberCodeInfo extends NumberCodeInfo {
  private static final long serialVersionUID = 1L;

  public RunningZeros7DigitsNumberCodeInfo(final String componentId,
      final Integer majorNumber, final Integer minorNumber)
    throws NullPointerException {
    super(componentId, majorNumber, minorNumber);
  }

  @Override
  public String getCode() {
    int number = majorNumber.intValue();
    if (minorNumber != null) {
      number += minorNumber.intValue();
    }

    return String.format("%07d", number);
  }
}

This implementation simply provides codes with 7 digits (instead of 6 as does the RunningZerosNumberCodeInfo), padding with zeros from the left side.

If you would like to customize not only the number code, but the whole representation of the code including the component, then also override

public class RunningZeros7DigitsNumberCodeInfo extends NumberCodeInfo {
  ... SNIP ...

  @Override
  public String getDisplayId() {
    final String code = getCode();

    final StringBuilder buffer = new StringBuilder();

    if (componentId != null) {
      buffer.append(componentId.toUpperCase(Locale.ENGLISH)).append('(');
    }
    buffer.append(code);
    if(componentId != null) {
      buffer.append(')');
    }

    return buffer.toString();
  }

  ... below is unchanged ...
}

The code layout would be:

SECURITY(0001023)

Using a customized Code

Simply use the customized implementation in your code enumerations.

public enum ServiceCode implements NumberCode {
  // define your codes here ...
  MY_X(1);

  private final NumberCode info;

  private ServiceCode(final Integer minorNumber) {
    this.info = new RunningZeros7DigitsNumberCodeInfo("SERVICE", 1000, minorNumber);
  }

  @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 getDisplayId() {
    return info.getDisplayId();
  }

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

Codes and Reports

Note that reports may sort codes on particular information provided by the code implementation. That is: not every report implementation may render any codes. So check the selected report with your code to see, if the result suits your requirements.

For rendering reports with Maven please refer to the exceptioncodes-maven-plugin