package org.webpieces.router.impl.loader; import java.util.ArrayList; import java.util.List; import javax.inject.Singleton; import org.webpieces.router.api.actions.Action; import org.webpieces.router.api.dto.MethodMeta; import org.webpieces.router.api.routing.RouteFilter; import org.webpieces.router.impl.FilterInfo; import org.webpieces.router.impl.RouteMeta; import org.webpieces.router.impl.hooks.MetaLoaderProxy; import org.webpieces.util.filters.Service; import com.google.inject.Injector; public abstract class AbstractLoader implements MetaLoaderProxy { private MetaLoader loader; public AbstractLoader(MetaLoader loader) { this.loader = loader; } protected void loadRouteImpl(RouteMeta meta, ResolvedMethod method) { String controllerStr = method.getControllerStr(); String methodStr = method.getMethodStr(); Injector injector = meta.getInjector(); Object controllerInst = createController(injector, controllerStr); Singleton singleton = controllerInst.getClass().getAnnotation(Singleton.class); if(singleton == null) throw new IllegalArgumentException("EVERY controller must be marked with @javax.inject.Singleton not @com.google.inject.Singleton. bad controller="+controllerInst.getClass().getName()); loader.loadInstIntoMeta(meta, controllerInst, methodStr); } protected abstract Object createController(Injector injector, String controllerStr); @Override public Service<MethodMeta, Action> createServiceFromFilters(RouteMeta meta, List<FilterInfo<?>> filterInfos) { Injector injector = meta.getInjector(); List<RouteFilter<?>> filters = createFilters(injector, filterInfos); Service<MethodMeta, Action> svcWithFilters = loader.loadFilters(filters); return svcWithFilters; } public void loadFiltersIntoMeta(RouteMeta meta, List<FilterInfo<?>> filterInfos) { meta.setService(createServiceFromFilters(meta, filterInfos)); } protected List<RouteFilter<?>> createFilters(Injector injector, List<FilterInfo<?>> filterInfos) { List<RouteFilter<?>> filters = new ArrayList<>(); for(FilterInfo<?> info : filterInfos) { RouteFilter<?> filter = createFilter2(injector, info); filters.add(filter); } return filters; } protected <T> RouteFilter<T> createFilter2(Injector injector, FilterInfo<T> info) { //This is a bit crazy in Development Server(production server is straightforward!!!). In Dev Server //If the Filter java file changed, this filterClass was reloaded from a different classloader to //blow away the previous filter. That was done upstream in the DevRoutingService Class<? extends RouteFilter<T>> filterClass = info.getFilter(); RouteFilter<T> f = injector.getInstance(filterClass); f.initialize(info.getInitialConfig()); return f; } }