Skip to content

Commit

Permalink
#1113 Drop explicitly scoped processors in favor of additional contex…
Browse files Browse the repository at this point in the history
…t passing
  • Loading branch information
GuusLieben committed Oct 25, 2024
1 parent 87d6429 commit 12001e4
Show file tree
Hide file tree
Showing 17 changed files with 213 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@

import org.checkerframework.checker.nullness.qual.NonNull;
import org.dockbox.hartshorn.inject.ContextKey;
import org.dockbox.hartshorn.inject.binding.DefaultBindingConfigurerContext;
import org.dockbox.hartshorn.inject.InjectionCapableApplication;
import org.dockbox.hartshorn.inject.binding.HierarchicalBinder;
import org.dockbox.hartshorn.inject.processing.ComponentProcessorRegistry;
import org.dockbox.hartshorn.inject.processing.CompositeHierarchicalBinderPostProcessor;
import org.dockbox.hartshorn.inject.processing.HierarchicalBinderPostProcessor;
import org.dockbox.hartshorn.inject.processing.HierarchicalBinderProcessorRegistry;
import org.dockbox.hartshorn.inject.processing.MultiMapComponentProcessorRegistry;
Expand Down Expand Up @@ -68,28 +68,31 @@ public class HierarchicalComponentProviderOrchestrator
private final transient ComponentRegistry registry;
private final transient ComponentPostConstructor postConstructor;

private final ComponentProcessorRegistry componentProcessorRegistry = new MultiMapComponentProcessorRegistry();
private final HierarchicalBinderProcessorRegistry binderProcessorRegistry = new MultiMapHierarchicalBinderProcessorRegistry();

private HierarchicalBinderAwareComponentProvider getOrCreateProvider(Scope scope) {
if (scope == null) {
scope = this.applicationScope;
}
synchronized (this.scopedProviders) {
return this.scopedProviders.computeIfAbsent(scope, this::createComponentProvider);
}
}
private final ComponentProcessorRegistry componentProcessorRegistry;
private final HierarchicalBinderProcessorRegistry binderProcessorRegistry;

protected HierarchicalComponentProviderOrchestrator(InjectionCapableApplication application, ComponentRegistry registry, ComponentPostConstructor postConstructor) {
this.registry = registry;
this.application = application;
this.postConstructor = postConstructor;

// Eagerly initialize the application provider
this.applicationScope = ScopeAdapter.of(this);
this.componentProcessorRegistry = new MultiMapComponentProcessorRegistry();
this.binderProcessorRegistry = new MultiMapHierarchicalBinderProcessorRegistry();

// Eagerly initialize the application provider
this.getOrCreateProvider(this.applicationScope);
}

private HierarchicalBinderAwareComponentProvider getOrCreateProvider(Scope scope) {
if (scope == null) {
scope = this.applicationScope;
}
synchronized (this.scopedProviders) {
return this.scopedProviders.computeIfAbsent(scope, this::createComponentProvider);
}
}

@NonNull
private HierarchicalBinderAwareComponentProvider createComponentProvider(Scope scope) {
HierarchicalBinderAwareComponentProvider provider = HierarchyAwareComponentProvider.create(
Expand All @@ -109,7 +112,8 @@ private HierarchicalBinderAwareComponentProvider createComponentProvider(Scope s
}
}

this.binderProcessorRegistry.process(this.application, provider.binder());
HierarchicalBinderPostProcessor binderPostProcessor = new CompositeHierarchicalBinderPostProcessor(this.binderProcessorRegistry()::processors);
binderPostProcessor.process(this.application, provider.scope(), provider.binder());
return provider;
}

Expand Down Expand Up @@ -200,8 +204,7 @@ public static ContextualInitializer<ComponentRegistry, ComponentProviderOrchestr

ComponentRegistry registry = context.input();
ComponentPostConstructor postConstructor = configurer.componentPostConstructor.initialize(SimpleSingleElementContext.create(application));
HierarchicalComponentProviderOrchestrator componentProvider = new HierarchicalComponentProviderOrchestrator(application, registry, postConstructor);
return componentProvider;
return new HierarchicalComponentProviderOrchestrator(application, registry, postConstructor);
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dockbox.hartshorn.inject;

@FunctionalInterface
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dockbox.hartshorn.inject;

import java.lang.reflect.InvocationTargetException;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dockbox.hartshorn.inject.processing;

import java.util.function.Supplier;
import org.dockbox.hartshorn.inject.InjectionCapableApplication;
import org.dockbox.hartshorn.inject.binding.HierarchicalBinder;
import org.dockbox.hartshorn.inject.scope.Scope;
import org.dockbox.hartshorn.util.collections.MultiMap;

