mirror of
https://github.com/apache/struts.git
synced 2026-08-31 19:35:40 +00:00
Merge pull request #392 from JCgH4164838Gh792C124B5/WW-5050_Followup
Minor follow-up to WW-5050 changes to ContainerImpl
This commit is contained in:
@@ -37,7 +37,7 @@ class ContainerImpl implements Container {
|
||||
|
||||
ContainerImpl(Map<Key<?>, InternalFactory<?>> factories) {
|
||||
this.factories = factories;
|
||||
Map<Class<?>, Set<String>> map = new HashMap<>();
|
||||
final Map<Class<?>, Set<String>> map = new HashMap<>();
|
||||
for (Key<?> key : factories.keySet()) {
|
||||
Set<String> names = map.get(key.getType());
|
||||
if (names == null) {
|
||||
@@ -151,13 +151,25 @@ class ContainerImpl implements Container {
|
||||
throws MissingDependencyException;
|
||||
}
|
||||
|
||||
private boolean isStatic(Member member) {
|
||||
/**
|
||||
* Determines if a given {@link Member} is static or not.
|
||||
*
|
||||
* @param member checked for the static modifier.
|
||||
* @return true if member is static, false otherwise.
|
||||
*/
|
||||
private static boolean isStatic(Member member) {
|
||||
return Modifier.isStatic(member.getModifiers());
|
||||
}
|
||||
|
||||
private static boolean isNotPublic(Member member) {
|
||||
return !Modifier.isPublic(member.getModifiers()) ||
|
||||
!Modifier.isPublic(member.getDeclaringClass().getModifiers());
|
||||
/**
|
||||
* Determines if a given {@link Member} is considered to be public for reflection usage or not.
|
||||
*
|
||||
* @param member checked to see if it is public for reflection usage.
|
||||
* @return true if member is public for reflection usage, false otherwise.
|
||||
*/
|
||||
private static boolean isPublicForReflection(Member member) {
|
||||
return Modifier.isPublic(member.getModifiers()) &&
|
||||
Modifier.isPublic(member.getDeclaringClass().getModifiers());
|
||||
}
|
||||
|
||||
static class FieldInjector implements Injector {
|
||||
@@ -169,7 +181,7 @@ class ContainerImpl implements Container {
|
||||
public FieldInjector(ContainerImpl container, Field field, String name)
|
||||
throws MissingDependencyException {
|
||||
this.field = field;
|
||||
if (isNotPublic(field) && !field.isAccessible()) {
|
||||
if (!isPublicForReflection(field) && !field.isAccessible()) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (sm != null) {
|
||||
@@ -182,7 +194,7 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
}
|
||||
|
||||
Key<?> key = Key.newInstance(field.getType(), name);
|
||||
final Key<?> key = Key.newInstance(field.getType(), name);
|
||||
factory = container.getFactory(key);
|
||||
if (factory == null) {
|
||||
throw new MissingDependencyException("No mapping found for dependency " + key + " in " + field + ".");
|
||||
@@ -191,8 +203,9 @@ class ContainerImpl implements Container {
|
||||
this.externalContext = ExternalContext.newInstance(field, key, container);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(InternalContext context, Object o) {
|
||||
ExternalContext<?> previous = context.getExternalContext();
|
||||
final ExternalContext<?> previous = context.getExternalContext();
|
||||
context.setExternalContext(externalContext);
|
||||
try {
|
||||
field.set(o, factory.create(context));
|
||||
@@ -214,9 +227,9 @@ class ContainerImpl implements Container {
|
||||
*/
|
||||
<M extends AccessibleObject & Member> ParameterInjector<?>[]
|
||||
getParametersInjectors(M member, Annotation[][] annotations, Class[] parameterTypes, String defaultName) throws MissingDependencyException {
|
||||
List<ParameterInjector<?>> parameterInjectors = new ArrayList<>();
|
||||
final List<ParameterInjector<?>> parameterInjectors = new ArrayList<>();
|
||||
|
||||
Iterator<Annotation[]> annotationsIterator = Arrays.asList(annotations).iterator();
|
||||
final Iterator<Annotation[]> annotationsIterator = Arrays.asList(annotations).iterator();
|
||||
for (Class<?> parameterType : parameterTypes) {
|
||||
Inject annotation = findInject(annotationsIterator.next());
|
||||
String name = annotation == null ? defaultName : annotation.value();
|
||||
@@ -228,12 +241,12 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
|
||||
<T> ParameterInjector<T> createParameterInjector(Key<T> key, Member member) throws MissingDependencyException {
|
||||
InternalFactory<? extends T> factory = getFactory(key);
|
||||
final InternalFactory<? extends T> factory = getFactory(key);
|
||||
if (factory == null) {
|
||||
throw new MissingDependencyException("No mapping found for dependency " + key + " in " + member + ".");
|
||||
}
|
||||
|
||||
ExternalContext<T> externalContext = ExternalContext.newInstance(member, key, this);
|
||||
final ExternalContext<T> externalContext = ExternalContext.newInstance(member, key, this);
|
||||
return new ParameterInjector<T>(externalContext, factory);
|
||||
}
|
||||
|
||||
@@ -261,8 +274,8 @@ class ContainerImpl implements Container {
|
||||
|
||||
public MethodInjector(ContainerImpl container, Method method, String name) throws MissingDependencyException {
|
||||
this.method = method;
|
||||
if (isNotPublic(method) && !method.isAccessible()) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (!isPublicForReflection(method) && !method.isAccessible()) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
|
||||
@@ -274,7 +287,7 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
}
|
||||
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
final Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
if (parameterTypes.length == 0) {
|
||||
throw new DependencyException(method + " has no parameters to inject.");
|
||||
}
|
||||
@@ -282,6 +295,7 @@ class ContainerImpl implements Container {
|
||||
method, method.getParameterAnnotations(), parameterTypes, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(InternalContext context, Object o) {
|
||||
try {
|
||||
method.invoke(o, getParameters(method, context, parameterInjectors));
|
||||
@@ -311,8 +325,8 @@ class ContainerImpl implements Container {
|
||||
this.implementation = implementation;
|
||||
|
||||
constructor = findConstructorIn(implementation);
|
||||
if (isNotPublic(constructor) && !constructor.isAccessible()) {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (!isPublicForReflection(constructor) && !constructor.isAccessible()) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
try {
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new ReflectPermission("suppressAccessChecks"));
|
||||
@@ -359,7 +373,7 @@ class ContainerImpl implements Container {
|
||||
@SuppressWarnings("unchecked")
|
||||
private Constructor<T> findConstructorIn(Class<T> implementation) {
|
||||
Constructor<T> found = null;
|
||||
Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation.getDeclaredConstructors();
|
||||
final Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation.getDeclaredConstructors();
|
||||
for (Constructor<T> constructor : declaredConstructors) {
|
||||
if (constructor.getAnnotation(Inject.class) != null) {
|
||||
if (found != null) {
|
||||
@@ -386,7 +400,7 @@ class ContainerImpl implements Container {
|
||||
* Construct an instance. Returns {@code Object} instead of {@code T} because it may return a proxy.
|
||||
*/
|
||||
Object construct(InternalContext context, Class<? super T> expectedType) {
|
||||
ConstructionContext<T> constructionContext = context.getConstructionContext(this);
|
||||
final ConstructionContext<T> constructionContext = context.getConstructionContext(this);
|
||||
|
||||
// We have a circular reference between constructors. Return a proxy.
|
||||
if (constructionContext.isConstructing()) {
|
||||
@@ -406,7 +420,7 @@ class ContainerImpl implements Container {
|
||||
// First time through...
|
||||
constructionContext.startConstruction();
|
||||
try {
|
||||
Object[] parameters = getParameters(constructor, context, parameterInjectors);
|
||||
final Object[] parameters = getParameters(constructor, context, parameterInjectors);
|
||||
t = constructor.newInstance(parameters);
|
||||
constructionContext.setProxyDelegates(t);
|
||||
} finally {
|
||||
@@ -442,7 +456,7 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
|
||||
T inject(Member member, InternalContext context) {
|
||||
ExternalContext<?> previous = context.getExternalContext();
|
||||
final ExternalContext<?> previous = context.getExternalContext();
|
||||
context.setExternalContext(externalContext);
|
||||
try {
|
||||
return factory.create(context);
|
||||
@@ -457,7 +471,7 @@ class ContainerImpl implements Container {
|
||||
return null;
|
||||
}
|
||||
|
||||
Object[] parameters = new Object[parameterInjectors.length];
|
||||
final Object[] parameters = new Object[parameterInjectors.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
parameters[i] = parameterInjectors[i].inject(member, context);
|
||||
}
|
||||
@@ -465,7 +479,7 @@ class ContainerImpl implements Container {
|
||||
}
|
||||
|
||||
void inject(Object o, InternalContext context) {
|
||||
List<Injector> injectors = this.injectors.get(o.getClass());
|
||||
final List<Injector> injectors = this.injectors.get(o.getClass());
|
||||
for (Injector injector : injectors) {
|
||||
injector.inject(context, o);
|
||||
}
|
||||
@@ -473,7 +487,7 @@ class ContainerImpl implements Container {
|
||||
|
||||
<T> T inject(Class<T> implementation, InternalContext context) {
|
||||
try {
|
||||
ConstructorInjector<T> constructor = getConstructor(implementation);
|
||||
final ConstructorInjector<T> constructor = getConstructor(implementation);
|
||||
return implementation.cast(constructor.construct(context, implementation));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -482,11 +496,11 @@ class ContainerImpl implements Container {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T getInstance(Class<T> type, String name, InternalContext context) {
|
||||
ExternalContext<?> previous = context.getExternalContext();
|
||||
Key<T> key = Key.newInstance(type, name);
|
||||
final ExternalContext<?> previous = context.getExternalContext();
|
||||
final Key<T> key = Key.newInstance(type, name);
|
||||
context.setExternalContext(ExternalContext.newInstance(null, key, this));
|
||||
try {
|
||||
InternalFactory o = getFactory(key);
|
||||
final InternalFactory o = getFactory(key);
|
||||
if (o != null) {
|
||||
return getFactory(key).create(context);
|
||||
} else {
|
||||
@@ -501,6 +515,7 @@ class ContainerImpl implements Container {
|
||||
return getInstance(type, DEFAULT_NAME, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject(final Object o) {
|
||||
callInContext(new ContextualCallable<Void>() {
|
||||
public Void call(InternalContext context) {
|
||||
@@ -510,6 +525,7 @@ class ContainerImpl implements Container {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T inject(final Class<T> implementation) {
|
||||
return callInContext(new ContextualCallable<T>() {
|
||||
public T call(InternalContext context) {
|
||||
@@ -518,6 +534,7 @@ class ContainerImpl implements Container {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(final Class<T> type, final String name) {
|
||||
return callInContext(new ContextualCallable<T>() {
|
||||
public T call(InternalContext context) {
|
||||
@@ -526,6 +543,7 @@ class ContainerImpl implements Container {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getInstance(final Class<T> type) {
|
||||
return callInContext(new ContextualCallable<T>() {
|
||||
public T call(InternalContext context) {
|
||||
@@ -534,6 +552,7 @@ class ContainerImpl implements Container {
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getInstanceNames(final Class<?> type) {
|
||||
Set<String> names = factoryNamesByType.get(type);
|
||||
if (names == null) {
|
||||
@@ -553,7 +572,7 @@ class ContainerImpl implements Container {
|
||||
* Looks up thread local context. Creates (and removes) a new context if necessary.
|
||||
*/
|
||||
<T> T callInContext(ContextualCallable<T> callable) {
|
||||
Object[] reference = localContext.get();
|
||||
final Object[] reference = localContext.get();
|
||||
if (reference[0] == null) {
|
||||
reference[0] = new InternalContext(this);
|
||||
try {
|
||||
@@ -584,10 +603,12 @@ class ContainerImpl implements Container {
|
||||
|
||||
final ThreadLocal<Object> localScopeStrategy = new ThreadLocal<>();
|
||||
|
||||
@Override
|
||||
public void setScopeStrategy(Scope.Strategy scopeStrategy) {
|
||||
this.localScopeStrategy.set(scopeStrategy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeScopeStrategy() {
|
||||
this.localScopeStrategy.remove();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user