package com.fredhopper.server; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ResourceHandler; import org.eclipse.jetty.util.resource.Resource; import com.fredhopper.environment.Environment; import com.fredhopper.server.spi.ContextHandlerFactory; /** * A {@link ContextHandlerFactory} that creates a context * located at <code>/docs</code> if the necessary elements are * available in the provided environment. */ public class DocumentationContextHandlerFactory implements ContextHandlerFactory { /** * Default name of the folder inside application root to hold * documentation. */ private static final String DEFAULT_DOCS_FOLDER = "docs"; /** * The default context path of the documentation. */ private static final String CONTEXT_PATH = "/" + DEFAULT_DOCS_FOLDER; /** * The directory from which the server/application might be * launched. */ private static final String APPLICATION_BASE = "application.base"; @Override public ContextHandler createContextHandler(Environment environment) { String appName = environment.getApplicationName(); String docsRootPath = environment.getValue(appName + ".docs.root"); if (docsRootPath != null && containsDocumentation(Paths.get(docsRootPath))) { return createDocumentationContext(Paths.get(docsRootPath)); } Path root = environment.getApplicationRoot(); if (root != null && containsDocumentation(root.resolve(DEFAULT_DOCS_FOLDER))) { return createDocumentationContext(root.resolve(DEFAULT_DOCS_FOLDER)); } String appBasePath = environment.getValue(APPLICATION_BASE); if (appBasePath != null && Files.isDirectory(Paths.get(appBasePath)) && containsDocumentation(Paths.get(appBasePath).resolve(DEFAULT_DOCS_FOLDER))) { return createDocumentationContext(Paths.get(appBasePath).resolve(DEFAULT_DOCS_FOLDER)); } return null; } /** * Creates a {@link ContextHandler} with * {@link ResourceHandler} using the root of documentation. * * @param docsRoot the path to the documentation root * @return an instance {@link ContextHandler} */ protected ContextHandler createDocumentationContext(Path docsRoot) { ContextHandler contextHandler = new ContextHandler(); contextHandler.setContextPath(CONTEXT_PATH); ResourceHandler resourceHandler = new ResourceHandler(); resourceHandler.setBaseResource(Resource.newResource(docsRoot.toFile())); contextHandler.setHandler(resourceHandler); return contextHandler; } /** * Checks if the documentation root path contains actual * documentation. * * @param docsRoot the documentation root path * @return <code>true</code> if the documentation default * <code>index.html</code> is readable in the * documentation root path; otherwise * <code>false</code> */ protected boolean containsDocumentation(Path docsRoot) { return Files.exists(docsRoot) && Files.isReadable(docsRoot.resolve("index.html")); } }