package com.englishtown.vertx.jersey.impl; import com.englishtown.vertx.jersey.ApplicationConfigurator; import com.englishtown.vertx.jersey.ApplicationHandlerDelegate; import com.englishtown.vertx.jersey.JerseyOptions; import com.englishtown.vertx.jersey.VertxContainer; import com.englishtown.vertx.jersey.inject.InternalVertxJerseyBinder; import com.englishtown.vertx.jersey.inject.Nullable; import io.vertx.core.Vertx; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.jersey.server.ApplicationHandler; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.spi.Container; import org.jvnet.hk2.annotations.Optional; import javax.inject.Inject; import java.util.List; import java.util.Map; import java.util.Set; /** * Vert.x implementation of {@link Container} */ public class DefaultVertxContainer implements VertxContainer { private final Vertx vertx; private final ServiceLocator locator; private final ApplicationConfigurator configurator; private JerseyOptions options; private ApplicationHandlerDelegate applicationHandlerDelegate; private boolean started; @Inject public DefaultVertxContainer(Vertx vertx, JerseyOptions options, @Optional @Nullable ServiceLocator locator, @Optional @Nullable ApplicationConfigurator configurator) { this.vertx = vertx; this.options = options; this.locator = locator; this.configurator = configurator; } /** * Starts the container */ @Override public void start() { if (started) { return; } ApplicationHandler handler = getApplicationHandler(); if (handler == null) { throw new IllegalStateException("ApplicationHandler cannot be null"); } handler.onStartup(this); started = true; } /** * Stops the container */ @Override public void stop() { if (!started) { return; } getApplicationHandler().onShutdown(this); applicationHandlerDelegate = null; started = false; } /** * Returns the current vertx instance * * @return the {@link Vertx} instance */ @Override public Vertx getVertx() { return vertx; } @Override public JerseyOptions getOptions() { return options; } /** * Set the jersey configuration options * * @param options * @return */ @Override public VertxContainer setOptions(JerseyOptions options) { this.options = options; return this; } @Override public ApplicationHandlerDelegate getApplicationHandlerDelegate() { if (applicationHandlerDelegate == null) { ResourceConfig rc = createConfiguration(); ApplicationHandler applicationHandler = new ApplicationHandler(rc, null, locator); applicationHandlerDelegate = new DefaultApplicationHandlerDelegate(applicationHandler); } return applicationHandlerDelegate; } /** * Return an immutable representation of the current {@link ResourceConfig * configuration}. * * @return current configuration of the hosted Jersey application. */ @Override public ResourceConfig getConfiguration() { ApplicationHandler handler = getApplicationHandler(); return handler == null ? null : handler.getConfiguration(); } /** * Get the Jersey server-side application handler associated with the container. * * @return Jersey server-side application handler associated with the container. */ @Override public ApplicationHandler getApplicationHandler() { return getApplicationHandlerDelegate().getApplicationHandler(); } /** * Reload the hosted Jersey application using the current {@link ResourceConfig * configuration}. */ @Override public void reload() { reload(getConfiguration()); } /** * Reload the hosted Jersey application using a new {@link ResourceConfig * configuration}. * * @param configuration new configuration used for the reload. */ @Override public void reload(ResourceConfig configuration) { ApplicationHandler applicationHandler = new ApplicationHandler(configuration, null, locator); applicationHandlerDelegate = new DefaultApplicationHandlerDelegate(applicationHandler); getApplicationHandler().onReload(this); applicationHandler.onStartup(this); } protected ResourceConfig createConfiguration() { ResourceConfig rc = new ResourceConfig(); List<String> packages = options.getPackages(); Set<Class<?>> components = options.getComponents(); boolean hasPackages = (packages != null && !packages.isEmpty()); boolean hasComponents = (components != null && !components.isEmpty()); if (!hasComponents && !hasPackages) { throw new IllegalStateException("At least one resource package name or component must be specified"); } if (hasPackages) { rc.packages(packages.toArray(new String[packages.size()])); } if (hasComponents) { rc.registerClasses(components); } // Always register the InternalVertxJerseyBinder rc.register(new InternalVertxJerseyBinder(vertx)); // Register configured binders Set<Object> instances = options.getInstances(); if (instances != null) { rc.registerInstances(instances); } Map<String, Object> properties = options.getProperties(); if (properties != null) { rc.addProperties(properties); } if (configurator != null) { rc = configurator.configure(rc); } return rc; } }