2016-12-29 10 views
1

Comment pourrais-je obtenir Immutables pour générer une classe avec ce genreComment serait-il conseillé de se Immutables pour construire cet objet avec ce genre

public class IdentifiedUserDetails implements UserDetails, CredentialsContainer, Identified<UUID> { 
    private static final long serialVersionUID = 4905378177558522349L; 

    private final UUID id; 
    private final String username; 
    private final Set<GrantedAuthority> authorities; 
    private boolean accountNonExpired = true; 
    private boolean accountNonLocked = true; 
    private boolean credentialsNonExpired = true; 
    private boolean enabled = true; 
    private String password; 

    IdentifiedUserDetails(final UUID id, final String username, final String password) { 
     this.id = Objects.requireNonNull(id); 
     this.username = Objects.requireNonNull(username); 
     this.password = Objects.requireNonNull(password); 
     this.authorities = Collections.unmodifiableSet(sortAuthorities(Collections.emptySet())); 
    } 

    private static SortedSet<GrantedAuthority> sortAuthorities(
     final Collection<? extends GrantedAuthority> authorities) { 
     // Ensure array iteration order is predictable (as per 
     // UserDetails.getAuthorities() contract and SEC-717) 
     return authorities.stream() 
      .filter(Objects::nonNull) 
      .collect(Collectors.toCollection(() -> { 
       return new TreeSet<GrantedAuthority>(
        Comparator.nullsFirst(Comparator.comparing(GrantedAuthority::getAuthority))); 
      })); 
    } 
} 

Note: l'ensemble vide est un espace réservé pour un vrai jeu passé à partir d'une source de données externe, je n'ai pas encore commencé à le peupler mais je vais à un moment donné, et le genre est une ré-implémentation de celui de la sécurité de printemps, vous devriez supposer que le tri doit être appliqué à n'importe quel ensemble cela serait transmis au constructeur Immutables.

+0

Votre question n'est pas claire ... – assylias

+0

@assylias comment n'est-il pas clair? Qu'est-ce que tu ne comprends pas? – xenoterracide

+0

Il n'est vraiment pas clair ce que vous voulez accomplir avec votre code; et où vous avez perçu le problème est! – GhostCat

Répondre

1

Il y a beaucoup de variations sur la façon dont vous pouvez y parvenir en utilisant le processeur d'annotation Immutables, étant donné que je comprends ce que vous essayez d'atteindre;)

Immutables soutient SortedSet hors de la boîte, mais seulement en utilisant l'ordre naturel (voir @Value.NaturalOrder et @Value.ReverseOrder). Si vous voulez appliquer un comparateur spécial, Immutables vous permettra seulement de construire l'ensemble vous-même et de le définir sur un constructeur. A en juger par l'exemple, il est souhaitable que la commande soit quelque chose de spécifique à l'implémentation de l'objet, donc je passerai à d'autres options.

La fonctionnalité @Value.Check permet de normaliser/canoniser l'objet avec une fonctionnalité puissante (mais plutôt sujette aux erreurs). Il est décrit dans le guide: http://immutables.github.io/immutable.html#normalization. Cependant, l'utilisation de la normalisation est un peu compliquée par la nécessité de vérifier si un ensemble/collection est déjà trié. En fin de compte, je proposerais une autre approche, plus simple, que j'ai utilisée à des fins similaires. @Value.Derived L'annotation vous permet de créer une vue alternative d'une donnée pendant la construction de l'objet. Dans ce cas, il y aura une collection utilisée comme tampon d'initialisation et la vue alternative calculée de ces données. Le calcul aura lieu pendant la construction et un objet immuable ne changera jamais après cela. Nous jouerons avec les noms d'accès et d'attributs pour le rendre joli. Voici l'exemple:

 
@Value.Immutable 
public abstract class IdentifiedUserDetails implements UserDetails, CredentialsContainer, Identified<UUID> { 
    private static final long serialVersionUID = 4905378177558522349L; 

    public abstract UUID getId(); 
    public abstract String getUsername(); 
    public abstract String getPassword(); 
    // other attributes omitted for brevity 
    // ... 

    abstract @SkipNulls List<GrantedAuthority> authority(); 

    @Value.Derived 
    public SortedSet<GrantedAuthority> getAuthorities() { 
     return authority().stream() 
       .collect(Collectors.toCollection(() -> { 
        return new TreeSet(
          Comparator.nullsFirst(Comparator.comparing(GrantedAuthority::getAuthority))); 
       })); 
    } 
} 

public static void demonstration(GrantedAuthority ga1, GrantedAuthority ga2) { 

    IdentifiedUserDetails details = 
      ImmutableIdentifiedUserDetails.builder() 
        .id(UUID.randomUUID()) 
        .username("Name") 
        .password("String") 
        //... 
        .addAuthority(ga1) 
        .addAuthority(ga2) 
        .build(); 

    SortedSet<GrantedAuthority> sortedAuthorities = details.getAuthorities(); 
} 

P.S. @SkipNulls est une sorte de BYOAnnotation. Créez-le, si nécessaire, et il sera reconnu par un nom simple.