Les « design patterns » clés en main
La maintenabilité en bonus
Nous avons tous les mêmes problèmes
La différence entre le bon développeur et le mauvais développeur...
Outillage
/**
 * Copyright Sénat.
 */
package fr.senat.model.dosleg;
import fr.senat.model.dosleg.validator.ActiviteValide;
import fr.senat.model.senateurs.GroupePolitique;
import fr.senat.util.Constants;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import org.hibernate.annotations.Type;
import static org.joda.time.DateTimeConstants.OCTOBER;
import org.joda.time.LocalDate;
import static org.joda.time.LocalDate.now;
/**
 * Représente une mission de contrôle et d'évaluation du Sénat. Peut être une Mission Commune d'Information, une
 * commission d'enquête, un contrôle d'application d'une loi, un contrôle de commission permanente, etc... Par défaut,
 * le contrôle n'est à l'initiative des groupes, ni avec l'aide de la cour des comptes ou clôturé, mais il est considéré
 * comme avec rapport. Par ailleurs, les organismes, lois, livrables, acteurs et thèmes sont des ensembles vides.
 */
@Entity
@ActiviteValide
public class Controle implements Serializable {
    private static final String FOREIGN_KEY_ID = "CON_ID";
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    @Size(max = 256, message = "trop long.")
    @Column(name = "LIB", length = 256)
    @NotNull
    private String libelle;
    @Size(max = 2048, message = "trop long.")
    private String objet;
    @Pattern(regexp = Constants.URL_PATTERN, message = "pas au bon format (par exemple : http://www.senat.fr/commission/XX/missions_d_information/mission_dinformation_sur_YY.html)")
    private String url;
    @NotNull
    @Column(name = "INITIATIVE_GROUPES")
    @Type(type = "fr.senat.util.hibernate.usertype.OuiNonSmallType")
    private boolean initiativeDesGroupes = false;
    @NotNull
    @Column(name = "COUR_COMPTES")
    @Type(type = "fr.senat.util.hibernate.usertype.OuiNonSmallType")
    private boolean courDesComptes = false;
    @NotNull
    @Column(name = "PROGRAMME_CREATION")
    private int programmeCreation = Controle.getSession(now());
    @Column(name = "PROGRAMME_REPORT")
    private Integer programmeReport;
    @Column(name = "DATE_CREATION")
    @Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDate")
    private LocalDate dateCreation;
    @NotNull
    @Type(type = "fr.senat.util.hibernate.usertype.OuiNonSmallType")
    private boolean cloture = false;
    @NotNull
    @Column(name = "AVEC_RAPPORT")
    @Type(type = "fr.senat.util.hibernate.usertype.OuiNonSmallType")
    private boolean avecRapport = true;
    @Embedded
    @NotNull
    private EcheanceControle echeance = new EcheanceControle();
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "GRPPOL")
    private GroupePolitique groupePolitique;
    @ManyToMany
    @JoinTable(name = "CONTROLE_ORG", joinColumns = @JoinColumn(name = FOREIGN_KEY_ID), inverseJoinColumns = @JoinColumn(name = "ORGCOD"))
    private Set<Organisme> organismes = new HashSet<Organisme>();
    @ManyToMany
    @JoinTable(name = "CONTROLE_LOI", joinColumns = @JoinColumn(name = FOREIGN_KEY_ID), inverseJoinColumns = @JoinColumn(name = "LOICOD"))
    private Set<Loi> lois = new HashSet<Loi>();
    @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL)
    @JoinColumn(name = FOREIGN_KEY_ID, nullable = false)
    private Set<LivrableControle> livrables = new HashSet<LivrableControle>();
    @OneToMany(orphanRemoval = true, cascade = CascadeType.ALL)
    @JoinColumn(name = FOREIGN_KEY_ID, nullable = false)
    @OrderBy("id asc")
    private Set<ActeurControle> acteurs = new HashSet<ActeurControle>();
    private final java.util.concurrent.AtomicReference<java.lang.Object> themes = new java.util.concurrent.AtomicReference<java.lang.Object>();
    public Controle() {
    }
    public Integer getId() {
        return this.id;
    }
    public String getLibelle() {
        return this.libelle;
    }
    public String getObjet() {
        return this.objet;
    }
    public String getUrl() {
        return this.url;
    }
    public boolean isInitiativeDesGroupes() {
        return this.initiativeDesGroupes;
    }
    public boolean isCourDesComptes() {
        return this.courDesComptes;
    }
    public int getProgrammeCreation() {
        return this.programmeCreation;
    }
    public Integer getProgrammeReport() {
        return this.programmeReport;
    }
    public LocalDate getDateCreation() {
        return this.dateCreation;
    }
    public boolean isCloture() {
        return this.cloture;
    }
    public boolean isAvecRapport() {
        return this.avecRapport;
    }
    public EcheanceControle getEcheance() {
        return this.echeance;
    }
    public GroupePolitique getGroupePolitique() {
        return this.groupePolitique;
    }
    public Set<Organisme> getOrganismes() {
        return this.organismes;
    }
    public Set<Loi> getLois() {
        return this.lois;
    }
    public Set<LivrableControle> getLivrables() {
        return this.livrables;
    }
    public Set<ActeurControle> getActeurs() {
        return this.acteurs;
    }
    public Set<Theme> getThemes() {
        java.lang.Object value = this.themes.get();
        if (value == null) {
            synchronized(this.themes) {
                value = this.themes.get();
                if (value == null) {
                    final Set<Theme> actualValue = Cache.getInstance().calculateThemes();
                    value = actualValue == null ? this.themes : actualValue;
                    this.themes.set(value);
                }
            }
        }
        return (Set<Theme>)(value == this.themes ? null : value);
     }
    public void setId(final Integer id) {
        this.id = id;
    }
    public void setLibelle(final String libelle) {
        this.libelle = libelle;
    }
    public void setObjet(final String objet) {
        this.objet = objet;
    }
    public void setUrl(final String url) {
        this.url = url;
    }
    public void setInitiativeDesGroupes(final boolean initiativeDesGroupes) {
        this.initiativeDesGroupes = initiativeDesGroupes;
    }
    public void setCourDesComptes(final boolean courDesComptes) {
        this.courDesComptes = courDesComptes;
    }
    public void setProgrammeCreation(final int programmeCreation) {
        this.programmeCreation = programmeCreation;
    }
    public void setProgrammeReport(final Integer programmeReport) {
        this.programmeReport = programmeReport;
    }
    public void setDateCreation(final LocalDate dateCreation) {
        this.dateCreation = dateCreation;
    }
    public void setCloture(final boolean cloture) {
        this.cloture = cloture;
    }
    public void setAvecRapport(final boolean avecRapport) {
        this.avecRapport = avecRapport;
    }
    public void setEcheance(final EcheanceControle echeance) {
        this.echeance = echeance;
    }
    public void setGroupePolitique(final GroupePolitique groupePolitique) {
        this.groupePolitique = groupePolitique;
    }
    public void setOrganismes(final Set<Organisme> organismes) {
        this.organismes = organismes;
    }
    public void setLois(final Set<Loi> lois) {
        this.lois = lois;
    }
    public void setLivrables(final Set<LivrableControle> livrables) {
        this.livrables = livrables;
    }
    public void setActeurs(final Set<ActeurControle> acteurs) {
        this.acteurs = acteurs;
    }
    public void setThemes(final Set<Theme> themes) {
        this.themes = themes;
    }
    
    /**
     * Renvoie la date à prendre en compte pour le nommage du groupe politique lié à ce contrôle. TODO vérifier cette
     * règle de gestion avec S. Dubourg.
     *
     * @return la date à prendre en compte.
     */
    private LocalDate getDateNommageGroupePolitique() {
        if (isClosed()) {
            return echeance.getDate();
        } else {
            return LocalDate.now();
        }
    }
    /**
     * Renvoie le libellé de groupe politique à la date adéquate pour ce contrôle, préfixé de l'article adéquat. Ainsi,
     * un contrôle en cours prendra le nom à la date du jour alors qu'un contrôle fini prendra le nom à la date
     * d'échéance.
     *
     * @return le libellé préfixé de l'article. <code>null</code> si le groupe politique n'est pas défini.
     */
    public String getLibelleLongEtArticleGroupePolitique() {
        if (groupePolitique != null) {
            LocalDate d = getDateNommageGroupePolitique();
            StringBuilder sb = new StringBuilder(groupePolitique.getArticle(d));
            sb.append(" ");
            sb.append(groupePolitique.getLibelleLong(d));
            return sb.toString();
        }
        return null;
    }
    /**
     * Détermine si le contrôle est fini.
     *
     * @return <code>true</code> si le contrôle est fini.
     */
    public boolean isClosed() {
        return echeance != null && echeance.getDate().isBefore(LocalDate.now());
    }
    /**
     * Reporte d'un an le contrôle. La date de début d'activité est inchangée mais la date de report est décalée d'un an
     * (année suivant le démarrage si c'est le premier report)
     */
    public void reporter() {
        if (canReporteControle()) {
            if (programmeReport == null) {
                programmeReport = programmeCreation + 1;
            } else {
                programmeReport++;
            }
        }
    }
    /**
     * Renvoie le dernier programme d'activité du contrôle.
     *
     * @return le dernier programme d'activité du contrôle.
     */
    public int getDernierProgramme() {
        if (programmeReport == null) {
            return programmeCreation;
        } else {
            return programmeReport;
        }
    }
    /**
     * Indique si un contrôle peut être reporté. C'est le cas si l'échéance correspond à une session strictement
     * postérieure supérieure à la session de report actuelle.
     *
     * @return <code>true</code> si le contrôle peut être reporté. <code>false</code> sinon.
     */
    public boolean canReporteControle() {
        if (echeance.getDate() != null) {
            return (getDernierProgramme() < echeance.getSession());
        } else {
            return false;
        }
    }
    /**
     * Renvoie la session correspondant à une date.
     *
     * @param date la date dont on cherche la session.
     * @return la session, représentée par l'année de démarrage de la session (2013 pour la session 2013-2014 par
     * exemple). <code>null</code> si la date en paramètre est nulle.
     */
    public static Integer getSession(LocalDate date) {
        if (date != null) {
            if (date.getMonthOfYear() < OCTOBER) {
                return date.getYear() - 1;
            } else {
                return date.getYear();
            }
        } else {
            return null;
        }
    }
    /**
     * Renvoie l'année de fin d'activité du contrôle.
     *
     * @return l'année de fin d'activité.
     */
    public int getFinActivite() {
        return getDernierProgramme() + 1;
    }
    /**
     * Définit la fin d'activité. Calcule le programme correspondant et définit éventuellement un report sur le
     * contrôle.
     *
     * @param fin l'année de fin d'activité spécifiée dans le formulaire.
     */
    public void setFinActivite(int fin) {
        if (fin > getProgrammeCreation() + 1) {
            setProgrammeReport(fin - 1);
        } else {
            setProgrammeReport(null);
        }
    }
    @java.lang.Override
    public boolean equals(final java.lang.Object o) {
        if (o == this) return true;
        if (!(o instanceof Controle)) return false;
        final Controle other = (Controle)o;
        if (!other.canEqual((java.lang.Object)this)) return false;
        final java.lang.Object this$id = this.getId();
        final java.lang.Object other$id = other.getId();
        if (this$id == null ? other$id != null : !this$id.equals(other$id)) return false;
        final java.lang.Object this$libelle = this.getLibelle();
        final java.lang.Object other$libelle = other.getLibelle();
        if (this$libelle == null ? other$libelle != null : !this$libelle.equals(other$libelle)) return false;
        final java.lang.Object this$objet = this.getObjet();
        final java.lang.Object other$objet = other.getObjet();
        if (this$objet == null ? other$objet != null : !this$objet.equals(other$objet)) return false;
        final java.lang.Object this$url = this.getUrl();
        final java.lang.Object other$url = other.getUrl();
        if (this$url == null ? other$url != null : !this$url.equals(other$url)) return false;
        if (this.isInitiativeDesGroupes() != other.isInitiativeDesGroupes()) return false;
        if (this.isCourDesComptes() != other.isCourDesComptes()) return false;
        if (this.getProgrammeCreation() != other.getProgrammeCreation()) return false;
        final java.lang.Object this$programmeReport = this.getProgrammeReport();
        final java.lang.Object other$programmeReport = other.getProgrammeReport();
        if (this$programmeReport == null ? other$programmeReport != null : !this$programmeReport.equals(other$programmeReport)) return false;
        final java.lang.Object this$dateCreation = this.getDateCreation();
        final java.lang.Object other$dateCreation = other.getDateCreation();
        if (this$dateCreation == null ? other$dateCreation != null : !this$dateCreation.equals(other$dateCreation)) return false;
        if (this.isCloture() != other.isCloture()) return false;
        if (this.isAvecRapport() != other.isAvecRapport()) return false;
        final java.lang.Object this$echeance = this.getEcheance();
        final java.lang.Object other$echeance = other.getEcheance();
        if (this$echeance == null ? other$echeance != null : !this$echeance.equals(other$echeance)) return false;
        final java.lang.Object this$groupePolitique = this.getGroupePolitique();
        final java.lang.Object other$groupePolitique = other.getGroupePolitique();
        if (this$groupePolitique == null ? other$groupePolitique != null : !this$groupePolitique.equals(other$groupePolitique)) return false;
        final java.lang.Object this$organismes = this.getOrganismes();
        final java.lang.Object other$organismes = other.getOrganismes();
        if (this$organismes == null ? other$organismes != null : !this$organismes.equals(other$organismes)) return false;
        final java.lang.Object this$lois = this.getLois();
        final java.lang.Object other$lois = other.getLois();
        if (this$lois == null ? other$lois != null : !this$lois.equals(other$lois)) return false;
        final java.lang.Object this$livrables = this.getLivrables();
        final java.lang.Object other$livrables = other.getLivrables();
        if (this$livrables == null ? other$livrables != null : !this$livrables.equals(other$livrables)) return false;
        final java.lang.Object this$acteurs = this.getActeurs();
        final java.lang.Object other$acteurs = other.getActeurs();
        if (this$acteurs == null ? other$acteurs != null : !this$acteurs.equals(other$acteurs)) return false;
        final java.lang.Object this$themes = this.getThemes();
        final java.lang.Object other$themes = other.getThemes();
        if (this$themes == null ? other$themes != null : !this$themes.equals(other$themes)) return false;
        return true;
    }
    public boolean canEqual(final java.lang.Object other) {
        return other instanceof Controle;
    }
    @java.lang.Override
    public int hashCode() {
        final int PRIME = 59;
        int result = 1;
        final java.lang.Object $id = this.getId();
        result = result * PRIME + ($id == null ? 0 : $id.hashCode());
        final java.lang.Object $libelle = this.getLibelle();
        result = result * PRIME + ($libelle == null ? 0 : $libelle.hashCode());
        final java.lang.Object $objet = this.getObjet();
        result = result * PRIME + ($objet == null ? 0 : $objet.hashCode());
        final java.lang.Object $url = this.getUrl();
        result = result * PRIME + ($url == null ? 0 : $url.hashCode());
        result = result * PRIME + (this.isInitiativeDesGroupes() ? 79 : 97);
        result = result * PRIME + (this.isCourDesComptes() ? 79 : 97);
        result = result * PRIME + this.getProgrammeCreation();
        final java.lang.Object $programmeReport = this.getProgrammeReport();
        result = result * PRIME + ($programmeReport == null ? 0 : $programmeReport.hashCode());
        final java.lang.Object $dateCreation = this.getDateCreation();
        result = result * PRIME + ($dateCreation == null ? 0 : $dateCreation.hashCode());
        result = result * PRIME + (this.isCloture() ? 79 : 97);
        result = result * PRIME + (this.isAvecRapport() ? 79 : 97);
        final java.lang.Object $echeance = this.getEcheance();
        result = result * PRIME + ($echeance == null ? 0 : $echeance.hashCode());
        final java.lang.Object $groupePolitique = this.getGroupePolitique();
        result = result * PRIME + ($groupePolitique == null ? 0 : $groupePolitique.hashCode());
        final java.lang.Object $organismes = this.getOrganismes();
        result = result * PRIME + ($organismes == null ? 0 : $organismes.hashCode());
        final java.lang.Object $lois = this.getLois();
        result = result * PRIME + ($lois == null ? 0 : $lois.hashCode());
        final java.lang.Object $livrables = this.getLivrables();
        result = result * PRIME + ($livrables == null ? 0 : $livrables.hashCode());
        final java.lang.Object $acteurs = this.getActeurs();
        result = result * PRIME + ($acteurs == null ? 0 : $acteurs.hashCode());
        final java.lang.Object $themes = this.getThemes();
        result = result * PRIME + ($themes == null ? 0 : $themes.hashCode());
        return result;
    }
    @java.lang.Override
    public java.lang.String toString() {
        return "Controle(id=" + this.getId() + ", libelle=" + this.getLibelle() + ", objet=" + this.getObjet() + ", url=" + this.getUrl() + ", initiativeDesGroupes=" + this.isInitiativeDesGroupes() + ", courDesComptes=" + this.isCourDesComptes() + ", programmeCreation=" + this.getProgrammeCreation() + ", programmeReport=" + this.getProgrammeReport() + ", dateCreation=" + this.getDateCreation() + ", cloture=" + this.isCloture() + ", avecRapport=" + this.isAvecRapport() + ", echeance=" + this.getEcheance() + ")";
    }
}
				
					<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.12.6</version> <scope>provided</scope> </dependency>
SuperHero.builder().name("Superman").from("Krypton").alias("Clark").build();