*/
package org.opendaylight.mdsal.binding.dom.adapter.query;
-import static com.google.common.base.Verify.verify;
import static java.util.Objects.requireNonNull;
-import com.google.common.base.MoreObjects;
+import com.google.common.base.VerifyException;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.function.Function;
+import org.eclipse.jdt.annotation.NonNullByDefault;
import org.opendaylight.mdsal.binding.api.query.MatchBuilderPath.LeafReference;
-import org.opendaylight.yangtools.concepts.Immutable;
/**
* Utility class for forcing decoding lambda instances to the method being invoked. The theory here is that
* messier, less type-safe and a perf-killer.
*/
final class LambdaDecoder {
- // FIXME: when we have JDK16: this should be a record
- static final class LambdaTarget implements Immutable {
- final String targetClass;
- final String targetMethod;
-
- LambdaTarget(final String targetClass, final String targetMethod) {
- this.targetClass = requireNonNull(targetClass);
- this.targetMethod = requireNonNull(targetMethod);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this).add("class", targetClass).add("method", targetMethod).toString();
+ @NonNullByDefault
+ record LambdaTarget(String targetClass, String targetMethod) {
+ LambdaTarget {
+ requireNonNull(targetClass);
+ requireNonNull(targetMethod);
}
}
private static final LoadingCache<Class<?>, Method> REPLACE_CACHE = CacheBuilder.newBuilder()
- .weakKeys().weakValues().build(new CacheLoader<Class<?>, Method>() {
- @Override
- public Method load(final Class<?> key) throws PrivilegedActionException {
- return AccessController.doPrivileged((PrivilegedExceptionAction<Method>) () -> {
- final Method method = key.getDeclaredMethod("writeReplace");
- method.setAccessible(true);
- return method;
- });
- }
- });
+ .weakKeys().weakValues().build(new CacheLoader<Class<?>, Method>() {
+ @Override
+ public Method load(final Class<?> key) throws PrivilegedActionException {
+ return AccessController.doPrivileged((PrivilegedExceptionAction<Method>) () -> {
+ final var method = key.getDeclaredMethod("writeReplace");
+ method.setAccessible(true);
+ return method;
+ });
+ }
+ });
private static final LoadingCache<LeafReference<?, ?>, LambdaTarget> LAMBDA_CACHE = CacheBuilder.newBuilder()
- .weakKeys().build(new CacheLoader<LeafReference<?, ?>, LambdaTarget>() {
- @Override
- public LambdaTarget load(final LeafReference<?, ?> ref) throws Exception {
- final Object replaced = REPLACE_CACHE.get(ref.getClass()).invoke(ref);
- verify(replaced instanceof SerializedLambda, "Unexpected replaced object %s", replaced);
- final SerializedLambda serialized = (SerializedLambda) replaced;
+ .weakKeys().build(new CacheLoader<LeafReference<?, ?>, LambdaTarget>() {
+ @Override
+ public LambdaTarget load(final LeafReference<?, ?> ref) throws Exception {
+ final var replaced = REPLACE_CACHE.get(ref.getClass()).invoke(ref);
+ if (replaced instanceof SerializedLambda serialized) {
return new LambdaTarget(serialized.getImplClass().replace('/', '.'),
serialized.getImplMethodName());
}
- });
+ throw new VerifyException("Unexpected replaced object " + replaced);
+ }
+ });
private LambdaDecoder() {
// Hidden on purpose
verify(targetSchema instanceof DataNodeContainer, "Unexpected target schema %s", targetSchema);
final LambdaTarget targetLeaf = LambdaDecoder.resolveLambda(ref);
- verify(targetLeaf.targetClass.equals(bindingPath.getTargetType().getName()), "Mismatched target %s and path %s",
- targetLeaf, bindingPath);
- final NodeIdentifier childId = factory.findChild((DataNodeContainer) targetSchema, targetLeaf.targetMethod);
+ verify(targetLeaf.targetClass().equals(bindingPath.getTargetType().getName()),
+ "Mismatched target %s and path %s", targetLeaf, bindingPath);
+ final NodeIdentifier childId = factory.findChild((DataNodeContainer) targetSchema, targetLeaf.targetMethod());
final YangInstanceIdentifier absTarget = fromBinding(bindingPath);
final YangInstanceIdentifier relTarget = absTarget.relativeTo(absoluteSelect)
.orElseThrow(() -> new IllegalStateException(absoluteSelect + " is not an ancestor of " + absTarget));