001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2019–2020 microBean™.
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
014 * implied.  See the License for the specific language governing
015 * permissions and limitations under the License.
016 */
017package org.microbean.jersey.netty;
018
019import javax.ws.rs.core.Application;
020
021import org.glassfish.jersey.server.ApplicationHandler;
022import org.glassfish.jersey.server.ResourceConfig;
023
024import org.glassfish.jersey.server.spi.Container;
025
026/**
027 * A straightforward {@link Container} implementation that is not
028 * actually needed for Jersey integration.
029 *
030 * @author <a href="https://about.me/lairdnelson"
031 * target="_parent">Laird Nelson</a>
032 *
033 * @see Container
034 */
035public class SimpleContainer implements Container {
036
037
038  /*
039   * Instance fields.
040   */
041
042
043  private volatile ApplicationHandler applicationHandler;
044
045
046  /*
047   * Constructors.
048   */
049
050
051  /**
052   * Creates a new {@link SimpleContainer}.
053   *
054   * @param application the {@link Application} to host; may be {@code
055   * null} in which case a {@linkplain Application#Application() new}
056   * {@link Application} will be used instead
057   *
058   * @see #SimpleContainer(ApplicationHandler)
059   */
060  public SimpleContainer(final Application application) {
061    this(application == null ? (ApplicationHandler)null : new ApplicationHandler(application));
062  }
063
064  /**
065   * Creates a new {@link SimpleContainer}.
066   *
067   * @param applicationHandler the {@link ApplicationHandler} that
068   * actually does the work of hosting an application; may be {@code
069   * null} in which case a {@linkplain
070   * ApplicationHandler#ApplicationHandler() new} {@link
071   * ApplicationHandler} will be used instead
072   */
073  public SimpleContainer(final ApplicationHandler applicationHandler) {
074    super();
075    this.applicationHandler = applicationHandler == null ? new ApplicationHandler() : applicationHandler;
076  }
077
078
079  /*
080   * Instance methods.
081   */
082
083
084  /**
085   * Returns a {@link ResourceConfig} representing the configuration
086   * of the application hosted by this {@link SimpleContainer}.
087   *
088   * <p>This method may return {@code null}.</p>
089   *
090   * @return a {@link ResourceConfig} representing the configuration
091   * of the application hosted by this {@link SimpleContainer}, or
092   * {@code null}
093   *
094   * @see ApplicationHandler#getConfiguration()
095   */
096  @Override
097  public final ResourceConfig getConfiguration() {
098    final ResourceConfig returnValue;
099    final ApplicationHandler handler = this.getApplicationHandler(); // volatile read
100    if (handler == null) {
101      returnValue = null;
102    } else {
103      returnValue = handler.getConfiguration();
104    }
105    return returnValue;
106  }
107
108  /**
109   * Returns the {@link ApplicationHandler} this {@link
110   * SimpleContainer} uses.
111   *
112   * <p>This method may return {@code null}.</p>
113   *
114   * @return the {@link ApplicationHandler} this {@link
115   * SimpleContainer} uses, or {@code null}
116   */
117  @Override
118  public final ApplicationHandler getApplicationHandler() {
119    return this.applicationHandler;
120  }
121
122  /**
123   * Reloads the application hosted by this {@link SimpleContainer}.
124   *
125   * @see #reload(ResourceConfig)
126   */
127  @Override
128  public final void reload() {
129    this.reload(this.getConfiguration());
130  }
131
132  /**
133   * Loads what amounts to a new application using the supplied {@link
134   * ResourceConfig}.
135   *
136   * @param resourceConfig the {@link ResourceConfig} representing the
137   * new application; may be {@code null}
138   *
139   * @see ApplicationHandler#onShutdown(Container)
140   *
141   * @see ApplicationHandler#onReload(Container)
142   *
143   * @see ApplicationHandler#onStartup(Container)
144   */
145  @Override
146  public void reload(final ResourceConfig resourceConfig) {
147    ApplicationHandler handler = this.getApplicationHandler(); // volatile read
148    if (handler != null) {
149      handler.onShutdown(this);
150    }
151    handler = new ApplicationHandler(resourceConfig);
152    this.applicationHandler = handler; // volatile write
153    handler.onReload(this); // reference to local handler variable vs. instance variable is deliberate
154    handler.onStartup(this); // reference to local handler variable vs. instance variable is deliberate
155  }
156
157}