Skip to content

Commit

Permalink
fixed error handling; refactored ordering of grains; fixed proxy regi…
Browse files Browse the repository at this point in the history
…stry
  • Loading branch information
7aske committed Jun 11, 2024
1 parent ec3307b commit 3d149df
Show file tree
Hide file tree
Showing 14 changed files with 88 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class DependencyContainerImpl implements DependencyContainer, Iterable<In
private final GrainNameResolver grainNameResolver = GrainNameResolver.getDefault();

public DependencyContainerImpl() {
this.dependencies = new PriorityQueue<>(By.order());
this.dependencies = new PriorityQueue<>(By.injectableOrder());
}

@Override
Expand Down Expand Up @@ -158,7 +158,7 @@ private Optional<Injectable> resolveSingleDependency(String name, List<Injectabl
public Collection<Injectable> getAll() {
return dependencies
.stream()
.sorted(By.<Injectable>order().thenComparing(Injectable::getType, By::packages))
.sorted(By.injectableOrder())
.toList();

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ public void inject(Set<Class<?>> classes) {
// These should be skipped as they are added to the dependency
// container but are not actual classes that we should initialize
// in the DI process. Rather we let grain methods do that.
if (dependency.isGrainMethodDependency()) {
continue;
}
// if (dependency.isGrainMethodDependency()) {
// continue;
// }

initialize(dependency);
}
Expand Down Expand Up @@ -257,6 +257,10 @@ private void initialize(Injectable dependency) {
// If the dependency is initialized already we do nothing.
if (dependency.isInitialized()) return;

if (dependency.isGrainMethodDependency()) {
initialize(dependency.getParent());
}


GrainFactory grainFactory = container.getOptionalGrain(GrainFactory.class)
.orElse(new DefaultGrainFactory());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ public String toString() {
builder.append("(").append(parentName).append(")");
}

builder.append("[").append(getOrder()).append("]");
builder.append("[").append(type.getPackageName()).append("]");
builder.append("[").append(order).append("]");


return builder.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,23 @@
@Grain
@Order(Order.HIGHEST_PRECEDENCE)
public class ProxyInterceptorAbstractFactoryRegistry {
private final Map<Class<?>, ProxyInterceptorAbstractFactory> factories;
private final List<ProxyInterceptorAbstractFactory> factories;

public ProxyInterceptorAbstractFactoryRegistry(List<ProxyInterceptorAbstractFactory> factoryList) {
factories = new HashMap<>();
for (ProxyInterceptorAbstractFactory factory : factoryList) {
factories.put(factory.getDiscriminatorType(), factory);
}
this.factories = factoryList;
}

public Optional<ProxyInterceptorAbstractFactory> getFactory(Class<?> clazz) {
public Optional<ProxyInterceptorAbstractFactory> getFactory(Object object) {
return factories
.entrySet()
.stream()
.filter(entry -> entry.getKey().isAssignableFrom(clazz))
.map(Map.Entry::getValue)
.filter(factory -> factory.supports(object))
.findFirst();
}


public boolean supports(Class<?> clazz) {
return getFactory(clazz).isPresent();
public boolean supports(Object object) {
return factories
.stream()
.anyMatch(factory -> factory.supports(object));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public boolean supports(Injectable dependency) {

@Override
public <T> T create(Injectable dependency, Object[] args) {
for (GrainFactory factory : factories) {
for (GrainFactory factory : factories.stream().sorted(By.order()).toList()) {
if (factory.supports(dependency)) {
return factory.create(dependency, args);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public int getOrder() {

@Override
public boolean supports(Injectable dependency) {
return !Modifier.isFinal(dependency.getType().getModifiers()) && proxyRegistry != null;
return !Modifier.isFinal(dependency.getType().getModifiers()) && Optional.of(proxyRegistry)
.map(registry -> registry.supports(dependency.getType()))
.orElse(false);
}

@Override
Expand All @@ -46,7 +48,7 @@ public <T> T create(Injectable dependency, Object[] args) {
DynamicType.Builder<?> byteBuddy = new ByteBuddy()
.subclass(clazz);
for (Method method : clazz.getDeclaredMethods()) {
Optional<ProxyInterceptorAbstractFactory> factoryOptional = proxyRegistry.getFactory(clazz);
Optional<ProxyInterceptorAbstractFactory> factoryOptional = proxyRegistry.getFactory(method);
if (factoryOptional.isEmpty()) {
continue;
}
Expand Down
15 changes: 15 additions & 0 deletions grain-core/src/main/java/com/_7aske/grain/util/By.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com._7aske.grain.util;

import com._7aske.grain.GrainApp;
import com._7aske.grain.core.component.Injectable;
import com._7aske.grain.core.component.Order;
import com._7aske.grain.core.component.Ordered;
import com._7aske.grain.core.reflect.ProxyInterceptorAbstractFactory;
import com._7aske.grain.core.reflect.factory.GrainFactory;

import java.lang.reflect.Method;
import java.util.Comparator;
Expand Down Expand Up @@ -68,6 +71,18 @@ public static <T extends Ordered> Comparator<T> order() {
return Comparator.comparingInt(T::getOrder);
}

public static Comparator<Injectable> injectableOrder() {
return Comparator.<Injectable, Boolean>comparing(i -> !i.getType().getPackageName().startsWith(GrainApp.class.getPackageName()))
.thenComparing(i -> !GrainFactory.class.isAssignableFrom(i.getType()))
.thenComparing(i -> !ProxyInterceptorAbstractFactory.class.isAssignableFrom(i.getType()))
.thenComparing((i1, i2) -> {
if (i1.getType().isAssignableFrom(i2.getType())) return 0;
if (i2.getType().isAssignableFrom(i1.getType())) return 0;
return i1.getType().getPackageName().compareTo(i2.getType().getPackageName());
})
.thenComparing(Injectable::getOrder);
}

/**
* Comparator that is comparing objects by their package names.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com._7aske.grain.core.component;

import com._7aske.grain.core.configuration.Configuration;
import com._7aske.grain.core.reflect.factory.CompositeGrainFactory;
import com._7aske.grain.core.reflect.factory.DefaultGrainFactory;
import com._7aske.grain.core.reflect.factory.GrainMethodGrainFactory;
import com._7aske.grain.core.reflect.factory.InterfaceGrainFactory;
import com._7aske.grain.exception.GrainInitializationException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -17,6 +21,7 @@ class GrainInitializerTest {
@BeforeEach
void setUp() {
grainInitializer = new GrainInjector(Configuration.createDefault());
grainInitializer.inject(Set.of(CompositeGrainFactory.class, InterfaceGrainFactory.class, DefaultGrainFactory.class, GrainMethodGrainFactory.class));
}

interface TestGrain {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com._7aske.grain.security.authentication;

import com._7aske.grain.core.component.Order;
import com._7aske.grain.web.controller.annotation.Controller;
import com._7aske.grain.core.component.Inject;
import com._7aske.grain.web.exception.HttpException;
Expand All @@ -21,6 +22,7 @@
* Default authentication entry point handling form POST requests to /login
*/
@Controller
@Order(Order.LOWEST_PRECEDENCE)
@RequestMapping
public class FormLoginAuthenticationEntryPointController {
@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class DefaultExceptionController {
@Order(255)
@ExceptionHandler(HttpException.class)
public Object handle(HttpException ex, HttpRequest request, HttpResponse response) throws IOException {
response.reset();
if (!response.isCommitted())
response.reset();
response.setStatus(ex.getStatus());

if (Objects.equals(request.getHeader(ACCEPT), ContentType.APPLICATION_JSON) ||
Expand All @@ -42,7 +43,8 @@ public Object handle(HttpException ex, HttpRequest request, HttpResponse respons
@Order(256)
@ExceptionHandler(Exception.class)
public Object handle(Exception ex, HttpRequest request, HttpResponse response) throws IOException {
response.reset();
if (!response.isCommitted())
response.reset();
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);

if (Objects.equals(request.getHeader(ACCEPT), ContentType.APPLICATION_JSON) ||
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com._7aske.grain.web.controller.exceptionhandler;


import com._7aske.grain.web.controller.annotation.ExceptionController;
import com._7aske.grain.core.component.Grain;
import com._7aske.grain.core.component.Inject;
import com._7aske.grain.exception.GrainRuntimeException;
import com._7aske.grain.util.Pair;
import com._7aske.grain.web.controller.ResponseStatusResolver;
import com._7aske.grain.web.controller.annotation.ExceptionController;
import com._7aske.grain.web.controller.annotation.ResponseStatus;
import com._7aske.grain.web.controller.response.ResponseWriter;
import com._7aske.grain.web.controller.response.ResponseWriterRegistry;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com._7aske.grain.web.requesthandler.controller;

import com._7aske.grain.util.By;
import com._7aske.grain.web.controller.annotation.Controller;
import com._7aske.grain.core.component.Grain;
import com._7aske.grain.core.component.Inject;
Expand Down Expand Up @@ -30,6 +31,7 @@ public ControllerHandlerRegistry(HandlerProxyFactory handlerProxyFactory,
ResponseWriterRegistry responseWriterRegistry,
@Inject(annotatedBy = Controller.class) List<Object> controllers) {
this.controllers = controllers.stream()
.sorted(By::objectOrder)
.map(ControllerWrapper::new)
.map(wrapper -> new ControllerHandler(wrapper, parameterConverterRegistry, responseWriterRegistry))
.toList();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com._7aske.grain.web.server.silo;

import com._7aske.grain.core.component.Grain;
import com._7aske.grain.core.component.Order;
import com._7aske.grain.core.configuration.Configuration;
import com._7aske.grain.core.context.ApplicationContext;
import com._7aske.grain.web.server.Server;
Expand All @@ -9,6 +10,7 @@
public class SiloServerProvider {

@Grain
@Order(Order.LOWEST_PRECEDENCE)
public Server server(Configuration configuration, ApplicationContext context) {
return new Silo(configuration, context);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com._7aske.grain.web.view;

import com._7aske.grain.core.component.Grain;
import com._7aske.grain.core.component.Order;
import com._7aske.grain.exception.GrainRuntimeException;
import com._7aske.grain.security.Authentication;
import com._7aske.grain.web.http.HttpRequest;
import com._7aske.grain.web.http.HttpResponse;
import com._7aske.grain.web.http.session.Session;

import java.io.IOException;
import java.io.OutputStream;

@Grain
@Order(Order.LOWEST_PRECEDENCE)
public class DefaultViewResolver implements ViewResolver {
@Override
public void resolve(View view, HttpRequest request, HttpResponse response, Session session, Authentication authentication) {
populateImplicitObjects(view, request, response, session, authentication, null);

response.setHeader("Content-Type", view.getContentType());
response.setContentLength(view.getContent().length());
try (OutputStream outputStream = response.getOutputStream()) {
byte[] output = view.getContent().getBytes();
outputStream.write(view.getContent().getBytes());
response.setContentType(view.getContentType());
response.setContentLength(output.length);
outputStream.flush();
} catch (IOException e) {
throw new GrainRuntimeException(e);
}
}
}

0 comments on commit 3d149df

Please sign in to comment.