Conversation
# Conflicts: # besser/utilities/web_modeling_editor/backend/backend.py
… that compiles The generator could not be instantiated by the web editor at all: SpringBackendGenerator required spring_boot_version, java_version and app_name positionally before output_dir, while the router calls every generator as generator_class(model, output_dir=...). Those are now keyword arguments with defaults, matching the rest of besser/generators. The generated project also did not compile. Four copies of the B-UML to Java type map had drifted apart: TimeType mapped to LocalTime in the entity and controller generators but to LocalDateTime in the repository and service generators, so an entity field and the methods taking it disagreed on type. The map now lives once in java_types.py, and the findAllBy signature builder is shared so the two sides cannot drift again. Association ownership compared a Multiplicity object against the integer 1, which is always unequal, so every association resolved to the same end as owner and mappedBy was placed arbitrarily. Ownership is now decided from multiplicity.max against UNLIMITED_MAX_MULTIPLICITY, which also fixes self-associations emitting one end twice instead of both. B-UML names reached the filesystem unsanitized. NamedElement.name rejects spaces and hyphens but permits "..", "/" and "\", so a class named ../../evil was a valid model that wrote outside output_dir. Class, field, package and file names now go through Java identifier sanitization, and the new _generate_spring router branch resolves the project directory with the existing _safe_path helper rather than a raw os.path.join. The Maven wrapper shipped as three .j2 templates containing no Jinja tags at all, rendered into .mvn/ where Maven does not look for them. They are static files under resources/ now, copied to the project root with the executable bit and fixed line endings, and declared as package data so they ship in the wheel. Also: the generator is registered in SUPPORTED_GENERATORS and dispatched with its configuration rather than falling through to the generic path that ignored it; unmapped types fall back to Object instead of raising KeyError; a class with no identifier reports which class rather than a bare StopIteration; the controller uses the resolved identifier accessor instead of a hardcoded setId; enumeration literals and associations are sorted so output is deterministic; and example.py, a 206-line scratch script no other generator ships, is removed. Adds tests/generators/spring with 24 tests covering structure, content, determinism, name sanitization and config pass-through. Verified end to end by running mvnw compile on a generated project.
|
Hi @miloss01 — thanks for opening this, and congratulations again on the thesis. I've brought it up to current It couldn't be called by the editor. The generated project didn't compile. There were four copies of the B-UML→Java type map, and they had drifted: Association ownership was effectively random. Path traversal. The Maven wrapper. Your Smaller things: unmapped types fall back to Added The structure you chose held up well: the split into entity/repository/service/controller/http generators, the inheritance handling via |
The traversal test asserted evil.java while the generator correctly writes Evil.java, since a class name is capitalized on the way to a Java identifier. Windows matched it case-insensitively so the assertion passed locally and failed on the Linux CI runners.
This generator generates Spring Boot project. It consists of several generators:
SpringBackendGenerator- Combining work of all other generators (instanties them and calls theirsgeneratemethods). Aside from that that it generates fixed files (files that are not based on structural model). For example: files needed formvn,pom.xmletc.SpringEntityGenerator- Generates entity classes (and enumeration classes). It generates simple fields (and sets default value if provided), fields made by relationships (with needed anotations), empty and parametrized constructor, methods, getters and setters.SpringRepositoryGenerator- Generates Spring Data JPA repositories. For every entity, one repository is generated. Repositories includefindAllBy...methods based on entity's fields.SpringServiceGenerator- Generates service interface and implementation. Interface includes same custom methods based on fields as repository and, also, some basic methods that are implicitly generated by JPA repository (findAll,findById,save,delete). Implemetation of service generates all methods including theirs bodies which call the same named methods from generated repository.SpringControllerGenerator- Generates basic endpoints (getAll,getById,create,update,deleteById) and theirs bodies. Endpoints for updating and creating have checks if passed ID already exists and if not returns 404 exception.SpringHttpGenerator- Generates.httpfiles that are used for quick endpoint testing.