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();