Stagean annotations

Stagean is a Java library of annotation types that let you document development stage of your project on class or method level. Hand-edited Stagean annotations complement automated coverage and analysis tools to create overall picture of project's state and progress.

Example

In the example below, @NoDocs, @DraftTests, and @StubCode are development stage annotations. They inform developers and users about development stages reached by this particular class and method.

@NoDocs
@DraftTests("async scenarios are untested")
public class MyClass {
    @StubCode
    public void doSomething() {
        throw new UnsupportedOperationException();
    }
    // ...
}

Download

Get Stagean from Maven Central:

Tool
<dependency>
    <groupId>com.machinezoo.stagean</groupId>
    <artifactId>stagean</artifactId>
    <version>1.0.2</version>
</dependency>

Or clone sources from GitHub or Bitbucket. Don't forget to configure your build for Java 8+. Sources and binaries are distributed under Apache License 2.0.

Available annotations

All annotations currently defined by Stagean are arranged in the table below. Stagean recognizes four different development stages that can be assigned to four different content types.

No* Stub* Draft* Complete*
*Api @StubApi @DraftApi @CompleteApi
*Code @StubCode @DraftCode @CompleteCode
*Tests @NoTests @StubTests @DraftTests @CompleteTests
*Docs @NoDocs @StubDocs @DraftDocs @CompleteDocs

Annotations NoApi and NoCode do not exist, because they don't have any meaning. Use @StubApi and @StubCode instead. Applications and libraries are free to define their own annotations, but the annotations defined by Stagean are expected to have the best support in scanning and reporting tools.

How to track project progress

Common approaches that existed before Stagean:

All of the above solutions still apply. Stagean just adds another tool to your toolbox:

Development stages

Stagean recognizes four development stages:

@Draft* stage is deliberately broad to minimize ambiguity and to avoid wasteful tinkering with annotations. Some ambiguity might arise at its extremes with @Stub* near 0% and with @Complete* near 100%. Criteria for @Stub* and @Complete* are somewhat project-specific. If in doubt, use @Draft* annotation.

// BAD: Abusing stub for working code.
@StubCode("switch to front crawl, improve speed") // DON'T DO THIS
void swim() {
    // ...
}

// GOOD: Any non-placeholder implementation, even simple one, is a draft.
@DraftCode("switch to front crawl, improve speed")
void swim() {
    // ...
}

// GOOD: Appropriate use of stub annotation for do-nothing implementation.
@StubCode
void swim() {
    logger.warn("Swimming is not implemented yet.");
}

@Complete* stage is the default when no annotation is present. You can use it anyway for clarity, but the advantage of omitting it is that Stagean annotations will add overhead only in unfinished code.

// BAD: If there are TODOs, it is not done yet.
@CompleteCode("just improve performance")
class MyClass {
    // ...
}

// OKAY: Redundant but technically correct.
@CompleteCode
class MyClass {
    // ...
}

// BEST: No need to annotate finished code.
class MyClass {
    // ...
}

Target content

Stagean currently supports flagging of these kinds of content:

Comments

Annotations other than @Draft* are unambiguous. They don't need further comment. @Draft* stage, on the other hand, is very broad. The annotation needs a summary of what needs to be done in order to reach @Complete* stage. Short comment will fit in annotation's parameter. Longer comment can be left above the annotation.

// BAD: No information about what needs to be improved.
@DraftCode
class MyClass {
    // ...
}

// GOOD: Annotation's parameter lists remaining issues.
@DraftCode("no exception handling, O(N*N) complexity")
class MyClass {
    // ...
}

// GOOD: Parameter summarizes issues and surrounding comments add details.
/*
 * Required performance improvements:
 * - set operations: O(NlogN)
 * - search methods: O(logN)
 * - editing methods: O(logN)
 */
@DraftCode("suboptimal performance")
class MyClass {
    // ...
}

Cascading

Annotations cascade to nested language constructs. For example, package annotations also apply to all types in the package and type annotations also apply to all members of the type.

@DraftCode("no logging or metrics")
class MyClass {
    @StubCode
    void doSomething() {
        throw new UnsupportedOperationException();
    }
    void orOther() {
        // ...
    }
    // ...
}

In the above example, all methods inherit @DraftCode annotation from MyClass except method doSomething() that has overriding local annotation @StubCode.

Cascading of @StubDocs and @StubTests is an exception. If there are any nested constructs, @Stub* cascades to them as @NoDocs and @NoTests respectively.

Contribute

Stagean was developed by Robert Važan. If you have any suggestions, including requests for documentation, report an issue (GitHub, Bitbucket) or submit a pull request (GitHub, Bitbucket). You can reach the author via email .