<commit_before>
# Data Transfer Objects (DTOs)

DTOs are used in AIDR to transfer data. In AIDR most DTOs contain all the properties of an entity.

## Types of properties

DTOs in AIDR have mandatory and optional properties.

All _mandatory_ properties must be marked final, so they are initialized by the constructor. Their getter does not need to test that the property exists. Their setter needs to verify the values given before setting.

In _optional_ properties: the getter needs to test if the property exist, and if not, must throw an exception of type `PropertyNotSetException`. Their setter needs to verify the values given before setting.

## Mapping

Mapping from/to entities in done by the DTO class, not by a helper class.

Mapping from entities is done through the constructor and the constructor only.

Mapping to entities is done by a method `toEntity()`. This method is always called `toEntity()`, no matter what the class name is.

## Example

Entity:

    @Entity
    @Table(name = "crisis", ...)
    public class Crisis ... {

        private Long crisisId;

        private String name;

        private List<ModelFamily> modelFamilies = null;

        // + getters and setters
    }

DTO (this example assumes crisisID and name are mandatory, for example purposes only):

    @XmlRootElement
    @JsonIgnoreProperties(ignoreUnknown=true)
    public class CrisisDTO implements Serializable {

        /* Mandatory properties */

        @XmlElement
        private final Long crisisID;

        @XmlElement
        private final String name;

        /* Optional properties */

        @XmlElement
        private List<ModelFamilyDTO> modelFamiliesDTO = null;

        /* Constructors from entity and from mandatory properties */

        public CrisisDTO( Crisis crisis ) {
            this.setCrisisID(crisis.getCrisisID());
            this.setName(crisis.getName());
        }

        public CrisisDTO( Long crisisID, String name ) {
            this.setCrisisID(crisisID);
            this.setName(name);
        }

        /* Mapping to entity */

        public Crisis toEntity() {
            Crisis crisis = new Crisis();
            crisis.setCrisisID(getCrisisID());
            crisis.setName(getName());
            return crisis;
        }

        /* Getters for mandatory properties */

        public getCrisisID() {
            return crisisID;
        }

        public getName() {
            return name;
        }

        /* Getters for optional properties, must thrown exception if property not set */

        public getModelFamiliesDTO() {
            if( modelFamiliesDTO == null ) {
                logger.error( "Attempt to access unset property" );
                throw new PropertyNotSetException();
            } else {
                return modelFamiliesDTO;
            }
        }

        /* Setters, which must always verify */

        public setCrisisID(Long crisisID) {
            if( crisisID == null ) {
                throw new IllegalArgumentException("crisisID cannot be null");
            } else if( crisisID.longValue() <= 0 ) {
                throw new IllegalArgumentException("crisisID cannot be zero or a negative number");
            } else {
                this.crisisID = crisisID;
            }
        }

        // + other setters
<commit_msg>Updated DTO standards (markdown)<commit_after>
# Data Transfer Objects (DTOs)

DTOs are used in AIDR to transfer data. In AIDR most DTOs contain all the properties of an entity.

## Types of properties

DTOs in AIDR have mandatory and optional properties.

All _mandatory_ properties must be marked final, so they are initialized by the constructor. Their getter does not need to test that the property exists. Their setter needs to verify the values given before setting.

In _optional_ properties: the getter needs to test if the property exist, and if not, must throw an exception of type `PropertyNotSetException`. Their setter needs to verify the values given before setting.

## Mapping

Mapping from/to entities in done by the DTO class, not by a helper class.

Mapping from entities is done through the constructor and the constructor only.

Mapping to entities is done by a method `toEntity()`. This method is always called `toEntity()`, no matter what the class name is.

## Example

Entity:

    @Entity
    @Table(name = "crisis", ...)
    public class Crisis ... {

        private Long crisisId;

        private String name;

        private List<ModelFamily> modelFamilies = null;

        // + getters and setters
    }

DTO (this example assumes crisisID and name are mandatory, for example purposes only):

    @XmlRootElement
    @JsonIgnoreProperties(ignoreUnknown=true)
    public class CrisisDTO implements Serializable {

        /* Mandatory properties */

        @XmlElement
        private final Long crisisID;

        @XmlElement
        private final String name;

        /* Optional properties */

        @XmlElement
        private List<ModelFamilyDTO> modelFamiliesDTO = null;

        /* Constructors from entity and from mandatory properties */

        public CrisisDTO( Crisis crisis ) {
            this.setCrisisID(crisis.getCrisisID());
            this.setName(crisis.getName());
        }

        public CrisisDTO( Long crisisID, String name ) {
            this.setCrisisID(crisisID);
            this.setName(name);
        }

        /* Mapping to entity */

        public Crisis toEntity() {
            Crisis crisis = new Crisis();
            crisis.setCrisisID(getCrisisID());
            crisis.setName(getName());
            return crisis;
        }

        /* Getters for mandatory properties */

        public getCrisisID() {
            return crisisID;
        }

        public getName() {
            return name;
        }

        /* Getters for optional properties, must thrown exception if property not set */

        public getModelFamiliesDTO() {
            if( modelFamiliesDTO == null ) {
                logger.error( "Attempt to access unset property" );
                throw new PropertyNotSetException();
            } else {
                return modelFamiliesDTO;
            }
        }

        /* Setters, which must always verify */

        public setCrisisID(Long crisisID) {
            if( crisisID == null ) {
                logger.error( "Attempt to set a crisisID to null" );
                throw new IllegalArgumentException("crisisID cannot be null");
            } else if( crisisID.longValue() <= 0 ) {
                logger.error( "Attempt to set a crisisID to zero or a negative number" );
                throw new IllegalArgumentException("crisisID cannot be zero or a negative number");
            } else {
                this.crisisID = crisisID;
            }
        }

        // + other setters, which must also verify

{'fraction_non_alphanumeric': 0.07124125874125874, 'fraction_numerical': 0.0002913752913752914, 'mean_word_length': 2.157773689052438, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3574310', 'n_tokens_mistral': 1759, 'n_tokens_neox': 1700, 'n_words': 675}