com.arangodb.shaded.vertx.core.shareddata.impl.Checker Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2022 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
*
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
*/
package com.arangodb.shaded.vertx.core.shareddata.impl;
import com.arangodb.shaded.vertx.core.impl.ClusterSerializableUtils;
import com.arangodb.shaded.vertx.core.impl.SerializableUtils;
import com.arangodb.shaded.vertx.core.impl.logging.Logger;
import com.arangodb.shaded.vertx.core.impl.logging.LoggerFactory;
import com.arangodb.shaded.vertx.core.shareddata.Shareable;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toSet;
/**
* @author Tim Fox
*/
class Checker {
private static final Logger log = LoggerFactory.getLogger(Checker.class);
private static final Set> IMMUTABLE_TYPES = Stream.>builder()
.add(String.class)
.add(Integer.class)
.add(Long.class)
.add(Boolean.class)
.add(Double.class)
.add(Float.class)
.add(Short.class)
.add(Byte.class)
.add(Character.class)
.add(BigInteger.class)
.add(BigDecimal.class)
.build()
.collect(toSet());
static void checkType(Object obj) {
Objects.requireNonNull(obj, "null not allowed for shareddata data structure");
// All immutables and byte arrays are Serializable by the platform
if (!(obj instanceof Serializable || obj instanceof Shareable || obj instanceof ClusterSerializable)) {
throw new IllegalArgumentException("Invalid type for shareddata data structure: " + obj.getClass().getName());
}
}
@SuppressWarnings("unchecked")
static T copyIfRequired(T obj) {
Object result;
if (obj == null) {
// Happens with putIfAbsent
result = null;
} else if (IMMUTABLE_TYPES.contains(obj.getClass())) {
result = obj;
} else if (obj instanceof byte[]) {
result = copyByteArray((byte[]) obj);
} else if (obj instanceof Shareable) {
result = ((Shareable) obj).copy();
} else if (obj instanceof ClusterSerializable) {
result = copyClusterSerializable((ClusterSerializable) obj);
} else if (obj instanceof Serializable) {
result = copySerializable(obj);
} else {
throw new IllegalStateException();
}
return (T) result;
}
private static byte[] copyByteArray(byte[] bytes) {
byte[] copy = new byte[bytes.length];
System.arraycopy(bytes, 0, copy, 0, bytes.length);
return copy;
}
private static ClusterSerializable copyClusterSerializable(ClusterSerializable obj) {
logDeveloperInfo(obj);
return ClusterSerializableUtils.copy(obj);
}
private static void logDeveloperInfo(Object obj) {
if (log.isDebugEnabled()) {
log.debug("Copying " + obj.getClass() + " for shared data. Consider implementing " + Shareable.class + " for better performance.");
}
}
private static Object copySerializable(Object obj) {
logDeveloperInfo(obj);
return SerializableUtils.fromBytes(SerializableUtils.toBytes(obj), ObjectInputStream::new);
}
}