Skip to content

Validating Builders

Alexander Yevsyukov edited this page Aug 20, 2024 · 2 revisions

Warning

This page refers to features of Spine v1.9.. Validating builders work differently in Spine v2.0.


Concepts

ValidatingBuilder is a builder that validates messages according to their Protobuf definition during instantiation.

Spine Model Compiler Gradle plugin generates the validating builders for the project message types.

By convention, a validating builder class has the same Java package as the corresponding message class and the same class name as the corresponding message with the VBuilder postfix. For example, the validating builder class for the spine.core.Command message has name io.spine.core.CommandVBuilder.

The Google Proto definitions (i.e. messages under the google.protobuf.* package) are always ignored by the generator. Note that there are validating builders for Any, Timestamp, and other messages under the io.spine.validate Java package.

Configuration

The validating builders are generated for the Proto definitions of a Gradle project by default. Those are the .proto files under the project modelCompiler.mainProtoSrcDir (or modelCompiler.testProtoSrcDir for tests) path. By default, this path is equal to <projectDir>/src/main/proto.

The generation can be turned off as follows:

modelCompiler {
    generateValidatingBuilders = false
}

Also, there is a possibility to generate the validating builders for all the message definitions in the project compile classpath. In this case, all .proto files under modelCompiler.mainProtoSrcDir, as well as all the .proto files found in the Gradle project compile classpath, are included for the validating builders generation.

This generation mode can be enabled as follows:

modelCompiler {
    generateBuildersFromClasspath = true
}

Otherwise, the builders will be generated only for the definitions from the current Gradle project.

Artifacts

Spine artifacts include the validating builders for the definitions from the particular module.

For example, spine-server artifact includes io.spine.server.aggregate.SnapshotVBuilder class since spine.server.aggregate.Snapshot message is defined in the server module. But io.spine.core.EventVBuilder is not included because spine.core.Event message is defined in the core module. Instead, the io.spine.core.EventVBuilder class is resolved from the spine-core dependency (as it would be done with the message classes).

It's recommended that the framework users follow this convention.

Example

Given following message definition:

syntax = "proto3";

package example.accounts;

import "spine/options.proto"

option (type_url_prefix) = "type.example.org";
option java_package = "org.example.accounts";

import "spine/net/email_address.proto";
import "google/protobuf/timestamp.proto";

message AccountId {
    string uid = 1 [(required) = true];
}

message Account {
    AccountId id = 1 [(required) = true, (valid) = true];
    spine.net.EmailAddress email = 2 [(required) = true];
    google.protobuf.Timestamp last_seen = 3 [(required) = true, (when).in = PAST];
}

After building the Gradle project, the org.example.accounts.AccountVBuilder class will be generated. When setting the value to last_seen field, the value is checked to be in the past. Also, when build() is called, fields marked as (required) are checked to be present. Also, the id.uid is checked, since the id field is marked as (valid). A separate org.example.accounts.AccountIdVBuilder is generated as well.

Validating builders for neither spine.net.EmailAddress nor google.protobuf.Timestamp are generated by default, as the messages do not belong to the current Gradle project.

If the modelCompiler.generateBuildersFromClasspath is set to true, the io.spine.net.EmailAddressVBuilder is also generated. No validating builder for google.protobuf.Timestamp is ever generated, since it belongs to the Google Proto package. See Configuration section for details.

Clone this wiki locally