package ameba.container; import ameba.container.event.*; import ameba.container.server.Connector; import ameba.core.Application; import ameba.event.SystemEventBus; import ameba.i18n.Messages; import ameba.util.ClassUtils; import org.glassfish.jersey.internal.inject.AbstractBinder; import org.glassfish.jersey.internal.inject.InjectionManager; import org.glassfish.jersey.server.ResourceConfig; import org.glassfish.jersey.server.spi.ContainerLifecycleListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.websocket.server.ServerContainer; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.List; /** * <p>Abstract Container class.</p> * * @author icode */ public abstract class Container { /** * Constant <code>logger</code> */ protected static final Logger logger = LoggerFactory.getLogger(Container.class); private Application application; /** * <p>Constructor for Container.</p> * * @param application a {@link ameba.core.Application} object. */ public Container(final Application application) { this.application = application; prepare(); configureHttpServer(); registerBinder(application.getConfig()); configureHttpContainer(); } /** * <p>create.</p> * * @param application a {@link ameba.core.Application} object. * @return a {@link ameba.container.Container} object. * @throws java.lang.IllegalAccessException if any. * @throws java.lang.InstantiationException if any. */ @SuppressWarnings("unchecked") public static Container create(Application application) throws IllegalAccessException, InstantiationException { String provider = (String) application.getProperty("container.provider"); logger.debug(Messages.get("info.container.provider", provider)); try { Class<Container> ContainerClass = (Class<Container>) ClassUtils.getClass(provider); Constructor<Container> constructor = ContainerClass.<Container>getDeclaredConstructor(Application.class); return constructor.newInstance(application); } catch (InvocationTargetException | NoSuchMethodException | ClassNotFoundException e) { throw new ContainerException(e); } } /** * <p>registerBinder.</p> * * @param configuration a {@link org.glassfish.jersey.server.ResourceConfig} object. * @since 0.1.6e */ protected void registerBinder(ResourceConfig configuration) { configuration.register(new AbstractBinder() { @Override protected void configure() { bind(Container.this).to(Container.class).proxy(false); } }); configuration.registerInstances(new ContainerLifecycleListener() { @Override public void onStartup(org.glassfish.jersey.server.spi.Container container) { SystemEventBus.publish(new StartupEvent(Container.this, application)); logger.trace(Messages.get("info.container.startup")); } @Override public void onReload(org.glassfish.jersey.server.spi.Container container) { SystemEventBus.publish(new ReloadedEvent(Container.this, application)); logger.trace(Messages.get("info.container.reload")); } @Override public void onShutdown(org.glassfish.jersey.server.spi.Container container) { logger.info("Container onShutdown"); SystemEventBus.publish(new ShutdownEvent(Container.this, application)); logger.trace(Messages.get("info.container.shutdown")); } }); } /** * <p>Getter for the field <code>application</code>.</p> * * @return a {@link ameba.core.Application} object. */ public Application getApplication() { return application; } /** * <p>getInjectionManager.</p> * * @return a InjectionManager object. */ public abstract InjectionManager getInjectionManager(); /** * <p>prepare.</p> * * @since 0.1.6e */ protected void prepare() { } /** * <p>configureHttpServer.</p> */ protected abstract void configureHttpServer(); /** * <p>configureHttpContainer.</p> */ protected abstract void configureHttpContainer(); /** * <p>getWebSocketContainer.</p> * * @return a {@link javax.websocket.server.ServerContainer} object. */ public abstract ServerContainer getWebSocketContainer(); /** * <p>start.</p> * * @throws java.lang.Exception if any. */ public void start() throws Exception { logger.trace(Messages.get("info.container.starting")); SystemEventBus.publish(new StartEvent(this, application)); doStart(); } /** * <p>reload.</p> * * @throws java.lang.Exception if any * @since 0.1.6e */ public void reload() throws Exception { SystemEventBus.publish(new BeginReloadEvent(this, application)); doReload(); } /** * <p>doReload.</p> * * @throws java.lang.Exception if any */ protected abstract void doReload() throws Exception; /** * <p>doStart.</p> * * @throws java.lang.Exception if any. */ protected abstract void doStart() throws Exception; /** * <p>shutdown.</p> * * @throws java.lang.Exception if any. */ public void shutdown() throws Exception { SystemEventBus.publish(new BeginShutdownEvent(this, application)); doShutdown(); } /** * <p>doShutdown.</p> * * @throws java.lang.Exception if any. */ public abstract void doShutdown() throws Exception; /** * <p>getConnectors.</p> * * @return a {@link java.util.List} object. */ public abstract List<Connector> getConnectors(); /** * <p>getType.</p> * * @return a {@link java.lang.String} object. */ public abstract String getType(); }