Revert: Search for scope first in parent locator. PR #1166
diff --git a/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java b/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java
index a6ecdf2..5dd241e 100755
--- a/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java
+++ b/hk2-locator/src/main/java/org/jvnet/hk2/internal/ServiceLocatorImpl.java
@@ -113,9 +113,9 @@
public String run() {
return System.getProperty(BIND_TRACING_PATTERN_PROPERTY);
}
-
+
});
-
+
private final static String BIND_TRACING_STACKS_PROPERTY = "org.jvnet.hk2.properties.bind.tracing.stacks";
private static final boolean BIND_TRACING_STACKS = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
@@ -123,7 +123,7 @@
return Boolean.parseBoolean(
System.getProperty(BIND_TRACING_STACKS_PROPERTY, "false"));
}
-
+
});
private final static int CACHE_SIZE = 20000;
@@ -152,7 +152,7 @@
private final LinkedHashSet<ValidationService> allValidators = new LinkedHashSet<>();
private final LinkedList<ErrorService> errorHandlers = new LinkedList<>(Collections.singletonList(new RethrowErrorService()));
private final LinkedList<ServiceHandle<?>> configListeners = new LinkedList<>();
-
+
private volatile boolean hasInterceptionServices = false;
private final LinkedList<InterceptionService> interceptionServices =
new LinkedList<InterceptionService>();
@@ -176,14 +176,14 @@
private final ReentrantLock allResolversLock = new ReentrantLock();
private ConcurrentHashMap<Class<? extends Annotation>, InjectionResolver<?>> allResolvers =
new ConcurrentHashMap<Class<? extends Annotation>, InjectionResolver<?>>();
- private final Cache<SystemInjecteeImpl, InjectionResolver<?>> injecteeToResolverCache =
+ private final Cache<SystemInjecteeImpl, InjectionResolver<?>> injecteeToResolverCache =
new Cache<SystemInjecteeImpl, InjectionResolver<?>>(new Computable<SystemInjecteeImpl, InjectionResolver<?>>() {
@Override
public InjectionResolver<?> compute(SystemInjecteeImpl key) {
return perLocatorUtilities.getInjectionResolver(getMe(), key);
}
-
+
});
private ServiceLocatorState state = ServiceLocatorState.RUNNING;
@@ -218,10 +218,10 @@
" with stacks " + BIND_TRACING_STACKS + " in " + this);
}
}
-
+
/**
* Must have read lock held
- *
+ *
* @param vi The non-null validation
* @return
*/
@@ -231,7 +231,7 @@
}
catch (Throwable th) {
List<ErrorService> localErrorServices = new LinkedList<ErrorService>(errorHandlers);
-
+
MultiException useException;
if (th instanceof MultiException) {
useException = (MultiException) th;
@@ -239,13 +239,13 @@
else {
useException = new MultiException(th);
}
-
+
ErrorInformationImpl ei = new ErrorInformationImpl(
ErrorType.VALIDATE_FAILURE,
vi.getCandidate(),
vi.getInjectee(),
useException);
-
+
for (ErrorService errorService : localErrorServices) {
try {
errorService.onFailure(ei);
@@ -254,9 +254,9 @@
Logger.getLogger().debug("ServiceLocatorImpl", "callValidate", th2);
}
}
-
+
}
-
+
return false;
}
@@ -534,7 +534,7 @@
if (Provider.class.equals(rawType) || Iterable.class.equals(rawType) || IterableProvider.class.equals(rawType) ) {
boolean isIterable = (IterableProvider.class.equals(rawType));
-
+
IterableProviderImpl<?> value = new IterableProviderImpl<Object>(this,
(ReflectionHelper.getFirstTypeArgument(requiredType)),
injectee.getRequiredQualifiers(),
@@ -562,12 +562,12 @@
}
return descriptor;
}
-
+
if (Topic.class.equals(rawType)) {
TopicImpl<?> value = new TopicImpl<Object>(this,
ReflectionHelper.getFirstTypeArgument(requiredType),
injectee.getRequiredQualifiers());
-
+
return new ConstantActiveDescriptor<Object>(value, this);
}
@@ -601,28 +601,28 @@
throw new IllegalArgumentException("The descriptor passed to getServiceHandle must have been bound into a ServiceLocator. " +
"The descriptor is of type " + activeDescriptor.getClass().getName());
}
-
+
Long sdLocator = activeDescriptor.getLocatorId();
if (sdLocator == null) {
throw new IllegalArgumentException("The descriptor passed to getServiceHandle is not associated with any ServiceLocator");
}
-
+
if (sdLocator != id) {
if (parent != null) {
return parent.getServiceHandle(activeDescriptor, injectee);
}
-
+
throw new IllegalArgumentException("The descriptor passed to getServiceHandle is not associated with this ServiceLocator (id=" +
id + "). It is associated ServiceLocator id=" + sdLocator);
}
-
+
Long sdSID = activeDescriptor.getServiceId();
if ((activeDescriptor instanceof SystemDescriptor) && (sdSID == null)) {
throw new IllegalArgumentException("The descriptor passed to getServiceHandle was never added to this ServiceLocator (id=" +
id + ")");
}
}
-
+
return getServiceHandleImpl(activeDescriptor, injectee);
}
@@ -682,7 +682,7 @@
ServiceHandleImpl<T> tmpRoot = new ServiceHandleImpl<T>(this, activeDescriptor, originalRequest);
return Utilities.createService(activeDescriptor, originalRequest, this, tmpRoot, rawClass);
}
-
+
ServiceHandleImpl<?> rootImpl = (ServiceHandleImpl<?>) root;
ServiceHandleImpl<T> subHandle = internalGetServiceHandle(activeDescriptor, contractOrImpl, originalRequest);
@@ -733,38 +733,38 @@
throws MultiException {
return internalGetService(contractOrImpl, name, null, qualifiers);
}
-
+
private <T> T internalGetService(Type contractOrImpl, String name, Unqualified unqualified, Annotation... qualifiers) {
return internalGetService(contractOrImpl, name, unqualified, false, qualifiers);
-
+
}
@SuppressWarnings("unchecked")
private <T> T internalGetService(Type contractOrImpl, String name, Unqualified unqualified, boolean calledFromSecondChanceResolveMethod, Annotation... qualifiers) {
checkState();
-
+
Class<?> rawType = ReflectionHelper.getRawClass(contractOrImpl);
if (rawType != null &&
(Provider.class.equals(rawType) || IterableProvider.class.equals(rawType)) ) {
boolean isIterable = IterableProvider.class.equals(rawType);
-
+
Type requiredType = ReflectionHelper.getFirstTypeArgument(contractOrImpl);
HashSet<Annotation> requiredQualifiers = new HashSet<Annotation>();
for (Annotation qualifier : qualifiers) {
requiredQualifiers.add(qualifier);
}
-
+
InjecteeImpl injectee = new InjecteeImpl(requiredType);
injectee.setRequiredQualifiers(requiredQualifiers);
injectee.setUnqualified(unqualified);
-
+
IterableProviderImpl<?> retVal = new IterableProviderImpl<Object>(this,
requiredType,
requiredQualifiers,
unqualified,
injectee,
isIterable);
-
+
return (T) retVal;
}
@@ -878,7 +878,7 @@
rLock.unlock();
}
}
-
+
@Override
public boolean isShutdown() {
return state.equals(ServiceLocatorState.SHUTDOWN);
@@ -889,8 +889,8 @@
*/
@Override
public void shutdown() {
-
-
+
+
wLock.lock();
try {
if (state.equals(ServiceLocatorState.SHUTDOWN)) return;
@@ -914,7 +914,7 @@
finally {
wLock.unlock();
}
-
+
// These things must be done OUTSIDE the lock
List<ServiceHandle<?>> handles = getAllServiceHandles(new IndexedFilter() {
@@ -932,7 +932,7 @@
public String getName() {
return null;
}
-
+
});
for (ServiceHandle<?> handle : handles) {
@@ -960,7 +960,7 @@
classReflectionHelper.dispose();
contextCache.clear();
perLocatorUtilities.shutdown();
-
+
childrenLock.lock();
try {
children.clear();
@@ -1003,16 +1003,16 @@
public void inject(Object injectMe) {
inject(injectMe, null);
}
-
+
@Override
public Object assistedInject(Object injectMe, Method method, MethodParameter... params) {
return assistedInject(injectMe, method, null, params);
}
-
+
@Override
public Object assistedInject(Object injectMe, Method method, ServiceHandle<?> root, MethodParameter... params) {
checkState();
-
+
return Utilities.justAssistedInject(injectMe, method, this, root, params);
}
@@ -1171,7 +1171,7 @@
}
return true;
}
-
+
@Override
public String toString() {
return "IgdCacheKey(" + cacheKey + "," + name + "," + onBehalfOf + "," +
@@ -1198,7 +1198,7 @@
return igdCacheCompute(key);
}
}, CACHE_SIZE, false);
-
+
private IgdValue igdCacheCompute(final IgdCacheKey key) {
final List<SystemDescriptor<?>> candidates = getDescriptors(key.filter, key.onBehalfOf, true, false, true);
final ImmediateResults immediate = narrow(ServiceLocatorImpl.this, // locator
@@ -1211,21 +1211,21 @@
null, // cachedResults
key.filter, // filter
key.qualifiers); // qualifiers
-
+
final NarrowResults results = immediate.getTimelessResults();
if (!results.getErrors().isEmpty()) {
Utilities.handleErrors(results, new LinkedList<ErrorService>(errorHandlers));
throw new ComputationErrorException(new IgdValue(results, immediate));
}
-
+
return new IgdValue(results, immediate);
}
-
+
private Unqualified getEffectiveUnqualified(Unqualified givenUnqualified, boolean isIterable, Annotation qualifiers[]) {
if (givenUnqualified != null) return givenUnqualified;
if (qualifiers.length > 0) return null;
if (isIterable) return null;
-
+
// Given unqualified is null and there are no qualifiers
return defaultUnqualified;
}
@@ -1237,7 +1237,7 @@
Annotation... qualifiers) throws MultiException {
return internalGetDescriptor(onBehalfOf, contractOrImpl, name, unqualified, isIterable, false, qualifiers);
}
-
+
@SuppressWarnings("unchecked")
private <T> ActiveDescriptor<T> internalGetDescriptor(Injectee onBehalfOf, Type contractOrImpl,
String name,
@@ -1260,7 +1260,7 @@
LinkedList<ErrorService> currentErrorHandlers = null;
ImmediateResults immediate = null;
-
+
unqualified = getEffectiveUnqualified(unqualified, isIterable, qualifiers);
final CacheKey cacheKey = new CacheKey(contractOrImpl, name, unqualified, qualifiers);
@@ -1331,7 +1331,7 @@
}
postValidateResult = (ActiveDescriptor<T>)secondChanceResolve(injectee);
}
-
+
return postValidateResult;
}
@@ -1425,7 +1425,7 @@
Utilities.handleErrors(results, new LinkedList<ErrorService>(errorHandlers));
throw new ComputationErrorException(new IgdValue(results, immediate)) ;
}
-
+
return new IgdValue(results, immediate);
}
}, CACHE_SIZE, false);
@@ -1452,7 +1452,7 @@
LinkedList<ErrorService> currentErrorHandlers = null;
ImmediateResults immediate = null;
-
+
unqualified = getEffectiveUnqualified(unqualified, isIterable, qualifiers);
final CacheKey cacheKey = new CacheKey(contractOrImpl, null, unqualified, qualifiers);
@@ -1604,10 +1604,10 @@
});
}
-
+
/* package */ List<InterceptionService> getInterceptionServices() {
if (!hasInterceptionServices) return null;
-
+
rLock.lock();
try {
return new LinkedList<InterceptionService>(interceptionServices);
@@ -1676,7 +1676,7 @@
for (SystemDescriptor<?> sd : dci.getAllDescriptors()) {
transactionData.toAdd(sd);
-
+
affectedContracts.addAll(getAllContracts(sd));
boolean checkScope = false;
@@ -1714,13 +1714,13 @@
addOrRemoveOfInjectionResolver = true;
}
-
+
if (sd.getAdvertisedContracts().contains(DynamicConfigurationListener.class.getName())) {
// This gets reified right away
reifyDescriptor(sd);
-
+
checkScope = true;
-
+
addOrRemoveOfConfigListener = true;
}
@@ -1754,29 +1754,29 @@
}
}
}
-
+
List<Filter> idempotentFilters = dci.getIdempotentFilters();
if (!idempotentFilters.isEmpty()) {
List<ActiveDescriptor<?>> allValidatedDescriptors = getDescriptors(BuilderHelper.allFilter());
-
+
List<Throwable> idempotentFailures = new LinkedList<>();
for (ActiveDescriptor<?> aValidatedDescriptor : allValidatedDescriptors) {
for (Filter idempotentFilter : idempotentFilters) {
if (BuilderHelper.filterMatches(aValidatedDescriptor, idempotentFilter)) {
idempotentFailures.add(new DuplicateServiceException(aValidatedDescriptor, locatorName));
}
-
+
}
}
-
+
if (!idempotentFailures.isEmpty()) {
throw new MultiException(idempotentFailures);
}
}
-
+
LinkedList<TwoPhaseResource> resources = dci.getResources();
List<TwoPhaseResource> completedPrepares = new LinkedList<TwoPhaseResource>();
-
+
for (TwoPhaseResource resource : resources) {
try {
resource.prepareDynamicConfiguration(transactionData);
@@ -1791,11 +1791,11 @@
Logger.getLogger().debug("Rollback of TwoPhaseResource " + resource + " failed with exception", ignore);
}
}
-
+
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
}
-
+
throw new RuntimeException(th);
}
}
@@ -1856,18 +1856,18 @@
ValidationService vs = handle.getService();
allValidators.remove(vs);
}
-
+
if (unbind.isReified()) {
for (Injectee injectee : unbind.getInjectees()) {
if (injectee instanceof SystemInjecteeImpl) {
injecteeToResolverCache.remove((SystemInjecteeImpl) injectee);
}
}
-
+
classReflectionHelper.clean(unbind.getImplementationClass());
}
}
-
+
boolean hasOneUnbind = false;
for (SystemDescriptor<?> unbind : unbinds) {
hasOneUnbind = true;
@@ -1876,7 +1876,7 @@
// as the validation service while we are unbinding
unbind.close();
}
-
+
if (hasOneUnbind) {
perLocatorUtilities.releaseCaches();
}
@@ -1981,13 +1981,13 @@
}
injecteeToResolverCache.clear();
}
-
+
private void reupInterceptionServices() {
List<InterceptionService> allInterceptionServices = protectedGetAllServices(InterceptionService.class);
interceptionServices.clear();
interceptionServices.addAll(allInterceptionServices);
-
+
hasInterceptionServices = !interceptionServices.isEmpty();
}
@@ -1997,7 +1997,7 @@
errorHandlers.clear();
errorHandlers.addAll(allErrorServices);
}
-
+
private void reupConfigListeners() {
List<ServiceHandle<?>> allConfigListeners = protectedGetAllServiceHandles(DynamicConfigurationListener.class);
@@ -2072,7 +2072,7 @@
if (errorHandlersModified) {
reupErrorHandlers();
}
-
+
if (dynamicConfigurationListenersModified) {
reupConfigListeners();
}
@@ -2087,7 +2087,7 @@
if (classAnalyzersModified) {
reupClassAnalyzers();
}
-
+
// Should be last in order to ensure none of the
// things added in this update are intercepted
if (interceptionServicesModified) {
@@ -2112,14 +2112,14 @@
sli.getAllChildren(allMyChildren);
}
}
-
+
private void callAllConfigurationListeners(List<ServiceHandle<?>> allListeners) {
if (allListeners == null) return;
-
+
for (ServiceHandle<?> listener : allListeners) {
ActiveDescriptor<?> listenerDescriptor = listener.getActiveDescriptor();
if (listenerDescriptor.getLocatorId() != id) continue;
-
+
try {
((DynamicConfigurationListener) listener.getService()).configurationChanged();
}
@@ -2131,7 +2131,7 @@
/* package */ void addConfiguration(DynamicConfigurationImpl dci) {
CheckConfigurationData checkData;
-
+
List<ServiceHandle<?>> allConfigurationListeners = null;
MultiException configurationError = null;
@@ -2151,7 +2151,7 @@
checkData.getDynamicConfigurationListenerModificationMade(),
checkData.getAffectedContracts(),
checkData.getInterceptionServiceModificationMade());
-
+
allConfigurationListeners = new LinkedList<ServiceHandle<?>>(configListeners);
} catch (MultiException me) {
configurationError = me;
@@ -2161,9 +2161,9 @@
if (configurationError != null) {
errorServices = new LinkedList<ErrorService>(errorHandlers);
}
-
+
wLock.unlock();
-
+
if (errorServices != null && !errorServices.isEmpty()) {
for (ErrorService errorService : errorServices) {
try {
@@ -2177,7 +2177,7 @@
// Ignore
}
}
-
+
}
}
@@ -2187,9 +2187,9 @@
for (ServiceLocatorImpl sli : allMyChildren) {
sli.reupCache(checkData.getAffectedContracts());
}
-
+
callAllConfigurationListeners(allConfigurationListeners);
-
+
LinkedList<TwoPhaseResource> resources = dci.getResources();
for (TwoPhaseResource resource : resources) {
try {
@@ -2224,12 +2224,6 @@
private Context<?> _resolveContext(final Class<? extends Annotation> scope) throws IllegalStateException {
Context<?> retVal = null;
- if (parent != null) {
- retVal = parent._resolveContext(scope);
- if (retVal != null) {
- return retVal;
- }
- }
Type actuals[] = new Type[1];
actuals[0] = scope;
ParameterizedType findContext = new ParameterizedTypeImpl(Context.class, actuals);
@@ -2257,7 +2251,7 @@
if (scope.equals(PerLookup.class)) return perLookupContext;
Context<?> retVal = contextCache.compute(scope);
if (retVal.isActive()) return retVal;
-
+
// Not active anymore, maybe there is another. But first, clear the cache!
contextCache.remove(scope);
return contextCache.compute(scope);
@@ -2464,7 +2458,7 @@
wLock.unlock();
}
}
-
+
@Override
public Unqualified getDefaultUnqualified() {
rLock.lock();
@@ -2475,7 +2469,7 @@
rLock.unlock();
}
}
-
+
@Override
public void setDefaultUnqualified(Unqualified unqualified) {
wLock.lock();
@@ -2485,7 +2479,7 @@
finally {
wLock.unlock();
}
-
+
}
/* package */ ClassAnalyzer getAnalyzer(String name, Collector collector) {
@@ -2562,7 +2556,7 @@
private boolean getClassAnalyzerModificationMade() {
return classAnalyzerModificationMade;
}
-
+
private boolean getDynamicConfigurationListenerModificationMade() {
return dynamicConfigurationListenerModificationMade;
}
@@ -2570,11 +2564,11 @@
private HashSet<String> getAffectedContracts() {
return affectedContracts;
}
-
+
private boolean getInterceptionServiceModificationMade() {
return interceptionServiceModificationMade;
}
-
+
private TwoPhaseTransactionData getTransactionData() {
return transactionData;
}
@@ -2594,7 +2588,7 @@
@Override
public boolean matches(Descriptor d) {
if (unqualified == null) return true;
-
+
Class<? extends Annotation> unqualifiedAnnos[] = unqualified.value();
if (unqualifiedAnnos.length <= 0) {
@@ -2622,7 +2616,7 @@
public String getName() {
return name;
}
-
+
@Override
public String toString() {
return "UnqualifiedIndexFilter(" + contract + "," + name + "," + unqualified + "," + System.identityHashCode(this) + ")";
@@ -2651,28 +2645,28 @@
}
}
-
+
/**
* Used to get the ServiceLocatorImpl in inner classes
- *
+ *
* @return This current object
*/
private ServiceLocatorImpl getMe() {
return this;
}
-
+
/* package */ boolean hasInjectAnnotation(AnnotatedElement annotated) {
return perLocatorUtilities.hasInjectAnnotation(annotated);
}
-
+
/* package */ InjectionResolver<?> getInjectionResolverForInjectee(SystemInjecteeImpl injectee) {
- return injecteeToResolverCache.compute(injectee);
+ return injecteeToResolverCache.compute(injectee);
}
-
+
/* package */ ClassReflectionHelper getClassReflectionHelper() {
return classReflectionHelper;
}
-
+
/* package */ LinkedList<ErrorService> getErrorHandlers() {
rLock.lock();
try {
@@ -2682,7 +2676,7 @@
rLock.unlock();
}
}
-
+
/* package */ PerLocatorUtilities getPerLocatorUtilities() {
return perLocatorUtilities;
}
@@ -2711,7 +2705,7 @@
/* package */ void clearServiceCache() {
igdCache.clear();
-
+
}
/* package */ int getReflectionCacheSize() {
@@ -2727,22 +2721,22 @@
wLock.unlock();
}
}
-
+
/* package */ int unsortIndexes(int newRank, SystemDescriptor<?> desc, Set<IndexedListData> myLists) {
wLock.lock();
try {
int retVal = desc.setRankWithLock(newRank);
-
+
for (IndexedListData myList : myLists) {
myList.unSort();
}
-
+
return retVal;
}
finally {
wLock.unlock();
}
-
+
}
@Override