Как бы посоветовали получить Immutables для создания этого объекта с такого рода

Как я мог заставить Immutables генерировать класс с такого рода

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

примечание: пустой набор - это заполнитель для реального набора, переданного из какого-то внешнего источника данных, я еще не начал его заполнять, но в какой-то момент я сделаю это, и сортировка - это повторная реализация той, что в весенней безопасности, Вы должны предположить, что сортировку необходимо применить к любому набору, который будет передан сборщику Immutables.

1 ответ

Решение

Есть много вариантов того, как вы можете добиться этого, используя процессор аннотаций Immutables, учитывая, что я понимаю, чего вы пытаетесь достичь;)

Неподвижные опоры SortedSet из коробки, но только используя естественный порядок (см. @Value.NaturalOrder а также @Value.ReverseOrder). Если вы хотите применить специальный компаратор, Immutables позволит вам только построить набор самостоятельно и установить его на строителя. Судя по примеру, желательно, чтобы упорядочение было чем-то конкретным для реализации объекта, поэтому я перейду к другим вариантам.

Существует мощная (но несколько подверженная ошибкам) ​​функциональность, позволяющая нормализовать / канонизировать объект с помощью @Value.Check метод. Это описано в руководстве: http://immutables.github.io/immutable.html. Однако использование нормализации немного усложняется необходимостью проверить, отсортирован ли набор / коллекция.

В конце я бы предложил еще один, более простой подход, который я использовал для аналогичных целей. @Value.Derived аннотация позволяет построить альтернативное представление данных во время построения объекта. В этом случае будет использоваться коллекция, используемая в качестве буфера инициализации, и вычисленное альтернативное представление этих данных. Вычисления произойдут во время строительства, и неизменный объект никогда не изменится после этого. Мы будем играть с именами доступа и атрибутов, чтобы они выглядели красиво. Вот пример:

@ Value.Immutable
открытый абстрактный класс IdentifiedUserDetails реализует UserDetails, CredentialsContainer, Identified {
    приватный статический финал long serialVersionUID = 4905378177558522349L;

    открытый абстрактный UUID getId();
    public abstract String getUsername();
    public abstract String getPassword();
    // другие атрибуты опущены для краткости
    // ...

    abstract @SkipNulls List полномочия ();

    @ Value.Derived
    public SortedSet getAuthorities () {
        вернуть полномочия ().stream()
                .collect(Collectors.toCollection(() -> {
                    вернуть новый TreeSet(
                            Comparator.nullsFirst(Comparator.comparing(GrantedAuthority::getAuthority)));
                }));
    }
}

публичная демонстрация статической пустоты (GrantedAuthority ga1, GrantedAuthority ga2) {

    IdentifiedUserDetails details =
            ImmutableIdentifiedUserDetails.builder()
                    .id(UUID.randomUUID())
                    .username("Name")
                    .password("Строка")
                    //...
                    .addAuthority(GA1).addAuthority (GA2).build ();

    SortedSet sortedAuthorities = details.getAuthorities ();
}

PS @SkipNulls это своего рода аннотация. При необходимости создайте его, и оно будет распознано по простому имени.

Другие вопросы по тегам