All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.muserver.handlers.ResourceHandlerBuilder Maven / Gradle / Ivy

The newest version!
package io.muserver.handlers;

import io.muserver.MuHandlerBuilder;
import io.muserver.rest.RestHandlerBuilder;

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;

import static io.muserver.handlers.ResourceType.DEFAULT_EXTENSION_MAPPINGS;

/**
 * 

Used to create a {@link ResourceHandler} for serving static files.

*

In order to serve from the filesystem during development, and from classpath and deploy time, see * {@link #fileOrClasspath(String, String)}

*/ public class ResourceHandlerBuilder implements MuHandlerBuilder { private DateTimeFormatter directoryListingDateFormatter; private Map extensionToResourceType = DEFAULT_EXTENSION_MAPPINGS; private String defaultFile = "index.html"; private ResourceProviderFactory resourceProviderFactory; private boolean directoryListingEnabled = false; private String directoryListingCss = null; private ResourceCustomizer resourceCustomizer = null; private BareDirectoryRequestAction bareDirectoryRequestAction = BareDirectoryRequestAction.REDIRECT_WITH_TRAILING_SLASH; /** * Specify custom filename extension to mime-type mappings. By default {@link ResourceType#DEFAULT_EXTENSION_MAPPINGS} * are used. * @param extensionToResourceType The mappings to use. * @return This builder */ public ResourceHandlerBuilder withExtensionToResourceType(Map extensionToResourceType) { this.extensionToResourceType = extensionToResourceType; return this; } /** * Specifies the file to use when a request such as /web/ is made. Defaults to index.html * @param defaultFile The default file to use when a directory is requested, or null for no default. * @return This builder */ public ResourceHandlerBuilder withDefaultFile(String defaultFile) { this.defaultFile = defaultFile; return this; } ResourceHandlerBuilder withResourceProviderFactory(ResourceProviderFactory resourceProviderFactory) { this.resourceProviderFactory = resourceProviderFactory; return this; } /** * Specifies whether or not to allow directory listing. This is disabled by default. *

Note that directory listings will not show if there is a file in the directory * that matches the {@link #withDefaultFile(String)} setting. Set that to null * if you do not want the default file (e.g. index.html) to display.

* @param enabled true to turn it on; false to disable it. * @return This builder */ public ResourceHandlerBuilder withDirectoryListing(boolean enabled) { this.directoryListingEnabled = enabled; return this; } /** * Specifies a custom date format for the "Last modified" column when directory listing is enabled. * @param dateTimeFormatter A format object, or null to use the default * @return This builder */ public ResourceHandlerBuilder withDirectoryListingDateFormatter(DateTimeFormatter dateTimeFormatter) { this.directoryListingDateFormatter = dateTimeFormatter; return this; } /** * Specifies CSS to use for the HTML directory listing page, if directory listing is enabled. * @param css CSS styles to use, or null for the default * @return This builder */ public ResourceHandlerBuilder withDirectoryListingCSS(String css) { this.directoryListingCss = css; return this; } /** * Registers a hook to intercept responses, allowing things such as response header customization based on the request. * @param resourceCustomizer A class to intercept responses * @return This builder */ public ResourceHandlerBuilder withResourceCustomizer(ResourceCustomizer resourceCustomizer) { this.resourceCustomizer = resourceCustomizer; return this; } /** * @return The current value of this property */ public DateTimeFormatter directoryListingDateFormatter() { return directoryListingDateFormatter; } /** * @return The current value of this property */ public Map extensionToResourceType() { return Collections.unmodifiableMap(extensionToResourceType); } /** * @return The current value of this property */ public String defaultFile() { return defaultFile; } /** * @return The current value of this property */ public boolean directoryListingEnabled() { return directoryListingEnabled; } /** * @return The current value of this property */ public String directoryListingCss() { return directoryListingCss; } /** * @return The current value of this property */ public ResourceCustomizer resourceCustomizer() { return resourceCustomizer; } /** * @return The action to take when a directory is requested without a trailing slash */ public BareDirectoryRequestAction bareDirectoryRequestAction() { return bareDirectoryRequestAction; } /** * Specifies the action to take when a directory is requested without a trailing slash. * *

The default is {@link BareDirectoryRequestAction#REDIRECT_WITH_TRAILING_SLASH} which means a request * to /{dirname} will be redirected to /{dirname}/

* @param action The action to take * @return this builder */ public ResourceHandlerBuilder withBareDirectoryRequestAction(BareDirectoryRequestAction action) { if (action == null) { throw new IllegalArgumentException("BareDirectoryRequestAction cannot be null"); } this.bareDirectoryRequestAction = action; return this; } /** * Creates the handler * @return The built handler */ public ResourceHandler build() { if (resourceProviderFactory == null) { throw new IllegalStateException("No resourceProviderFactory has been set"); } String css = this.directoryListingCss; if (directoryListingEnabled && css == null) { InputStream cssStream = RestHandlerBuilder.class.getResourceAsStream("/io/muserver/resources/api.css"); Scanner scanner = new Scanner(cssStream, "UTF-8").useDelimiter("\\A"); css = scanner.next(); scanner.close(); } DateTimeFormatter formatterToUse = this.directoryListingDateFormatter; if (directoryListingEnabled && formatterToUse == null) { formatterToUse = DateTimeFormatter.ofPattern("yyyy/MM/dd hh:mm:ss") .withLocale(Locale.US) .withZone(ZoneId.systemDefault()); } return new ResourceHandler(resourceProviderFactory, defaultFile, extensionToResourceType, directoryListingEnabled, css, formatterToUse, this.resourceCustomizer, this.bareDirectoryRequestAction); } /** * Creates a handler that serves files from the given directory. * @param directoryPath The directory. * @return A new builder. */ public static ResourceHandlerBuilder fileHandler(String directoryPath) { return fileHandler(Paths.get(directoryPath)); } /** * Creates a handler that serves files from the given directory. * @param baseDirectory The directory. * @return A new builder. */ public static ResourceHandlerBuilder fileHandler(File baseDirectory) { return fileHandler(baseDirectory.toPath()); } /** * Creates a handler that serves files from the given directory. * @param path The directory. * @return A new builder. */ public static ResourceHandlerBuilder fileHandler(Path path) { return new ResourceHandlerBuilder().withResourceProviderFactory(ResourceProviderFactory.fileBased(path)); } /** * Creates a handler that serves files from the classpath.. * @param classpathRoot A classpath directory, such as /web * @return A new builder. */ public static ResourceHandlerBuilder classpathHandler(String classpathRoot) { return new ResourceHandlerBuilder().withResourceProviderFactory(ResourceProviderFactory.classpathBased(classpathRoot)); } /** * Creates a resource handler that serves from the file system if the directory exists; otherwise from the class path. *

* A common use case is for when you want to serve from the file path at development time (so you can update * files without restarting) but at deploy time resources are packaged in an uber jar. * @param fileRootIfExists A path to a directory holding static content, which may not exist, e.g. src/main/resources/web * @param classpathRoot A classpath path to a directory holding static content, e.g. /web * @return Returns a file-based resource handler builder or a classpath-based one. */ public static ResourceHandlerBuilder fileOrClasspath(String fileRootIfExists, String classpathRoot) { Path path = Paths.get(fileRootIfExists); if (Files.isDirectory(path)) { return fileHandler(path); } else { return classpathHandler(classpathRoot); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy