diff --git a/src/org/kar/archidata/annotation/CreationTimestamp.java b/src/org/kar/archidata/annotation/CreationTimestamp.java index d8cda81..a805078 100644 --- a/src/org/kar/archidata/annotation/CreationTimestamp.java +++ b/src/org/kar/archidata/annotation/CreationTimestamp.java @@ -5,6 +5,39 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The CreationTimestamp annotation is used to automatically set the creation + * date of an object in the database. This annotation ensures that the field + * marked with @CreationTimestamp is populated with the current timestamp + * when the object is first created. + * + *
Usage: + * - Target: This annotation can be applied to fields within a class. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle data persistence logic. + * + *
Behavior: + * - When a field is annotated with @CreationTimestamp, it will automatically + * be set to the current date and time when the object is inserted into the + * database. + * - This annotation is typically used in conjunction with other annotations + * such as @Column to define database column properties. + * + *
Example: + *
{@code + * public class MyEntity { + * @DataNotRead + * @CreationTimestamp + * @Column(nullable = false, insertable = false, updatable = false) + * @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") // optional depend on the configuration + * @Nullable + * public Date createdAt = null; + * } + * }+ * + * In this example, the createdAt field will be automatically set to the + * current timestamp when a new User object is created in the database. + */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface CreationTimestamp { diff --git a/src/org/kar/archidata/annotation/DataDeleted.java b/src/org/kar/archidata/annotation/DataDeleted.java index bacde04..a5248d1 100644 --- a/src/org/kar/archidata/annotation/DataDeleted.java +++ b/src/org/kar/archidata/annotation/DataDeleted.java @@ -5,6 +5,40 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The DataDeleted annotation is used to manage a boolean variable that marks + * an object as 'deleted' in the database. This annotation helps in soft deletion + * by excluding marked objects from being automatically retrieved unless + * explicitly specified. + * + *
Usage: + * - Target: This annotation can be applied to fields within a class. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle data retrieval logic. + * + *
Behavior: + * - When a field is annotated with @DataDeleted, it will not be included in the + * default data retrieval process from the database if its value is false. + * - To override this behavior and access deleted items, the query must include + * the option AccessDeletedItems. + * + *
Example: + *
{@code + * public class MyEntity { + * public String username; + * + * @DataDeleted + * @DataNotRead + * @Column(nullable = false) + * @DefaultValue("'0'") + * public Boolean deleted = null; + * } + * }+ * + * In this example, objects with `deleted` set to true will not be retrieved + * by default. To include them in the query results, the AccessDeletedItems + * option must be specified in the query. + */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface DataDeleted { diff --git a/src/org/kar/archidata/annotation/DataJson.java b/src/org/kar/archidata/annotation/DataJson.java index b133dc9..5bb5c28 100644 --- a/src/org/kar/archidata/annotation/DataJson.java +++ b/src/org/kar/archidata/annotation/DataJson.java @@ -5,6 +5,41 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The DataJson annotation is used to convert fields or classes to JSON format + * for storage in a database. This annotation allows storing complex data types + * such as lists, maps, and other objects in SQL databases as JSON or STRING + * (for SQLite). + * + *
Usage: + * - Target: This annotation can be applied to both fields and classes. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle data persistence logic. + * + *
Behavior: + * - When applied to a field or class, the DataJson annotation enables the + * conversion of the annotated element to JSON format before storing it in + * the database. + * - This is particularly useful in SQL databases where only basic data types + * (char, short, int, long, float, string, timestamp) can be stored directly. + * The DataJson annotation makes it possible to store complex data structures + * by converting them to JSON. + * + *
Attributes: + * - targetEntity: Specifies the target entity class to which the JSON data + * should be mapped. Defaults auto-detect if not specified. + * + *
Example: + *
{@code + * public class User { + * @DataJson + * public Map+ * + * In this example, the additionalData field can store complex data structures + * as JSON in the database. + */ @Target({ ElementType.TYPE, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface DataJson { diff --git a/src/org/kar/archidata/annotation/DataNotRead.java b/src/org/kar/archidata/annotation/DataNotRead.java index 9b27b81..eb9e538 100644 --- a/src/org/kar/archidata/annotation/DataNotRead.java +++ b/src/org/kar/archidata/annotation/DataNotRead.java @@ -5,6 +5,37 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The DataNotRead annotation is used to mark fields in a class that should not + * be automatically read from the database. This annotation helps in optimizing + * data retrieval by excluding certain fields from being fetched unless + * explicitly specified. + * + *additionalData; + * } + * }
Usage: + * - Target: This annotation can be applied to fields within a class. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle data retrieval logic. + * + *
Behavior: + * - When a field is annotated with @DataNotRead, it will not be included in the + * default data retrieval process from the database. + * - To override this behavior and read all columns, including those marked with + * @DataNotRead, the query must include the option ReadAllColumn. + * + *
Example: + *
{@code + * public class MyEntity { + * public String username; + * + * @DataNotRead + * private String sensitiveData; + * } + * }+ * + * In this example, the sensitiveData field will not be read from the database + * by default. To include it in the query results, the ReadAllColumn option must + * be specified in the query. + */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface DataNotRead { diff --git a/src/org/kar/archidata/annotation/FormDataOptional.java b/src/org/kar/archidata/annotation/FormDataOptional.java index 53f2175..a724c7e 100644 --- a/src/org/kar/archidata/annotation/FormDataOptional.java +++ b/src/org/kar/archidata/annotation/FormDataOptional.java @@ -5,6 +5,70 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The FormDataOptional annotation is used to indicate that a form data parameter + * is optional when generating client code. By default, form data parameters are + * required, but this annotation allows them to be optional, enabling the creation + * of polymorphic APIs. + * + *
Usage: + * - Target: This annotation can be applied to method parameters. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle code generation logic. + * + *
Behavior: + * - When applied to a parameter, the FormDataOptional annotation specifies that + * the parameter is optional in the generated client code. This allows for + * more flexible API designs where certain inputs can be omitted. + * + *
Example: + *
{@code + * public class AlbumService { + * + * @POST + * @Path("{id}/cover") + * @RolesAllowed("ADMIN") + * @Consumes({ MediaType.MULTIPART_FORM_DATA }) + * @Operation(description = "Add a cover on a specific album") + * @TypeScriptProgress + * public Album uploadCover(@PathParam("id") final Long id, + * @FormDataOptional @FormDataParam("uri") final String uri, + * @FormDataOptional @FormDataParam("file") final InputStream fileInputStream, + * @FormDataOptional @FormDataParam("file") final FormDataContentDisposition fileMetaData) + * throws Exception { + * // some code + * } + * } + * }+ * + * Note: @FormDataParam must be allway at the last position. + * + * In this example, the uri, fileInputStream, and fileMetaData parameters are + * marked as optional, allowing the client to omit them when calling the API. + * + *
Generated TypeScript code example: + *
{@code + * //Add a cover on a specific album + * export function uploadCover({ + * restConfig, + * params, + * data, + * callbacks, + * }: { + * restConfig: RESTConfig, + * params: { + * id: Long, + * }, + * data: { + * file?: File, // element is optional + * uri?: string, // element is optional + * }, + * callbacks?: RESTCallbacks, + * }): Promise+ * + * The generated TypeScript function reflects the optional nature of the form data parameters. + */ @Target({ ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) public @interface FormDataOptional { diff --git a/src/org/kar/archidata/annotation/NoWriteSpecificMode.java b/src/org/kar/archidata/annotation/NoWriteSpecificMode.java index 4d6a2e8..fcad39d 100644 --- a/src/org/kar/archidata/annotation/NoWriteSpecificMode.java +++ b/src/org/kar/archidata/annotation/NoWriteSpecificMode.java @@ -5,7 +5,35 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** When we wend to have only One type for read and write mode (Wrapping API). */ +/** + * The NoWriteSpecificMode annotation is used to indicate that there is no + * specific API for write mode when generating code for other languages. This + * annotation is particularly useful in code generators for client libraries + * where a separate, reduced data structure for write operations is not needed. + * + *{ ... + * }
Usage: + * - Target: This annotation can be applied to class types. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle code generation logic. + * + *
Behavior: + * - When applied to a class, the NoWriteSpecificMode annotation specifies + * that the class does not require a separate API or data structure for + * write operations. This can simplify the generated code by avoiding the + * creation of redundant structures. + * + *
Example: + *
{@code + * @NoWriteSpecificMode + * public class User { + * public String username; + * public String email; + * } + * }+ * + * In this example, the User class will not generate a separate API or data + * structure for write operations in the client code. + */ @Target({ ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) public @interface NoWriteSpecificMode { diff --git a/src/org/kar/archidata/annotation/TypeScriptProgress.java b/src/org/kar/archidata/annotation/TypeScriptProgress.java index 726796d..d766f44 100644 --- a/src/org/kar/archidata/annotation/TypeScriptProgress.java +++ b/src/org/kar/archidata/annotation/TypeScriptProgress.java @@ -5,7 +5,67 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** In case of the update parameter with String input to detect null element. */ +/** + * The TypeScriptProgress annotation is used to specify that an API method + * will take a significant amount of time to complete, and thus requires a + * callback API to provide more precise progress tracking, particularly for + * upload operations. + * + *
Usage: + * - Target: This annotation can be applied to method parameters and methods. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle code generation logic. + * + *
Behavior: + * - When applied to a method or parameter, the TypeScriptProgress annotation + * indicates that the client code generator should provide a callback API + * for tracking the progress of the operation. + * - Note: The use of this annotation implies that the standard browser fetch + * API is not used, as the callback API is not yet operational. Instead, + * the older XMLHttpRequest interface is utilized. + * + *
Example: + *
{@code + * public class SeasonService { + * + * @POST + * @Path("{id}/cover") + * @RolesAllowed("ADMIN") + * @Consumes(MediaType.MULTIPART_FORM_DATA) + * @Operation(description = "Upload a new season cover season", tags = "GLOBAL") + * @TypeScriptProgress + * public Season uploadCover(@PathParam("id") final Long id, + * @FormDataParam("file") final InputStream fileInputStream, + * @FormDataParam("file") final FormDataContentDisposition fileMetaData) + * throws Exception { + * // Upload logic + * } + * } + * }+ * + * In this example, the uploadCover method will generate a client-side API + * with progress tracking capabilities using XMLHttpRequest. + * + *
Generated TypeScript code example: + *
{@code + * export function uploadCover({ + * restConfig, + * params, + * data, + * callbacks, // add this callback handle + * }: { + * restConfig: RESTConfig, + * params: { + * id: Long, + * }, + * data: { + * file: File, + * }, + * callbacks?: RESTCallbacks, + * }): Promise+ * + */ @Target({ ElementType.PARAMETER, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface TypeScriptProgress {} diff --git a/src/org/kar/archidata/annotation/UpdateTimestamp.java b/src/org/kar/archidata/annotation/UpdateTimestamp.java index 92d9b25..3a1993f 100644 --- a/src/org/kar/archidata/annotation/UpdateTimestamp.java +++ b/src/org/kar/archidata/annotation/UpdateTimestamp.java @@ -5,6 +5,38 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * The UpdateTimestamp annotation is used to automatically update the timestamp + * of an object in the database whenever it is modified. This annotation ensures + * that the field marked with @UpdateTimestamp is set to the current timestamp + * each time the object is updated. + * + *{... + * }
Usage: + * - Target: This annotation can be applied to fields within a class. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle data persistence logic. + * + *
Behavior: + * - When a field is annotated with @UpdateTimestamp, it will automatically + * be updated to the current date and time whenever the object is modified + * in the database. + * - This annotation is typically used in conjunction with other annotations + * such as @Column to define database column properties. + * + *
Example: + *
{@code + * public class MyEntity { + * @UpdateTimestamp + * @Column(nullable = false, insertable = false, updatable = false) + * @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") + * @Nullable + * public Date updatedAt = null; + * } + * }+ * + * In this example, the updatedAt field will be automatically set to the + * current timestamp whenever the User object is modified in the database. + */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface UpdateTimestamp { diff --git a/src/org/kar/archidata/annotation/checker/Checker.java b/src/org/kar/archidata/annotation/checker/Checker.java index 2ed388f..a50cd8e 100644 --- a/src/org/kar/archidata/annotation/checker/Checker.java +++ b/src/org/kar/archidata/annotation/checker/Checker.java @@ -7,6 +7,44 @@ import java.lang.annotation.Target; import org.kar.archidata.dataAccess.options.CheckFunctionInterface; +/** + * The Checker annotation is used to specify a checker class that automatically + * validates data for a parent class. This annotation can be applied to both + * classes and fields to enforce validation rules defined in the checker class. + * + *
Usage: + * - Target: This annotation can be applied to types (classes) and fields. + * - Retention: The annotation is retained at runtime, allowing it to be + * processed by frameworks or libraries that handle data validation logic. + * + *
Behavior: + * - When applied to a class or field, the Checker annotation specifies a + * checker class that implements the CheckFunctionInterface. This checker + * class is responsible for validating the data associated with the annotated + * element. + * - The validation is automatically triggered when the data of the parent class + * is validated, ensuring that the data adheres to the specified rules. + * + *
Attributes: + * - value: Specifies the checker class that implements the validation logic. + * This class must extend the CheckFunctionInterface. + * + *
Example: + *
{@code + * public class User { + * + * @Checker(UserDataChecker.class) + * public String email; + * } + * + * public class UserDataChecker implements CheckFunctionInterface { + * ... + * } + * }+ * + * In this example, the email field in the User class is validated using the + * UserDataChecker class whenever the User class data is validated. + */ @Target({ ElementType.TYPE, ElementType.FIELD }) @Retention(RetentionPolicy.RUNTIME) public @interface Checker { diff --git a/src/org/kar/archidata/model/GenericTiming.java b/src/org/kar/archidata/model/GenericTiming.java index 7217dd9..3e0bfec 100644 --- a/src/org/kar/archidata/model/GenericTiming.java +++ b/src/org/kar/archidata/model/GenericTiming.java @@ -15,14 +15,14 @@ import jakarta.persistence.Column; public class GenericTiming { @DataNotRead @CreationTimestamp - @Column(nullable = false) + @Column(nullable = false, insertable = false, updatable = false) @Schema(description = "Create time of the object", required = false, example = "2000-01-23T01:23:45.678+01:00", readOnly = true) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") @Nullable public Date createdAt = null; @DataNotRead @UpdateTimestamp - @Column(nullable = false) + @Column(nullable = false, insertable = false, updatable = false) @Schema(description = "When update the object", required = false, example = "2000-01-23T00:23:45.678Z", readOnly = true) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") // public Instant updatedAt = null;