com.github.mvysny.fakeservlet.FakeContext.kt Maven / Gradle / Ivy
The newest version!
package com.github.mvysny.fakeservlet
import org.slf4j.LoggerFactory
import java.io.File
import java.io.InputStream
import java.io.Serializable
import java.lang.Exception
import java.net.URL
import java.net.URLConnection
import java.nio.file.Paths
import java.util.*
import java.util.concurrent.ConcurrentHashMap
import jakarta.servlet.*
import jakarta.servlet.descriptor.JspConfigDescriptor
import java.util.concurrent.ConcurrentMap
import kotlin.collections.HashMap
public open class FakeContext : ServletContext, Serializable {
@Deprecated("Deprecated in Java")
override fun getServlet(name: String): Servlet? {
// this method is deprecated since servlet spec 2.1 and should always return null.
// see javadoc for more details.
return null
}
override fun createServlet(clazz: Class?): T {
throw UnsupportedOperationException("not implemented")
}
override fun getEffectiveMajorVersion(): Int = 3
override fun getResource(path: String): URL? {
// for example @HtmlImport("frontend://reviews-list.html") will expect the resource to be present in the war file,
// which is typically located in $CWD/src/main/webapp/frontend, so let's search for that first
val realPath = getRealPath(path)
if (realPath != null) {
return File(realPath).toURI().toURL()
}
// nope, fall back to class loading.
//
// for example @HtmlImport("frontend://bower_components/vaadin-button/src/vaadin-button.html") will try to look up
// the following resources:
//
// 1. /frontend/bower_components/vaadin-button/src/vaadin-button.html
// 2. /webjars/vaadin-button/src/vaadin-button.html
//
// we need to match the latter one to a resource on classpath
if (path.startsWith("/")) {
val resource: URL? = Thread.currentThread().contextClassLoader.getResource("META-INF/resources$path")
if (resource != null) {
return resource
}
}
if (path.startsWith("/VAADIN/")) {
// Vaadin 8 exposed directory
@Suppress("NAME_SHADOWING")
var path = path
if (path.contains("..")) {
// to be able to resolve ThemeResource("../othertheme/img/foo.png") which work from the browser.
path = Paths.get(path).normalize().toString()
// convert Windows path separators to Linux ones, so that the follow-up code works
path = path.replace('\\', '/')
}
// reject to serve "/VAADIN/../" resources
if (path.startsWith("/VAADIN/")) {
val resource: URL? = Thread.currentThread().contextClassLoader.getResource(path.trimStart('/'))
if (resource != null) {
return resource
}
}
}
return null
}
override fun addListener(className: String) {
throw UnsupportedOperationException("not implemented")
}
override fun addListener(t: T) {
throw UnsupportedOperationException("not implemented")
}
override fun addListener(listenerClass: Class) {
throw UnsupportedOperationException("not implemented")
}
override fun getClassLoader(): ClassLoader = Thread.currentThread().contextClassLoader
override fun getAttributeNames(): Enumeration = attributes.keys()
override fun getMajorVersion(): Int = 3
override fun log(msg: String) {
log.error(msg)
}
@Deprecated("Deprecated in Java")
override fun log(exception: Exception, msg: String) {
log.error(msg, exception)
}
override fun log(message: String, throwable: Throwable) {
log.error(message, throwable)
}
override fun getFilterRegistration(filterName: String): FilterRegistration? = filters[filterName]
private var sessionTrackingModes = defaultSessionTrackingModes
override fun setSessionTrackingModes(sessionTrackingModes: MutableSet) {
require(!(sessionTrackingModes.contains(SessionTrackingMode.SSL) && sessionTrackingModes.size > 1)) {
"sessionTrackingModes: Invalid value $sessionTrackingModes: SSL must not be combined with other values"
}
this.sessionTrackingModes = sessionTrackingModes.toSet()
}
override fun setInitParameter(name: String, value: String): Boolean = initParameters.putIfAbsent(name, value) == null
override fun getResourceAsStream(path: String): InputStream? = getResource(path)?.openStream()
override fun getNamedDispatcher(name: String?): RequestDispatcher {
throw UnsupportedOperationException("not implemented")
}
override fun getFilterRegistrations(): MutableMap = HashMap(filters)
@Deprecated("Deprecated in Java")
override fun getServletNames(): Enumeration = Collections.emptyEnumeration()
override fun getDefaultSessionTrackingModes(): Set = setOf(SessionTrackingMode.COOKIE, SessionTrackingMode.URL)
override fun getMimeType(file: String): String = URLConnection.guessContentTypeFromName(file) ?: "application/octet-stream"
override fun declareRoles(vararg roleNames: String) {
throw UnsupportedOperationException("not implemented")
}
override fun createFilter(clazz: Class): T {
throw UnsupportedOperationException("not implemented")
}
/**
* [getRealPath] will only resolve `path` in these folders.
*/
public var realPathRoots: List = listOf("src/main/webapp/frontend", "src/main/webapp")
override fun getRealPath(path: String): String? {
for (realPathRoot in realPathRoots) {
val realPath: File = File(moduleDir, "$realPathRoot/$path").canonicalFile.absoluteFile
if (realPath.absolutePath.startsWith(File(realPathRoot).absolutePath) && realPath.exists()) {
return realPath.absolutePath
}
}
return null
}
public val initParameters: MutableMap = mutableMapOf()
override fun getInitParameter(name: String): String? = initParameters[name]
override fun getMinorVersion(): Int = 0
override fun getJspConfigDescriptor(): JspConfigDescriptor? = null
override fun removeAttribute(name: String) {
attributes.remove(name)
}
override fun getServletContextName(): String = "Fake context"
/**
* Maps filter name to its registration. All filters registered via [addFilter] will be present here.
*/
public val filters: ConcurrentMap = ConcurrentHashMap()
override fun addFilter(filterName: String, className: String): FilterRegistration.Dynamic {
val reg = FakeFilterRegistration(filterName, className)
filters[filterName] = reg
return reg
}
override fun addFilter(filterName: String, filter: Filter): FilterRegistration.Dynamic = addFilter(filterName, filter.javaClass)
override fun addFilter(filterName: String, filterClass: Class): FilterRegistration.Dynamic = addFilter(filterName, filterClass.name)
override fun getContextPath(): String = ""
private val sessionCookieConfig = FakeSessionCookieConfig()
override fun getSessionCookieConfig(): SessionCookieConfig = sessionCookieConfig
override fun getVirtualServerName(): String = "mock/localhost" // Tomcat returns "Catalina/localhost"
private var sessionTimeout: Int = 30
override fun getSessionTimeout(): Int = sessionTimeout
override fun setSessionTimeout(sessionTimeout: Int) {
this.sessionTimeout = sessionTimeout
}
private var requestCharacterEncoding: String? = null
override fun getRequestCharacterEncoding(): String? = requestCharacterEncoding
override fun setRequestCharacterEncoding(encoding: String?) {
requestCharacterEncoding = encoding
}
private var responseCharacterEncoding: String? = null
override fun getResponseCharacterEncoding(): String? = responseCharacterEncoding
override fun setResponseCharacterEncoding(encoding: String?) {
responseCharacterEncoding = encoding
}
override fun getContext(uripath: String): ServletContext {
throw UnsupportedOperationException("not implemented")
}
override fun getRequestDispatcher(path: String?): RequestDispatcher {
throw UnsupportedOperationException("not implemented")
}
private val attributes = ConcurrentHashMap()
override fun getAttribute(name: String): Any? = attributes[name]
override fun setAttribute(name: String, value: Any?) {
attributes.putOrRemove(name, value)
}
override fun getServletRegistration(servletName: String): ServletRegistration? = null
override fun createListener(clazz: Class?): T {
throw UnsupportedOperationException("not implemented")
}
private val _servlets = ConcurrentHashMap()
override fun addServlet(servletName: String, className: String): ServletRegistration.Dynamic {
val reg = FakeServletRegistration(servletName, className)
_servlets[servletName] = reg
return reg
}
override fun addServlet(servletName: String, servlet: Servlet): ServletRegistration.Dynamic = addServlet(servletName, servlet.javaClass)
override fun addServlet(servletName: String, servletClass: Class): ServletRegistration.Dynamic = addServlet(servletName, servletClass.name)
override fun addJspFile(servletName: String, jspFile: String): ServletRegistration.Dynamic = FakeServletRegistration(servletName, jspFile)
@Deprecated("Deprecated in Java")
override fun getServlets(): Enumeration = Collections.emptyEnumeration()
override fun getEffectiveMinorVersion(): Int = 0
override fun getServletRegistrations(): MutableMap = HashMap()
override fun getResourcePaths(path: String?): MutableSet = mutableSetOf()
override fun getInitParameterNames(): Enumeration = Collections.enumeration(initParameters.keys)
override fun getServerInfo(): String = "Mock"
override fun getEffectiveSessionTrackingModes(): Set = sessionTrackingModes.toSet()
public companion object {
@JvmStatic
private val log = LoggerFactory.getLogger(FakeContext::class.java)
}
}
internal val moduleDir: File get() {
var dir = File("").absoluteFile
// Workaround for https://youtrack.jetbrains.com/issue/IDEA-188466
// When using $MODULE_DIR$, IDEA will set CWD to, say, karibu-testing/.idea/modules/karibu-testing-v8
// We need to revert that back to karibu-testing/karibu-testing-v8
if (dir.absolutePath.contains("/.idea/modules")) {
dir = File(dir.absolutePath.replace("/.idea/modules", ""))
}
return dir
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy