com.atlassian.plugin.clientsideextensions.ExtensionPageServlet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of atlassian-clientside-extensions-page-bootstrapper Show documentation
Show all versions of atlassian-clientside-extensions-page-bootstrapper Show documentation
Provides code for bootstrapping CSE pages.
The newest version!
package com.atlassian.plugin.clientsideextensions;
import com.atlassian.annotations.VisibleForTesting;
import com.atlassian.sal.api.message.I18nResolver;
import com.atlassian.soy.renderer.SoyException;
import com.atlassian.soy.renderer.SoyTemplateRenderer;
import com.google.common.collect.ImmutableMap;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.StringUtils.defaultIfEmpty;
import static org.apache.commons.lang3.StringUtils.isBlank;
/**
* Servlet that bootstraps the Client-side Extension based on provided extension-point and extension-key
*/
public class ExtensionPageServlet extends HttpServlet {
@VisibleForTesting
static final String CONTENT_TYPE = "text/html;charset=UTF-8";
// ----- ServletConfig keys
public static final String EXTENSION_KEY_PARAM_NAME = "extension-key";
public static final String EXTENSION_POINT_PARAM_NAME = "extension-point";
public static final String PAGE_DATA_PROVIDER_KEY_PARAM_NAME = "page-data-provider-key";
public static final String PAGE_DECORATOR_PARAM_NAME = "page-decorator";
public static final String PAGE_TITLE_PARAM_NAME = "page-title";
public static final String PAGE_TITLE_KEY_PARAM_NAME = "page-title-key";
public static final String WEB_RESOURCE_KEYS_PARAM_NAME = "web-resources";
public static final String WEB_RESOURCE_KEYS_SEPARATOR = ",";
// ----- ServletConfig defaults
// https://developer.atlassian.com/server/framework/atlassian-sdk/using-standard-page-decorators
@VisibleForTesting
static final String DEFAULT_PAGE_DECORATOR = "atl.general";
@VisibleForTesting
static final String DEFAULT_PAGE_TITLE = "";
// ----- Soy template coordinates
@VisibleForTesting
static final String RESOURCE_KEY = "com.atlassian.plugins.atlassian-clientside-extensions-page-bootstrapper:server-soy-templates";
@VisibleForTesting
static final String TEMPLATE_KEY = "CSE.Templates.page";
// ----- Soy template model keys
@VisibleForTesting
static final String MODEL_KEY_EXTENSION_POINT = "extensionPoint";
@VisibleForTesting
static final String MODEL_KEY_EXTENSION_KEY = "extensionKey";
@VisibleForTesting
static final String MODEL_KEY_PAGE_DATA_PROVIDER_KEY = "pageDataProviderKey";
@VisibleForTesting
static final String MODEL_KEY_PAGE_DECORATOR = "pageDecorator";
@VisibleForTesting
static final String MODEL_KEY_PAGE_TITLE = "pageTitle";
@VisibleForTesting
static final String MODEL_KEY_PATH = "path";
@VisibleForTesting
static final String MODEL_KEY_WEB_RESOURCE_KEYS = "webResourceKeys";
private final I18nResolver i18nResolver;
private final SoyTemplateRenderer soyTemplateRenderer;
private String extensionPoint;
private String extensionKey;
private String pageDecorator;
private String pageTitle;
private String pageDataProviderKey;
private String pageTitleKey;
/**
* Comma separated list of web-resource keys
*/
private String webResourceKeys;
public ExtensionPageServlet(final I18nResolver i18nResolver, final SoyTemplateRenderer soyTemplateRenderer) {
this.i18nResolver = requireNonNull(i18nResolver);
this.soyTemplateRenderer = requireNonNull(soyTemplateRenderer);
}
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
extensionPoint = getRequiredInitParam(EXTENSION_POINT_PARAM_NAME, config);
extensionKey = getRequiredInitParam(EXTENSION_KEY_PARAM_NAME, config);
webResourceKeys = getRequiredInitParam(WEB_RESOURCE_KEYS_PARAM_NAME, config);
pageDataProviderKey = getOptionalInitParam(PAGE_DATA_PROVIDER_KEY_PARAM_NAME, config, null);
pageDecorator = getOptionalInitParam(PAGE_DECORATOR_PARAM_NAME, config, DEFAULT_PAGE_DECORATOR);
pageTitle = getOptionalInitParam(PAGE_TITLE_PARAM_NAME, config, DEFAULT_PAGE_TITLE);
pageTitleKey = getOptionalInitParam(PAGE_TITLE_KEY_PARAM_NAME, config, null);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final ImmutableMap.Builder params = ImmutableMap.builder();
final String path = req.getPathInfo();
if (path != null) {
params.put(MODEL_KEY_PATH, path);
}
params
.put(MODEL_KEY_PAGE_TITLE, getPageTitle())
.put(MODEL_KEY_PAGE_DECORATOR, pageDecorator)
.put(MODEL_KEY_EXTENSION_POINT, extensionPoint)
.put(MODEL_KEY_EXTENSION_KEY, extensionKey)
.put(MODEL_KEY_WEB_RESOURCE_KEYS, getWebResourceKeys());
if (pageDataProviderKey != null) {
params.put(MODEL_KEY_PAGE_DATA_PROVIDER_KEY, pageDataProviderKey);
}
render(resp, params.build());
}
private String getPageTitle() {
//noinspection ConstantConditions
return Optional.ofNullable(pageTitleKey)
.map(i18nResolver::getText)
.filter(Objects::nonNull)
.filter(text -> !text.equals(pageTitleKey)) // i.e. a translation was found
.orElse(pageTitle);
}
private List getWebResourceKeys() {
return Arrays.stream(webResourceKeys.split(WEB_RESOURCE_KEYS_SEPARATOR))
.map(String::trim)
.collect(toList());
}
private void render(ServletResponse resp, Map data) throws IOException, ServletException {
resp.setContentType(CONTENT_TYPE);
try {
soyTemplateRenderer.render(resp.getWriter(), RESOURCE_KEY, TEMPLATE_KEY, data);
} catch (SoyException e) {
Throwable cause = e.getCause();
if (cause instanceof IOException) {
throw (IOException) cause;
}
throw new ServletException(e);
}
}
private static String getRequiredInitParam(final String key, final ServletConfig config) throws UnavailableException {
final String paramValue = config.getInitParameter(key);
if (isBlank(paramValue)) {
throw new UnavailableException("The required '" + key + "' init-param is missing or undefined");
}
return paramValue;
}
private static String getOptionalInitParam(final String key, final ServletConfig config, final String defaultValue) {
return defaultIfEmpty(config.getInitParameter(key), defaultValue);
}
}