Search in sources :

Example 1 with Handler

use of org.jdbi.v3.sqlobject.Handler in project jdbi by jdbi.

the class TestUseCustomHandlerFactory method setUp.

@Before
public void setUp() throws Exception {
    Jdbi db = dbRule.getJdbi();
    HandlerFactory defaultHandlerFactory = new HandlerFactory() {

        @Override
        public Optional<Handler> buildHandler(Class<?> sqlObjectType, Method method) {
            return getImplementation(sqlObjectType, method).map(m -> (Handler) (target, args, handle) -> m.invoke(null, Stream.concat(Stream.of(target), Stream.of(args)).toArray()));
        }

        private Optional<Method> getImplementation(Class<?> type, Method method) {
            return Stream.of(type.getClasses()).filter(c -> c.getSimpleName().equals("DefaultImpls")).flatMap(c -> Stream.of(c.getMethods()).filter(m -> m.getName().equals(method.getName()))).findAny();
        }
    };
    db.configure(Handlers.class, c -> c.register(defaultHandlerFactory));
    handle = db.open();
}
Also used : Jdbi(org.jdbi.v3.core.Jdbi) Handlers(org.jdbi.v3.sqlobject.Handlers) BindBean(org.jdbi.v3.sqlobject.customizer.BindBean) SqlObjectPlugin(org.jdbi.v3.sqlobject.SqlObjectPlugin) Bind(org.jdbi.v3.sqlobject.customizer.Bind) Transaction(org.jdbi.v3.sqlobject.transaction.Transaction) Something(org.jdbi.v3.core.Something) SqlUpdate(org.jdbi.v3.sqlobject.statement.SqlUpdate) H2DatabaseRule(org.jdbi.v3.core.rule.H2DatabaseRule) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Test(org.junit.Test) Handler(org.jdbi.v3.sqlobject.Handler) Rule(org.junit.Rule) Stream(java.util.stream.Stream) Handle(org.jdbi.v3.core.Handle) HandlerFactory(org.jdbi.v3.sqlobject.HandlerFactory) Optional(java.util.Optional) SomethingMapper(org.jdbi.v3.core.mapper.SomethingMapper) Method(java.lang.reflect.Method) SqlQuery(org.jdbi.v3.sqlobject.statement.SqlQuery) Before(org.junit.Before) Jdbi(org.jdbi.v3.core.Jdbi) HandlerFactory(org.jdbi.v3.sqlobject.HandlerFactory) Handler(org.jdbi.v3.sqlobject.Handler) Method(java.lang.reflect.Method) Before(org.junit.Before)

Example 2 with Handler

use of org.jdbi.v3.sqlobject.Handler in project jdbi by jdbi.

the class SqlObjectFactory method attach.

/**
 * Create a sql object of the specified type bound to this handle. Any state changes to the handle, or the sql
 * object, such as transaction status, closing it, etc, will apply to both the object and the handle.
 *
 * @param extensionType the type of sql object to create
 * @param handle the Handle instance to attach ths sql object to
 * @return the new sql object bound to this handle
 */
@Override
public <E> E attach(Class<E> extensionType, HandleSupplier handle) {
    Map<Method, Handler> handlers = methodHandlersFor(extensionType, handle.getConfig(Handlers.class), handle.getConfig(HandlerDecorators.class));
    ConfigRegistry instanceConfig = handle.getConfig().createCopy();
    for (Class<?> iface : extensionType.getInterfaces()) {
        forEachConfigurer(iface, (configurer, annotation) -> configurer.configureForType(instanceConfig, annotation, extensionType));
    }
    forEachConfigurer(extensionType, (configurer, annotation) -> configurer.configureForType(instanceConfig, annotation, extensionType));
    InvocationHandler invocationHandler = createInvocationHandler(extensionType, instanceConfig, handlers, handle);
    return extensionType.cast(Proxy.newProxyInstance(extensionType.getClassLoader(), new Class[] { extensionType }, invocationHandler));
}
Also used : ConfigRegistry(org.jdbi.v3.core.config.ConfigRegistry) InvocationHandler(java.lang.reflect.InvocationHandler) ExtensionMethod(org.jdbi.v3.core.extension.ExtensionMethod) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler)

