Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions PRDs/20251229-javadoc-coverage/PRD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# PRD: Full Javadoc Coverage

## Document Information

| Field | Value |
|-------|-------|
| **PRD ID** | JAVADOC-COVERAGE |
| **Status** | Approved |
| **Author** | David Waltermire |
| **Created** | 2025-12-29 |
| **Last Updated** | 2025-12-29 |

---

## 1. Overview

### 1.1 Problem Statement

The metaschema-java project has a goal of full Javadoc coverage for all public and protected members. Currently, there are significant gaps in Javadoc coverage across multiple modules, resulting in:
- 337 `MissingJavadocMethod` Checkstyle warnings
- ~185 Javadoc "no comment" warnings

These gaps affect code maintainability, API usability, and generated documentation quality.

### 1.2 Goals

1. Achieve 100% Javadoc coverage on all public/protected methods
2. Add package-level documentation where missing
3. Ensure all Javadoc follows the project's style guide
4. Eliminate all Javadoc-related Checkstyle warnings

### 1.3 Non-Goals

- Modifying generated code (binding classes, ANTLR output)
- Adding Javadoc to test classes
- Adding Javadoc to private methods
- Changing code behavior or structure

### 1.4 Success Metrics

| Metric | Current | Target |
|--------|---------|--------|
| MissingJavadocMethod warnings | 337 | 0 |
| Javadoc "no comment" warnings | ~185 | 0 |
| Build with `-PCI -Prelease` | Pass with warnings | Pass without Javadoc warnings |

---

## 2. Issue Breakdown by Module

### 2.1 schemagen Module

| Metric | Count |
|--------|-------|
| Files affected | 36 |
| MissingJavadocMethod | 154 |

This module is the most isolated and a good starting point.

### 2.2 databind Module

| Metric | Count |
|--------|-------|
| Files affected | 64 |
| MissingJavadocMethod | 176 |
| Package-info warnings | ~99 |

This is the largest module with the most issues.

### 2.3 metaschema-maven-plugin Module

| Metric | Count |
|--------|-------|
| MissingJavadocMethod | 7 |

Small number of issues, can be combined with another PR.

---

## 3. Implementation Strategy

### 3.1 PR Approach

Given the volume of changes (100+ files), split into module-focused PRs:

| PR | Module | Est. Files | Est. Methods |
|----|--------|-----------|--------------|
| 1 | schemagen | 36 | 154 |
| 2 | databind | 64 | 176 |
| 3 | maven-plugin | ~5 | 7 |

### 3.2 Javadoc Guidelines

Follow the project's [Javadoc style guide](../../docs/javadoc-style-guide.md):

1. **First sentence**: Brief summary ending with period
2. **@param tags**: Document all parameters
3. **@return tags**: Document non-void return values
4. **@throws tags**: Document declared exceptions
5. **@Override methods**: Use `{@inheritDoc}` only if adding implementation notes

### 3.3 Package Documentation

For missing package-info.java documentation:
- Add brief package description
- Document package purpose and key classes
- Cross-reference related packages

---

## 4. Verification

After each PR, run:

```bash
mvn clean install -PCI -Prelease
```

Verify:
- All tests pass
- No new Javadoc warnings for the module
- Checkstyle passes without Javadoc violations

---

## 5. Exclusions

The following are excluded from Javadoc requirements:

1. **Generated code**: `target/generated-sources/`, binding classes
2. **Test classes**: All files in `src/test/`
3. **@Override methods**: Unless adding implementation notes
4. **Private members**: Only public/protected require Javadoc
180 changes: 180 additions & 0 deletions PRDs/20251229-javadoc-coverage/implementation-plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Implementation Plan: Full Javadoc Coverage

This document details the implementation for achieving full Javadoc coverage.

---

## Prerequisites

- Build the project: `mvn install -DskipTests`
- Review [Javadoc style guide](../../docs/javadoc-style-guide.md)

---

## Phase 1: schemagen Module

### PR 1: Add Javadoc to schemagen Module

| Attribute | Value |
|-----------|-------|
| **Files Changed** | ~35 |
| **Methods to Document** | 154 |
| **Risk Level** | Low |
| **Dependencies** | None |
| **Target Branch** | develop |
| **Status** | Pending |