public class CompositeHierarchicalBinderPostProcessor implements HierarchicalBinderPostProcessor {

private final Supplier<MultiMap<Integer, HierarchicalBinderPostProcessor>> postProcessors;

public CompositeHierarchicalBinderPostProcessor(Supplier<MultiMap<Integer, HierarchicalBinderPostProcessor>> postProcessors) {
this.postProcessors = postProcessors;
}

@Override
public void process(InjectionCapableApplication application, Scope scope, HierarchicalBinder binder) {
MultiMap<Integer, HierarchicalBinderPostProcessor> processors = this.postProcessors.get();
for (Integer priority : processors.keySet()) {
for(HierarchicalBinderPostProcessor processor : processors.get(priority)) {
processor.process(application, scope, binder);
}
}
}

@Override
public int priority() {
return ProcessingPriority.NORMAL_PRECEDENCE;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.dockbox.hartshorn.inject.processing;

import org.dockbox.hartshorn.inject.InjectionCapableApplication;
import org.dockbox.hartshorn.inject.binding.HierarchicalBinder;
import org.dockbox.hartshorn.inject.scope.Scope;

/**
* A post processor for hierarchical binders. This can be used to add additional functionality to a binder, or to modify
Expand All @@ -17,7 +34,7 @@
*/
public interface HierarchicalBinderPostProcessor {

void process(InjectionCapableApplication application, HierarchicalBinder binder);
void process(InjectionCapableApplication application, Scope scope, HierarchicalBinder binder);

int priority();
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,18 @@

package org.dockbox.hartshorn.inject.processing;

import org.dockbox.hartshorn.inject.scope.ScopeKey;
import org.dockbox.hartshorn.util.collections.MultiMap;
import org.dockbox.hartshorn.util.option.Option;

public interface HierarchicalBinderProcessorRegistry extends HierarchicalBinderPostProcessor{
public interface HierarchicalBinderProcessorRegistry {

void register(HierarchicalBinderPostProcessor processor);

void register(ScopeKey scope, HierarchicalBinderPostProcessor processor);

void unregister(HierarchicalBinderPostProcessor processor);

void unregister(ScopeKey scope, HierarchicalBinderPostProcessor processor);

boolean isRegistered(Class<? extends HierarchicalBinderPostProcessor> componentProcessor);

boolean isRegistered(ScopeKey scope, Class<? extends HierarchicalBinderPostProcessor> componentProcessor);

<T extends HierarchicalBinderPostProcessor> Option<T> lookup(Class<T> componentProcessor);

<T extends HierarchicalBinderPostProcessor> Option<T> lookup(ScopeKey scope, Class<T> componentProcessor);

MultiMap<Integer, HierarchicalBinderPostProcessor> processors();

MultiMap<Integer, HierarchicalBinderPostProcessor> processors(ScopeKey scope);

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
package org.dockbox.hartshorn.inject.processing;
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import java.util.Map;
package org.dockbox.hartshorn.inject.processing;

import org.dockbox.hartshorn.inject.InjectionCapableApplication;
import org.dockbox.hartshorn.inject.binding.HierarchicalBinder;
import org.dockbox.hartshorn.inject.scope.ScopeKey;
import org.dockbox.hartshorn.util.collections.ConcurrentSetTreeMultiMap;
import org.dockbox.hartshorn.util.collections.MultiMap;
import org.dockbox.hartshorn.util.option.Option;
Expand All @@ -18,33 +29,17 @@ public void register(HierarchicalBinderPostProcessor processor) {
this.globalProcessors.put(processor.priority(), processor);
}

@Override
public void register(ScopeKey scope, HierarchicalBinderPostProcessor processor) {
// TODO: #1113 Implement scoped registration
}

@Override
public void unregister(HierarchicalBinderPostProcessor processor) {
this.globalProcessors.remove(processor.priority(), processor);
}

@Override
public void unregister(ScopeKey scope, HierarchicalBinderPostProcessor processor) {
// TODO: #1113 Implement scoped registration
}

@Override
public boolean isRegistered(Class<? extends HierarchicalBinderPostProcessor> componentProcessor) {
return this.globalProcessors.allValues().stream()
.anyMatch(processor -> processor.getClass().equals(componentProcessor));
}

@Override
public boolean isRegistered(ScopeKey scope, Class<? extends HierarchicalBinderPostProcessor> componentProcessor) {
// TODO: #1113 Implement scoped registration
return false;
}

@Override
public <T extends HierarchicalBinderPostProcessor> Option<T> lookup(Class<T> componentProcessor) {
return Option.of(this.globalProcessors.allValues().stream()
Expand All @@ -53,35 +48,8 @@ public <T extends HierarchicalBinderPostProcessor> Option<T> lookup(Class<T> com
.findFirst());
}

@Override
public <T extends HierarchicalBinderPostProcessor> Option<T> lookup(ScopeKey scope, Class<T> componentProcessor) {
// TODO: #1113 Implement scoped registration
return null;
}

@Override
public MultiMap<Integer, HierarchicalBinderPostProcessor> processors() {
return this.globalProcessors;
}

@Override
public MultiMap<Integer, HierarchicalBinderPostProcessor> processors(ScopeKey scope) {
// TODO: #1113 Implement scoped registration
return null;
}

@Override
public void process(InjectionCapableApplication application, HierarchicalBinder binder) {
MultiMap<Integer, HierarchicalBinderPostProcessor> processors = this.processors();
for (Integer priority : processors.keySet()) {
for(HierarchicalBinderPostProcessor processor : processors.get(priority)) {
processor.process(application, binder);
}
}
}

@Override
public int priority() {
return 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,20 +62,10 @@ public static ComponentConstructorResolver create(InjectorEnvironment environmen
}

public static ComponentConstructorResolver create(InjectionCapableApplication applicationContext) {
HierarchyLookup hierarchyLookup;
if (applicationContext.defaultBinder() instanceof HierarchyLookup lookup) {
hierarchyLookup = lookup;
}
else if (applicationContext.defaultProvider() instanceof HierarchyLookup lookup) {
hierarchyLookup = lookup;
}
else {
throw new IllegalStateException("No hierarchy lookup found");
}
return new ComponentConstructorResolver(
applicationContext.environment().injectionPointsResolver(),
applicationContext.environment().introspector(),
hierarchyLookup
applicationContext.defaultBinder()
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/*
* Copyright 2019-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package test.org.dockbox.hartshorn.inject.processing;

import org.dockbox.hartshorn.inject.ComponentKey;
Expand Down
Loading

0 comments on commit 12001e4

Please sign in to comment.