io.quarkus.websockets.next.runtime.WebSocketSessionContext Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of quarkus-websockets-next Show documentation
Show all versions of quarkus-websockets-next Show documentation
Implementation of the WebSocket API with enhanced efficiency and usability
package io.quarkus.websockets.next.runtime;
import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import jakarta.enterprise.context.BeforeDestroyed;
import jakarta.enterprise.context.ContextNotActiveException;
import jakarta.enterprise.context.Destroyed;
import jakarta.enterprise.context.Initialized;
import jakarta.enterprise.context.SessionScoped;
import jakarta.enterprise.context.spi.Contextual;
import jakarta.enterprise.context.spi.CreationalContext;
import jakarta.enterprise.event.Event;
import jakarta.enterprise.inject.Any;
import org.jboss.logging.Logger;
import io.quarkus.arc.Arc;
import io.quarkus.arc.ArcContainer;
import io.quarkus.arc.ContextInstanceHandle;
import io.quarkus.arc.CurrentContext;
import io.quarkus.arc.CurrentContextFactory;
import io.quarkus.arc.InjectableBean;
import io.quarkus.arc.ManagedContext;
import io.quarkus.arc.impl.ComputingCacheContextInstances;
import io.quarkus.arc.impl.ContextInstanceHandleImpl;
import io.quarkus.arc.impl.ContextInstances;
import io.quarkus.arc.impl.LazyValue;
public class WebSocketSessionContext implements ManagedContext {
private static final Logger LOG = Logger.getLogger(WebSocketSessionContext.class);
private final CurrentContext currentContext;
private final LazyValue> initializedEvent;
private final LazyValue> beforeDestroyEvent;
private final LazyValue> destroyEvent;
public WebSocketSessionContext(CurrentContextFactory currentContextFactory) {
this.currentContext = currentContextFactory.create(SessionScoped.class);
this.initializedEvent = newEvent(Initialized.Literal.SESSION, Any.Literal.INSTANCE);
this.beforeDestroyEvent = newEvent(BeforeDestroyed.Literal.SESSION, Any.Literal.INSTANCE);
this.destroyEvent = newEvent(Destroyed.Literal.SESSION, Any.Literal.INSTANCE);
}
@Override
public Class extends Annotation> getScope() {
return SessionScoped.class;
}
@Override
public ContextState getState() {
SessionContextState state = currentState();
if (state == null) {
throw notActive();
}
return state;
}
@Override
public ContextState activate(ContextState initialState) {
if (initialState == null) {
SessionContextState state = initializeContextState();
currentContext.set(state);
return state;
} else {
if (initialState instanceof SessionContextState) {
currentContext.set((SessionContextState) initialState);
return initialState;
} else {
throw new IllegalArgumentException("Invalid initial state: " + initialState.getClass().getName());
}
}
}
@Override
public void deactivate() {
currentContext.remove();
}
@SuppressWarnings("unchecked")
@Override
public T get(Contextual contextual, CreationalContext creationalContext) {
Objects.requireNonNull(contextual, "Contextual must not be null");
Objects.requireNonNull(creationalContext, "CreationalContext must not be null");
InjectableBean bean = (InjectableBean) contextual;
if (!SessionScoped.class.getName().equals(bean.getScope().getName())) {
throw invalidScope();
}
SessionContextState state = currentState();
if (state == null || !state.isValid()) {
throw notActive();
}
return (T) state.contextInstances.computeIfAbsent(bean.getIdentifier(), new Supplier>() {
@Override
public ContextInstanceHandle> get() {
return new ContextInstanceHandleImpl<>(bean, contextual.create(creationalContext), creationalContext);
}
}).get();
}
@Override
public T get(Contextual contextual) {
Objects.requireNonNull(contextual, "Contextual must not be null");
InjectableBean bean = (InjectableBean) contextual;
if (!SessionScoped.class.getName().equals(bean.getScope().getName())) {
throw invalidScope();
}
SessionContextState state = currentState();
if (state == null || !state.isValid()) {
throw notActive();
}
@SuppressWarnings("unchecked")
ContextInstanceHandle instance = (ContextInstanceHandle) state.contextInstances
.getIfPresent(bean.getIdentifier());
return instance == null ? null : instance.get();
}
@Override
public boolean isActive() {
SessionContextState contextState = currentState();
return contextState == null ? false : contextState.isValid();
}
@Override
public void destroy() {
destroy(currentState());
}
@Override
public void destroy(Contextual> contextual) {
SessionContextState state = currentState();
if (state == null || !state.isValid()) {
throw notActive();
}
InjectableBean> bean = (InjectableBean>) contextual;
ContextInstanceHandle> instance = state.contextInstances.remove(bean.getIdentifier());
if (instance != null) {
instance.destroy();
}
}
@Override
public void destroy(ContextState state) {
if (state == null) {
// nothing to destroy
return;
}
if (state instanceof SessionContextState) {
SessionContextState sessionState = ((SessionContextState) state);
if (sessionState.invalidate()) {
fireIfNotNull(beforeDestroyEvent.get());
sessionState.contextInstances.removeEach(ContextInstanceHandle::destroy);
fireIfNotNull(destroyEvent.get());
}
} else {
throw new IllegalArgumentException("Invalid state implementation: " + state.getClass().getName());
}
}
SessionContextState initializeContextState() {
SessionContextState state = new SessionContextState(new ComputingCacheContextInstances());
fireIfNotNull(initializedEvent.get());
return state;
}
private SessionContextState currentState() {
return currentContext.get();
}
private IllegalArgumentException invalidScope() {
throw new IllegalArgumentException("The bean does not declare @SessionScoped");
}
private ContextNotActiveException notActive() {
return new ContextNotActiveException("Session context is not active");
}
private void fireIfNotNull(Event
© 2015 - 2024 Weber Informatics LLC | Privacy Policy