#### Files to Modify

| Package | Files |
|---------|-------|
| `schemagen` | `AbstractGenerationState.java`, `FlagInstanceFilter.java`, `IGenerationState.java`, `IInlineStrategy.java`, `ISchemaGenerator.java`, `ModuleIndex.java`, `SchemaGenerationException.java` |
| `schemagen.datatype` | `AbstractDatatypeManager.java`, `IDatatypeManager.java` |
| `schemagen.json` | `JsonSchemaGenerator.java` |
| `schemagen.json.impl` | `IJsonGenerationState.java`, `JsonGenerationState.java`, `JsonSchemaHelper.java` |
| `schemagen.xml` | `XmlDatatypeManager.java`, `XmlSchemaGenerator.java` |
| `schemagen.xml.impl` | `AbstractDatatypeContent.java`, `AbstractXmlDatatypeProvider.java`, `AbstractXmlMarkupDatatypeProvider.java`, `CompositeDatatypeProvider.java`, `DocumentationGenerator.java`, `IDatatypeProvider.java`, `JDom2DatatypeContent.java`, `JDom2XmlSchemaLoader.java`, `XmlGenerationState.java`, `XmlProseCompositDatatypeProvider.java` |
| `schemagen.xml.impl.schematype` | `AbstractXmlComplexType.java`, `AbstractXmlSimpleType.java`, `AbstractXmlType.java`, `IXmlComplexType.java`, `IXmlSimpleType.java`, `XmlComplexTypeAssemblyDefinition.java`, `XmlComplexTypeFieldDefinition.java`, `XmlSimpleTypeDataTypeReference.java`, `XmlSimpleTypeDataTypeRestriction.java`, `XmlSimpleTypeUnion.java` |

#### Implementation Approach

1. Start with interfaces (define the API contract)
2. Move to abstract classes (document template methods)
3. Finish with concrete implementations

#### Acceptance Criteria

- [ ] All public/protected methods have Javadoc
- [ ] All @param tags document parameters
- [ ] All @return tags document return values
- [ ] All @throws tags document exceptions
- [ ] Checkstyle passes: `mvn -pl schemagen checkstyle:check`
- [ ] Build succeeds: `mvn -pl schemagen install`
- [ ] Full build passes: `mvn clean install -PCI -Prelease`

---

## Phase 2: databind Module

### PR 2: Add Javadoc to databind Module (Part 1 - Core)

| Attribute | Value |
|-----------|-------|
| **Files Changed** | ~30 |
| **Risk Level** | Low |
| **Dependencies** | None |
| **Target Branch** | develop |
| **Status** | Pending |

#### Packages to Address

- `databind` (root package)
- `databind.codegen`
- `databind.codegen.impl`
- `databind.codegen.typeinfo`
- `databind.codegen.typeinfo.def`

### PR 3: Add Javadoc to databind Module (Part 2 - IO)

| Attribute | Value |
|-----------|-------|
| **Files Changed** | ~15 |
| **Risk Level** | Low |
| **Dependencies** | PR 2 |
| **Target Branch** | develop |
| **Status** | Pending |

#### Packages to Address

- `databind.io`
- `databind.io.json`
- `databind.io.xml`

### PR 4: Add Javadoc to databind Module (Part 3 - Model)

| Attribute | Value |
|-----------|-------|
| **Files Changed** | ~20 |
| **Risk Level** | Low |
| **Dependencies** | PR 3 |
| **Target Branch** | develop |
| **Status** | Pending |

#### Packages to Address

- `databind.model`
- `databind.model.annotations`
- `databind.model.impl`
- `databind.model.info`
- `databind.model.metaschema`
- `databind.model.metaschema.impl`
- `databind.metapath.function`

---

## Phase 3: Maven Plugin

### PR 5: Add Javadoc to metaschema-maven-plugin

| Attribute | Value |
|-----------|-------|
| **Files Changed** | ~5 |
| **Methods to Document** | 7 |
| **Risk Level** | Low |
| **Dependencies** | None |
| **Target Branch** | develop |
| **Status** | Pending |

#### Acceptance Criteria

