DATALDAP-45 - Introduced usage of nullable annotations for API validation.
Mark all packages with Spring Frameworks @NonNullApi. Add Spring's @Nullable to methods, parameters and fields that take or produce null values. Adapt using code to make sure the IDE can evaluate the null flow properly. Introduce methods that return required (non-null) values.
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* XML configuration support for Spring Data LDAP repositories.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.data.ldap.config;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Support infrastructure for the configuration of LDAP specific repositories.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.data.ldap.repository.config;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
@@ -38,7 +38,7 @@ public abstract class AbstractLdapRepositoryQuery implements RepositoryQuery {
|
||||
/**
|
||||
* Creates a new {@link AbstractLdapRepositoryQuery} instance given {@link LdapQuery}, {@link Class} and
|
||||
* {@link LdapOperations}.
|
||||
*
|
||||
*
|
||||
* @param queryMethod must not be {@literal null}.
|
||||
* @param entityType must not be {@literal null}.
|
||||
* @param ldapOperations must not be {@literal null}.
|
||||
@@ -58,6 +58,7 @@ public abstract class AbstractLdapRepositoryQuery implements RepositoryQuery {
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public final Object execute(Object[] parameters) {
|
||||
|
||||
LdapQuery query = createQuery(parameters);
|
||||
@@ -75,7 +76,7 @@ public abstract class AbstractLdapRepositoryQuery implements RepositoryQuery {
|
||||
|
||||
/**
|
||||
* Creates a {@link Query} instance using the given {@literal parameters}.
|
||||
*
|
||||
*
|
||||
* @param parameters must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +26,7 @@ import org.springframework.util.Assert;
|
||||
* Handles queries for repository methods annotated with {@link org.springframework.data.ldap.repository.Query}.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class AnnotatedLdapRepositoryQuery extends AbstractLdapRepositoryQuery {
|
||||
|
||||
@@ -33,7 +34,7 @@ public class AnnotatedLdapRepositoryQuery extends AbstractLdapRepositoryQuery {
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*
|
||||
*
|
||||
* @param queryMethod the QueryMethod.
|
||||
* @param entityType the managed class.
|
||||
* @param ldapOperations the LdapOperations instance to use.
|
||||
@@ -45,7 +46,7 @@ public class AnnotatedLdapRepositoryQuery extends AbstractLdapRepositoryQuery {
|
||||
Assert.notNull(queryMethod.getQueryAnnotation(), "Annotation must be present");
|
||||
Assert.hasLength(queryMethod.getQueryAnnotation().value(), "Query filter must be specified");
|
||||
|
||||
queryAnnotation = queryMethod.getQueryAnnotation();
|
||||
queryAnnotation = queryMethod.getRequiredQueryAnnotation();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -19,6 +19,7 @@ import static org.springframework.ldap.query.LdapQueryBuilder.*;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.mapping.PropertyPath;
|
||||
import org.springframework.data.repository.query.Parameters;
|
||||
@@ -31,6 +32,7 @@ import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
|
||||
import org.springframework.ldap.query.ConditionCriteria;
|
||||
import org.springframework.ldap.query.ContainerCriteria;
|
||||
import org.springframework.ldap.query.LdapQuery;
|
||||
import org.springframework.ldap.query.LdapQueryBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -71,8 +73,15 @@ class LdapQueryCreator extends AbstractQueryCreator<LdapQuery, ContainerCriteria
|
||||
@Override
|
||||
protected ContainerCriteria create(Part part, Iterator<Object> iterator) {
|
||||
|
||||
String base = entityType.getAnnotation(Entry.class).base();
|
||||
ConditionCriteria criteria = query().base(base).where(getAttribute(part));
|
||||
Entry entry = AnnotatedElementUtils.findMergedAnnotation(entityType, Entry.class);
|
||||
|
||||
LdapQueryBuilder query = query();
|
||||
|
||||
if (entry != null) {
|
||||
query = query.base(entry.base());
|
||||
}
|
||||
|
||||
ConditionCriteria criteria = query.where(getAttribute(part));
|
||||
|
||||
return appendCondition(part, iterator, criteria);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,12 +22,14 @@ import org.springframework.data.ldap.repository.Query;
|
||||
import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryMethod;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* QueryMethod for Ldap Queries.
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Eddu Melendez
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class LdapQueryMethod extends QueryMethod {
|
||||
|
||||
@@ -48,7 +50,7 @@ public class LdapQueryMethod extends QueryMethod {
|
||||
|
||||
/**
|
||||
* Check whether the target method is annotated with {@link org.springframework.data.ldap.repository.Query}.
|
||||
*
|
||||
*
|
||||
* @return <code>true</code> if the target method is annotated with
|
||||
* {@link org.springframework.data.ldap.repository.Query}, <code>false</code> otherwise.
|
||||
*/
|
||||
@@ -58,11 +60,29 @@ public class LdapQueryMethod extends QueryMethod {
|
||||
|
||||
/**
|
||||
* Get the {@link org.springframework.data.ldap.repository.Query} annotation of the target method (if any).
|
||||
*
|
||||
*
|
||||
* @return the {@link org.springframework.data.ldap.repository.Query} annotation of the target method if present, or
|
||||
* <code>null</code> otherwise.
|
||||
*/
|
||||
@Nullable
|
||||
Query getQueryAnnotation() {
|
||||
return AnnotationUtils.getAnnotation(method, Query.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the required {@link org.springframework.data.ldap.repository.Query} annotation of the target method.
|
||||
*
|
||||
* @return the {@link org.springframework.data.ldap.repository.Query} annotation of the target method if present, or
|
||||
* {@link IllegalStateException} otherwise.
|
||||
*/
|
||||
Query getRequiredQueryAnnotation() {
|
||||
|
||||
Query queryAnnotation = getQueryAnnotation();
|
||||
|
||||
if (queryAnnotation != null) {
|
||||
return queryAnnotation;
|
||||
}
|
||||
|
||||
throw new IllegalStateException("Required @Query annotation is not present!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Query derivation mechanism for LDAP specific repositories.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.data.ldap.repository.query;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,22 +22,24 @@ import java.util.Map;
|
||||
import javax.annotation.processing.RoundEnvironment;
|
||||
import javax.lang.model.element.VariableElement;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.ldap.odm.annotations.Id;
|
||||
|
||||
import com.querydsl.apt.DefaultConfiguration;
|
||||
|
||||
/**
|
||||
* Configuration for {@link LdapAnnotationProcessor}.
|
||||
*
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Eddu Melendez
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class DefaultLdapAnnotationProcessorConfiguration extends DefaultConfiguration {
|
||||
|
||||
public DefaultLdapAnnotationProcessorConfiguration(RoundEnvironment roundEnv, Map<String, String> options,
|
||||
Collection<String> keywords, Class<? extends Annotation> entitiesAnn, Class<? extends Annotation> entityAnn,
|
||||
Class<? extends Annotation> superTypeAnn, Class<? extends Annotation> embeddableAnn,
|
||||
Class<? extends Annotation> embeddedAnn, Class<? extends Annotation> skipAnn) {
|
||||
@Nullable Class<? extends Annotation> superTypeAnn, @Nullable Class<? extends Annotation> embeddableAnn,
|
||||
@Nullable Class<? extends Annotation> embeddedAnn, Class<? extends Annotation> skipAnn) {
|
||||
|
||||
super(roundEnv, options, keywords, entitiesAnn, entityAnn, superTypeAnn, embeddableAnn, embeddedAnn, skipAnn);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.ldap.repository.support;
|
||||
|
||||
import javax.naming.Name;
|
||||
|
||||
import org.springframework.data.repository.core.support.AbstractEntityInformation;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.ldap.odm.core.impl.DefaultObjectDirectoryMapper;
|
||||
|
||||
/**
|
||||
* ODM-based {@link org.springframework.data.repository.core.EntityInformation} for LDAP entities.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.0
|
||||
* @see org.springframework.ldap.odm.core.ObjectDirectoryMapper
|
||||
* @see org.springframework.ldap.odm.annotations.Entry
|
||||
*/
|
||||
class LdapEntityInformation<T> extends AbstractEntityInformation<T, Name> {
|
||||
|
||||
private final DefaultObjectDirectoryMapper MAPPER = new DefaultObjectDirectoryMapper();
|
||||
|
||||
public LdapEntityInformation(Class<T> domainClass) {
|
||||
super(domainClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Name getId(T entity) {
|
||||
return MAPPER.getId(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Name> getIdType() {
|
||||
return Name.class;
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ package org.springframework.data.ldap.repository.support;
|
||||
|
||||
import static org.springframework.data.querydsl.QuerydslUtils.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Optional;
|
||||
|
||||
@@ -35,6 +34,7 @@ import org.springframework.data.repository.query.EvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.ldap.core.LdapOperations;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -68,8 +68,9 @@ public class LdapRepositoryFactory extends RepositoryFactorySupport {
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getEntityInformation(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> domainClass) {
|
||||
return null;
|
||||
return new LdapEntityInformation(domainClass);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -99,7 +100,7 @@ public class LdapRepositoryFactory extends RepositoryFactorySupport {
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
|
||||
*/
|
||||
@Override
|
||||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(Key key,
|
||||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(@Nullable Key key,
|
||||
EvaluationContextProvider evaluationContextProvider) {
|
||||
return Optional.of(queryLookupStrategy);
|
||||
}
|
||||
@@ -109,9 +110,9 @@ public class LdapRepositoryFactory extends RepositoryFactorySupport {
|
||||
private LdapOperations ldapOperations;
|
||||
|
||||
/**
|
||||
* @param ldapOperations
|
||||
* @param ldapOperations must not be {@literal null}.
|
||||
*/
|
||||
public LdapQueryLookupStrategy(LdapOperations ldapOperations) {
|
||||
LdapQueryLookupStrategy(LdapOperations ldapOperations) {
|
||||
this.ldapOperations = ldapOperations;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -20,6 +20,7 @@ import javax.naming.Name;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.ldap.core.LdapOperations;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -29,15 +30,16 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Mattias Hellborg Arthursson
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public class LdapRepositoryFactoryBean<T extends Repository<S, Name>, S>
|
||||
extends RepositoryFactoryBeanSupport<T, S, Name> {
|
||||
|
||||
private LdapOperations ldapOperations;
|
||||
private @Nullable LdapOperations ldapOperations;
|
||||
|
||||
/**
|
||||
* Creates a new {@link LdapRepositoryFactoryBean} for the given repository interface.
|
||||
*
|
||||
*
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
*/
|
||||
public LdapRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
|
||||
@@ -54,6 +56,9 @@ public class LdapRepositoryFactoryBean<T extends Repository<S, Name>, S>
|
||||
*/
|
||||
@Override
|
||||
protected RepositoryFactorySupport createRepositoryFactory() {
|
||||
|
||||
Assert.state(ldapOperations != null, "LdapOperations must be set");
|
||||
|
||||
return new LdapRepositoryFactory(ldapOperations);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 the original author or authors.
|
||||
* Copyright 2016-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -41,7 +41,7 @@ class LdapSerializer implements Visitor<Object, Void> {
|
||||
|
||||
/**
|
||||
* Creates a new {@link LdapSerializer}.
|
||||
*
|
||||
*
|
||||
* @param odm
|
||||
* @param entityType
|
||||
*/
|
||||
|
||||
@@ -42,8 +42,7 @@ public class QuerydslLdapQuery<K> implements FilteredClause<QuerydslLdapQuery<K>
|
||||
private final Class<? extends K> entityType;
|
||||
private final LdapSerializer filterGenerator;
|
||||
|
||||
private QueryMixin<QuerydslLdapQuery<K>> queryMixin = new QueryMixin<>(this,
|
||||
new DefaultQueryMetadata().noValidate());
|
||||
private QueryMixin<QuerydslLdapQuery<K>> queryMixin = new QueryMixin<>(this, new DefaultQueryMetadata().noValidate());
|
||||
|
||||
/**
|
||||
* Creates a new {@link QuerydslLdapQuery}.
|
||||
@@ -88,8 +87,13 @@ public class QuerydslLdapQuery<K> implements FilteredClause<QuerydslLdapQuery<K>
|
||||
return ldapOperations.findOne(buildQuery(), entityType);
|
||||
}
|
||||
|
||||
LdapQuery buildQuery() {
|
||||
return query().filter(filterGenerator.handle(queryMixin.getMetadata().getWhere()));
|
||||
}
|
||||
private LdapQuery buildQuery() {
|
||||
|
||||
Predicate where = queryMixin.getMetadata().getWhere();
|
||||
if (where != null) {
|
||||
return query().filter(filterGenerator.handle(where));
|
||||
}
|
||||
|
||||
return query();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.dao.EmptyResultDataAccessException;
|
||||
import org.springframework.data.domain.Persistable;
|
||||
import org.springframework.data.ldap.repository.LdapRepository;
|
||||
import org.springframework.data.util.Optionals;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.ldap.NameNotFoundException;
|
||||
import org.springframework.ldap.core.LdapOperations;
|
||||
import org.springframework.ldap.core.support.CountNameClassPairCallbackHandler;
|
||||
@@ -83,7 +84,7 @@ public class SimpleLdapRepository<T> implements LdapRepository<T> {
|
||||
return callback.getNoOfRows();
|
||||
}
|
||||
|
||||
private <S extends T> boolean isNew(S entity, Name id) {
|
||||
private <S extends T> boolean isNew(S entity, @Nullable Name id) {
|
||||
|
||||
if (entity instanceof Persistable) {
|
||||
Persistable<?> persistable = (Persistable<?>) entity;
|
||||
@@ -171,7 +172,7 @@ public class SimpleLdapRepository<T> implements LdapRepository<T> {
|
||||
|
||||
Assert.notNull(name, "Id must not be null");
|
||||
|
||||
return findById(name) != null;
|
||||
return findById(name).isPresent();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Support infrastructure for query derivation of LDAP specific repositories.
|
||||
*/
|
||||
@NonNullApi
|
||||
package org.springframework.data.ldap.repository.support;
|
||||
|
||||
import org.springframework.lang.NonNullApi;
|
||||
Reference in New Issue
Block a user