private Application createApplication(Class<? extends Application> applicationClass) {
   // need to handle ResourceConfig and Application separately as invoking forContract() on these
   // will trigger the factories which we don't want at this point
   if (applicationClass == ResourceConfig.class) {
     return new ResourceConfig();
   } else if (applicationClass == Application.class) {
     return new Application();
   } else {
     Application app = locator.createAndInitialize(applicationClass);
     if (app instanceof ResourceConfig) {
       final ResourceConfig _rc = (ResourceConfig) app;
       final Class<? extends Application> innerAppClass = _rc.getApplicationClass();
       if (innerAppClass != null) {
         final Application innerApp = createApplication(innerAppClass);
         _rc.setApplication(innerApp);
       }
     }
     return app;
   }
 }
  /** Assumes the configuration field is initialized with a valid ResourceConfig. */
  private void initialize() {
    LOGGER.info(LocalizationMessages.INIT_MSG(Version.getBuildId()));

    // Lock original ResourceConfig.
    if (application instanceof ResourceConfig) {
      ((ResourceConfig) application).lock();
    }

    // add WADL support
    runtimeConfig.register(WadlModelProcessorFeature.class);

    // Configure binders and features.
    runtimeConfig.configureMetaProviders(locator);

    // Introspecting classes & instances
    final ResourceBag.Builder resourceBagBuilder = new ResourceBag.Builder();
    for (Class<?> c : runtimeConfig.getClasses()) {
      try {
        Resource resource = Resource.from(c);
        if (resource != null) {
          resourceBagBuilder.registerResource(c, resource);
        }
      } catch (IllegalArgumentException ex) {
        LOGGER.warning(ex.getMessage());
      }
    }

    for (Object o : runtimeConfig.getSingletons()) {
      try {
        Resource resource = Resource.from(o.getClass());
        if (resource != null) {
          resourceBagBuilder.registerResource(o, resource);
        }
      } catch (IllegalArgumentException ex) {
        LOGGER.warning(ex.getMessage());
      }
    }

    // Adding programmatic resource models
    for (Resource programmaticResource : runtimeConfig.getResources()) {
      resourceBagBuilder.registerProgrammaticResource(programmaticResource);
    }

    final ResourceBag resourceBag = resourceBagBuilder.build();

    runtimeConfig.lock();

    // Registering Injection Bindings
    final Set<ComponentProvider> componentProviders = new HashSet<ComponentProvider>();

    for (ComponentProvider provider : ServiceFinder.find(ComponentProvider.class)) {
      provider.initialize(locator);
      componentProviders.add(provider);
    }

    final ComponentBag componentBag = runtimeConfig.getComponentBag();
    bindProvidersAndResources(
        componentProviders, componentBag, resourceBag.classes, resourceBag.instances);
    for (ComponentProvider componentProvider : componentProviders) {
      componentProvider.done();
    }

    // scan for NameBinding annotations attached to the application class
    Collection<Class<? extends Annotation>> applicationNameBindings =
        ReflectionHelper.getAnnotationTypes(application.getClass(), NameBinding.class);

    // find all filters, interceptors and dynamic features
    final Iterable<RankedProvider<ContainerResponseFilter>> responseFilters =
        Providers.getAllRankedProviders(locator, ContainerResponseFilter.class);
    final MultivaluedMap<Class<? extends Annotation>, RankedProvider<ContainerResponseFilter>>
        nameBoundResponseFilters =
            filterNameBound(responseFilters, null, componentBag, applicationNameBindings);

    final Iterable<RankedProvider<ContainerRequestFilter>> requestFilters =
        Providers.getAllRankedProviders(locator, ContainerRequestFilter.class);
    final List<RankedProvider<ContainerRequestFilter>> preMatchFilters = Lists.newArrayList();
    final MultivaluedMap<Class<? extends Annotation>, RankedProvider<ContainerRequestFilter>>
        nameBoundRequestFilters =
            filterNameBound(requestFilters, preMatchFilters, componentBag, applicationNameBindings);

    final Iterable<RankedProvider<ReaderInterceptor>> readerInterceptors =
        Providers.getAllRankedProviders(locator, ReaderInterceptor.class);
    final MultivaluedMap<Class<? extends Annotation>, RankedProvider<ReaderInterceptor>>
        nameBoundReaderInterceptors =
            filterNameBound(readerInterceptors, null, componentBag, applicationNameBindings);

    final Iterable<RankedProvider<WriterInterceptor>> writerInterceptors =
        Providers.getAllRankedProviders(locator, WriterInterceptor.class);
    final MultivaluedMap<Class<? extends Annotation>, RankedProvider<WriterInterceptor>>
        nameBoundWriterInterceptors =
            filterNameBound(writerInterceptors, null, componentBag, applicationNameBindings);
    final Iterable<DynamicFeature> dynamicFeatures =
        Providers.getAllProviders(locator, DynamicFeature.class);

    ResourceModel resourceModel =
        new ResourceModel.Builder(resourceBag.getRootResources(), false).build();

    resourceModel = processResourceModel(resourceModel);
    // validate the models
    validate(resourceModel);

    bindEnhancingResourceClasses(resourceModel, resourceBag, componentProviders);

    final RuntimeModelBuilder runtimeModelBuilder = locator.getService(RuntimeModelBuilder.class);
    runtimeModelBuilder.setGlobalInterceptors(readerInterceptors, writerInterceptors);
    runtimeModelBuilder.setBoundProviders(
        nameBoundRequestFilters,
        nameBoundResponseFilters,
        nameBoundReaderInterceptors,
        nameBoundWriterInterceptors,
        dynamicFeatures);

    // assembly request processing chain
    /**
     * Root hierarchical request matching acceptor. Invoked in a single linear stage as part of the
     * main linear accepting chain.
     */
    final Router resourceRoutingRoot =
        runtimeModelBuilder.buildModel(resourceModel.getRuntimeResourceModel(), false);

    final ContainerFilteringStage preMatchRequestFilteringStage =
        locator
            .createAndInitialize(ContainerFilteringStage.Builder.class)
            .build(preMatchFilters, responseFilters);
    final RoutingStage routingStage =
        locator.createAndInitialize(RoutingStage.Builder.class).build(resourceRoutingRoot);
    final ContainerFilteringStage resourceFilteringStage =
        locator
            .createAndInitialize(ContainerFilteringStage.Builder.class)
            .build(requestFilters, null);
    final RoutedInflectorExtractorStage routedInflectorExtractorStage =
        locator.createAndInitialize(RoutedInflectorExtractorStage.class);
    /**
     * Root linear request acceptor. This is the main entry point for the whole request processing.
     */
    final Stage<ContainerRequest> rootStage =
        Stages.chain(locator.createAndInitialize(ReferencesInitializer.class))
            .to(locator.createAndInitialize(ContainerMessageBodyWorkersInitializer.class))
            .to(preMatchRequestFilteringStage)
            .to(routingStage)
            .to(resourceFilteringStage)
            .build(routedInflectorExtractorStage);

    // Inject instances.
    for (Object instance : componentBag.getInstances(ComponentBag.EXCLUDE_META_PROVIDERS)) {
      locator.inject(instance);
    }
    for (Object instance : resourceBag.instances) {
      locator.inject(instance);
    }

    // initiate resource model into JerseyResourceContext
    JerseyResourceContext jerseyResourceContext = locator.getService(JerseyResourceContext.class);
    jerseyResourceContext.setResourceModel(resourceModel);

    this.runtime = locator.createAndInitialize(ServerRuntime.Builder.class).build(rootStage);

    // inject self
    locator.inject(this);
  }
  /**
   * Build a runtime model.
   *
   * @param subResourceMode if {@code true}, all resources will be processed as sub-resources.
   * @return runtime request routing root.
   */
  public Router buildModel(boolean subResourceMode) {
    final PushMatchedUriRouter uriPushingRouter =
        locator.createAndInitialize(PushMatchedUriRouter.class);
    RouteToPathBuilder<PathPattern> lastRoutedBuilder = null;

    // route resource method acceptors
    if (!rootAcceptors.isEmpty()) {
      for (Map.Entry<PathPattern, List<MethodAcceptorPair>> entry : rootAcceptors.entrySet()) {
        final PathPattern closedResourcePathPattern = entry.getKey();
        List<MethodAcceptorPair> methodAcceptorPairs = entry.getValue();

        lastRoutedBuilder =
            routeMethodAcceptor(
                lastRoutedBuilder,
                closedResourcePathPattern,
                uriPushingRouter,
                methodSelectingAcceptorBuilder.build(workers, methodAcceptorPairs),
                subResourceMode);
      }
      rootAcceptors.clear();
    }

    // route sub-resource method and locator acceptors
    if (!subResourceAcceptors.isEmpty()) {
      for (Map.Entry<PathPattern, TreeMap<PathPattern, List<MethodAcceptorPair>>>
          singleResourcePathEntry : subResourceAcceptors.entrySet()) {

        RouteToPathBuilder<PathPattern> srRoutedBuilder = null;
        for (Map.Entry<PathPattern, List<MethodAcceptorPair>> singlePathEntry :
            singleResourcePathEntry.getValue().entrySet()) {

          // there can be multiple sub-resource methods on the same path
          // but only a single sub-resource locator.
          List<MethodAcceptorPair> resourceMethods = Lists.newLinkedList();
          MethodAcceptorPair resourceLocator = null;

          for (MethodAcceptorPair methodAcceptorPair : singlePathEntry.getValue()) {
            if (methodAcceptorPair.model.getType() == ResourceMethod.JaxrsType.RESOURCE_METHOD) {
              resourceMethods.add(methodAcceptorPair);
            } else {
              resourceLocator = methodAcceptorPair;
            }
          }
          if (!resourceMethods.isEmpty()) {
            final PathPattern subResourceMethodPath =
                PathPattern.asClosed(singlePathEntry.getKey());
            srRoutedBuilder =
                routedBuilder(srRoutedBuilder)
                    .route(subResourceMethodPath)
                    .to(uriPushingRouter)
                    .to(methodSelectingAcceptorBuilder.build(workers, resourceMethods));
          }

          if (resourceLocator != null) {
            srRoutedBuilder =
                routedBuilder(srRoutedBuilder)
                    .route(singlePathEntry.getKey())
                    .to(uriPushingRouter)
                    .to(resourceLocator.router);
          }
        }
        assert srRoutedBuilder != null;
        lastRoutedBuilder =
            routeMethodAcceptor(
                lastRoutedBuilder,
                singleResourcePathEntry.getKey(),
                uriPushingRouter,
                srRoutedBuilder.build(),
                subResourceMode);
      }
      subResourceAcceptors.clear();
    }
    return createRootTreeAcceptor(lastRoutedBuilder, subResourceMode);
  }
Beispiel #4
0
 /**
  * Get the class by contract or create and inject a new instance.
  *
  * @param <T> instance type.
  * @param serviceLocator HK2 service locator.
  * @param clazz class of the instance to be provider.
  * @return instance of the class either provided as a service or created and injected by HK2.
  */
 public static <T> T getOrCreate(ServiceLocator serviceLocator, Class<T> clazz) {
   T component = serviceLocator.getService(clazz);
   return component == null ? serviceLocator.createAndInitialize(clazz) : component;
 }