A documentation generation tool for Groovy code, part of the Apache Groovy programming language suite
—
The output management system provides a flexible framework for writing generated documentation to various targets including file systems, in-memory storage, and custom implementations. This abstraction allows the documentation generation process to work with different output destinations.
Abstract interface that defines the contract for all output implementations.
public interface OutputTool {
void makeOutputArea(String filename) // Create output directory/area
void writeToOutput(String fileName, String text, String charset) // Write content to output
}The OutputTool interface provides the foundation for all output operations:
makeOutputArea() - Ensures the output location exists and is ready for writingwriteToOutput() - Writes text content to a specific file with specified character encodingConcrete implementation for writing documentation to the file system.
public class FileOutputTool implements OutputTool {
public FileOutputTool() // Default constructor
public void makeOutputArea(String filename) // Create directory structure
public void writeToOutput(String fileName, String text, String charset) // Write file to disk
}The FileOutputTool handles:
In-memory implementation primarily used for testing and validation.
public class MockOutputTool implements OutputTool {
public MockOutputTool() // Default constructor
public void makeOutputArea(String filename) // Track output areas
public void writeToOutput(String fileName, String text, String charset) // Store in memory
public boolean isValidOutputArea(String fileName) // Check if area exists
public String getText(String fileName) // Retrieve stored text
}The MockOutputTool provides additional methods for testing:
isValidOutputArea() - Verify that an output area was createdgetText() - Retrieve content that was written to a specific fileimport org.codehaus.groovy.tools.groovydoc.FileOutputTool;
import org.codehaus.groovy.tools.groovydoc.GroovyDocTool;
// Create file system output tool
FileOutputTool output = new FileOutputTool();
// Set up documentation tool
String[] sourcePaths = {"src/main/groovy"};
GroovyDocTool tool = new GroovyDocTool(sourcePaths);
tool.add(Arrays.asList("com/example/MyClass.groovy"));
// Generate documentation to file system
String outputDirectory = "build/docs/groovydoc";
tool.renderToOutput(output, outputDirectory);
// Files will be created in build/docs/groovydoc/
// - index.html
// - package directories with class documentation
// - CSS and JavaScript resourcesimport org.codehaus.groovy.tools.groovydoc.MockOutputTool;
import org.codehaus.groovy.tools.groovydoc.GroovyDocTool;
// Create mock output tool for testing
MockOutputTool mockOutput = new MockOutputTool();
// Set up documentation tool
GroovyDocTool tool = new GroovyDocTool(new String[]{"src/test/groovy"});
tool.add(Arrays.asList("TestClass.groovy"));
// Generate documentation to memory
tool.renderToOutput(mockOutput, "test-docs");
// Verify output was generated
if (mockOutput.isValidOutputArea("test-docs/index.html")) {
String indexContent = mockOutput.getText("test-docs/index.html");
System.out.println("Generated index.html:");
System.out.println(indexContent);
}
// Check for specific class documentation
String classDocPath = "test-docs/TestClass.html";
if (mockOutput.isValidOutputArea(classDocPath)) {
String classContent = mockOutput.getText(classDocPath);
assert classContent.contains("class TestClass");
}You can create custom output implementations for specialized requirements:
import org.codehaus.groovy.tools.groovydoc.OutputTool;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;
// Custom output tool that tracks generation statistics
public class StatisticsOutputTool implements OutputTool {
private final OutputTool delegate;
private final Map<String, Integer> fileSizes = new ConcurrentHashMap<>();
private int totalFiles = 0;
public StatisticsOutputTool(OutputTool delegate) {
this.delegate = delegate;
}
@Override
public void makeOutputArea(String filename) {
delegate.makeOutputArea(filename);
}
@Override
public void writeToOutput(String fileName, String text, String charset) {
delegate.writeToOutput(fileName, text, charset);
// Track statistics
fileSizes.put(fileName, text.length());
totalFiles++;
}
public int getTotalFiles() { return totalFiles; }
public int getTotalSize() { return fileSizes.values().stream().mapToInt(Integer::intValue).sum(); }
public Map<String, Integer> getFileSizes() { return new HashMap<>(fileSizes); }
}
// Usage
FileOutputTool fileOutput = new FileOutputTool();
StatisticsOutputTool statsOutput = new StatisticsOutputTool(fileOutput);
tool.renderToOutput(statsOutput, "docs");
System.out.println("Generated " + statsOutput.getTotalFiles() + " files");
System.out.println("Total size: " + statsOutput.getTotalSize() + " characters");import org.codehaus.groovy.tools.groovydoc.FileOutputTool;
import java.io.IOException;
// Wrapper to handle output errors gracefully
public class SafeOutputTool implements OutputTool {
private final OutputTool delegate;
private final List<String> errors = new ArrayList<>();
public SafeOutputTool(OutputTool delegate) {
this.delegate = delegate;
}
@Override
public void makeOutputArea(String filename) {
try {
delegate.makeOutputArea(filename);
} catch (Exception e) {
errors.add("Failed to create output area " + filename + ": " + e.getMessage());
}
}
@Override
public void writeToOutput(String fileName, String text, String charset) {
try {
delegate.writeToOutput(fileName, text, charset);
} catch (Exception e) {
errors.add("Failed to write " + fileName + ": " + e.getMessage());
}
}
public List<String> getErrors() { return new ArrayList<>(errors); }
public boolean hasErrors() { return !errors.isEmpty(); }
}
// Usage with error handling
SafeOutputTool safeOutput = new SafeOutputTool(new FileOutputTool());
tool.renderToOutput(safeOutput, "docs");
if (safeOutput.hasErrors()) {
System.err.println("Documentation generation completed with errors:");
for (String error : safeOutput.getErrors()) {
System.err.println(" " + error);
}
}The output management system works closely with the template engine to write processed templates:
import org.codehaus.groovy.tools.groovydoc.*;
// The template engine uses the output tool internally
ResourceManager resourceManager = new FileSystemResourceManager("templates");
GroovyDocTemplateEngine templateEngine = new GroovyDocTemplateEngine(
tool, resourceManager, new String[]{"class.html"}
);
// When renderToOutput() is called, the template engine processes templates
// and uses the provided OutputTool to write the results
FileOutputTool output = new FileOutputTool();
tool.renderToOutput(output, "generated-docs");
// The process internally does something like:
// 1. templateEngine.applyClassTemplates(classDoc) -> returns HTML string
// 2. output.writeToOutput("ClassName.html", htmlContent, "UTF-8")The typical output structure created by the documentation generation process includes:
output-directory/
├── index.html # Main index page
├── overview-frame.html # Package overview frame
├── allclasses-frame.html # All classes frame
├── stylesheet.css # Default stylesheet
├── package-list # Package list for external links
└── [package-name]/ # Package directories
├── package-frame.html # Package frame
├── package-summary.html # Package summary
└── [ClassName].html # Individual class documentationThe exact structure depends on the templates being used and the organization of the source code being documented.
Install with Tessl CLI
npx tessl i tessl/maven-org-apache-groovy--groovy-groovydoc