1
CONTRIBUTING
Thibaud edited this page 2026-03-27 15:43:53 +01:00

Contributing Guide

Prerequisites

  • Java 16 or later (uses switch expressions, records, etc.)
  • Maven 3.6+

Building

mvn compile

Running

mvn exec:java -Dexec.mainClass=ovh.gasser.newshapes.App

Or run ovh.gasser.newshapes.App.main() from your IDE.

Testing

mvn test

Uses JUnit 5 (Jupiter). Tests are in src/test/java/ovh/gasser/newshapes/.

Current test coverage:

  • Shape classes: AbstractShapeTest, SRectangleTest, SCircleTest, STriangleTest, STextTest
  • Exporters: SVGExporterTest, HTMLExporterTest
  • See TESTING_HANDOFF.md at the project root for detailed coverage analysis and recommendations.

Project Structure

src/
├── main/java/ovh/gasser/newshapes/    — Application source
│   ├── shapes/                         — Shape hierarchy
│   ├── attributes/                     — Attribute types
│   ├── ui/                             — Swing UI (view, controller, listeners)
│   │   ├── listeners/                  — Menu and selection listeners
│   │   └── visitors/                   — HTML/SVG visitor implementations
│   └── util/                           — Utility interfaces
└── test/java/ovh/gasser/newshapes/    — JUnit 5 tests
    ├── shapes/                         — Shape unit tests
    └── exporters/                      — Exporter integration tests

Adding a New Shape

  1. Create a class extending AbstractShape in ovh.gasser.newshapes.shapes.
  2. Implement accept(ShapeVisitor visitor) — call visitor.visitYourShape(this).
  3. Implement clone() — return a deep copy.
  4. Provide a static create() factory method.
  5. Optionally override resize() if the shape needs custom resize behavior (e.g., SCircle maintains radius).
  6. Add a visitYourShape() method to the ShapeVisitor interface.
  7. Implement the new visit method in all three visitors: ShapeDraftman, HTMLDraftman, SVGDraftman.
  8. Add a menu item in App.buildFileMenu() with a MenuAddListener.
  9. Write tests.

Adding a New Attribute

  1. Create a class implementing Attributes in ovh.gasser.newshapes.attributes.
  2. Define a public static final String ID constant.
  3. Implement getID() returning the ID.
  4. Use shape.addAttributes(new YourAttribute(...)) to attach, and shape.getAttributes(YourAttribute.ID) to retrieve.

Adding a New Exporter

  1. Create a visitor class implementing ShapeVisitor in ovh.gasser.newshapes.ui.visitors.
  2. Implement all visit methods to generate the target format.
  3. Create an exporter class (like HTMLExporter / SVGExporter) that uses the visitor and writes to a file.
  4. Wire it up in App.buildFileMenu().

Conventions

  • Static factory methods (create()) over public constructors.
  • getBounds() always returns a defensive copy.
  • Shapes are cloneable via the clone() method.
  • Attributes are keyed by string IDs and stored in a TreeMap.
  • Logging via SLF4J (LoggerFactory.getLogger(YourClass.class)).