- [ ] All public/protected methods have Javadoc
- [ ] Checkstyle passes: `mvn -pl metaschema-maven-plugin checkstyle:check`
- [ ] Build succeeds: `mvn clean install -PCI -Prelease`

---

## Verification Commands

```bash
# Check specific module
mvn -pl <module> checkstyle:check

# Run Javadoc to find issues
mvn -pl <module> javadoc:javadoc

# Full CI build
mvn clean install -PCI -Prelease

# Count remaining warnings
grep -c "MissingJavadocMethod" build-output.txt
```

---

## PR Summary Table

| PR | Module | Est. Files | Status |
|----|--------|-----------|--------|
| 1 | schemagen | 35 | Pending |
| 2 | databind (core) | 30 | Pending |
| 3 | databind (io) | 15 | Pending |
| 4 | databind (model) | 20 | Pending |
| 5 | maven-plugin | 5 | Pending |

**Total PRs**: 5
**Total Files Changed**: ~105

---

## Notes

### Generated Code Exclusions

The following are generated and excluded from Javadoc requirements:
- `databind/.../config/binding/` - Bootstrap bindings
- `databind/.../model/metaschema/binding/` - Bootstrap bindings
- `target/generated-sources/` - All generated code

### Package-info Files

Some package-info.java files have "no comment" warnings but are in generated packages. Only source package-info files need documentation.
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,59 @@

import edu.umd.cs.findbugs.annotations.NonNull;

/**
* A module loader strategy that applies post-processors to loaded modules.
* <p>
* This strategy wraps another {@link IBindingContext.IModuleLoaderStrategy} and
* ensures that configured {@link IModuleLoader.IModulePostProcessor} instances
* are invoked on each module before it is registered. Post-processing is
* applied only once per module, even if the module is referenced multiple
* times.
*
* @since 2.0.0
*/
public class PostProcessingModuleLoaderStrategy
implements IBindingContext.IModuleLoaderStrategy {
@NonNull
private final List<IModuleLoader.IModulePostProcessor> modulePostProcessors;
// private final Set<IModule> resolvedModules = new HashSet<>();
// private final Lock resolvedModulesLock = new ReentrantLock();
private final IBindingContext.IModuleLoaderStrategy delegate;
private final Set<IModule> postProcessedModules = new HashSet<>();
private final Lock postProcessedModulesLock = new ReentrantLock();

/**
* Construct a new post-processing module loader strategy using the default
* delegate strategy.
*
* @param modulePostProcessors
* the post-processors to apply to loaded modules
*/
public PostProcessingModuleLoaderStrategy(
@NonNull List<IModuleLoader.IModulePostProcessor> modulePostProcessors) {
this(modulePostProcessors, new SimpleModuleLoaderStrategy());
}

/**
* Construct a new post-processing module loader strategy with a custom
* delegate.
*
* @param modulePostProcessors
* the post-processors to apply to loaded modules
* @param delegate
* the delegate strategy to use for actual module loading and
* registration
*/
public PostProcessingModuleLoaderStrategy(
@NonNull List<IModuleLoader.IModulePostProcessor> modulePostProcessors,
@NonNull IBindingContext.IModuleLoaderStrategy delegate) {
this.modulePostProcessors = CollectionUtil.unmodifiableList(new ArrayList<>(modulePostProcessors));
this.delegate = delegate;
}

/**
* Get the configured module post-processors.
*
* @return an unmodifiable list of post-processors
*/
@NonNull
protected List<IModuleLoader.IModulePostProcessor> getModulePostProcessors() {
return modulePostProcessors;
Expand Down Expand Up @@ -109,21 +140,6 @@ public Collection<IBindingMatcher> getBindingMatchers() {
public IBoundDefinitionModelComplex getBoundDefinitionForClass(
Class<? extends IBoundObject> clazz,
IBindingContext bindingContext) {

//
// resolvedModulesLock.lock();
// try {
// if (!resolvedModules.contains(module)) {
// // add first, to avoid loops
// resolvedModules.add(module);
// for (IModuleLoader.IModulePostProcessor postProcessor :
// getModulePostProcessors()) {
// postProcessor.processModule(module);
// }
// }
// } finally {
// resolvedModulesLock.unlock();
// }
return delegate.getBoundDefinitionForClass(clazz, bindingContext);
}
}
Loading
Loading