Polishing.
Replace instanceof check with pattern variable in production code. Add missing Deprecated annotations. See #2967 Original pull request: #2971
This commit is contained in:
@@ -151,10 +151,9 @@ public class BitFieldSubCommands implements Iterable<BitFieldSubCommand> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BitFieldSubCommands)) {
|
||||
if (!(o instanceof BitFieldSubCommands that)) {
|
||||
return false;
|
||||
}
|
||||
BitFieldSubCommands that = (BitFieldSubCommands) o;
|
||||
return ObjectUtils.nullSafeEquals(subCommands, that.subCommands);
|
||||
}
|
||||
|
||||
@@ -437,10 +436,9 @@ public class BitFieldSubCommands implements Iterable<BitFieldSubCommand> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof Offset)) {
|
||||
if (!(o instanceof Offset that)) {
|
||||
return false;
|
||||
}
|
||||
Offset that = (Offset) o;
|
||||
if (offset != that.offset) {
|
||||
return false;
|
||||
}
|
||||
@@ -549,10 +547,9 @@ public class BitFieldSubCommands implements Iterable<BitFieldSubCommand> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BitFieldType)) {
|
||||
if (!(o instanceof BitFieldType that)) {
|
||||
return false;
|
||||
}
|
||||
BitFieldType that = (BitFieldType) o;
|
||||
if (signed != that.signed) {
|
||||
return false;
|
||||
}
|
||||
@@ -597,10 +594,9 @@ public class BitFieldSubCommands implements Iterable<BitFieldSubCommand> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof AbstractBitFieldSubCommand)) {
|
||||
if (!(o instanceof AbstractBitFieldSubCommand that)) {
|
||||
return false;
|
||||
}
|
||||
AbstractBitFieldSubCommand that = (AbstractBitFieldSubCommand) o;
|
||||
if (!ObjectUtils.nullSafeEquals(getClass(), that.getClass())) {
|
||||
return false;
|
||||
}
|
||||
@@ -680,13 +676,12 @@ public class BitFieldSubCommands implements Iterable<BitFieldSubCommand> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BitFieldSet)) {
|
||||
if (!(o instanceof BitFieldSet that)) {
|
||||
return false;
|
||||
}
|
||||
if (!super.equals(o)) {
|
||||
return false;
|
||||
}
|
||||
BitFieldSet that = (BitFieldSet) o;
|
||||
if (value != that.value) {
|
||||
return false;
|
||||
}
|
||||
@@ -832,10 +827,9 @@ public class BitFieldSubCommands implements Iterable<BitFieldSubCommand> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BitFieldIncrBy)) {
|
||||
if (!(o instanceof BitFieldIncrBy that)) {
|
||||
return false;
|
||||
}
|
||||
BitFieldIncrBy that = (BitFieldIncrBy) o;
|
||||
if (value != that.value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -108,10 +108,9 @@ public class RedisSocketConfiguration implements RedisConfiguration, DomainSocke
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof RedisSocketConfiguration)) {
|
||||
if (!(o instanceof RedisSocketConfiguration that)) {
|
||||
return false;
|
||||
}
|
||||
RedisSocketConfiguration that = (RedisSocketConfiguration) o;
|
||||
if (database != that.database) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -137,10 +137,9 @@ public class RedisStandaloneConfiguration
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof RedisStandaloneConfiguration)) {
|
||||
if (!(o instanceof RedisStandaloneConfiguration that)) {
|
||||
return false;
|
||||
}
|
||||
RedisStandaloneConfiguration that = (RedisStandaloneConfiguration) o;
|
||||
if (port != that.port) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -159,10 +159,9 @@ public class RedisStaticMasterReplicaConfiguration implements RedisConfiguration
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof RedisStaticMasterReplicaConfiguration)) {
|
||||
if (!(o instanceof RedisStaticMasterReplicaConfiguration that)) {
|
||||
return false;
|
||||
}
|
||||
RedisStaticMasterReplicaConfiguration that = (RedisStaticMasterReplicaConfiguration) o;
|
||||
if (database != that.database) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -246,10 +246,9 @@ public interface RedisStreamCommands {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof XAddOptions)) {
|
||||
if (!(o instanceof XAddOptions that)) {
|
||||
return false;
|
||||
}
|
||||
XAddOptions that = (XAddOptions) o;
|
||||
if (nomkstream != that.nomkstream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,10 +51,9 @@ class SentinelMasterId implements NamedNode {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SentinelMasterId)) {
|
||||
if (!(o instanceof SentinelMasterId that)) {
|
||||
return false;
|
||||
}
|
||||
SentinelMasterId that = (SentinelMasterId) o;
|
||||
return ObjectUtils.nullSafeEquals(name, that.name);
|
||||
}
|
||||
|
||||
|
||||
@@ -748,9 +748,8 @@ abstract class JedisConverters extends Converters {
|
||||
return param;
|
||||
}
|
||||
|
||||
if (predicate instanceof BoxShape) {
|
||||
if (predicate instanceof BoxShape boxPredicate) {
|
||||
|
||||
BoxShape boxPredicate = (BoxShape) predicate;
|
||||
BoundingBox boundingBox = boxPredicate.getBoundingBox();
|
||||
|
||||
param.byBox(boundingBox.getWidth().getValue(), boundingBox.getHeight().getValue(),
|
||||
@@ -770,9 +769,8 @@ abstract class JedisConverters extends Converters {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reference instanceof GeoReference.GeoCoordinateReference) {
|
||||
if (reference instanceof GeoReference.GeoCoordinateReference<?> coordinates) {
|
||||
|
||||
GeoReference.GeoCoordinateReference<?> coordinates = (GeoReference.GeoCoordinateReference<?>) reference;
|
||||
param.fromLonLat(coordinates.getLongitude(), coordinates.getLatitude());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -96,9 +96,8 @@ class StreamConverters {
|
||||
|
||||
if (v instanceof StreamEntryID) {
|
||||
sources.add(v.toString());
|
||||
} else if (v instanceof StreamEntry) {
|
||||
} else if (v instanceof StreamEntry streamEntry) {
|
||||
List<Object> entries = new ArrayList<>(2);
|
||||
StreamEntry streamEntry = (StreamEntry) v;
|
||||
entries.add(streamEntry.getID().toString());
|
||||
entries.add(streamEntry.getFields());
|
||||
sources.add(entries);
|
||||
|
||||
@@ -863,9 +863,8 @@ public abstract class LettuceConverters extends Converters {
|
||||
return GeoSearch.byRadius(radius.getValue(), toGeoArgsUnit(radius.getMetric()));
|
||||
}
|
||||
|
||||
if (predicate instanceof BoxShape) {
|
||||
if (predicate instanceof BoxShape boxPredicate) {
|
||||
|
||||
BoxShape boxPredicate = (BoxShape) predicate;
|
||||
BoundingBox boundingBox = boxPredicate.getBoundingBox();
|
||||
|
||||
return GeoSearch.byBox(boundingBox.getWidth().getValue(), boundingBox.getHeight().getValue(),
|
||||
@@ -881,9 +880,7 @@ public abstract class LettuceConverters extends Converters {
|
||||
return GeoSearch.fromMember(((GeoMemberReference<T>) reference).getMember());
|
||||
}
|
||||
|
||||
if (reference instanceof GeoReference.GeoCoordinateReference) {
|
||||
|
||||
GeoCoordinateReference<?> coordinates = (GeoCoordinateReference<?>) reference;
|
||||
if (reference instanceof GeoCoordinateReference<?> coordinates) {
|
||||
|
||||
return GeoSearch.fromCoordinates(coordinates.getLongitude(), coordinates.getLatitude());
|
||||
}
|
||||
|
||||
@@ -165,9 +165,8 @@ class LettucePoolingConnectionProvider implements LettuceConnectionProvider, Red
|
||||
|
||||
private void discardIfNecessary(StatefulConnection<?, ?> connection) {
|
||||
|
||||
if (connection instanceof StatefulRedisConnection) {
|
||||
if (connection instanceof StatefulRedisConnection<?, ?> redisConnection) {
|
||||
|
||||
StatefulRedisConnection<?, ?> redisConnection = (StatefulRedisConnection<?, ?>) connection;
|
||||
if (redisConnection.isMulti()) {
|
||||
redisConnection.async().discard();
|
||||
}
|
||||
|
||||
@@ -58,9 +58,8 @@ public class DefaultTuple implements Tuple {
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (!(obj instanceof DefaultTuple))
|
||||
if (!(obj instanceof DefaultTuple other))
|
||||
return false;
|
||||
DefaultTuple other = (DefaultTuple) obj;
|
||||
if (score == null) {
|
||||
if (other.score != null)
|
||||
return false;
|
||||
|
||||
@@ -151,11 +151,10 @@ public class Weights {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Weights)) {
|
||||
if (!(o instanceof Weights that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Weights that = (Weights) o;
|
||||
return ObjectUtils.nullSafeEquals(this.weights, that.weights);
|
||||
}
|
||||
|
||||
|
||||
@@ -185,6 +185,7 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
* @deprecated since 3.0, use {@link #difference(Object)} instead to follow a consistent method naming scheme.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(since = "3.0")
|
||||
default Set<V> diff(K key) {
|
||||
return difference(key);
|
||||
}
|
||||
@@ -209,6 +210,7 @@ public interface BoundSetOperations<K, V> extends BoundKeyOperations<K> {
|
||||
* @deprecated since 3.0, use {@link #difference(Collection)} instead to follow a consistent method naming scheme.
|
||||
*/
|
||||
@Nullable
|
||||
@Deprecated(since = "3.0")
|
||||
default Set<V> diff(Collection<K> keys) {
|
||||
return difference(keys);
|
||||
}
|
||||
|
||||
@@ -74,11 +74,10 @@ public class GeoIndexedPropertyValue implements IndexedData {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof GeoIndexedPropertyValue)) {
|
||||
if (!(o instanceof GeoIndexedPropertyValue that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GeoIndexedPropertyValue that = (GeoIndexedPropertyValue) o;
|
||||
if (!ObjectUtils.nullSafeEquals(keyspace, that.keyspace)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,10 +105,9 @@ public abstract class RedisIndexDefinition implements IndexDefinition {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (!(obj instanceof RedisIndexDefinition)) {
|
||||
if (!(obj instanceof RedisIndexDefinition that)) {
|
||||
return false;
|
||||
}
|
||||
RedisIndexDefinition that = (RedisIndexDefinition) obj;
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(this.keyspace, that.keyspace)) {
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.data.redis.domain.geo;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -94,10 +93,9 @@ public class BoundingBox implements Shape {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BoundingBox)) {
|
||||
if (!(o instanceof BoundingBox that)) {
|
||||
return false;
|
||||
}
|
||||
BoundingBox that = (BoundingBox) o;
|
||||
if (!ObjectUtils.nullSafeEquals(width, that.width)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
@@ -49,12 +48,10 @@ public class GeoLocation<T> {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof GeoLocation)) {
|
||||
if (!(o instanceof GeoLocation<?> that)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GeoLocation<?> that = (GeoLocation<?>) o;
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(name, that.name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -133,10 +133,9 @@ public interface GeoReference<T> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof GeoReference.GeoMemberReference)) {
|
||||
if (!(o instanceof GeoMemberReference<?> that)) {
|
||||
return false;
|
||||
}
|
||||
GeoMemberReference<?> that = (GeoMemberReference<?>) o;
|
||||
return ObjectUtils.nullSafeEquals(member, that.member);
|
||||
}
|
||||
|
||||
@@ -178,10 +177,9 @@ public interface GeoReference<T> {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof GeoReference.GeoCoordinateReference)) {
|
||||
if (!(o instanceof GeoCoordinateReference<?> that)) {
|
||||
return false;
|
||||
}
|
||||
GeoCoordinateReference<?> that = (GeoCoordinateReference<?>) o;
|
||||
if (longitude != that.longitude) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -15,23 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.redis.hash;
|
||||
|
||||
import static com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping.EVERYTHING;
|
||||
import static com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.data.mapping.MappingException;
|
||||
import org.springframework.data.redis.support.collections.CollectionUtils;
|
||||
@@ -379,13 +368,11 @@ public class Jackson2HashMapper implements HashMapper<Object, String, Object> {
|
||||
|
||||
private void flattenElement(String propertyPrefix, Object source, Map<String, Object> resultMap) {
|
||||
|
||||
if (!(source instanceof JsonNode)) {
|
||||
if (!(source instanceof JsonNode element)) {
|
||||
resultMap.put(propertyPrefix, source);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonNode element = (JsonNode) source;
|
||||
|
||||
if (element.isArray()) {
|
||||
|
||||
Iterator<JsonNode> nodes = element.elements();
|
||||
|
||||
@@ -135,8 +135,8 @@ public class ReactiveRedisMessageListenerContainer implements DisposableBean {
|
||||
*/
|
||||
public Collection<ReactiveSubscription> getActiveSubscriptions() {
|
||||
|
||||
return subscriptions.entrySet().stream().filter(entry -> entry.getValue().hasRegistration())
|
||||
.map(Map.Entry::getKey).collect(Collectors.toList());
|
||||
return subscriptions.entrySet().stream().filter(entry -> entry.getValue().hasRegistration()).map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,8 +295,7 @@ public class ReactiveRedisMessageListenerContainer implements DisposableBean {
|
||||
}
|
||||
|
||||
return doReceive(channelSerializer, messageSerializer,
|
||||
getRequiredConnection().pubSubCommands().createSubscription(subscriptionListener), patterns,
|
||||
channels);
|
||||
getRequiredConnection().pubSubCommands().createSubscription(subscriptionListener), patterns, channels);
|
||||
}
|
||||
|
||||
private <C, B> Flux<Message<C, B>> doReceive(SerializationPair<C> channelSerializer,
|
||||
@@ -361,7 +360,7 @@ public class ReactiveRedisMessageListenerContainer implements DisposableBean {
|
||||
|
||||
return doReceiveLater(channelSerializer, messageSerializer,
|
||||
getRequiredConnection().pubSubCommands().createSubscription(readyListener), patterns, channels)
|
||||
.delayUntil(it -> readyListener.getTrigger());
|
||||
.delayUntil(it -> readyListener.getTrigger());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -441,7 +440,7 @@ public class ReactiveRedisMessageListenerContainer implements DisposableBean {
|
||||
private <C, B> Message<C, B> readMessage(RedisElementReader<C> channelSerializer,
|
||||
RedisElementReader<B> messageSerializer, Message<ByteBuffer, ByteBuffer> message) {
|
||||
|
||||
if (message instanceof PatternMessage) {
|
||||
if (message instanceof PatternMessage<?, ?, ?>) {
|
||||
|
||||
PatternMessage<ByteBuffer, ByteBuffer, ByteBuffer> patternMessage = (PatternMessage<ByteBuffer, ByteBuffer, ByteBuffer>) message;
|
||||
|
||||
|
||||
@@ -70,8 +70,7 @@ public class RedisKeyValueAdapterBean extends CdiBean<RedisKeyValueAdapter> {
|
||||
return type;
|
||||
}
|
||||
|
||||
if (type instanceof ParameterizedType) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) type;
|
||||
if (type instanceof ParameterizedType parameterizedType) {
|
||||
if (parameterizedType.getRawType() instanceof Class<?>
|
||||
&& RedisOperations.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())) {
|
||||
return type;
|
||||
|
||||
@@ -224,9 +224,7 @@ class DefaultStreamMessageListenerContainer<K, V extends Record<K, ?>> implement
|
||||
byte[] rawKey = ((RedisSerializer<K>) template.getKeySerializer())
|
||||
.serialize(streamRequest.getStreamOffset().getKey());
|
||||
|
||||
if (streamRequest instanceof StreamMessageListenerContainer.ConsumerStreamReadRequest) {
|
||||
|
||||
ConsumerStreamReadRequest<K> consumerStreamRequest = (ConsumerStreamReadRequest<K>) streamRequest;
|
||||
if (streamRequest instanceof ConsumerStreamReadRequest<K> consumerStreamRequest) {
|
||||
|
||||
StreamReadOptions readOptions = consumerStreamRequest.isAutoAcknowledge() ? this.readOptions.autoAcknowledge()
|
||||
: this.readOptions;
|
||||
|
||||
@@ -170,10 +170,10 @@ public class PubSubTests<T> {
|
||||
|
||||
private static boolean isClusterAware(RedisConnectionFactory connectionFactory) {
|
||||
|
||||
if (connectionFactory instanceof LettuceConnectionFactory lettuceConnectionFactory) {
|
||||
return lettuceConnectionFactory.isClusterAware();
|
||||
} else if (connectionFactory instanceof JedisConnectionFactory jedisConnectionFactory) {
|
||||
return jedisConnectionFactory.isRedisClusterAware();
|
||||
if (connectionFactory instanceof LettuceConnectionFactory lettuce) {
|
||||
return lettuce.isClusterAware();
|
||||
} else if (connectionFactory instanceof JedisConnectionFactory jedis) {
|
||||
return jedis.isRedisClusterAware();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.springframework.data.redis.stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import io.lettuce.core.codec.StringCodec;
|
||||
import io.lettuce.core.output.NestedMultiOutput;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
@@ -48,9 +51,6 @@ import org.springframework.data.redis.stream.StreamMessageListenerContainer.Stre
|
||||
import org.springframework.data.redis.test.condition.EnabledOnCommand;
|
||||
import org.springframework.util.NumberUtils;
|
||||
|
||||
import io.lettuce.core.codec.StringCodec;
|
||||
import io.lettuce.core.output.NestedMultiOutput;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link StreamMessageListenerContainer}.
|
||||
*
|
||||
@@ -395,9 +395,9 @@ abstract class AbstractStreamMessageListenerContainerIntegrationTests {
|
||||
|
||||
RedisConnection connection = connectionFactory.getConnection();
|
||||
|
||||
if (connection instanceof LettuceConnection lettuceConnection) {
|
||||
if (connection instanceof LettuceConnection lettuce) {
|
||||
|
||||
String value = ((List) lettuceConnection.execute("XPENDING",
|
||||
String value = ((List) lettuce.execute("XPENDING",
|
||||
new NestedMultiOutput<>(StringCodec.UTF8), new byte[][] { stream.getBytes(), group.getBytes() })).get(0)
|
||||
.toString();
|
||||
return NumberUtils.parseNumber(value, Integer.class);
|
||||
|
||||
@@ -123,10 +123,10 @@ public class BoundKeyOperationsIntegrationTests {
|
||||
collection.add("dummy");
|
||||
} else if (keyOps instanceof Map map) {
|
||||
map.put("dummy", "dummy");
|
||||
} else if (keyOps instanceof RedisAtomicInteger redisAtomicInteger) {
|
||||
redisAtomicInteger.set(42);
|
||||
} else if (keyOps instanceof RedisAtomicLong redisAtomicLong) {
|
||||
redisAtomicLong.set(42L);
|
||||
} else if (keyOps instanceof RedisAtomicInteger atomic) {
|
||||
atomic.set(42);
|
||||
} else if (keyOps instanceof RedisAtomicLong atomic) {
|
||||
atomic.set(42L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user