Example 3 with Handler

use of org.jdbi.v3.sqlobject.Handler in project jdbi by jdbi.

the class OnDemandExtensions method create.

static <E> E create(Jdbi db, Class<E> extensionType) {
    ThreadLocal<E> threadExtension = new ThreadLocal<>();
    InvocationHandler handler = (proxy, method, args) -> {
        if (EQUALS_METHOD.equals(method)) {
            return proxy == args[0];
        }
        if (HASHCODE_METHOD.equals(method)) {
            return System.identityHashCode(proxy);
        }
        if (TOSTRING_METHOD.equals(method)) {
            return extensionType + "@" + Integer.toHexString(System.identityHashCode(proxy));
        }
        if (threadExtension.get() != null) {
            return invoke(threadExtension.get(), method, args);
        }
        return db.withExtension(extensionType, extension -> JdbiThreadLocals.invokeInContext(threadExtension, extension, () -> invoke(extension, method, args)));
    };
    return extensionType.cast(Proxy.newProxyInstance(extensionType.getClassLoader(), new Class[] { extensionType }, handler));
}
Also used : Proxy(java.lang.reflect.Proxy) JdbiThreadLocals(org.jdbi.v3.core.internal.JdbiThreadLocals) MethodHandles(java.lang.invoke.MethodHandles) InvocationHandler(java.lang.reflect.InvocationHandler) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler)

Example 4 with Handler

use of org.jdbi.v3.sqlobject.Handler in project jdbi by jdbi.

the class SqlObjectFactory method methodHandlersFor.

private Map<Method, Handler> methodHandlersFor(Class<?> sqlObjectType, Handlers registry, HandlerDecorators decorators) {
    return handlersCache.computeIfAbsent(sqlObjectType, type -> {
        final Map<Method, Handler> handlers = new HashMap<>();
        handlers.putAll(handlerEntry((t, a, h) -> sqlObjectType.getName() + '@' + Integer.toHexString(t.hashCode()), Object.class, "toString"));
        handlers.putAll(handlerEntry((t, a, h) -> t == a[0], Object.class, "equals", Object.class));
        handlers.putAll(handlerEntry((t, a, h) -> System.identityHashCode(t), Object.class, "hashCode"));
        handlers.putAll(handlerEntry((t, a, h) -> h.getHandle(), SqlObject.class, "getHandle"));
        try {
            handlers.putAll(handlerEntry((t, a, h) -> null, sqlObjectType, "finalize"));
        }// optional implementation
         catch (IllegalStateException expected) {
        }
        for (Method method : sqlObjectType.getMethods()) {
            handlers.computeIfAbsent(method, m -> buildMethodHandler(sqlObjectType, m, registry, decorators));
        }
        return handlers;
    });
}
Also used : ExtensionMethod(org.jdbi.v3.core.extension.ExtensionMethod) HandleSupplier(org.jdbi.v3.core.extension.HandleSupplier) Arrays(java.util.Arrays) Proxy(java.lang.reflect.Proxy) ConfiguringAnnotation(org.jdbi.v3.sqlobject.config.ConfiguringAnnotation) HashMap(java.util.HashMap) ConfigRegistry(org.jdbi.v3.core.config.ConfigRegistry) Stream(java.util.stream.Stream) Collections.synchronizedMap(java.util.Collections.synchronizedMap) Map(java.util.Map) Annotation(java.lang.annotation.Annotation) BiConsumer(java.util.function.BiConsumer) ExtensionFactory(org.jdbi.v3.core.extension.ExtensionFactory) InvocationHandler(java.lang.reflect.InvocationHandler) Configurer(org.jdbi.v3.sqlobject.config.Configurer) Method(java.lang.reflect.Method) Collections(java.util.Collections) WeakHashMap(java.util.WeakHashMap) AnnotatedElement(java.lang.reflect.AnnotatedElement) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) InvocationHandler(java.lang.reflect.InvocationHandler) ExtensionMethod(org.jdbi.v3.core.extension.ExtensionMethod) Method(java.lang.reflect.Method)

