Staccatissimo-Restrictions is the core annotations library of the Staccatissimo project. It contains annotations that express restrictions, that can be used in the form of preconditions, postconditions or invariants over objects and messages, focused on documentation reuse.
Staccatissimo-Restrictions promotes reuse of common code properties expressed in the form of constraints, like NotNull, Positive, SideEffectFree or Unmodifiable. Just like executable code, such restrictions can be encapsulated - by defining the restrictions semantics once and only once - and composed - by creating new restrictions aggregating existing ones, thus making consistent and meaningful documentation easier to write.
With such principles in mind, the Restrictions API is composed by source and class level annotations that express constraints over code elements, and the Restriction meta-annotation, that express the semantics of such annotations, like for example, how both implementor and client code should behave on constraints violations, or how do they react to inheritance.
Although it is primary targeted for documenting such constraints, many of them may be processed in a non intrusive ways through Staccatissimo-Restrictions-Instrument.
In addition to that, the project encapsulates consistent use of words of must, must not, etc. with RFC2119 across Javadoc. This means that whenever such words are used within Staccatissimo-Restrictions and the rest of the projects, they must be interpreted following such guidelines.
Check restrictions are simple constraints that can annotate indistinctly return values, parameters and attributes, to express postconditions, preconditions and invariants, respectively. Not all them are targeted for being used in combination with any type, for instance, NotNull should not be used with primitive types, and NotEmpty should not be used with objects without methods or public attributes like length, size or isEmpty:
//Postcondition: the returned value is always > 0 @Positive protected int activeThreadsCount() { ... } //Invariant: the size of the string builder is always <= 256 characters @MaxSize(256) private StringBuilder builder; //Precondition: recipients collection must be not null and not empty public void sendTo(@NotEmpty Collection<User> recipients); //Precondition: Username must match be non null and match the given regexp public void setUserName(@Matches(USERNAME_REGEXP) username);
Instantiation restriction are constraints about the number of different instances a method returns. They express postconditions.
//Postcondition: this method always returns the same instance. //This does not mean it is a singleton - in fact Staccatissimo discourages them @Constant public static <T> Predicate<T> notNull() { ... }
Value Restrictions are constrains over types regarding their state changes and identity. They always express invariants over instances of such types:
//Invariant: state of Currency instances is always constant @Immutable public class Currency { ... } //Invariant: BoundingBox equals, hashcode and toString are implemented //based on the BoundingBox state instead of identity @Value public class BoundingBox { ... }
Processing directives are annotation that exists just for passing hints to automated annotations processors regarding when they should be processed:
//Directive for processors: restrictions in this constructor //should be ignored, as they are manually handled. @IgnoreRestrictions public CopyOnWriteMemoryArea(@NotEmpty MemoryArea original) { ... }