Skip to content

Commit

Permalink
Put the call scoper into the client
Browse files Browse the repository at this point in the history
  • Loading branch information
GedMarc committed Apr 14, 2024
1 parent c5e76b5 commit 24aaddb
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 2 deletions.
157 changes: 157 additions & 0 deletions guice-inject-client/src/main/java/com/guicedee/client/CallScoper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package com.guicedee.client;

import com.google.common.collect.Maps;
import com.google.inject.*;
import com.guicedee.guicedservlets.servlets.services.IOnCallScopeEnter;
import com.guicedee.guicedservlets.servlets.services.IOnCallScopeExit;

import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import static com.google.common.base.Preconditions.checkState;


public class CallScoper implements Scope
{
private static final Provider<Object> SEEDED_KEY_PROVIDER =
new Provider<Object>()
{
public Object get()
{
throw new IllegalStateException("If you got here then it means that" +
" your code asked for scoped object which should have been" +
" explicitly seeded in this scope by calling" +
" CallScoper.seed(), but was not.");
}
};
private static final ThreadLocal<Map<Key<?>, Object>> values
= new ThreadLocal<Map<Key<?>, Object>>();

private boolean startedScope;

public void enter()
{
try
{
checkState(values.get() == null, "A scoping block is already in progress");
values.set(Maps.<Key<?>, Object>newHashMap());
startedScope = true;
@SuppressWarnings("rawtypes")
Set<IOnCallScopeEnter> scopeEnters = IGuiceContext.loaderToSet(ServiceLoader.load(IOnCallScopeEnter.class));
for (IOnCallScopeEnter<?> scopeEnter : scopeEnters)
{
try
{
scopeEnter.onScopeEnter(this);
} catch (Throwable T)
{
Logger.getLogger("CallScoper")
.log(Level.WARNING, "Exception on scope entry - " + scopeEnter, T);
}
}
} catch (Throwable T)
{
startedScope = false;
}
}

public void exit()
{
try
{
checkState(values.get() != null, "No scoping block in progress");
Set<IOnCallScopeExit> scopeEnters = IGuiceContext.loaderToSet(ServiceLoader.load(IOnCallScopeExit.class));
for (IOnCallScopeExit<?> scopeEnter : scopeEnters)
{
try
{
scopeEnter.onScopeExit();
} catch (Throwable T)
{
Logger.getLogger("CallScoper")
.log(Level.WARNING, "Exception on call scope exit", T);
}
}
values.remove();
} catch (IllegalStateException T)
{
Logger.getLogger("CallScoper")
.log(Level.WARNING, "NOT IN SCOPE ", T);

} catch (Throwable T)
{
Logger.getLogger("CallScoper")
.log(Level.WARNING, "Cannot perform close scope", T);
}
}

public <T> void seed(Key<T> key, T value)
{
Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);
checkState(!scopedObjects.containsKey(key), "A value for the key %s was " +
"already seeded in this scope. Old value: %s New value: %s", key,
scopedObjects.get(key), value);
scopedObjects.put(key, value);
}

public <T> void seed(Class<T> clazz, T value)
{
seed(Key.get(clazz), value);
}

public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped)
{
return new Provider<T>()
{
public T get()
{
Map<Key<?>, Object> scopedObjects = getScopedObjectMap(key);

@SuppressWarnings("unchecked")
T current = (T) scopedObjects.get(key);
if (current == null && !scopedObjects.containsKey(key))
{
current = unscoped.get();

// don't remember proxies; these exist only to serve circular dependencies
if (Scopes.isCircularProxy(current))
{
return current;
}

scopedObjects.put(key, current);
}
return current;
}
};
}

private <T> Map<Key<?>, Object> getScopedObjectMap(Key<T> key)
{
Map<Key<?>, Object> scopedObjects = values.get();
if (scopedObjects == null)
{
//enter();
// scopedObjects = values.get();
throw new OutOfScopeException("Cannot access " + key
+ " outside of a scoping block - " + key.toString());
}
return scopedObjects;
}

/**
* Returns a provider that always throws exception complaining that the object
* in question must be seeded before it can be injected.
*
* @return typed provider
*/
@SuppressWarnings({"unchecked"})
public static <T> Provider<T> seededKeyProvider()
{
return (Provider<T>) SEEDED_KEY_PROVIDER;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.guicedee.client.implementations;

import com.google.inject.AbstractModule;
import com.guicedee.client.CallScoper;
import com.guicedee.guicedinjection.interfaces.IGuiceModule;
import com.guicedee.guicedservlets.servlets.services.scopes.CallScope;
import com.guicedee.guicedservlets.websockets.options.CallScopeProperties;

public class GuicedEEClientModule extends AbstractModule implements IGuiceModule<GuicedEEClientModule>
{
@Override
protected void configure()
{
bindScope(CallScope.class, new CallScoper());
bind(CallScopeProperties.class).in(CallScope.class);
}
}
8 changes: 6 additions & 2 deletions guice-inject-client/src/main/java/module-info.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import com.guicedee.client.implementations.GuicedEEClientModule;
import com.guicedee.client.implementations.GuicedEEClientStartup;
import com.guicedee.guicedinjection.interfaces.IGuiceModule;
import com.guicedee.guicedinjection.interfaces.IGuicePreStartup;
import com.guicedee.guicedinjection.interfaces.IGuiceProvider;
import com.guicedee.guicedinjection.interfaces.IJobServiceProvider;
Expand Down Expand Up @@ -43,7 +45,9 @@

uses IGuiceProvider;
uses IJobServiceProvider;

uses com.guicedee.guicedservlets.servlets.services.IOnCallScopeEnter;
uses com.guicedee.guicedservlets.servlets.services.IOnCallScopeExit;

opens com.guicedee.guicedservlets.websockets.options to com.fasterxml.jackson.databind;
opens com.guicedee.guicedservlets.undertow.services to com.google.guice;
opens com.guicedee.guicedservlets.websockets.services to com.google.guice;
Expand All @@ -53,5 +57,5 @@
opens com.guicedee.guicedinjection.pairing to com.fasterxml.jackson.databind;

provides IGuicePreStartup with GuicedEEClientStartup;
provides IGuiceModule with GuicedEEClientModule;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
com.guicedee.client.implementations.GuicedEEClientModule

0 comments on commit 24aaddb

Please sign in to comment.