Example 5 with Handler

use of org.jdbi.v3.sqlobject.Handler in project jdbi by jdbi.

the class TransactionDecorator method decorateHandler.

@Override
public Handler decorateHandler(Handler base, Class<?> sqlObjectType, Method method) {
    final Transaction txnAnnotation = method.getAnnotation(Transaction.class);
    final TransactionIsolationLevel isolation = txnAnnotation.value();
    final boolean readOnly = txnAnnotation.readOnly();
    return (target, args, handle) -> {
        Handle h = handle.getHandle();
        if (h.isInTransaction()) {
            // Already in transaction. The outermost @Transaction method determines the transaction isolation level.
            TransactionIsolationLevel currentLevel = h.getTransactionIsolationLevel();
            if (currentLevel != isolation && isolation != TransactionIsolationLevel.UNKNOWN) {
                throw new TransactionException("Tried to execute nested @Transaction(" + isolation + "), " + "but already running in a transaction with isolation level " + currentLevel + ".");
            }
            if (h.isReadOnly() && !readOnly) {
                throw new TransactionException("Tried to execute a nested @Transaction(readOnly=false) " + "inside a readOnly transaction");
            }
            return base.invoke(target, args, handle);
        }
        HandleCallback<Object, Exception> callback = th -> base.invoke(target, args, handle);
        final boolean flipReadOnly = readOnly != h.isReadOnly();
        if (flipReadOnly) {
            h.setReadOnly(readOnly);
        }
        try {
            if (isolation == TransactionIsolationLevel.UNKNOWN) {
                return h.inTransaction(callback);
            } else {
                return h.inTransaction(isolation, callback);
            }
        } finally {
            if (flipReadOnly) {
                h.setReadOnly(!readOnly);
            }
        }
    };
}
Also used : HandlerDecorator(org.jdbi.v3.sqlobject.HandlerDecorator) HandleCallback(org.jdbi.v3.core.HandleCallback) TransactionIsolationLevel(org.jdbi.v3.core.transaction.TransactionIsolationLevel) Transaction(org.jdbi.v3.sqlobject.transaction.Transaction) Handle(org.jdbi.v3.core.Handle) Method(java.lang.reflect.Method) TransactionException(org.jdbi.v3.core.transaction.TransactionException) Handler(org.jdbi.v3.sqlobject.Handler) TransactionException(org.jdbi.v3.core.transaction.TransactionException) Transaction(org.jdbi.v3.sqlobject.transaction.Transaction) HandleCallback(org.jdbi.v3.core.HandleCallback) TransactionIsolationLevel(org.jdbi.v3.core.transaction.TransactionIsolationLevel) Handle(org.jdbi.v3.core.Handle)

Aggregations

Method (java.lang.reflect.Method)5 InvocationHandler (java.lang.reflect.InvocationHandler)3 Proxy (java.lang.reflect.Proxy)2 Stream (java.util.stream.Stream)2 Handle (org.jdbi.v3.core.Handle)2 ConfigRegistry (org.jdbi.v3.core.config.ConfigRegistry)2 ExtensionMethod (org.jdbi.v3.core.extension.ExtensionMethod)2 Handler (org.jdbi.v3.sqlobject.Handler)2 Transaction (org.jdbi.v3.sqlobject.transaction.Transaction)2 Annotation (java.lang.annotation.Annotation)1 MethodHandles (java.lang.invoke.MethodHandles)1 AnnotatedElement (java.lang.reflect.AnnotatedElement)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 Collections.synchronizedMap (java.util.Collections.synchronizedMap)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 Optional (java.util.Optional)1 WeakHashMap (java.util.WeakHashMap)1 BiConsumer (java.util.function.BiConsumer)1