diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index e4ff4b1f..a8be88e4 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,10 +1,6 @@
name: build
-on:
- push:
- paths-ignore:
- - '.github/workflows/examples-**'
- - 'examples/**'
+on: [push, pull_request]
jobs:
build:
diff --git a/.github/workflows/examples-adder.yml b/.github/workflows/examples-adder.yml
deleted file mode 100644
index dcf59472..00000000
--- a/.github/workflows/examples-adder.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-adder
-
-on:
- push:
- paths:
- - '.github/workflows/examples-adder.yml'
- - 'examples/adder/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 11
- - run: |
- cd examples/adder
- sbt Jetty/test
diff --git a/.github/workflows/examples-async.yml b/.github/workflows/examples-async.yml
deleted file mode 100644
index 43e80797..00000000
--- a/.github/workflows/examples-async.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-async
-
-on:
- push:
- paths:
- - '.github/workflows/examples-async.yml'
- - 'examples/async/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/async
- sbt Jetty/test
diff --git a/.github/workflows/examples-free.yml b/.github/workflows/examples-free.yml
deleted file mode 100644
index fe56dc35..00000000
--- a/.github/workflows/examples-free.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-free
-
-on:
- push:
- paths:
- - '.github/workflows/examples-free.yml'
- - 'examples/free/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/free
- sbt Jetty/test
diff --git a/.github/workflows/examples-frege.yml b/.github/workflows/examples-frege.yml
deleted file mode 100644
index 80f4db84..00000000
--- a/.github/workflows/examples-frege.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-frege
-
-on:
- push:
- paths:
- - '.github/workflows/examples-frege.yml'
- - 'examples/frege/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/frege
- sbt Jetty/test
diff --git a/.github/workflows/examples-getting-started.yml b/.github/workflows/examples-getting-started.yml
deleted file mode 100644
index 33fc5330..00000000
--- a/.github/workflows/examples-getting-started.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-getting-started
-
-on:
- push:
- paths:
- - '.github/workflows/examples-getting-started.yml'
- - 'examples/getting-started/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/getting-started
- sbt Jetty/test
diff --git a/.github/workflows/examples-http4s.yml b/.github/workflows/examples-http4s.yml
deleted file mode 100644
index ea1843b5..00000000
--- a/.github/workflows/examples-http4s.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: examples-http4s
-on:
- push:
- paths:
- - '.github/workflows/examples-http4s.yml'
- - 'examples/http4s/**'
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: cachix/install-nix-action@v18
- with:
- nix_path: nixpkgs=channel:nixos-22.11
- - uses: workflow/nix-shell-action@v3
- with:
- script: |
- cd examples/http4s
- nix-shell --run 'sbt "Jetty / test"'
diff --git a/.github/workflows/examples-https.yml b/.github/workflows/examples-https.yml
deleted file mode 100644
index 6bf73e6b..00000000
--- a/.github/workflows/examples-https.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-https
-
-on:
- push:
- paths:
- - '.github/workflows/examples-https.yml'
- - 'examples/https/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/https
- sbt Tomcat/test
diff --git a/.github/workflows/examples-jetty-11.yml b/.github/workflows/examples-jetty-11.yml
deleted file mode 100644
index a6da3d32..00000000
--- a/.github/workflows/examples-jetty-11.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: examples-jetty-11
-on:
- push:
- paths:
- - '.github/workflows/examples-jetty-11.yml'
- - 'examples/jetty-11/**'
-jobs:
- build:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: cachix/install-nix-action@v18
- with:
- nix_path: nixpkgs=channel:nixos-22.11
- - uses: workflow/nix-shell-action@v3
- with:
- script: |
- cd examples/jetty-11
- nix-shell --run 'sbt "Jetty / test"'
diff --git a/.github/workflows/examples-lift.yml b/.github/workflows/examples-lift.yml
deleted file mode 100644
index 322c6a02..00000000
--- a/.github/workflows/examples-lift.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-lift
-
-on:
- push:
- paths:
- - '.github/workflows/examples-lift.yml'
- - 'examples/lift/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/lift
- sbt Jetty/test
diff --git a/.github/workflows/examples-mustache.yml b/.github/workflows/examples-mustache.yml
deleted file mode 100644
index 09a3b5ec..00000000
--- a/.github/workflows/examples-mustache.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-mustache
-
-on:
- push:
- paths:
- - '.github/workflows/examples-mustache.yml'
- - 'examples/mustache/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/mustache
- sbt Jetty/test
diff --git a/.github/workflows/examples-payara-micro.yml b/.github/workflows/examples-payara-micro.yml
deleted file mode 100644
index dc18a91a..00000000
--- a/.github/workflows/examples-payara-micro.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-payara-micro
-
-on:
- push:
- paths:
- - '.github/workflows/examples-payara-micro.yml'
- - 'examples/payara-micro/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 11
- - run: |
- cd examples/payara-micro
- sbt Container/test
diff --git a/.github/workflows/examples-sbt-0.x.yml b/.github/workflows/examples-sbt-0.x.yml
deleted file mode 100644
index ee991cc7..00000000
--- a/.github/workflows/examples-sbt-0.x.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-sbt-0.x
-
-on:
- push:
- paths:
- - '.github/workflows/examples-sbt-0.x.yml'
- - 'examples/sbt-0.x/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/sbt-0.x
- sbt jetty:test
diff --git a/.github/workflows/examples-sbt-1.x.yml b/.github/workflows/examples-sbt-1.x.yml
deleted file mode 100644
index 13569452..00000000
--- a/.github/workflows/examples-sbt-1.x.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-sbt-1.x
-
-on:
- push:
- paths:
- - '.github/workflows/examples-sbt-1.x.yml'
- - 'examples/sbt-1.x/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/sbt-1.x
- sbt Jetty/test
diff --git a/.github/workflows/examples-scala-js.yml b/.github/workflows/examples-scala-js.yml
deleted file mode 100644
index f0d8c1a8..00000000
--- a/.github/workflows/examples-scala-js.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-scala-js
-
-on:
- push:
- paths:
- - '.github/workflows/examples-scala-js.yml'
- - 'examples/scala-js/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/scala-js
- sbt fastOptJS Jetty/test
diff --git a/.github/workflows/examples-scalatra.yml b/.github/workflows/examples-scalatra.yml
deleted file mode 100644
index 396609af..00000000
--- a/.github/workflows/examples-scalatra.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-scalatra
-
-on:
- push:
- paths:
- - '.github/workflows/examples-scalatra.yml'
- - 'examples/scalatra/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/scalatra
- sbt Jetty/test
diff --git a/.github/workflows/examples-spray.yml b/.github/workflows/examples-spray.yml
deleted file mode 100644
index 2f979d19..00000000
--- a/.github/workflows/examples-spray.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-spray
-
-on:
- push:
- paths:
- - '.github/workflows/examples-spray.yml'
- - 'examples/spray/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 8
- - run: |
- cd examples/spray
- sbt Jetty/test
diff --git a/.github/workflows/examples-zio.yml b/.github/workflows/examples-zio.yml
deleted file mode 100644
index 525b2ac2..00000000
--- a/.github/workflows/examples-zio.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: examples-zio
-
-on:
- push:
- paths:
- - '.github/workflows/examples-zio.yml'
- - 'examples/zio/**'
-
-jobs:
- build:
-
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v1
- - uses: actions/setup-java@v1
- with:
- java-version: 11
- - run: |
- cd examples/zio
- sbt Jetty/test
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5b295c6c..4a05675f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,55 +1,76 @@
# Contributing
-## Testing
+## Architecture
-Publish to the local Maven repository:
+```mermaid
+flowchart TB
-```
-$ sbt
-> set version := "4.2.5"
-> ^publishM2
-```
+ subgraph webapp
+ WebappComponentsPlugin
+ WebappComponentsRunnerPlugin
+ webappRunnerCA[components-aware webapp-runner]
+ end
-Update the versions in plugins.sbt:
+ subgraph war
+ WarPackagePlugin
+ WarPackageRunnerPlugin
+ webappRunner[webapp-runner]
+ end
-```
-$ find examples -type f -name plugins.sbt -exec sed -i 's/4.2.4/4.2.5/' {} \;
+ SbtWar
+
+ subgraph project
+ resources
+ classes
+ lib
+ end
+
+
+ WebappComponentsPlugin-->resources
+ WebappComponentsPlugin-->classes
+ WebappComponentsPlugin-->lib
+
+ WebappComponentsRunnerPlugin-->WebappComponentsPlugin
+ WebappComponentsRunnerPlugin-->webappRunnerCA
+
+ WarPackagePlugin-->WebappComponentsPlugin
+
+ WarPackageRunnerPlugin-->WarPackagePlugin
+ WarPackageRunnerPlugin-->webappRunner
+
+ SbtWar-->WebappComponentsRunnerPlugin
+ SbtWar-->WarPackageRunnerPlugin
```
-Run the tests for each:
+
+## Testing
```
-$ for i in examples/*
- do
- pushd $i
- grep -q JettyPlugin build.sbt && sbt Jetty/test
- grep -q TomcatPlugin build.sbt && sbt Tomcat/test
- grep -q ContainerPlugin build.sbt && sbt Container/test
- popd
- done
+$ sbt test scripted
```
## Publishing
-xsbt-web-plugin uses the process outlined in the [Using Sonatype][1]
+sbt-war uses the process outlined in the [Using
+Sonatype](https://www.scala-sbt.org/release/docs/Using-Sonatype.html)
section of the sbt manual for publishing to Maven Central via Sonatype.
-[1]: https://www.scala-sbt.org/release/docs/Using-Sonatype.html
-
Create a staging release in Sonatype:
```
+$ nix-shell
$ sbt
> set version := "4.2.5"
-> ^publishSigned
+> publishSigned
```
Review it:
-* Go to [Staging Repositories][2] on Nexus Repository Manager
+* Go to [Staging
+ Repositories](https://oss.sonatype.org/#stagingRepositories) on Nexus
+ Repository Manager
* Review the contents of the staging repository
-[2]: https://oss.sonatype.org/#stagingRepositories
Release it:
@@ -58,8 +79,7 @@ Release it:
Wait for it to be synced to Maven Central:
-*
-*
+*
Update the documentation:
@@ -78,6 +98,5 @@ $ git tag 4.2.5
$ git push --tags origin
```
-Update the [Giter8 template][3] to use the new version.
-
-[3]: https://github.com/earldouglas/xsbt-web-plugin.g8
+Update the [Giter8 template](https://github.com/earldouglas/xsbt-web-plugin.g8)
+to use the new version.
diff --git a/README.md b/README.md
index de0624c0..607a9c14 100644
--- a/README.md
+++ b/README.md
@@ -1,75 +1,47 @@
[![Build status](https://github.com/earldouglas/xsbt-web-plugin/workflows/build/badge.svg)](https://github.com/earldouglas/xsbt-web-plugin/actions)
[![Latest version](https://img.shields.io/github/tag/earldouglas/xsbt-web-plugin.svg)](https://index.scala-lang.org/earldouglas/xsbt-web-plugin)
-# xsbt-web-plugin
+# sbt-war
-xsbt-web-plugin is an [sbt](https://www.scala-sbt.org/) plugin for
-building web applications with [Java
-servlets](https://en.wikipedia.org/wiki/Java_servlet).
+sbt-war is an [sbt](https://www.scala-sbt.org/) plugin for building Web
+apps with [servlets](https://en.wikipedia.org/wiki/Java_servlet).
-## Features
-
-* Package a project as a *.war* file
-* Test and run under Jetty or Tomcat
-* Deploy directly to Heroku or AWS
-* Supports sbt 0.13.6 and up
-* Supports Scala 2.10.2 and up
-
-## Getting help
-
-* Look for *earldouglas* in the `#sbt` channel on the [Scala](https://discord.com/invite/scala) Discord server
-* Use the [*xsbt-web-plugin* tag](https://stackoverflow.com/questions/tagged/xsbt-web-plugin) on Stack Overflow
-* Submit a bug report or feature request as a [new GitHub issue](https://github.com/earldouglas/xsbt-web-plugin/issues/new)
-* See examples in the [examples/](examples/) directory
-
-## Quick reference
-
-Add xsbt-web-plugin to *project/plugins.sbt*:
+sbt-war is formerly known as xsbt-web-plugin. For documentation and
+source code of prior versions, browse this repository from the desired
+git tag. The most recent prior version is [xsbt-web-plugin
+v4.2.4](https://github.com/earldouglas/xsbt-web-plugin/tree/4.2.4).
-```scala
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
-```
-
-Enable the Jetty plugin:
-
-*build.sbt*:
-
-```scala
-enablePlugins(JettyPlugin)
-```
-
-From the sbt console:
+## Features
-* Start (or restart) the container with `jetty:start`
-* Stop the container with `jetty:stop`
-* Build a *.war* file with `package`
+* Package your project as a *.war* file
+* Run your project in a Tomcat container
-To use Tomcat instead of Jetty:
+## Requirements
-* Substitute `TomcatPlugin` for `JettyPlugin`
-* Substitute `tomcat:start` for `jetty:start`
-* Substitute `tomcat:stop` for `jetty:stop`
+* sbt 1.x and up
+* Scala 2.12.x and up
-## Starting with Giter8
+## Getting help
-```
-sbt new earldouglas/xsbt-web-plugin.g8
-```
+* Submit a question, bug report, or feature request as a [new GitHub
+ issue](https://github.com/earldouglas/xsbt-web-plugin/issues/new)
+* Look for *earldouglas* in the `#sbt` channel on the [Scala Discord
+ server](https://discord.com/invite/scala)
-## Starting from scratch
+## Usage
Create a new empty project:
```
-mkdir myproject
-cd myproject
+$ mkdir myproject
+$ cd myproject
```
Set up the project structure:
```
-mkdir project
-mkdir -p src/main/scala/mypackage
+$ mkdir project
+$ mkdir -p src/main/scala/mypackage
```
Configure sbt:
@@ -77,21 +49,21 @@ Configure sbt:
*project/build.properties:*
```
-sbt.version=1.6.2
+sbt.version=1.10.2
```
*project/plugins.sbt:*
```scala
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
+addSbtPlugin("com.earldouglas" % "sbt-war" % "5.0.0-M1")
```
*build.sbt:*
```scala
-scalaVersion := "3.0.1"
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.0.1" % "provided"
-enablePlugins(TomcatPlugin)
+scalaVersion := "3.5.1"
+libraryDependencies += "jakarta.servlet" % "jakarta.servlet-api" % "6.0.0" % Provided
+enablePlugins(SbtWar)
```
Add a servlet:
@@ -101,24 +73,27 @@ Add a servlet:
```scala
package mypackage
-import javax.servlet.annotation.WebServlet
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
+import jakarta.servlet.annotation.WebServlet
+import jakarta.servlet.http.HttpServlet
+import jakarta.servlet.http.HttpServletRequest
+import jakarta.servlet.http.HttpServletResponse
@WebServlet(urlPatterns = Array("/hello"))
class MyServlet extends HttpServlet:
- override def doGet(req: HttpServletRequest, res: HttpServletResponse): Unit =
+ override def doGet(
+ req: HttpServletRequest,
+ res: HttpServletResponse
+ ): Unit =
res.setContentType("text/html")
res.setCharacterEncoding("UTF-8")
res.getWriter.write("""
Hello, world!
""")
```
-Run it with `tomcat:start`:
+Run it from sbt with `warStart`:
```
$ sbt
-> tomcat:start
+> warStart
```
```
@@ -126,549 +101,209 @@ $ curl localhost:8080/hello
Hello, world!
```
-## Configuration and use
-
-### Triggered execution
-
-xsbt-web-plugin supports sbt's [triggered
-execution](http://www.scala-sbt.org/1.0/docs/Triggered-Execution.html)
-by prefixing commands with `~`.
-
-*sbt console:*
+Stop it with `warStop`:
```
-> ~jetty:start
+> warStop
```
-This starts the Jetty container, then monitors the sources, resources,
-and webapp directories for changes, which triggers a container restart.
-
-### Testing
-
-To run a projects tests against a running instance of the webapp, use
-`:quicktest` or `:test`:
+Create a .war file with `package`:
```
-> ~jetty:quicktest
+> package
```
-### Container arguments
+## Settings and commands
-To pass extra arguments to the Jetty or Tomcat container, set
-`containerArgs`:
+| Setting Key | Type | Default | Notes |
+| --------------------- | ------------------ | ----------------- | ----------------------------------------------------------------------- |
+| `webappResources` | `Map[String,File]` | *src/main/webapp* | Static files (HTML, CSS, JS, images, etc.) to serve directly |
+| `webappClasses` | `Map[String,File]` | project classes | .class files to copy into the *WEB-INF/classes* directory |
+| `webappLib` | `Map[String,File]` | project libs | .jar files to copy into the *WEB-INF/lib* directory |
+| `webappRunnerVersion` | `String` | `"10.1.28.0"` | The version of `com.heroku:webapp-runner` to use for running the webapp |
+| `webappPort` | `Int` | `8080` | The local container port to use when running with `webappStart` |
+| `warPort` | `Int` | `8080` | The local container port to use when running with `warStart` |
+| `warForkOptions` | `ForkOptions` | `ForkOptions()` | Options for the forked JVM used when running with `warStart` |
-```scala
-containerArgs := Seq("--path", "/myservice")
-```
-
-* For available Jetty arguments, see the [Jetty Runner
- docs](https://www.eclipse.org/jetty/documentation/current/runner.html#_full_configuration_reference)
-* For available Tomcat arguments, see [webapp-runner#options](https://github.com/heroku/webapp-runner#options)
-
-### Custom container
-
-To use a custom J2EE container, e.g. a main class named `runner.Run`,
-enable `ContainerPlugin` and set `containerLibs` and
-`containerLaunchCmd`:
-
-```scala
-enablePlugins(ContainerPlugin)
-
-containerLibs in Container := Seq(
- "org.eclipse.jetty" % "jetty-webapp" % "9.1.0.v20131115"
- , "org.eclipse.jetty" % "jetty-plus" % "9.1.0.v20131115"
- , "test" %% "runner" % "0.1.0-SNAPSHOT"
-)
-
-containerLaunchCmd in Container :=
- { (port, path) => Seq("runner.Run", port.toString, path) }
-```
-
-*sbt:*
-
-```
-> container:start
-> container:stop
-```
-
-### Forked JVM options
-
-To set system properties for the forked container JVM, set
-`containerForkOptions`:
-
-```scala
-containerForkOptions := new ForkOptions(runJVMOptions = Seq("-Dh2g2=42"))
-```
+| Task Key | Notes |
+| ------------- | ----------------------------------------------------------------------- |
+| `warStart` | Starts a local container, serving content from the packaged .war file |
+| `warJoin` | Blocks until the container shuts down |
+| `warStop` | Shuts down the container |
+| `webappStart` | Starts a local container, serving content directly from project sources |
+| `webappJoin` | Blocks until the container shuts down |
+| `webappStop` | Shuts down the container |
-Alternatively, set `javaOptions` in the `Jetty` (or `Tomcat`)
-configuration:
+### `war` vs. `webapp`
-```scala
-javaOptions in Jetty += "-Dh2g2=42"
-```
-
-To attach a debugger, set `-Xdebug` and `-Xrunjdwp`:
+Settings and commands that begin with `war` apply to the packaged .war
+file, which includes resources, classes, and libraries. The development
+cycle can be sped up by serving resources, classes, and libraries
+directly from source, avoiding the overhead of packaging a
+*.war* file.
-*build.sbt:*
+Use the `webapp` prefix in place of `war` to skip packaging, and run the
+container directly from source:
-```scala
-javaOptions in Jetty ++= Seq(
- "-Xdebug",
- "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
-)
```
-
-In Eclipse:
-
-* Create and run a new *Remote Java Application* launch configuration
-* Set *Connection Type* to *Scala debugger (Socket Attach)*
-* Configure to connect to *localhost* on port *8000*
-
-In IntelliJ IDEA:
-
-* Add a Remote run configuration: *Run* -> *Edit Configurations...*
-* Under *Defaults* select *Remote* and push `+` to add a new
- configuration
-* By default the configuration uses port 5005; update it to 8000 as
- above
-* Name this configuration, and run it in debug mode
-
-### Debug mode
-
-To enable debugging through
-[JDWP](https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/introclientissues005.html),
-use `jetty:debug` or `tomcat:debug`. Optionally set `debugAddress`,
-which defaults to `"debug"` under Windows and `"8888"` otherwise, and
-`debugOptions`, which defaults to:
-
-```scala
-port =>
- Seq( "-Xdebug"
- , Seq( "-Xrunjdwp:transport=dt_socket"
- , "address=" + port
- , "server=y"
- , "suspend=n"
- ).mkString(",")
- )
+> webappStart
```
-### Jetty version
+### `webappResources`
-By default, [Jetty
-Runner](https://www.eclipse.org/jetty/documentation/current/runner.html)
-9.4.42 is used. To use a different version, set
-`containerLibs`:
+Webapp resources are the various static files, deployment descriptors,
+etc. that go into a .war file.
-```scala
-containerLibs in Jetty := Seq("org.mortbay.jetty" % "jetty-runner" % "7.0.0.v20091005" intransitive())
-```
-
-Depending on the version, it may also be necessary to specify the name
-of Jetty's runner:
+The `webappResources` setting is a mapping from destination to source of
+these files. The destination is a path relative to the contents of the
+.war file. The source is a path on the local filesystem.
-```scala
-containerMain := "org.mortbay.jetty.runner.Runner"
-```
+By default, everything in *src/main/webapp* is included.
-### Container port
+For example, given the following .war file:
-By default, the container runs on port *8080*. To use a different port,
-set `containerPort`:
-
-```scala
-containerPort := 9090
```
-
-### *jetty.xml*
-
-To use a *jetty.xml* configuration file, set `--config` in
-`containerArgs`:
-
-```scala
-containerArgs := Seq("--config", "/path/to/jetty.xml")
+myproject.war
+├── index.html
+├── styles/
+│ └── theme.css
+├── WEB-INF/
+│ └── web.xml
+└── META-INF/
+ └── MANIFEST.MF
```
-This option can be used to enable SSL and HTTPS.
+The `webappResources` mapping would look like this:
-### Tomcat version
-
-By default, [Webapp Runner](https://github.com/heroku/webapp-runner)
-9.0.41.0 is used. To use a different version, set `containerLibs`:
-41
-```scala
-containerLibs in Tomcat := Seq("com.heroku" % "webapp-runner" % "8.5.61.0" intransitive())
```
-
-Depending on the version, it may also be necessary to specify the name
-of Tomcat's runner:
-
-```scala
-containerMain in Tomcat := "webapp.runner.launch.Main"
+"index.html" -> File(".../src/main/webapp/index.html")
+"styles/theme.css" -> File(".../src/main/webapp/styles/theme.css")
+"WEB-INF/web.xml" -> File(".../src/main/webapp/WEB-INF/web.xml")
```
-### Extra container libraries
-
-Tomcat's webapp-runner does not ship with all of the libraries that can
-be found in a complete Tomcat installation. To include extras, use
-`containerLibs in Tomcat`:
+To use a different directory, e.g. *src/main/WebContent*:
```scala
-containerLibs in Tomcat += "org.apache.tomcat" % "tomcat-jdbc" % "8.5.15"
+webappResources :=
+ (Compile / sourceDirectory)
+ .map(_ / "WebContent")
+ .map(WebappComponents.getResources)
```
-### Renaming the *.war* file
-
-This can be useful for keeping the version number out of the *.war* file
-name, using a non-conventional file name or path, adding additional
-information to the file name, etc.
+Manifest attributes of the *.war* file can be configured via
+`packageOptions`:
```scala
-artifactName := { (v: ScalaVersion, m: ModuleID, a: Artifact) =>
- a.name + "." + a.extension
-}
+sbt.Keys.`package` / packageOptions +=
+ Package.ManifestAttributes(
+ java.util.jar.Attributes.Name.SEALED -> "true"
+ )
```
-See ["Modifying default
-artifacts"](http://www.scala-sbt.org/1.0/docs/Artifacts.html#Modifying+default+artifacts)
-in the sbt documentation for additional information.
-### Massaging the *.war* file
+### `webappClasses`
-After the */target/webapp* directory is prepared, it can be
-modified with an arbitrary `File => Unit` function by setting
-`webappPostProcess`.
-
-To list the contents of the *webapp* directory after it is prepared:
-
-```scala
-webappPostProcess := {
- val log = streams.value.log
- webappDir: File =>
- def listFiles(level: Int)(f: File): Unit = {
- val indent = ((1 until level) map { _ => " " }).mkString
- if (f.isDirectory) {
- log.info(indent + f.getName + "/")
- f.listFiles foreach { listFiles(level + 1) }
- } else log.info(indent + f.getName)
- }
- listFiles(1)(webappDir)
-}
-```
-
-To include webapp resources from multiple directories in the prepared
-*webapp* directory:
+By default, project classes are copied into the *WEB-INF/classes*
+directory of the *.war* file. To package them in a *.jar* file in the
+*WEB-INF/lib* directory instead, set `exportJars`:
```scala
-webappPostProcess := {
- webappDir: File =>
- val baseDir = baseDirectory.value / "src" / "main"
- IO.copyDirectory(baseDir / "webapp1", webappDir)
- IO.copyDirectory(baseDir / "webapp2", webappDir)
- IO.copyDirectory(baseDir / "webapp3", webappDir)
-}
+exportJars := true
```
-### Custom resources directory
+See ["Configure
+packaging"](https://www.scala-sbt.org/1.x/docs/Howto-Package.html) in
+the sbt documentation for additional information.
-Files in the extra resource directory are not compiled, and are bundled
-directly in the project artifact *.jar* file.
+### `webappLib`
-To add a custom resources directory, set `unmanagedResourceDirectories`:
+By default, all runtime dependencies are copied into the *WEB-INF/lib*
+directory.
-```scala
-unmanagedResourceDirectories in Compile += (sourceDirectory in Compile).value / "extra"
-```
-
-### Custom sources directory
-
-Scala files in the extra source directory are compiled, and bundled in
-the project artifact *.jar* file.
-
-To add a custom sources directory, set `unmanagedSourceDirectories`:
+To use a dependency at compile time but exclude it from the .war file,
+set its scope to `Provided`:
```scala
-unmanagedSourceDirectories in Compile += (sourceDirectory in Compile).value / "extra"
+libraryDependencies += "foo" % "bar" % "1.0.0" % Provided
```
-### Utilizing *WEB-INF/classes*
+### `webappRunnerVersion`
-By default, project classes are packaged into a *.jar* file, shipped in
-the *WEB-INF/lib* directory of the *.war* file. To instead keep them
-extracted in *WEB-INF/classes*, set `webappWebInfClasses`:
+By default, [Webapp Runner](https://github.com/heroku/webapp-runner)
+10.1.x is used. To use a different version, set `War /
+webappRunnerVersion`:
```scala
-webappWebInfClasses := true
+webappRunnerVersion := "9.0.93.0"
```
-### Web application destination
+### `warPort` and `webappPort`
-The web application destination directory is where the static Web
-content, compiled Scala classes, library *.jar* files, etc. are placed.
-By default, they go to */target/webapp*.
-
-To specify a different directory, set `target` in the `webappPrepare`
-configuration:
+By default, the container runs on port *8080*. To use a different port,
+set `warPort`/`webappPort`:
```scala
-target in webappPrepare := target.value / "WebContent"
+warPort := 9090
```
-### Web application resources
-
-The web application resources directory is where static Web content
-(including *.html*, *.css*, and *.js* files, the *web.xml* container
-configuration file, etc. By default, this is kept in
-*/src/main/webapp*.
-
-To specify a different directory, set `sourceDirectory` in the
-`webappPrepare` configuration:
-
```scala
-sourceDirectory in webappPrepare := (sourceDirectory in Compile).value / "WebContent"
+webappPort := 9090
```
-### Prepare the web application for execution and deployment
-
-For situations when the prepared */target/webapp* directory is
-needed, but the packaged *.war* file isn't.
+### `warForkOptions`
-*sbt console:*
+To set environment variables, system properties, and more for the
+forked container JVM, set a
+[ForkOptions](https://www.scala-sbt.org/1.x/api/sbt/ForkOptions.html)
+instance via `warForkOptions`.
-```
-webappPrepare
-```
-
-### Add manifest attributes
+For example: to attach a debugger, set `-Xdebug` and `-Xrunjdwp`:
-Manifest attributes of the *.war* file can be configured via
-`packageOptions in sbt.Keys.package` in *build.sbt*:
-
-```scala
-packageOptions in sbt.Keys.`package` +=
- Package.ManifestAttributes( java.util.jar.Attributes.Name.SEALED -> "true" )
-```
-
-### Inherit manifest attributes
-
-To configure the *.war* file to inherit the manifest attributes of the
-*.jar* file, typically set via `packageOptions in (Compile,
-packageBin)`, set `inheritJarManifest` to `true`:
+*build.sbt:*
```scala
-inheritJarManifest := true
+warForkOptions :=
+ ForkOptions()
+ .withRunJVMOptions(
+ Seq(
+ "-Xdebug",
+ "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000"
+ )
+ )
```
-### Container shutdown and sbt
+### `warStart` and `webappStart`
-By default, sbt will shutdown the running container when exiting sbt.
-
-To allow the container to continue running after sbt exits, set
-`containerShutdownOnExit`:
-
-```scala
-containerShutdownOnExit := false
```
-
-### Deploying to Heroku
-
-Enable the `HerokuDeploy` plugin and configure your app name:
-
-```scala
-enablePlugins(HerokuDeploy)
-
-herokuAppName := "my-heroku-app"
+> warStart
```
-Either install the [Heroku Toolbelt](https://toolbelt.heroku.com/), or
-set your Heroku API key as an environment variable, launch sbt, and
-deploy with `herokuDeploy`:
-
```
-$ HEROKU_API_KEY="xxx-xxx-xxxx" sbt
-> herokuDeploy
+> webappStart
```
-Check out your deployed application at
-`https://my-heroku-app.herokuapp.com`.
+### `warJoin` and `webappJoin`
-### Deploying to Elastic Beanstalk
+To block sbt while the container is running, use `warJoin`/`webappJoin`:
-Before trying to deploy anything, create an application and a
-Tomcat-based environment for it in Elastic Beanstalk.
-
-Enable the `ElasticBeanstalkDeployPlugin` plugin, and configure your
-application's name, environment, and region:
-
-```scala
-enablePlugins(ElasticBeanstalkDeployPlugin)
-
-elasticBeanstalkAppName := "my-elastic-beanstalk-app"
-
-elasticBeanstalkEnvName := "production"
-
-elasticBeanstalkRegion := "us-west-1"
```
-
-Add AWS credentials to your environment, launch sbt, and deploy with
-`elasticBeanstalkDeploy`:
-
-```
-$ AWS_ACCESS_KEY="xxx" AWS_SECRET_KEY="xxx" sbt
-> elasticBeanstalkDeploy
+$ sbt warStart warJoin
```
-Check out your deployed application at
-`http://my-elastic-beanstalk-app.us-west-1.elasticbeanstalk.com`.
-
-### Block sbt on running container
-
-To start the container from the command line and block sbt from exiting
-prematurely, use `jetty:join`:
-
```
-$ sbt jetty:start jetty:join
+$ sbt webappStart webappJoin
```
This is useful for running sbt in production (e.g. in a Docker
-container).
+container), if you're into that kind of thing.
-### Build and run from Docker
+### `warStop` and `webappStop`
-Choose a Docker image that has sbt installed, and use `sbt
-:start :join`:
-
-Using [hseeberger/scala-sbt](https://hub.docker.com/r/hseeberger/scala-sbt/);
-
-```
-$ docker run -p 8080:8080 -v $PWD:/root hseeberger/scala-sbt sbt tomcat:start tomcat:join
-```
-
-Using [bigtruedata/sbt](https://hub.docker.com/r/bigtruedata/sbt/):
-
-```
-$ docker run -p 8080:8080 -v $PWD:/app bigtruedata/sbt sbt tomcat:start tomcat:join
-```
-
-Test it out:
-
-```
-$ curl localhost:8080/hello
-
-
- Hello, world!
-
-
-```
-
-### Run a packaged *.war* file from Docker
-
-First, package a *.war* file:
-
-```
-$ sbt package
-[info] Packaging .../target/scala-2.10/getting-started_2.10-0.1-SNAPSHOT.war .
-```
-
-Run it using [Jetty](https://hub.docker.com/_/jetty/):
-
-```
-$ docker run -p 8080:8080 -v /path/to/myproject/target/scala-2.10:/var/lib/jetty/webapps jetty
-```
-
-Run it using [Tomcat](https://hub.docker.com/_/tomcat/):
+Stop the running container with `warStop`/`webappStop`:
```
-$ docker run -p 8080:8080 -v /path/to/myproject/target/scala-2.10:/usr/local/tomcat/webapps tomcat
+> warStop
```
-Test it out:
-
-```
-$ curl localhost:8080/myproject_2.10-0.1-SNAPSHOT/hello
-
-
- Hello, world!
-
-
-```
-
-### Build a Docker image
-
-Configure a Docker build with `sbt-native-packager`:
-
-*project/plugins.sbt:*
-
-```scala
-addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.11")
-```
-
-*build.sbt:*
-
-```scala
-enablePlugins(DockerPlugin)
-
-dockerBaseImage := "tomcat:9.0"
-
-Docker / defaultLinuxInstallLocation := "/usr/local/tomcat/webapps"
-
-dockerExposedVolumes := Seq((Docker / defaultLinuxInstallLocation).value)
-
-Docker / mappings += sbt.Keys.`package`.value -> "/usr/local/tomcat/webapps/ROOT.war"
-
-dockerEntrypoint := Seq("catalina.sh", "run")
-```
-
-Build the project from sbt as a Docker image:
-
-```
-> docker:publishLocal
-```
-
-Run it:
-
-```
-$ docker run -it --rm -p 8080:8080 my-web-project:0.1.0-SNAPSHOT
-```
-
-### Quickstart mode
-
-The development cycle can be sped up by serving static resources
-directly from source, and avoiding packaging of compiled artifacts.
-
-Use `:quickstart` in place of `:start` to run the
-container in quickstart mode:
-
-```
-> jetty:quickstart
-```
-
-### Running multiple containers
-
-To launch using more than a single container, set `containerScale`:
-
-```scala
-containerScale := 5
-```
-
-This will configure the container to launch in five forked JVMs, using
-five sequential ports starting from `containerPort`.
-
-In debug mode, five additional sequential debug ports starting from
-`debugPort` will be opened.
-
-### JRebel integration
-
-The development cycle can be further sped up by skipping server restarts
-between code recompilation.
-
-Add `-agentpath` to the container's JVM options:
-
-```
-javaOptions in Jetty += "-agentpath:/path/to/jrebel/lib/libjrebel64.so"
-```
-
-Launch the container with `quickstart`, and run triggered compilation:
-
```
-> jetty:quickstart
-> ~compile
+> webappStop
```
diff --git a/build.sbt b/build.sbt
index 4b5b28fb..7bbd0a61 100644
--- a/build.sbt
+++ b/build.sbt
@@ -1,6 +1,6 @@
// General
enablePlugins(SbtPlugin)
-name := "xsbt-web-plugin"
+name := "sbt-war"
organization := "com.earldouglas"
sbtPlugin := true
scalacOptions ++= Seq("-feature", "-deprecation")
diff --git a/examples/adder/README.md b/examples/adder/README.md
deleted file mode 100644
index bf52308c..00000000
--- a/examples/adder/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - get sum
-[info] - add some numbers
-[info] - post an unparseable number
-[info] Run completed in 1 second, 428 milliseconds.
-[info] Total number of tests run: 3
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 4 s, completed Nov 13, 2022 1:50:36 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/adder/build.sbt b/examples/adder/build.sbt
deleted file mode 100644
index 3c7be000..00000000
--- a/examples/adder/build.sbt
+++ /dev/null
@@ -1,15 +0,0 @@
-libraryDependencies += "com.h2database" % "h2" % "2.3.232"
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(JettyPlugin)
-
-containerForkOptions :=
- ForkOptions().withEnvVars(
- Map(
- "DB_DRIVER" -> "org.h2.Driver",
- "DB_URL" -> "jdbc:h2:mem:adder",
- "DB_USER" -> "sa",
- "DB_PASS" -> ""
- )
- )
diff --git a/examples/adder/project/build.properties b/examples/adder/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/adder/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/adder/project/plugins.sbt b/examples/adder/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/adder/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/adder/src/main/scala/adder.scala b/examples/adder/src/main/scala/adder.scala
deleted file mode 100644
index f53dea2a..00000000
--- a/examples/adder/src/main/scala/adder.scala
+++ /dev/null
@@ -1,71 +0,0 @@
-import scala.concurrent.{ExecutionContext => EC}
-
-object Adder {
-
- def init(implicit ec: EC): Service[Unit] =
- Service.update("""|create table if not exists
- | amounts ( id int not null auto_increment
- | , amount int not null
- | , primary key (id)
- | )
- |""".stripMargin) >>
- Service.update("""|create table if not exists
- | sums ( last_id int not null unique
- | , sum int not null
- | )
- |""".stripMargin)
-
- def add(amount: Int)(implicit ec: EC): Service[Unit] =
- Service.update(
- "insert into amounts (amount) values (?)",
- _.setInt(1, amount)
- )
-
- def getAmounts(afterId: Int)(implicit
- ec: EC
- ): Service[(Int, List[Int])] =
- Service.query(
- "select * from amounts where id > ? order by id asc",
- { s =>
- s.setInt(1, afterId)
- val r = s.executeQuery()
- var amounts: List[Int] = Nil
- var lastId: Int = afterId
- while (r.next()) {
- lastId = r.getInt("id")
- amounts = r.getInt("amount") :: amounts
- }
- (lastId, amounts)
- }
- )
-
- def getSum(implicit ec: EC): Service[(Int, Int)] =
- Service.query(
- "select last_id, sum from sums order by last_id desc limit 1",
- { s =>
- val r = s.executeQuery()
- if (r.next()) {
- (r.getInt("last_id"), r.getInt("sum"))
- } else {
- (0, 0)
- }
- }
- )
-
- def update(implicit ec: EC): Service[Unit] =
- for {
- sum <- getSum
- amt <- getAmounts(sum._1)
- _ <- Service.update(
- "insert into sums (last_id, sum) values (?, ?)",
- { s =>
- s.setInt(1, amt._1)
- s.setInt(2, sum._2 + amt._2.sum)
- }
- )
- _ <- Service.update(
- "delete from sums where last_id < ?",
- _.setInt(1, amt._1)
- )
- } yield ()
-}
diff --git a/examples/adder/src/main/scala/service.scala b/examples/adder/src/main/scala/service.scala
deleted file mode 100644
index f358023d..00000000
--- a/examples/adder/src/main/scala/service.scala
+++ /dev/null
@@ -1,117 +0,0 @@
-import java.sql.Connection
-import java.sql.PreparedStatement
-import scala.concurrent.Future
-import scala.concurrent.{ExecutionContext => EC}
-import scala.util.Failure
-import scala.util.Success
-import scala.util.Try
-
-object `package` {
- type JDBC[A] = Connection => A
- type Error = (Int, String)
-}
-
-object Service {
-
- def unsafeRun[A](s: Service[A], c: Connection)(implicit
- ec: EC
- ): Future[Either[Error, A]] =
- c synchronized {
- val ea =
- s.run(c) map {
- case r @ Right(_) =>
- c.commit()
- r
- case l @ Left(_) =>
- c.rollback()
- l
- }
- ea
- }
-
- def apply[A](a: => A)(implicit ec: EC): Service[A] =
- Service { _ =>
- Future {
- Try(a) match {
- case Failure(t) => Left((500, t.getMessage))
- case Success(x) => Right(x)
- }
- }
- }
-
- def apply[A](k: Connection => A)(implicit ec: EC): Service[A] =
- Service { c =>
- Future {
- Try(k(c)) match {
- case Failure(t) => Left((500, t.getMessage))
- case Success(x) => Right(x)
- }
- }
- }
-
- def update(u: String)(implicit ec: EC): Service[Unit] =
- apply { c =>
- val s = c.createStatement()
- s.executeUpdate(u)
- s.close()
- }
-
- def update(q: String, k: PreparedStatement => Unit)(implicit
- ec: EC
- ): Service[Unit] =
- apply { c =>
- val s = c.prepareStatement(q)
- k(s)
- s.executeUpdate()
- s.close()
- }
-
- def query[A](q: String, k: PreparedStatement => A)(implicit
- ec: EC
- ): Service[A] =
- apply { c =>
- val s = c.prepareStatement(q)
- val a = k(s)
- s.close()
- a
- }
-}
-
-case class Service[A](run: JDBC[Future[Either[Error, A]]]) {
-
- def map[B](f: A => B)(implicit ec: EC): Service[B] =
- Service { c =>
- run(c) map {
- case Left(e) => Left(e)
- case Right(a) => Right(f(a))
- }
- }
-
- def mapLeft(f: Error => Error)(implicit ec: EC): Service[A] =
- Service { c =>
- run(c) map {
- case Left(e) => Left(f(e))
- case Right(a) => Right(a)
- }
- }
-
- def withLeft(f: Error => Unit)(implicit ec: EC): Service[A] =
- Service { c =>
- run(c) map {
- case Left(e) => f(e); Left(e)
- case Right(a) => Right(a)
- }
- }
-
- def flatMap[B](f: A => Service[B])(implicit ec: EC): Service[B] =
- Service { c =>
- run(c) flatMap {
- case Left(e) => Future(Left(e))
- case Right(a) => f(a).run(c)
- }
- }
-
- def >>[B](x: Service[B])(implicit ec: EC): Service[B] =
- flatMap { _ => x }
-
-}
diff --git a/examples/adder/src/main/scala/servlet.scala b/examples/adder/src/main/scala/servlet.scala
deleted file mode 100644
index d83c301d..00000000
--- a/examples/adder/src/main/scala/servlet.scala
+++ /dev/null
@@ -1,115 +0,0 @@
-import java.sql.Connection
-import java.sql.DriverManager
-import java.util.concurrent.TimeUnit.MILLISECONDS
-import javax.servlet.AsyncContext
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-import scala.concurrent.Await
-import scala.concurrent.ExecutionContext.Implicits.global
-import scala.concurrent.Future
-import scala.concurrent.duration.Duration
-import scala.io.Source
-
-trait JdbcServlet {
-
- val c: Connection = {
- Class.forName(sys.env("DB_DRIVER"))
- val c: Connection =
- DriverManager.getConnection(
- sys.env("DB_URL"),
- sys.env("DB_USER"),
- sys.env("DB_PASS")
- )
- c.setAutoCommit(false)
- c
- }
-
- def unsafeRun[A](ctx: AsyncContext)(s: Service[A]): Future[Unit] =
- Service.unsafeRun(s, c) map { _ => ctx.complete() }
-}
-
-trait CommandServlet extends HttpServlet with JdbcServlet {
-
- override def doPost(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
- unsafeRun(req.startAsync()) {
- Service {
- Source.fromInputStream(req.getInputStream).mkString.toInt
- } mapLeft { _ =>
- (400, "couldn't parse number")
- } flatMap { amount =>
- Adder.add(amount)
- } map { _ =>
- res.setStatus(201)
- } withLeft { case (status, message) =>
- res.setContentType("text/plain")
- res.setStatus(status)
- res.getWriter.write(message)
- }
- }
- }
-}
-
-trait UpdateServlet extends HttpServlet with JdbcServlet {
-
- private val updater: Thread =
- new Thread {
- override def run(): Unit = {
- while (!isInterrupted) {
- Service.unsafeRun(Adder.update, c)
- Thread.sleep(250)
- }
- }
- }
-
- override def init(): Unit = {
- updater.start
- super.init()
- }
-
- override def destroy(): Unit = {
- updater.interrupt
- super.destroy()
- }
-}
-
-trait QueryServlet extends HttpServlet with JdbcServlet {
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
- unsafeRun(req.startAsync()) {
- Adder.getSum map { case (_, result) =>
- res.setContentType("text/plain")
- res.setCharacterEncoding("UTF-8")
- res.getWriter.write(s"${result}\n")
- } withLeft { case (status, message) =>
- res.setContentType("text/plain")
- res.setStatus(status)
- res.getWriter.write(message)
- }
- }
- }
-}
-
-class AdderServlet
- extends CommandServlet
- with UpdateServlet
- with QueryServlet {
-
- override def init(): Unit = {
- Await.result(
- Service.unsafeRun(Adder.init, c),
- Duration(5000, MILLISECONDS)
- )
- super.init()
- }
-
- override def destroy(): Unit = {
- super.destroy()
- }
-}
diff --git a/examples/adder/src/main/webapp/WEB-INF/web.xml b/examples/adder/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 2bc4e4b3..00000000
--- a/examples/adder/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- AdderServlet
- AdderServlet
- true
-
-
-
- AdderServlet
- /*
-
-
-
diff --git a/examples/adder/src/test/scala/Http.scala b/examples/adder/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/adder/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/adder/src/test/scala/TestSuite.scala b/examples/adder/src/test/scala/TestSuite.scala
deleted file mode 100644
index 7e7042d4..00000000
--- a/examples/adder/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("get sum") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- status = 200,
- Map("Content-Type" -> "text/plain;charset=utf-8"),
- "0\n"
- )
- }
-
- test("add some numbers") {
- Request(
- "POST",
- "http://localhost:8080/",
- Map.empty,
- Some("1")
- ) shouldBe
- Response(status = 201, Map.empty, "")
-
- Request(
- "POST",
- "http://localhost:8080/",
- Map.empty,
- Some("11")
- ) shouldBe
- Response(status = 201, Map.empty, "")
-
- Request(
- "POST",
- "http://localhost:8080/",
- Map.empty,
- Some("13")
- ) shouldBe
- Response(status = 201, Map.empty, "")
-
- Request(
- "POST",
- "http://localhost:8080/",
- Map.empty,
- Some("17")
- ) shouldBe
- Response(status = 201, Map.empty, "")
-
- Thread.sleep(300)
-
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- status = 200,
- Map("Content-Type" -> "text/plain;charset=utf-8"),
- "42\n"
- )
- }
-
- test("post an unparseable number") {
- Request(
- "POST",
- "http://localhost:8080/",
- Map.empty,
- Some("forty-two")
- ) shouldBe
- Response(
- status = 400,
- Map("Content-Type" -> "text/plain;charset=iso-8859-1"),
- "couldn't parse number"
- )
- }
-}
diff --git a/examples/async/README.md b/examples/async/README.md
deleted file mode 100644
index 92833f34..00000000
--- a/examples/async/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - add a message
-[info] Run completed in 783 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 3 s, completed Nov 13, 2022 1:51:05 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/async/build.sbt b/examples/async/build.sbt
deleted file mode 100644
index 6b942f4a..00000000
--- a/examples/async/build.sbt
+++ /dev/null
@@ -1,4 +0,0 @@
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
-
-enablePlugins(JettyPlugin)
diff --git a/examples/async/project/build.properties b/examples/async/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/async/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/async/project/plugins.sbt b/examples/async/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/async/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/async/src/main/scala/AsyncServlet.scala b/examples/async/src/main/scala/AsyncServlet.scala
deleted file mode 100644
index bbc93bdc..00000000
--- a/examples/async/src/main/scala/AsyncServlet.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-class AsyncServlet extends HttpServlet {
-
- val execSvc = java.util.concurrent.Executors.newFixedThreadPool(8)
-
- override def destroy(): Unit = {
- execSvc.shutdown
- }
-
- override def service(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
-
- val ctx = req.startAsync
-
- execSvc submit {
- new Runnable() {
- override def run(): Unit = {
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- val responseBody: String =
- """
- |
- | Hello, world!
- |
- |""".stripMargin
- res.getWriter.write(responseBody)
-
- ctx.complete
- }
- }
- }
- }
-}
diff --git a/examples/async/src/main/webapp/WEB-INF/web.xml b/examples/async/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 3fd3142c..00000000
--- a/examples/async/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- AsyncServlet
- AsyncServlet
- true
-
-
-
- AsyncServlet
- /*
-
-
-
diff --git a/examples/async/src/test/scala/Http.scala b/examples/async/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/async/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/async/src/test/scala/TestSuite.scala b/examples/async/src/test/scala/TestSuite.scala
deleted file mode 100644
index 3a210fdd..00000000
--- a/examples/async/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import org.scalatest.funsuite.AnyFunSuite
-import org.scalatest.matchers.should.Matchers
-
-class TestSuite extends AnyFunSuite with Matchers {
-
- test("add a message") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- """|
- |
- | Hello, world!
- |
- |""".stripMargin
- )
- }
-}
diff --git a/examples/free/README.md b/examples/free/README.md
deleted file mode 100644
index a4ea1e10..00000000
--- a/examples/free/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - require session
-[info] - require valid session
-[info] - sign in
-[info] Run completed in 663 milliseconds.
-[info] Total number of tests run: 3
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 4 s, completed Nov 13, 2022 1:52:46 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/free/build.sbt b/examples/free/build.sbt
deleted file mode 100644
index f0f8fa26..00000000
--- a/examples/free/build.sbt
+++ /dev/null
@@ -1,25 +0,0 @@
-scalaVersion := "2.13.14" // needed for fancy type inference
-scalacOptions ++= Seq(
- "-deprecation",
- "-encoding",
- "utf8",
- "-feature",
- "-language:existentials",
- "-language:experimental.macros",
- "-language:higherKinds",
- "-language:implicitConversions",
- "-unchecked",
- "-Xfatal-warnings",
- "-Xlint",
- "-Yrangepos",
- "-Ywarn-unused"
-)
-
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(JettyPlugin)
-
-addCompilerPlugin(
- "org.typelevel" %% "kind-projector" % "0.13.3" cross CrossVersion.full
-)
diff --git a/examples/free/project/build.properties b/examples/free/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/free/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/free/project/plugins.sbt b/examples/free/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/free/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/free/src/main/scala/Database.scala b/examples/free/src/main/scala/Database.scala
deleted file mode 100644
index de010225..00000000
--- a/examples/free/src/main/scala/Database.scala
+++ /dev/null
@@ -1,31 +0,0 @@
-class Database {
-
- private val permissions: Map[String, Set[Permission]] =
- Map(
- "tbuckland" -> Set(Read, Write),
- "lbracco" -> Set(Write),
- "jdoe" -> Set(Read)
- )
-
- private val passwordsByUsername: Map[String, String] =
- Map(
- "tbuckland" -> "alligator3",
- "lbracco" -> "secret",
- "jdoe" -> "unguessable"
- )
-
- private var sessions: Map[String, User] =
- Map.empty
-
- def getPermissions(username: String): Set[Permission] =
- permissions.getOrElse(username, Set.empty)
-
- def findUsernameAndPassword(
- username: String,
- password: String
- ): Boolean =
- passwordsByUsername.get(username) == Some(password)
-
- def addSession(sessionId: String, user: User): Unit =
- sessions = sessions + (sessionId -> user)
-}
diff --git a/examples/free/src/main/scala/FreeMonad.scala b/examples/free/src/main/scala/FreeMonad.scala
deleted file mode 100644
index 089c56b8..00000000
--- a/examples/free/src/main/scala/FreeMonad.scala
+++ /dev/null
@@ -1,40 +0,0 @@
-trait ~>[F[_], G[_]] {
- def apply[A](f: F[A]): G[A]
-}
-
-trait Monad[F[_]] {
- def pure[A](a: A): F[A]
- def bind[A, B](fa: F[A])(f: A => F[B]): F[B]
-}
-
-sealed trait Free[F[_], A] {
-
- import Free._
-
- def map[B](f: A => B): Free[F, B] = flatMap { a => pure(f(a)) }
-
- def flatMap[B](f: A => Free[F, B]): Free[F, B] = Bind(this, f)
-
- def foldMap[G[_]: Monad](nt: F ~> G): G[A] =
- this match {
- case Pure(a) => implicitly[Monad[G]].pure(a)
- case Suspend(fa) => nt(fa)
- case Bind(fa, f) =>
- val mg = implicitly[Monad[G]]
- val ga = fa.foldMap(nt)
- mg.bind(ga)(f(_).foldMap(nt))
- }
-
-}
-
-object Free {
-
- def pure[F[_], A](a: A): Free[F, A] = Pure(a)
-
- def liftM[F[_], A](fa: F[A]): Free[F, A] = Suspend(fa)
-
- final case class Pure[F[_], A](a: A) extends Free[F, A]
- final case class Suspend[F[_], A](fa: F[A]) extends Free[F, A]
- final case class Bind[F[_], A, B](fa: Free[F, A], f: A => Free[F, B])
- extends Free[F, B]
-}
diff --git a/examples/free/src/main/scala/FreeServlet.scala b/examples/free/src/main/scala/FreeServlet.scala
deleted file mode 100644
index 2c11317e..00000000
--- a/examples/free/src/main/scala/FreeServlet.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-class FreeServlet extends HttpServlet {
-
- implicit val responseMonad: Monad[Either[WebAppErr, *]] =
- new Monad[Either[WebAppErr, *]] {
- def pure[A](a: A): Either[WebAppErr, *][A] = Right(a)
- def bind[A, B](
- fa: Either[WebAppErr, *][A]
- )(f: A => Either[WebAppErr, *][B]): Either[WebAppErr, *][B] =
- fa match {
- case Left(e) => Left(e)
- case Right(a) => f(a)
- }
- }
-
- val database = new Database
-
- def interpreter(
- req: HttpServletRequest
- ): WebAppOp ~> Either[WebAppErr, *] =
- new ~>[WebAppOp, Either[WebAppErr, *]] {
- def apply[A](c: WebAppOp[A]): Either[WebAppErr, *][A] =
- try {
- c match {
- case Value(x) => Right(x)
- case GetDatabase => Right(database)
- case RequestHeader(name) =>
- Option(req.getHeader(name))
- .map(Right(_))
- .getOrElse(Left(MissingHeader(name)))
- case RequestParam(name) =>
- Option(req.getParameter(name))
- .map(Right(_))
- .getOrElse(Left(MissingParameter(name)))
- case Error(e) => Left(e)
- }
- } catch {
- case t: Throwable =>
- Left(InternalServerError(t))
- }
- }
-
- override def doPost(
- req: HttpServletRequest,
- res: HttpServletResponse
- ): Unit = {
- WebAppOp.signIn.foldMap(interpreter(req)) match {
- case Right(sessionId) =>
- res.setStatus(201)
- res.setHeader("X-Session-ID", sessionId)
- case Left(e) =>
- res.setStatus(e.status)
- res.getWriter.write(e.message)
- }
- }
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ): Unit = {
- WebAppOp.getSecret.foldMap(interpreter(req)) match {
- case Right(secret) =>
- res.setStatus(200)
- res.getWriter.write(secret)
- case Left(e) =>
- res.setStatus(e.status)
- res.getWriter.write(e.message)
- }
- }
-}
diff --git a/examples/free/src/main/scala/WebAppOp.scala b/examples/free/src/main/scala/WebAppOp.scala
deleted file mode 100644
index 09a740b7..00000000
--- a/examples/free/src/main/scala/WebAppOp.scala
+++ /dev/null
@@ -1,114 +0,0 @@
-import java.util.UUID
-
-case class User(username: String)
-
-sealed trait Permission
-case object Read extends Permission
-case object Write extends Permission
-case object Delete extends Permission
-
-sealed trait WebAppOp[+A]
-case class Value[A](value: A) extends WebAppOp[A]
-case object GetDatabase extends WebAppOp[Database]
-case class RequestParam(name: String) extends WebAppOp[String]
-case class RequestHeader(name: String) extends WebAppOp[String]
-case class Error(e: WebAppErr) extends WebAppOp[Nothing]
-
-sealed trait WebAppErr {
- def status: Int
- def message: String
-}
-case class InsufficientPermissions(
- required: Set[Permission],
- permissions: Set[Permission]
-) extends WebAppErr {
- val status: Int = 403
- val message: String =
- s"Insufficient permissions; required: ${required}, present: ${permissions}"
-}
-case class InvalidSession(sessionId: String) extends WebAppErr {
- val status: Int = 401
- val message: String = s"Invalid session: ${sessionId}"
-}
-case class InvalidUsernameOrPassword(username: String)
- extends WebAppErr {
- val status: Int = 404
- val message: String =
- s"Invalid username or password; username: ${username}"
-}
-case class MissingParameter(name: String) extends WebAppErr {
- val status: Int = 400
- val message: String = s"Missing required parameter: ${name}"
-}
-case class MissingHeader(name: String) extends WebAppErr {
- val status: Int = 400
- val message: String = s"Missing required header: ${name}"
-}
-case class InternalServerError(throwable: Throwable) extends WebAppErr {
- val status: Int = 500
- val message: String = throwable.getMessage
-}
-
-object WebAppOp {
-
- private val permissions: Map[String, Set[Permission]] =
- Map(
- "tbuckland" -> Set(Read, Write),
- "lbracco" -> Set(Write),
- "jdoe" -> Set(Read)
- )
-
- private val passwordsByUsername: Map[String, String] =
- Map(
- "tbuckland" -> "alligator3",
- "lbracco" -> "secret",
- "jdoe" -> "unguessable"
- )
-
- private var sessions: Map[String, User] =
- Map.empty
-
- def signIn: Free[WebAppOp, String] =
- for {
- username <- Free.liftM(RequestParam("username"))
- password <- Free.liftM(RequestParam("password"))
- sessionId <- Free.liftM {
- if (passwordsByUsername.get(username) == Some(password)) {
- val sessionId = UUID.randomUUID.toString
- val user = User(username)
- sessions = sessions + (sessionId -> user)
- Value(sessionId)
- } else {
- Error(InvalidUsernameOrPassword(username))
- }
- }
- } yield sessionId
-
- def authN: Free[WebAppOp, User] =
- for {
- sessionId <- Free.liftM(RequestHeader("x-session-id"))
- user <- Free.liftM {
- sessions.get(sessionId) match {
- case Some(user) => Value(user)
- case None => Error(InvalidSession(sessionId))
- }
- }
- } yield user
-
- def authZ[A](required: Set[Permission], k: => A): Free[WebAppOp, A] =
- for {
- perms <- getPermissions
- result <- Free.liftM {
- if ((required -- perms).isEmpty) Value(k)
- else Error(InsufficientPermissions(required, perms))
- }
- } yield result
-
- val getPermissions: Free[WebAppOp, Set[Permission]] =
- for {
- user <- WebAppOp.authN
- } yield permissions.getOrElse(user.username, Set.empty)
-
- val getSecret: Free[WebAppOp, String] =
- authZ(Set(Read), "The duck flies at midnight.")
-}
diff --git a/examples/free/src/main/webapp/WEB-INF/web.xml b/examples/free/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 28d52e2f..00000000
--- a/examples/free/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- free
- FreeServlet
-
-
-
- free
- /*
-
-
-
diff --git a/examples/free/src/test/scala/Http.scala b/examples/free/src/test/scala/Http.scala
deleted file mode 100644
index 591bbfef..00000000
--- a/examples/free/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.jdk.CollectionConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/free/src/test/scala/TestSuite.scala b/examples/free/src/test/scala/TestSuite.scala
deleted file mode 100644
index 2cba81c3..00000000
--- a/examples/free/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,39 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("require session") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(400, Map.empty, "Missing required header: x-session-id")
- }
-
- test("require valid session") {
- Request(
- "GET",
- "http://localhost:8080/",
- Map("X-Session-ID" -> "foo123"),
- None
- ) shouldBe
- Response(401, Map.empty, "Invalid session: foo123")
- }
-
- test("sign in") {
- val sessionId =
- Request(
- "POST",
- "http://localhost:8080/",
- Map.empty,
- Some("username=tbuckland&password=alligator3")
- ).headers
- .get("X-Session-ID")
- .get
-
- Request(
- "GET",
- "http://localhost:8080/",
- Map("X-Session-ID" -> sessionId),
- None
- ) shouldBe
- Response(200, Map.empty, "The duck flies at midnight.")
- }
-}
diff --git a/examples/frege/README.md b/examples/frege/README.md
deleted file mode 100644
index bb298dae..00000000
--- a/examples/frege/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] - /hello
-[info] - /foo
-[info] Run completed in 407 milliseconds.
-[info] Total number of tests run: 3
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 4 s, completed Nov 13, 2022 1:54:19 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/frege/build.sbt b/examples/frege/build.sbt
deleted file mode 100644
index 07d1cef6..00000000
--- a/examples/frege/build.sbt
+++ /dev/null
@@ -1,6 +0,0 @@
-enablePlugins(JettyPlugin)
-
-javacOptions ++= Seq("-encoding", "UTF-8")
-
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
diff --git a/examples/frege/project/build.properties b/examples/frege/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/frege/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/frege/project/plugins.sbt b/examples/frege/project/plugins.sbt
deleted file mode 100644
index 817df926..00000000
--- a/examples/frege/project/plugins.sbt
+++ /dev/null
@@ -1,3 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
-
-addSbtPlugin("com.earldouglas" % "sbt-frege" % "3.0.2")
diff --git a/examples/frege/src/main/frege/FregeWeb.fr b/examples/frege/src/main/frege/FregeWeb.fr
deleted file mode 100644
index ca63677a..00000000
--- a/examples/frege/src/main/frege/FregeWeb.fr
+++ /dev/null
@@ -1,12 +0,0 @@
-module fregeweb.FregeWeb where
-
-data Request = Request { method :: String, uri :: String }
-data Response = Response { status :: Int, body :: String }
-
-service :: Request -> Response
-service (Request "GET" "/") = response 200 "hello"
-service (Request "GET" "/hello") = response 200 "Hello, world!"
-service _ = response 404 "404'd!"
-
-response :: Int -> String -> Response
-response status body = Response status body
diff --git a/examples/frege/src/main/scala/FregeServlet.scala b/examples/frege/src/main/scala/FregeServlet.scala
deleted file mode 100644
index 425edce1..00000000
--- a/examples/frege/src/main/scala/FregeServlet.scala
+++ /dev/null
@@ -1,51 +0,0 @@
-package fregeweb
-
-import scala.language.implicitConversions
-
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.{HttpServletRequest => HSReq}
-import javax.servlet.http.{HttpServletResponse => HSRes}
-
-import FregeWeb.TRequest
-import FregeWeb.TResponse
-
-import frege.run8.Box
-
-class FregeServlet extends HttpServlet {
-
- override def service(hsReq: HSReq, hsRes: HSRes): Unit =
- hsRes service hsReq
-
-}
-
-object `package` {
-
- implicit class HSResService(val hsRes: HSRes) extends AnyVal {
-
- def service(hsReq: HSReq): Unit = {
- val tReq: TRequest =
- TRequest.mk(new Box(hsReq.method), new Box(hsReq.uri))
- val tRes: TResponse =
- FregeWeb.service(tReq).asInstanceOf[TResponse]
- write(tRes)
- }
-
- private def write(tRes: TResponse): Unit = {
- val status: Int = TResponse.status(tRes).asInstanceOf[Int]
- val body: String = TResponse.body(tRes).asInstanceOf[String]
- hsRes.setStatus(status)
- hsRes.getWriter().write(body)
- }
-
- }
-
- implicit class RichHSReq(val hsReq: HSReq) extends AnyVal {
- def method: String = hsReq.getMethod()
- def uri: String =
- if (hsReq.getRequestURI().startsWith(hsReq.getServletPath()))
- hsReq.getRequestURI().substring(hsReq.getServletPath().length())
- else
- hsReq.getRequestURI()
- }
-
-}
diff --git a/examples/frege/src/main/webapp/WEB-INF/web.xml b/examples/frege/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 2af0bc3e..00000000
--- a/examples/frege/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- frege-web
- fregeweb.FregeServlet
-
-
-
- frege-web
- /*
-
-
-
diff --git a/examples/frege/src/test/scala/Http.scala b/examples/frege/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/frege/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/frege/src/test/scala/TestSuite.scala b/examples/frege/src/test/scala/TestSuite.scala
deleted file mode 100644
index 10ef6b25..00000000
--- a/examples/frege/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,34 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("/") {
- Request(
- "GET",
- "http://localhost:8080/",
- Map.empty,
- body = None
- ) shouldBe
- Response(200, Map.empty, """hello""")
- }
-
- test("/hello") {
- Request(
- "GET",
- "http://localhost:8080/hello",
- Map.empty,
- None
- ) shouldBe
- Response(200, Map.empty, "Hello, world!")
- }
-
- test("/foo") {
- Request(
- "GET",
- "http://localhost:8080/foo",
- Map.empty,
- None
- ) shouldBe
- Response(404, Map.empty, "404'd!")
- }
-}
diff --git a/examples/getting-started/README.md b/examples/getting-started/README.md
deleted file mode 100644
index f599860e..00000000
--- a/examples/getting-started/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] Run completed in 739 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 3 s, completed Nov 13, 2022 1:55:49 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/getting-started/build.sbt b/examples/getting-started/build.sbt
deleted file mode 100644
index 23e477bd..00000000
--- a/examples/getting-started/build.sbt
+++ /dev/null
@@ -1,3 +0,0 @@
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
-enablePlugins(JettyPlugin)
diff --git a/examples/getting-started/project/build.properties b/examples/getting-started/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/getting-started/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/getting-started/project/plugins.sbt b/examples/getting-started/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/getting-started/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/getting-started/src/main/scala/GettingStartedServlet.scala b/examples/getting-started/src/main/scala/GettingStartedServlet.scala
deleted file mode 100644
index d0e2ec02..00000000
--- a/examples/getting-started/src/main/scala/GettingStartedServlet.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-class GettingStartedServlet extends HttpServlet {
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- val responseBody: String =
- """|
- |
- | Hello, world!
- |
- |""".stripMargin
- res.getWriter.write(responseBody)
- }
-}
diff --git a/examples/getting-started/src/main/webapp/WEB-INF/web.xml b/examples/getting-started/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index d86c711d..00000000
--- a/examples/getting-started/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- getting started
- GettingStartedServlet
-
-
-
- getting started
- /*
-
-
-
diff --git a/examples/getting-started/src/test/scala/Http.scala b/examples/getting-started/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/getting-started/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/getting-started/src/test/scala/TestSuite.scala b/examples/getting-started/src/test/scala/TestSuite.scala
deleted file mode 100644
index 12a38709..00000000
--- a/examples/getting-started/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import org.scalatest.funsuite.AnyFunSuite
-import org.scalatest.matchers.should.Matchers
-
-class TestSuite extends AnyFunSuite with Matchers {
-
- test("/") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |
- | Hello, world!
- |
- |""".stripMargin
- )
- }
-}
diff --git a/examples/http4s/README.md b/examples/http4s/README.md
deleted file mode 100644
index 3ccae223..00000000
--- a/examples/http4s/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - hello
-[info] Run completed in 1 second, 858 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 4 s, completed Nov 13, 2022 1:59:36 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/http4s/build.sbt b/examples/http4s/build.sbt
deleted file mode 100644
index 8e3ae9a8..00000000
--- a/examples/http4s/build.sbt
+++ /dev/null
@@ -1,14 +0,0 @@
-val http4sVersion = "1.0.0-M38"
-
-ThisBuild / scalaVersion := "3.2.2"
-
-libraryDependencies += "org.http4s" %% "http4s-dsl" % http4sVersion
-libraryDependencies += "org.http4s" %% "http4s-servlet" % http4sVersion
-libraryDependencies += "jakarta.servlet" % "jakarta.servlet-api" % "6.0.0" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
-
-Jetty / containerLibs := Seq(
- "org.eclipse.jetty" % "jetty-runner" % "11.0.15" intransitive ()
-)
-
-enablePlugins(JettyPlugin)
diff --git a/examples/http4s/project/build.properties b/examples/http4s/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/http4s/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/http4s/project/plugins.sbt b/examples/http4s/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/http4s/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/http4s/shell.nix b/examples/http4s/shell.nix
deleted file mode 100644
index 3d4d62d0..00000000
--- a/examples/http4s/shell.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{ pkgs ? import {} }:
-let
- jdk = pkgs.jdk11;
-in
- pkgs.mkShell {
- nativeBuildInputs = [
- (pkgs.sbt.override { jre = jdk; })
- ];
- shellHook = ''
- export JAVA_HOME=${jdk}
- PATH="${jdk}/bin:$PATH"
- '';
- }
diff --git a/examples/http4s/src/main/scala/HelloWorldServlet.scala b/examples/http4s/src/main/scala/HelloWorldServlet.scala
deleted file mode 100644
index 02d3e28b..00000000
--- a/examples/http4s/src/main/scala/HelloWorldServlet.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-import cats.effect.IO
-import cats.effect.std.Dispatcher
-import cats.effect.unsafe.IORuntime
-import org.http4s.implicits._
-import org.http4s.server.DefaultServiceErrorHandler
-import org.http4s.servlet.AsyncHttp4sServlet
-import org.http4s.servlet.NonBlockingServletIo
-import scala.concurrent.ExecutionContext
-import scala.concurrent.ExecutionContext.Implicits.global
-import scala.concurrent.Future
-import scala.concurrent.duration.Duration
-
-class HelloWorldServlet
- extends AsyncHttp4sServlet[IO](
- httpApp = Services.helloWorldService.orNotFound,
- asyncTimeout = Duration.Inf,
- servletIo = NonBlockingServletIo(4096),
- serviceErrorHandler = DefaultServiceErrorHandler,
- dispatcher = new Dispatcher[IO] {
- override def unsafeToFutureCancelable[A](
- fa: IO[A]
- ): (Future[A], () => Future[Unit]) =
- (fa.unsafeToFuture()(IORuntime.global), () => Future(()))
- }
- )(IO.asyncForIO)
diff --git a/examples/http4s/src/main/scala/Services.scala b/examples/http4s/src/main/scala/Services.scala
deleted file mode 100644
index bf80867d..00000000
--- a/examples/http4s/src/main/scala/Services.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-import cats.effect.IO
-import org.http4s.HttpRoutes
-import org.http4s.dsl.io._
-
-object Services {
-
- val helloWorldService =
- HttpRoutes.of[IO] { case GET -> Root / "hello" / name =>
- Ok(s"Hello, $name.")
- }
-}
diff --git a/examples/http4s/src/main/webapp/WEB-INF/web.xml b/examples/http4s/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 656a7d1b..00000000
--- a/examples/http4s/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- hello world
- HelloWorldServlet
- true
-
-
-
- hello world
- /*
-
-
-
diff --git a/examples/http4s/src/test/scala/Http.scala b/examples/http4s/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/http4s/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/http4s/src/test/scala/TestSuite.scala b/examples/http4s/src/test/scala/TestSuite.scala
deleted file mode 100644
index f17e73fe..00000000
--- a/examples/http4s/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-import org.scalatest.funsuite.AnyFunSuite
-import org.scalatest.matchers.should.Matchers
-
-class TestSuite extends AnyFunSuite with Matchers {
-
- test("hello") {
- Request(
- "GET",
- "http://localhost:8080/hello/James",
- Map.empty,
- None
- ) shouldBe
- Response(
- status = 200,
- Map("Content-Type" -> "text/plain;charset=utf-8"),
- "Hello, James."
- )
- }
-}
diff --git a/examples/https/README.md b/examples/https/README.md
deleted file mode 100644
index 73a09283..00000000
--- a/examples/https/README.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# HTTPS with Tomcat
-
-Let's serve our project over HTTPS directly from sbt.
-
-## Creating a certificate
-
-Create a basic self-signed certificate, KeyStore, and TrustStore by
-following the steps [in this tutorial][server-cert-tutorial]. By
-convention, passwords throughout will be `changeit`.
-
-[server-cert-tutorial]: https://docs.oracle.com/cd/E19798-01/821-1841/gjrgy/index.html)
-
-```
-$ keytool -genkey -alias server-alias -keyalg RSA -keypass changeit \
- -storepass changeit -keystore keystore.jks
-What is your first and last name?
- [Unknown]:
-What is the name of your organizational unit?
- [Unknown]:
-What is the name of your organization?
- [Unknown]:
-What is the name of your City or Locality?
- [Unknown]:
-What is the name of your State or Province?
- [Unknown]:
-What is the two-letter country code for this unit?
- [Unknown]:
-Is CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
- [no]: yes
-```
-
-```
-$ keytool -export -alias server-alias -storepass changeit \
- -file server.cer -keystore keystore.jks
-Certificate stored in file
-```
-
-```
-$ keytool -import -v -trustcacerts -alias server-alias \
- -file server.cer -keystore cacerts.jks -keypass changeit \
- -storepass changeit
-Trust this certificate? [no]: yes
-Certificate was added to keystore
-[Storing cacerts.jks]
-```
-
-## Configuring xsbt-web-plugin
-
-We'll use Tomcat:
-
-```scala
-enablePlugins(TomcatPlugin)
-```
-
-The Tomcat plugin uses [webapp-runner], which allows us to enable SSL
-via `--enable-ssl`:
-
-[webapp-runner]: https://github.com/jsimone/webapp-runner
-
-```scala
-containerArgs := Seq(
- "--enable-ssl"
-)
-```
-
-To enable SSL, we need to point the JVM toward our KeyStore, TrustStore,
-and proivde the corresponding passwords:
-
-```scala
-javaOptions in Tomcat ++= Seq(
- "-Djavax.net.ssl.keyStore=keystore.jks",
- "-Djavax.net.ssl.keyStorePassword=changeit",
- "-Djavax.net.ssl.trustStore=cacerts.jks",
- "-Djavax.net.ssl.trustStorePassword=changeit"
-)
-```
-
-By default, xsbt-web-plugin binds our project to port 8080, but let's
-use something more HTTPS-ish instead:
-
-```scala
-containerPort := 8443
-```
-
-Now we can run our project from sbt with `tomcat:start`, and view it at
-`https://localhost:8443/`. Since we used a self-signed certificate,
-we may need to reassure our Web browser that it's safe to proceed.
-
-```
-$ curl -ik https://localhost:8443
-HTTP/1.1 200
-Content-Type: text/html;charset=UTF-8
-Content-Length: 60
-Date: Wed, 06 Jun 2018 18:48:42 GMT
-
-
-
- Hello, world!
-
-
-```
-
-## Testing
-
-```
-$ sbt Tomcat/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] Run completed in 1 second, 806 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 5 s, completed Nov 13, 2022 2:03:45 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/https/build.sbt b/examples/https/build.sbt
deleted file mode 100644
index 0c55c928..00000000
--- a/examples/https/build.sbt
+++ /dev/null
@@ -1,17 +0,0 @@
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(TomcatPlugin)
-
-containerArgs := Seq(
- "--enable-ssl"
-)
-
-Tomcat / javaOptions ++= Seq(
- "-Djavax.net.ssl.keyStore=keystore.jks",
- "-Djavax.net.ssl.keyStorePassword=changeit",
- "-Djavax.net.ssl.trustStore=cacerts.jks",
- "-Djavax.net.ssl.trustStorePassword=changeit"
-)
-
-containerPort := 8443
diff --git a/examples/https/cacerts.jks b/examples/https/cacerts.jks
deleted file mode 100644
index 0eb1befd..00000000
Binary files a/examples/https/cacerts.jks and /dev/null differ
diff --git a/examples/https/keystore.jks b/examples/https/keystore.jks
deleted file mode 100644
index 2ecf7c10..00000000
Binary files a/examples/https/keystore.jks and /dev/null differ
diff --git a/examples/https/project/build.properties b/examples/https/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/https/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/https/project/plugins.sbt b/examples/https/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/https/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/https/server.cer b/examples/https/server.cer
deleted file mode 100644
index fe544151..00000000
Binary files a/examples/https/server.cer and /dev/null differ
diff --git a/examples/https/src/main/scala/GettingStartedServlet.scala b/examples/https/src/main/scala/GettingStartedServlet.scala
deleted file mode 100644
index 97e78a59..00000000
--- a/examples/https/src/main/scala/GettingStartedServlet.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-class GettingStartedServlet extends HttpServlet {
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- val responseBody: String =
- """
- |
- | Hello, world!
- |
- |""".stripMargin
- res.getWriter.write(responseBody)
- }
-}
diff --git a/examples/https/src/main/webapp/WEB-INF/web.xml b/examples/https/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index d86c711d..00000000
--- a/examples/https/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- getting started
- GettingStartedServlet
-
-
-
- getting started
- /*
-
-
-
diff --git a/examples/https/src/test/scala/Http.scala b/examples/https/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/https/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/https/src/test/scala/TestSuite.scala b/examples/https/src/test/scala/TestSuite.scala
deleted file mode 100644
index e1b511cf..00000000
--- a/examples/https/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-import java.security.cert._
-import javax.net.ssl._
-import org.scalatest._
-import java.security.SecureRandom
-
-class TestSuite extends FunSuite with BeforeAndAfterAll with Matchers {
-
- override def beforeAll(): Unit = {
- val sslContext = SSLContext.getInstance("SSL")
- sslContext.init(
- null,
- Array(
- new X509TrustManager {
- val getAcceptedIssuers = null
- def checkClientTrusted(
- x509Certificates: Array[X509Certificate],
- s: String
- ) = {}
- def checkServerTrusted(
- x509Certificates: Array[X509Certificate],
- s: String
- ) = {}
- }
- ),
- new SecureRandom()
- )
-
- HttpsURLConnection.setDefaultSSLSocketFactory(
- sslContext.getSocketFactory
- )
- HttpsURLConnection.setDefaultHostnameVerifier(
- new HostnameVerifier {
- def verify(s: String, sslSession: SSLSession) = true
- }
- )
- }
-
- test("/") {
- Request("GET", "https://localhost:8443/", Map.empty, None) shouldBe
- Response(
- 200,
- Map(
- "Keep-Alive" -> "timeout=60",
- "Connection" -> "keep-alive",
- "Content-Type" -> "text/html;charset=UTF-8"
- ),
- """
- |
- | Hello, world!
- |
- |""".stripMargin
- )
- }
-}
diff --git a/examples/jetty-11/README.md b/examples/jetty-11/README.md
deleted file mode 100644
index f599860e..00000000
--- a/examples/jetty-11/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] Run completed in 739 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 3 s, completed Nov 13, 2022 1:55:49 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/jetty-11/build.sbt b/examples/jetty-11/build.sbt
deleted file mode 100644
index 7ff54747..00000000
--- a/examples/jetty-11/build.sbt
+++ /dev/null
@@ -1,8 +0,0 @@
-libraryDependencies += "jakarta.servlet" % "jakarta.servlet-api" % "5.0.0" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
-
-enablePlugins(JettyPlugin)
-
-containerLibs in Jetty := Seq(
- "org.eclipse.jetty" % "jetty-runner" % "11.0.15" intransitive ()
-)
diff --git a/examples/jetty-11/project/build.properties b/examples/jetty-11/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/jetty-11/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/jetty-11/project/plugins.sbt b/examples/jetty-11/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/jetty-11/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/jetty-11/shell.nix b/examples/jetty-11/shell.nix
deleted file mode 100644
index 3d4d62d0..00000000
--- a/examples/jetty-11/shell.nix
+++ /dev/null
@@ -1,13 +0,0 @@
-{ pkgs ? import {} }:
-let
- jdk = pkgs.jdk11;
-in
- pkgs.mkShell {
- nativeBuildInputs = [
- (pkgs.sbt.override { jre = jdk; })
- ];
- shellHook = ''
- export JAVA_HOME=${jdk}
- PATH="${jdk}/bin:$PATH"
- '';
- }
diff --git a/examples/jetty-11/src/main/scala/GettingStartedServlet.scala b/examples/jetty-11/src/main/scala/GettingStartedServlet.scala
deleted file mode 100644
index 30d5a66e..00000000
--- a/examples/jetty-11/src/main/scala/GettingStartedServlet.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-import jakarta.servlet.http.HttpServlet
-import jakarta.servlet.http.HttpServletRequest
-import jakarta.servlet.http.HttpServletResponse
-
-class GettingStartedServlet extends HttpServlet {
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- val responseBody: String =
- """|
- |
- | Hello, world!
- |
- |""".stripMargin
- res.getWriter.write(responseBody)
- }
-}
diff --git a/examples/jetty-11/src/main/webapp/WEB-INF/web.xml b/examples/jetty-11/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index d86c711d..00000000
--- a/examples/jetty-11/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- getting started
- GettingStartedServlet
-
-
-
- getting started
- /*
-
-
-
diff --git a/examples/jetty-11/src/test/scala/Http.scala b/examples/jetty-11/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/jetty-11/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/jetty-11/src/test/scala/TestSuite.scala b/examples/jetty-11/src/test/scala/TestSuite.scala
deleted file mode 100644
index 12a38709..00000000
--- a/examples/jetty-11/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import org.scalatest.funsuite.AnyFunSuite
-import org.scalatest.matchers.should.Matchers
-
-class TestSuite extends AnyFunSuite with Matchers {
-
- test("/") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |
- | Hello, world!
- |
- |""".stripMargin
- )
- }
-}
diff --git a/examples/lift/README.md b/examples/lift/README.md
deleted file mode 100644
index d37ecf57..00000000
--- a/examples/lift/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] Run completed in 1 second, 81 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 5 s, completed Nov 13, 2022 2:05:08 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/lift/build.sbt b/examples/lift/build.sbt
deleted file mode 100644
index cfe7b9e5..00000000
--- a/examples/lift/build.sbt
+++ /dev/null
@@ -1,5 +0,0 @@
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "net.liftweb" %% "lift-webkit" % "3.5.0"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(JettyPlugin)
diff --git a/examples/lift/project/build.properties b/examples/lift/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/lift/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/lift/project/plugins.sbt b/examples/lift/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/lift/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/lift/src/main/scala/Boot.scala b/examples/lift/src/main/scala/Boot.scala
deleted file mode 100644
index 6741684f..00000000
--- a/examples/lift/src/main/scala/Boot.scala
+++ /dev/null
@@ -1,25 +0,0 @@
-package bootstrap.liftweb
-
-import net.liftweb.http.Html5Properties
-import net.liftweb.http.LiftRules
-import net.liftweb.http.Req
-import net.liftweb.sitemap.Menu
-import net.liftweb.sitemap.SiteMap
-
-class Boot {
-
- def boot {
-
- LiftRules.addToPackages("code")
-
- def sitemap(): SiteMap = SiteMap(
- Menu.i("Home") / "index"
- )
-
- LiftRules.htmlProperties.default.set((r: Req) =>
- new Html5Properties(r.userAgent)
- )
-
- }
-
-}
diff --git a/examples/lift/src/main/scala/code/snippet/HelloWorld.scala b/examples/lift/src/main/scala/code/snippet/HelloWorld.scala
deleted file mode 100644
index 6b17e5a2..00000000
--- a/examples/lift/src/main/scala/code/snippet/HelloWorld.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-package code.snippet
-
-import java.util.Date
-import net.liftweb.util.Helpers._
-
-class HelloWorld {
-
- def render = "* *" #> "Hello, world!"
-
-}
diff --git a/examples/lift/src/main/webapp/WEB-INF/web.xml b/examples/lift/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 9d587e9b..00000000
--- a/examples/lift/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- LiftFilter
- net.liftweb.http.LiftFilter
-
-
-
- LiftFilter
- /*
-
-
-
diff --git a/examples/lift/src/main/webapp/index.html b/examples/lift/src/main/webapp/index.html
deleted file mode 100644
index 6bd9ca35..00000000
--- a/examples/lift/src/main/webapp/index.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
- Lift
-
-
-
-
-
diff --git a/examples/lift/src/test/scala/Http.scala b/examples/lift/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/lift/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/lift/src/test/scala/TestSuite.scala b/examples/lift/src/test/scala/TestSuite.scala
deleted file mode 100644
index a5fbaf30..00000000
--- a/examples/lift/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,14 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("/") {
- val response =
- Request("GET", "http://localhost:8080/", Map.empty, None)
- response.status shouldBe 200
- response.headers.get("Content-Type") shouldBe Some(
- "text/html;charset=utf-8"
- )
- response.body.contains("Hello, world!") shouldBe true
- }
-}
diff --git a/examples/mustache/README.md b/examples/mustache/README.md
deleted file mode 100644
index a41a8ff8..00000000
--- a/examples/mustache/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] Run completed in 833 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 4 s, completed Nov 13, 2022 2:07:19 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/mustache/build.sbt b/examples/mustache/build.sbt
deleted file mode 100644
index bf26d026..00000000
--- a/examples/mustache/build.sbt
+++ /dev/null
@@ -1,8 +0,0 @@
-libraryDependencies += "com.github.spullara.mustache.java" % "scala-extensions-2.12" % "0.9.14"
-libraryDependencies += "com.github.spullara.mustache.java" % "compiler" % "0.9.14"
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(JettyPlugin)
-
-webappWebInfClasses := true
diff --git a/examples/mustache/project/build.properties b/examples/mustache/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/mustache/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/mustache/project/plugins.sbt b/examples/mustache/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/mustache/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/mustache/src/main/resources/greeting.mustache b/examples/mustache/src/main/resources/greeting.mustache
deleted file mode 100644
index c4507110..00000000
--- a/examples/mustache/src/main/resources/greeting.mustache
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
- {{ greeting }}
-
-
diff --git a/examples/mustache/src/main/scala/GettingStartedServlet.scala b/examples/mustache/src/main/scala/GettingStartedServlet.scala
deleted file mode 100644
index 4ec08494..00000000
--- a/examples/mustache/src/main/scala/GettingStartedServlet.scala
+++ /dev/null
@@ -1,46 +0,0 @@
-import com.github.mustachejava.DefaultMustacheFactory
-import com.twitter.mustache.ScalaObjectHandler
-import java.io.File
-import java.io.PrintWriter
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-object `package` {
-
- val mf = new DefaultMustacheFactory()
- mf.setObjectHandler(new ScalaObjectHandler)
-
- implicit class MustacheResonse(res: HttpServletResponse) {
-
- def render(templateName: String, model: Any): Unit = {
-
- val path: String =
- getClass.getClassLoader
- .getResource("greeting.mustache")
- .getFile
-
- val mustache = mf.compile(path)
-
- mustache.execute(res.getWriter, model)
- }
-
- }
-
-}
-
-class MustacheServlet extends HttpServlet {
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ) {
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- res.render("greeting.mustache", Map("greeting" -> "Hello, world"))
-
- }
-
-}
diff --git a/examples/mustache/src/main/webapp/WEB-INF/web.xml b/examples/mustache/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 6905e8b3..00000000
--- a/examples/mustache/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- mustache
- MustacheServlet
-
-
-
- mustache
- /*
-
-
-
diff --git a/examples/mustache/src/test/scala/Http.scala b/examples/mustache/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/mustache/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/mustache/src/test/scala/TestSuite.scala b/examples/mustache/src/test/scala/TestSuite.scala
deleted file mode 100644
index faa1c654..00000000
--- a/examples/mustache/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("/") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- status = 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- """|
- |
- | Hello, world
- |
- |
- |""".stripMargin
- )
- }
-}
diff --git a/examples/payara-micro/README.md b/examples/payara-micro/README.md
deleted file mode 100644
index 772afc51..00000000
--- a/examples/payara-micro/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Container/test
-[info] starting server ...
-[info] TestSuite:
-[info] - hello
-[info] Run completed in 8 seconds, 359 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 14 s, completed Nov 13, 2022 2:11:15 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/payara-micro/build.sbt b/examples/payara-micro/build.sbt
deleted file mode 100644
index f94a44bb..00000000
--- a/examples/payara-micro/build.sbt
+++ /dev/null
@@ -1,23 +0,0 @@
-enablePlugins(ContainerPlugin)
-
-libraryDependencies += "jakarta.platform" % "jakarta.jakartaee-api" % "10.0.0" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-Container / javaOptions ++=
- Seq(
- "--add-opens",
- "java.base/jdk.internal.loader=ALL-UNNAMED"
- )
-
-Container / containerLibs :=
- Seq("fish.payara.extras" % "payara-micro" % "6.2024.9")
-
-Container / containerLaunchCmd := { (port, path) =>
- Seq(
- "fish.payara.micro.PayaraMicro",
- "--deploy",
- path,
- "--contextroot",
- "/mycontext"
- )
-}
diff --git a/examples/payara-micro/project/build.properties b/examples/payara-micro/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/payara-micro/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/payara-micro/project/plugins.sbt b/examples/payara-micro/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/payara-micro/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/payara-micro/src/main/scala/local/test/Main.scala b/examples/payara-micro/src/main/scala/local/test/Main.scala
deleted file mode 100644
index 7fc1c31b..00000000
--- a/examples/payara-micro/src/main/scala/local/test/Main.scala
+++ /dev/null
@@ -1,7 +0,0 @@
-package local.test
-
-import jakarta.ws.rs.ApplicationPath
-import jakarta.ws.rs.core.Application
-
-@ApplicationPath("myapp")
-class Main extends Application {}
diff --git a/examples/payara-micro/src/main/scala/local/test/endpoint/Hello.scala b/examples/payara-micro/src/main/scala/local/test/endpoint/Hello.scala
deleted file mode 100644
index 625ac0a5..00000000
--- a/examples/payara-micro/src/main/scala/local/test/endpoint/Hello.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-package local.test.endpoint
-
-import jakarta.ws.rs.GET
-import jakarta.ws.rs.Path
-import jakarta.ws.rs.Produces
-import jakarta.ws.rs.QueryParam
-import jakarta.ws.rs.core.MediaType
-import jakarta.ws.rs.core.Response
-
-@Path("hello")
-class Hello {
-
- @GET
- @Produces(Array(MediaType.TEXT_PLAIN))
- def getMessage(@QueryParam("name") name: String): Response = {
- val greeting = if (name == null || name.isEmpty) "Nobody" else name
- Response.ok("Hallo " + greeting + "\n").build
- }
-}
diff --git a/examples/payara-micro/src/test/scala/Http.scala b/examples/payara-micro/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/payara-micro/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/payara-micro/src/test/scala/TestSuite.scala b/examples/payara-micro/src/test/scala/TestSuite.scala
deleted file mode 100644
index 401f880f..00000000
--- a/examples/payara-micro/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,37 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with BeforeAndAfterAll with Matchers {
-
- def waitForServer(retries: Int = 30): Unit =
- Request(
- "GET",
- "http://localhost:8080/mycontext/myapp/hello",
- Map.empty,
- None
- ).status match {
- case 404 if retries > 0 =>
- Thread.sleep(1000); waitForServer(retries - 1)
- case _ => ()
- }
-
- override def beforeAll(): Unit = {
- waitForServer()
- }
-
- test("hello") {
- Request(
- "GET",
- "http://localhost:8080/mycontext/myapp/hello?name=James",
- Map.empty,
- None
- ) shouldBe
- Response(
- status = 200,
- Map(
- "X-Frame-Options" -> "SAMEORIGIN",
- "Content-Type" -> "text/plain"
- ),
- "Hallo James\n"
- )
- }
-}
diff --git a/examples/sbt-0.x/build.sbt b/examples/sbt-0.x/build.sbt
deleted file mode 100644
index 09d9ec84..00000000
--- a/examples/sbt-0.x/build.sbt
+++ /dev/null
@@ -1,7 +0,0 @@
-scalaVersion := "2.10.2"
-
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
-
-libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
-
-enablePlugins(JettyPlugin)
diff --git a/examples/sbt-0.x/project/build.properties b/examples/sbt-0.x/project/build.properties
deleted file mode 100644
index 64abd373..00000000
--- a/examples/sbt-0.x/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=0.13.6
diff --git a/examples/sbt-0.x/project/plugins.sbt b/examples/sbt-0.x/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/sbt-0.x/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/sbt-0.x/src/main/scala/GettingStartedServlet.scala b/examples/sbt-0.x/src/main/scala/GettingStartedServlet.scala
deleted file mode 100644
index 11416193..00000000
--- a/examples/sbt-0.x/src/main/scala/GettingStartedServlet.scala
+++ /dev/null
@@ -1,23 +0,0 @@
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-class GettingStartedServlet extends HttpServlet {
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ): Unit = {
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- val responseBody: String =
- """|
- |
- | Hello, world!
- |
- |""".stripMargin
- res.getWriter.write(responseBody)
- }
-}
diff --git a/examples/sbt-0.x/src/main/webapp/WEB-INF/web.xml b/examples/sbt-0.x/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index d86c711d..00000000
--- a/examples/sbt-0.x/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- getting started
- GettingStartedServlet
-
-
-
- getting started
- /*
-
-
-
diff --git a/examples/sbt-0.x/src/test/scala/Http.scala b/examples/sbt-0.x/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/sbt-0.x/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/sbt-0.x/src/test/scala/TestSuite.scala b/examples/sbt-0.x/src/test/scala/TestSuite.scala
deleted file mode 100644
index bf724ac6..00000000
--- a/examples/sbt-0.x/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-class TestSuite {
-
- @Test
- def getRoot(): Unit = {
- assertEquals(
- Response(
- 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |
- | Hello, world!
- |
- |""".stripMargin
- ),
- Request("GET", "http://localhost:8080/", Map.empty, None)
- )
- }
-}
diff --git a/examples/sbt-1.x/build.sbt b/examples/sbt-1.x/build.sbt
deleted file mode 100644
index a2adb4ba..00000000
--- a/examples/sbt-1.x/build.sbt
+++ /dev/null
@@ -1,6 +0,0 @@
-scalaVersion := "3.4.2"
-
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
-libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test"
-
-enablePlugins(JettyPlugin)
diff --git a/examples/sbt-1.x/project/build.properties b/examples/sbt-1.x/project/build.properties
deleted file mode 100644
index ee4c672c..00000000
--- a/examples/sbt-1.x/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.10.1
diff --git a/examples/sbt-1.x/project/plugins.sbt b/examples/sbt-1.x/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/sbt-1.x/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/sbt-1.x/src/main/scala/GettingStartedServlet.scala b/examples/sbt-1.x/src/main/scala/GettingStartedServlet.scala
deleted file mode 100644
index 21bf4647..00000000
--- a/examples/sbt-1.x/src/main/scala/GettingStartedServlet.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-import javax.servlet.http.HttpServlet
-import javax.servlet.http.HttpServletRequest
-import javax.servlet.http.HttpServletResponse
-
-class GettingStartedServlet extends HttpServlet:
-
- override def doGet(
- req: HttpServletRequest,
- res: HttpServletResponse
- ): Unit =
-
- res.setContentType("text/html")
- res.setCharacterEncoding("UTF-8")
-
- val responseBody: String =
- """|
- |
- | Hello, world!
- |
- |""".stripMargin
- res.getWriter.write(responseBody)
diff --git a/examples/sbt-1.x/src/main/webapp/WEB-INF/web.xml b/examples/sbt-1.x/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index d86c711d..00000000
--- a/examples/sbt-1.x/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- getting started
- GettingStartedServlet
-
-
-
- getting started
- /*
-
-
-
diff --git a/examples/sbt-1.x/src/test/scala/Http.scala b/examples/sbt-1.x/src/test/scala/Http.scala
deleted file mode 100644
index 5ab1d57c..00000000
--- a/examples/sbt-1.x/src/test/scala/Http.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request:
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response =
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
diff --git a/examples/sbt-1.x/src/test/scala/TestSuite.scala b/examples/sbt-1.x/src/test/scala/TestSuite.scala
deleted file mode 100644
index 155133fd..00000000
--- a/examples/sbt-1.x/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,19 +0,0 @@
-import org.junit.Assert.assertEquals
-import org.junit.Test
-
-class TestSuite:
-
- @Test
- def getRoot(): Unit =
- assertEquals(
- Response(
- 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |
- | Hello, world!
- |
- |""".stripMargin
- ),
- Request("GET", "http://localhost:8080/", Map.empty, None)
- )
diff --git a/examples/scala-js/README.md b/examples/scala-js/README.md
deleted file mode 100644
index 9c39efc8..00000000
--- a/examples/scala-js/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-## Testing
-
-```
-$ sbt fastOptJS Jetty/test
-[info] starting server ...
-[success] Total time: 2 s, completed Nov 13, 2022 2:16:42 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/scala-js/build.sbt b/examples/scala-js/build.sbt
deleted file mode 100644
index f78dcb20..00000000
--- a/examples/scala-js/build.sbt
+++ /dev/null
@@ -1,8 +0,0 @@
-name := "scala-js"
-
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
-
-enablePlugins(JettyPlugin)
-enablePlugins(ScalaJSPlugin)
-
-scalaJSUseMainModuleInitializer := true
diff --git a/examples/scala-js/project/build.properties b/examples/scala-js/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/scala-js/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/scala-js/project/plugins.sbt b/examples/scala-js/project/plugins.sbt
deleted file mode 100644
index d2cb566c..00000000
--- a/examples/scala-js/project/plugins.sbt
+++ /dev/null
@@ -1,2 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
-addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.16.0")
diff --git a/examples/scala-js/scala-js.sbt b/examples/scala-js/scala-js.sbt
deleted file mode 100644
index a7fe9679..00000000
--- a/examples/scala-js/scala-js.sbt
+++ /dev/null
@@ -1,13 +0,0 @@
-enablePlugins(ScalaJSPlugin)
-
-libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.8.0"
-
-// Send generated JS to the XWP webapp dir
-crossTarget in fastOptJS := (target in webappPrepare).value
-crossTarget in fullOptJS := (target in webappPrepare).value
-
-// Don't append -fastopt/-fullopt to the generated .js filename
-artifactPath in (Compile, fastOptJS) :=
- ((crossTarget in fastOptJS).value / ((moduleName in fastOptJS).value + ".js"))
-artifactPath in (Compile, fullOptJS) :=
- ((crossTarget in fullOptJS).value / ((moduleName in fullOptJS).value + ".js"))
diff --git a/examples/scala-js/src/main/scala/HelloWorld.scala b/examples/scala-js/src/main/scala/HelloWorld.scala
deleted file mode 100644
index 0b07d599..00000000
--- a/examples/scala-js/src/main/scala/HelloWorld.scala
+++ /dev/null
@@ -1,17 +0,0 @@
-import org.scalajs.dom
-import dom.document
-
-object HelloWorld {
-
- def appendPar(targetNode: dom.Node, text: String): Unit = {
- val parNode = document.createElement("p")
- val textNode = document.createTextNode(text)
- parNode.appendChild(textNode)
- targetNode.appendChild(parNode)
- }
-
- def main(args: Array[String]): Unit = {
- appendPar(document.body, "Hello, world!")
- }
-
-}
diff --git a/examples/scala-js/src/main/webapp/WEB-INF/web.xml b/examples/scala-js/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 60b95d4c..00000000
--- a/examples/scala-js/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/examples/scala-js/src/main/webapp/index.html b/examples/scala-js/src/main/webapp/index.html
deleted file mode 100644
index 73628d6e..00000000
--- a/examples/scala-js/src/main/webapp/index.html
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
- Scala.js
-
-
-
-
-
diff --git a/examples/scalatra/README.md b/examples/scalatra/README.md
deleted file mode 100644
index 17d9c4f9..00000000
--- a/examples/scalatra/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-## Testing
-
-```
-$ sbt test
-[info] HelloWorldServletSuite:
-[info] - get /
-[info] Run completed in 2 seconds, 5 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 3 s, completed Nov 13, 2022 2:18:13 PM
-```
diff --git a/examples/scalatra/build.sbt b/examples/scalatra/build.sbt
deleted file mode 100644
index 1a56e98a..00000000
--- a/examples/scalatra/build.sbt
+++ /dev/null
@@ -1,7 +0,0 @@
-libraryDependencies += "org.scalatra" %% "scalatra" % "2.8.4"
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
-
-enablePlugins(JettyPlugin)
-
-Test / fork := true
diff --git a/examples/scalatra/project/build.properties b/examples/scalatra/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/scalatra/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/scalatra/project/plugins.sbt b/examples/scalatra/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/scalatra/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/scalatra/src/main/scala/HelloWorldServlet.scala b/examples/scalatra/src/main/scala/HelloWorldServlet.scala
deleted file mode 100644
index e194c0b4..00000000
--- a/examples/scalatra/src/main/scala/HelloWorldServlet.scala
+++ /dev/null
@@ -1,16 +0,0 @@
-import org.scalatra.ScalatraServlet
-
-class HelloWorldServlet extends ScalatraServlet {
-
- get("/") {
-
- contentType = "text/html; charset=utf-8"
-
- """
- |
- | Hello, world!
- |
- |""".stripMargin
- }
-
-}
diff --git a/examples/scalatra/src/main/webapp/WEB-INF/web.xml b/examples/scalatra/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 1dcb5a67..00000000
--- a/examples/scalatra/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- hello world
- HelloWorldServlet
-
-
-
- hello world
- /*
-
-
-
diff --git a/examples/scalatra/src/test/scala/Http.scala b/examples/scalatra/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/scalatra/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/scalatra/src/test/scala/TestSuite.scala b/examples/scalatra/src/test/scala/TestSuite.scala
deleted file mode 100644
index 12a38709..00000000
--- a/examples/scalatra/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-import org.scalatest.funsuite.AnyFunSuite
-import org.scalatest.matchers.should.Matchers
-
-class TestSuite extends AnyFunSuite with Matchers {
-
- test("/") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- 200,
- Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |
- | Hello, world!
- |
- |""".stripMargin
- )
- }
-}
diff --git a/examples/spray/README.md b/examples/spray/README.md
deleted file mode 100644
index e637cccc..00000000
--- a/examples/spray/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-[info] starting server ...
-[info] TestSuite:
-[info] - /
-[info] Run completed in 851 milliseconds.
-[info] Total number of tests run: 1
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 5 s, completed Nov 13, 2022 2:19:47 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/spray/build.sbt b/examples/spray/build.sbt
deleted file mode 100644
index a6d726ab..00000000
--- a/examples/spray/build.sbt
+++ /dev/null
@@ -1,8 +0,0 @@
-scalaVersion := "2.11.12" // spray only goes up to 2.11
-
-libraryDependencies += "io.spray" %% "spray-servlet" % "1.3.4"
-libraryDependencies += "com.typesafe.akka" %% "akka-actor" % "2.5.31"
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(JettyPlugin)
diff --git a/examples/spray/project/build.properties b/examples/spray/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/spray/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/spray/project/plugins.sbt b/examples/spray/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/spray/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/spray/src/main/resources/application.conf b/examples/spray/src/main/resources/application.conf
deleted file mode 100644
index 36cd707a..00000000
--- a/examples/spray/src/main/resources/application.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-spray.servlet {
- boot-class = "Boot"
- request-timeout = 6s
-}
diff --git a/examples/spray/src/main/scala/Boot.scala b/examples/spray/src/main/scala/Boot.scala
deleted file mode 100644
index 552c329c..00000000
--- a/examples/spray/src/main/scala/Boot.scala
+++ /dev/null
@@ -1,10 +0,0 @@
-import akka.actor.ActorSystem
-import akka.actor.Props
-import spray.servlet.WebBoot
-
-class Boot extends WebBoot {
-
- val system = ActorSystem("example")
- val serviceActor = system.actorOf(Props[HelloWorldService])
-
-}
diff --git a/examples/spray/src/main/scala/DemoService.scala b/examples/spray/src/main/scala/DemoService.scala
deleted file mode 100644
index b8d4dbb7..00000000
--- a/examples/spray/src/main/scala/DemoService.scala
+++ /dev/null
@@ -1,11 +0,0 @@
-import akka.actor._
-import spray.http._
-import spray.http.HttpMethods._
-
-class HelloWorldService extends Actor with ActorLogging {
-
- def receive = { case HttpRequest(GET, Uri.Path("/"), _, _, _) =>
- sender ! HttpResponse(entity = "Hello, world!")
- }
-
-}
diff --git a/examples/spray/src/main/webapp/WEB-INF/web.xml b/examples/spray/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index e71aa85e..00000000
--- a/examples/spray/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
- spray.servlet.Initializer
-
-
-
- SprayConnectorServlet
- spray.servlet.Servlet30ConnectorServlet
- true
-
-
-
- SprayConnectorServlet
- /*
-
-
-
diff --git a/examples/spray/src/test/scala/Http.scala b/examples/spray/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/spray/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/spray/src/test/scala/TestSuite.scala b/examples/spray/src/test/scala/TestSuite.scala
deleted file mode 100644
index ac4050fc..00000000
--- a/examples/spray/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,13 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("/") {
- Request("GET", "http://localhost:8080/", Map.empty, None) shouldBe
- Response(
- status = 200,
- Map("Content-Type" -> "text/plain;charset=utf-8"),
- "Hello, world!"
- )
- }
-}
diff --git a/examples/zio/README.md b/examples/zio/README.md
deleted file mode 100644
index f6c38c84..00000000
--- a/examples/zio/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Testing
-
-```
-$ sbt Jetty/test
-i[info] starting server ...
-[info] TestSuite:
-[info] - no messages yet
-[info] - add a message
-[info] - retrieve the message
-[info] Run completed in 1 second, 714 milliseconds.
-[info] Total number of tests run: 3
-[info] Suites: completed 1, aborted 0
-[info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
-[info] All tests passed.
-[success] Total time: 5 s, completed Nov 13, 2022 2:21:33 PM
-[info] waiting for server to shut down...
-```
diff --git a/examples/zio/build.sbt b/examples/zio/build.sbt
deleted file mode 100644
index 231ae093..00000000
--- a/examples/zio/build.sbt
+++ /dev/null
@@ -1,17 +0,0 @@
-libraryDependencies += "dev.zio" %% "zio" % "2.1.9"
-libraryDependencies += "javax.servlet" % "javax.servlet-api" % "4.0.1" % "provided"
-libraryDependencies += "com.h2database" % "h2" % "2.3.232"
-libraryDependencies += "com.jolbox" % "bonecp" % "0.8.0.RELEASE"
-libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.9" % "test"
-
-enablePlugins(JettyPlugin)
-
-containerForkOptions :=
- ForkOptions().withEnvVars {
- Map(
- "DB_DRIVER" -> "org.h2.Driver",
- "DB_URL" -> "jdbc:h2:mem:zio",
- "DB_USER" -> "sa",
- "DB_PASS" -> ""
- )
- }
diff --git a/examples/zio/project/build.properties b/examples/zio/project/build.properties
deleted file mode 100644
index c8fcab54..00000000
--- a/examples/zio/project/build.properties
+++ /dev/null
@@ -1 +0,0 @@
-sbt.version=1.6.2
diff --git a/examples/zio/project/plugins.sbt b/examples/zio/project/plugins.sbt
deleted file mode 100644
index 7d370e84..00000000
--- a/examples/zio/project/plugins.sbt
+++ /dev/null
@@ -1 +0,0 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "4.2.5")
diff --git a/examples/zio/src/main/scala/Database.scala b/examples/zio/src/main/scala/Database.scala
deleted file mode 100644
index 002ad5af..00000000
--- a/examples/zio/src/main/scala/Database.scala
+++ /dev/null
@@ -1,67 +0,0 @@
-object Database {
-
- import com.jolbox.bonecp.BoneCP
- import com.jolbox.bonecp.BoneCPConfig
- import zio.ZIO
-
- val connectionPool: BoneCP = {
-
- Class.forName(sys.env("DB_DRIVER"))
- val config = new BoneCPConfig()
- config.setJdbcUrl(sys.env("DB_URL"))
- config.setUsername(sys.env("DB_USER"))
- config.setPassword(sys.env("DB_PASS"))
- config.setMinConnectionsPerPartition(5)
- config.setMaxConnectionsPerPartition(10)
- config.setPartitionCount(1)
- new BoneCP(config)
- }
-
- def init: ZIO[JdbcIO, Throwable, Unit] =
- JdbcIO.effect { c =>
- val stmt = c.createStatement()
- stmt.executeUpdate {
- """|create table if not exists
- | guestbook ( id int not null auto_increment
- | , name varchar(255) not null
- | , message text not null
- | , primary key (id)
- | )
- |""".stripMargin
- }
- stmt.close()
- }
-
- def addEntry(
- name: String,
- message: String
- ): ZIO[JdbcIO, Throwable, Unit] =
- JdbcIO.effect { c =>
- val s = "insert into guestbook (name, message) values (?, ?)"
- val stmt = c.prepareStatement(s)
- stmt.setString(1, name)
- stmt.setString(2, message)
- stmt.executeUpdate
- stmt.close
- }
-
- val getEntries: ZIO[JdbcIO, Throwable, List[(String, String)]] =
- JdbcIO.effect { c =>
- val q = "select name, message from guestbook order by id asc"
- val stmt = c.createStatement
- val rs = stmt.executeQuery(q)
-
- def _entries(
- acc: List[(String, String)]
- ): List[(String, String)] =
- if (rs.next()) {
- val entry = (rs.getString("name"), rs.getString("message"))
- _entries(entry :: acc)
- } else {
- stmt.close
- acc
- }
-
- _entries(Nil)
- }
-}
diff --git a/examples/zio/src/main/scala/HttpClientIO.scala b/examples/zio/src/main/scala/HttpClientIO.scala
deleted file mode 100644
index 273118f1..00000000
--- a/examples/zio/src/main/scala/HttpClientIO.scala
+++ /dev/null
@@ -1,99 +0,0 @@
-object HttpClient {
-
- import java.net.HttpURLConnection
- import java.net.URL
- import scala.collection.JavaConverters._
- import scala.io.Source
- import zio.Task
- import zio.ZIO
-
- case class Request(
- method: String,
- url: URL,
- headers: Map[String, String],
- body: Option[String]
- )
-
- case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
- )
-
- def request(r: Request): Task[Response] =
- ZIO.attempt {
-
- val c = r.url.openConnection().asInstanceOf[HttpURLConnection]
-
- c.setRequestMethod(r.method)
- c.setInstanceFollowRedirects(false)
-
- c.setDoInput(true)
- c.setDoOutput(r.body.isDefined)
-
- r.headers foreach { case (k, v) => c.setRequestProperty(k, v) }
-
- r.body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val responseStatus = c.getResponseCode
-
- val responseHeaders =
- c.getHeaderFields.asScala.toMap map { case (k, v) =>
- (k, v.asScala.mkString(","))
- }
-
- val responseStream =
- if (responseStatus < 400) c.getInputStream
- else c.getErrorStream
-
- val responseBody =
- if (responseStream != null) {
- Source.fromInputStream(responseStream).mkString
- } else {
- ""
- }
-
- c.disconnect()
-
- Response(
- status = responseStatus,
- headers = responseHeaders,
- body = responseBody
- )
- }
-
- def post(
- url: URL,
- headers: Map[String, String] = Map.empty,
- body: Option[String] = None
- ): Task[Response] =
- request(Request("POST", url, headers, body))
-
- def get(
- url: URL,
- headers: Map[String, String] = Map.empty
- ): Task[Response] =
- request(Request("GET", url, headers, None))
-
- def put(
- url: URL,
- headers: Map[String, String] = Map.empty,
- body: Option[String] = None
- ): Task[Response] =
- request(Request("PUT", url, headers, body))
-
- def delete(
- url: URL,
- headers: Map[String, String] = Map.empty
- ): Task[Response] =
- request(Request("DELETE", url, headers, None))
-
- def head(url: URL, headers: Map[String, String]): Task[Response] =
- request(Request("HEAD", url, headers, None))
-
- def options(url: URL, headers: Map[String, String]): Task[Response] =
- request(Request("OPTIONS", url, headers, None))
-
-}
diff --git a/examples/zio/src/main/scala/JdbcIO.scala b/examples/zio/src/main/scala/JdbcIO.scala
deleted file mode 100644
index 72decbc3..00000000
--- a/examples/zio/src/main/scala/JdbcIO.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-import java.sql.Connection
-
-trait JdbcIO {
- def connection: Connection
-}
-
-object JdbcIO {
-
- import java.sql.SQLException
- import zio.ZEnvironment
- import zio.ZIO
-
- def effect[A](k: Connection => A): ZIO[JdbcIO, Throwable, A] =
- ZIO.environmentWithZIO(env => ZIO.attempt(k(env.get.connection)))
-
- def transact[R <: JdbcIO, A](
- k: ZIO[R, Throwable, A]
- ): ZIO[R, Throwable, A] =
- ZIO
- .environmentWith({ env: ZEnvironment[JdbcIO] =>
- env.get.connection.setAutoCommit(false)
- env
- })
- .flatMap { env =>
- k.map({ a =>
- env.get.connection.commit()
- env.get.connection.close()
- a
- }).catchSome({ case x: SQLException =>
- env.get.connection.rollback()
- env.get.connection.close()
- ZIO.fail(x)
- })
- }
-}
diff --git a/examples/zio/src/main/scala/ServletIO.scala b/examples/zio/src/main/scala/ServletIO.scala
deleted file mode 100644
index f861d19e..00000000
--- a/examples/zio/src/main/scala/ServletIO.scala
+++ /dev/null
@@ -1,395 +0,0 @@
-object Request {
-
- import javax.servlet.ServletRequest
- import javax.servlet.ServletRequest
- import javax.servlet.ServletResponse
- import javax.servlet.http.HttpServletRequest
- import javax.servlet.http.HttpUpgradeHandler
- import scala.collection.JavaConverters._
- import zio.ZEnvironment
- import zio.ZIO
-
- def effect[A](
- k: HttpServletRequest => A
- ): ZIO[WithRequest, Throwable, A] =
- ZIO.environmentWithZIO(e => ZIO.attempt(k(e.get.request)))
-
- def effectO[A](
- k: HttpServletRequest => A
- ): ZIO[WithRequest, Throwable, Option[A]] =
- ZIO.environmentWithZIO(e => ZIO.attempt(Option(k(e.get.request))))
-
- def route[A, R <: WithRequest](
- k: PartialFunction[List[String], ZIO[R, Throwable, A]]
- ): ZIO[R, Throwable, A] =
- for {
- method <- getMethod
- context <- getServletPath
- uri <- getRequestURI
- a <- k(
- method :: uri
- .substring(context.length)
- .split("/")
- .drop(1)
- .toList
- )
- } yield a
-
- val headers: ZIO[WithRequest, Throwable, Map[String, List[String]]] =
- getHeaderNames() flatMap { namesO =>
- ZIO.collectAll {
- namesO
- .map(_.asScala.toList)
- .getOrElse(Nil)
- .map({ name =>
- getHeaders(name) map { valuesO =>
- (
- name,
- valuesO
- .map(_.asScala.toList)
- .getOrElse(Nil)
- )
- }
- })
- } map {
- _.toMap
- }
- }
-
- // ServletRequest methods:
-
- def getAsyncContext() =
- effect(_.getAsyncContext())
-
- def getAttribute(name: String) =
- effectO(_.getAttribute(name))
-
- def getAttributeNames() =
- effect(_.getAttributeNames())
-
- def getCharacterEncoding() =
- effectO(_.getCharacterEncoding())
-
- def getContentLength() =
- effect(_.getContentLength())
-
- def getContentLengthLong() =
- effect(_.getContentLengthLong())
-
- def getContentType() =
- effectO(_.getContentType())
-
- def getDispatcherType() =
- effect(_.getDispatcherType())
-
- def getInputStream() =
- effect(_.getInputStream())
-
- def getLocalAddr() =
- effect(_.getLocalAddr())
-
- def getLocalName() =
- effect(_.getLocalName())
-
- def getLocalPort() =
- effect(_.getLocalPort())
-
- def getLocale() =
- effect(_.getLocale())
-
- def getLocales() =
- effect(_.getLocales())
-
- def getParameter(name: String) =
- effectO(_.getParameter(name))
-
- def getParameterMap() =
- effect(_.getParameterMap())
-
- def getParameterNames() =
- effect(_.getParameterNames())
-
- def getParameterValues(name: String) =
- effectO(_.getParameterValues(name))
-
- def getProtocol() =
- effect(_.getProtocol())
-
- def getReader() =
- effect(_.getReader())
-
- def getRemoteAddr() =
- effect(_.getRemoteAddr())
-
- def getRemoteHost() =
- effect(_.getRemoteHost())
-
- def getRemotePort() =
- effect(_.getRemotePort())
-
- def getRequestDispatcher(path: String) =
- effectO(_.getRequestDispatcher(path))
-
- def getScheme() =
- effect(_.getScheme())
-
- def getServerName() =
- effect(_.getServerName())
-
- def getServerPort() =
- effect(_.getServerPort())
-
- def getServletContext() =
- effect(_.getServletContext())
-
- def isAsyncStarted() =
- effect(_.isAsyncStarted())
-
- def isAsyncSupported() =
- effect(_.isAsyncSupported())
-
- def isSecure() =
- effect(_.isSecure())
-
- def removeAttribute(name: String) =
- effect(_.removeAttribute(name))
-
- def setAttribute(name: String, o: Object) =
- effect(_.setAttribute(name, o))
-
- def setCharacterEncoding(env: String) =
- effect(_.setCharacterEncoding(env))
-
- def startAsync() =
- effect(_.startAsync())
-
- def startAsync(
- servletRequest: ServletRequest,
- servletResponse: ServletResponse
- ) =
- effect(_.startAsync(servletRequest, servletResponse))
-
- // HttpServletRequest methods:
-
- def authenticate
- : ZIO[WithRequest with WithResponse, Throwable, Boolean] =
- ZIO.environmentWithZIO { req: ZEnvironment[WithRequest] =>
- ZIO.environmentWithZIO { res: ZEnvironment[WithResponse] =>
- ZIO.attempt(req.get.request.authenticate(res.get.response))
- }
- }
-
- def changeSessionId() =
- effect(_.changeSessionId())
-
- def getAuthType() =
- effectO(_.getAuthType())
-
- def getContextPath() =
- effect(_.getContextPath())
-
- def getCookies() =
- effectO(_.getCookies())
-
- def getDateHeader(name: String) =
- effect(_.getDateHeader(name))
-
- def getHeader(name: String) =
- effectO(_.getHeader(name))
-
- def getHeaderNames() =
- effectO(_.getHeaderNames())
-
- def getHeaders(name: String) =
- effectO(_.getHeaders(name))
-
- def getIntHeader(name: String) =
- effect(_.getIntHeader(name))
-
- def getMethod() =
- effect(_.getMethod())
-
- def getPart(name: String) =
- effectO(_.getPart(name))
-
- def getParts() =
- effect(_.getParts())
-
- def getPathInfo() =
- effectO(_.getPathInfo())
-
- def getPathTranslated() =
- effectO(_.getPathTranslated())
-
- def getQueryString() =
- effectO(_.getQueryString())
-
- def getRemoteUser() =
- effectO(_.getRemoteUser())
-
- def getRequestURI() =
- effect(_.getRequestURI())
-
- def getRequestURL() =
- effect(_.getRequestURL())
-
- def getRequestedSessionId() =
- effectO(_.getRequestedSessionId())
-
- def getServletPath() =
- effect(_.getServletPath())
-
- def getSession() =
- effect(_.getSession())
-
- def getSession(create: Boolean) =
- effectO(_.getSession(create))
-
- def getUserPrincipal() =
- effectO(_.getUserPrincipal())
-
- def isRequestedSessionIdFromCookie() =
- effect(_.isRequestedSessionIdFromCookie())
-
- def isRequestedSessionIdFromURL() =
- effect(_.isRequestedSessionIdFromURL())
-
- def isRequestedSessionIdValid() =
- effect(_.isRequestedSessionIdValid())
-
- def isUserInRole(role: String) =
- effect(_.isUserInRole(role))
-
- def login(username: String, password: String) =
- effect(_.login(username, password))
-
- def logout() =
- effect(_.logout())
-
- def upgrade[T <: HttpUpgradeHandler](handlerClass: Class[T]) =
- effect(_.upgrade(handlerClass))
-}
-
-object Response {
-
- import java.util.Locale
- import javax.servlet.http.Cookie
- import javax.servlet.http.HttpServletResponse
- import zio.ZIO
-
- def effect[A](
- k: HttpServletResponse => A
- ): ZIO[WithResponse, Throwable, A] =
- ZIO.environmentWithZIO(e => ZIO.attempt(k(e.get.response)))
-
- def effectO[A](
- k: HttpServletResponse => A
- ): ZIO[WithResponse, Throwable, Option[A]] =
- ZIO.environmentWithZIO(e => ZIO.attempt(Option(k(e.get.response))))
-
- // ServletResponse methods:
-
- def flushBuffer() =
- effect(_.flushBuffer())
-
- def getBufferSize() =
- effect(_.getBufferSize())
-
- def getCharacterEncoding() =
- effect(_.getCharacterEncoding())
-
- def getContentType() =
- effectO(_.getContentType())
-
- def getLocale() =
- effect(_.getLocale())
-
- def getOutputStream() =
- effect(_.getOutputStream())
-
- def getWriter() =
- effect(_.getWriter())
-
- def isCommitted() =
- effect(_.isCommitted())
-
- def reset() =
- effect(_.reset())
-
- def resetBuffer() =
- effect(_.resetBuffer())
-
- def setBufferSize(size: Int) =
- effect(_.setBufferSize(size))
-
- def setCharacterEncoding(charset: String) =
- effect(_.setCharacterEncoding(charset))
-
- def setContentLength(len: Int) =
- effect(_.setContentLength(len))
-
- def setContentLengthLong(len: Long) =
- effect(_.setContentLengthLong(len))
-
- def setContentType(contentType: String) =
- effect(_.setContentType(contentType))
-
- def setLocale(loc: Locale) =
- effect(_.setLocale(loc))
-
- // HttpServletResponse methods:
-
- def addCookie(cookie: Cookie) =
- effect(_.addCookie(cookie))
-
- def addDateHeader(name: String, date: Long) =
- effect(_.addDateHeader(name, date))
-
- def addHeader(name: String, value: String) =
- effect(_.addHeader(name, value))
-
- def addIntHeader(name: String, value: Int) =
- effect(_.addIntHeader(name, value))
-
- def containsHeader(name: String) =
- effect(_.containsHeader(name))
-
- def encodeRedirectURL(url: String) =
- effect(_.encodeRedirectURL(url))
-
- def encodeURL(url: String) =
- effect(_.encodeURL(url))
-
- def getHeader(name: String) =
- effectO(_.getHeader(name))
-
- def getHeaderNames() =
- effect(_.getHeaderNames())
-
- def getHeaders(name: String) =
- effect(_.getHeaders(name))
-
- def getStatus() =
- effect(_.getStatus())
-
- def sendError(sc: Int) =
- effect(_.sendError(sc))
-
- def sendError(sc: Int, msg: String) =
- effect(_.sendError(sc, msg))
-
- def sendRedirect(location: String) =
- effect(_.sendRedirect(location))
-
- def setDateHeader(name: String, date: Long) =
- effect(_.setDateHeader(name, date))
-
- def setHeader(name: String, value: String) =
- effect(_.setHeader(name, value))
-
- def setIntHeader(name: String, value: Int) =
- effect(_.setIntHeader(name, value))
-
- def setStatus(sc: Int) =
- effect(_.setStatus(sc))
-}
diff --git a/examples/zio/src/main/scala/ZioServlet.scala b/examples/zio/src/main/scala/ZioServlet.scala
deleted file mode 100644
index 838083ff..00000000
--- a/examples/zio/src/main/scala/ZioServlet.scala
+++ /dev/null
@@ -1,109 +0,0 @@
-import javax.servlet.http.HttpServlet
-import zio.ZIO
-
-object Services {
-
- val getMessages: ZIO[
- WithRequest with WithResponse with JdbcIO,
- Throwable,
- Unit
- ] =
- for {
- _ <- Response.setContentType("text/html;charset=UTF-8")
- entries <- Database.getEntries
- writer <- Response.getWriter
- _ = writer.write("\n")
- _ = entries map { case (name, message) =>
- writer.write(s" - ${name}: ${message}
\n")
- }
- _ = writer.write("
\n")
- } yield ()
-
- val addMessage: ZIO[
- WithRequest with WithResponse with JdbcIO,
- Throwable,
- Unit
- ] =
- for {
- nameO <- Request.getParameter("name")
- messageO <- Request.getParameter("message")
- _ <- (nameO, messageO) match {
- case (Some(name), Some(message)) =>
- for {
- _ <- Database.addEntry(name, message)
- _ <- Response.sendRedirect("/")
- } yield ()
- case _ =>
- for {
- _ <- Response.setStatus(400)
- } yield ()
- }
-
- } yield ()
-}
-
-class ZioServlet extends HttpServlet {
-
- import javax.servlet.http.HttpServletRequest
- import javax.servlet.http.HttpServletResponse
- import zio.Runtime
- import zio.Unsafe
- import zio.ZLayer
-
- def unsafeRun[A](
- req: HttpServletRequest,
- res: HttpServletResponse
- )(
- k: ZIO[WithRequest with WithResponse with JdbcIO, Throwable, A]
- ): Either[Throwable, A] = {
-
- val requestEnv = new WithRequest { val request = req }
- val responseEnv = new WithResponse { val response = res }
- val jdbcEnv =
- new JdbcIO {
- Class.forName("org.h2.Driver")
- val connection = Database.connectionPool.getConnection
- }
-
- Unsafe.unsafe { implicit u: Unsafe =>
- Runtime.default.unsafe
- .run(
- JdbcIO
- .transact(k)
- .map(a => Right(a))
- .catchAll { t =>
- ZIO.succeed(Left[Throwable, A](t))
- }
- .provide(
- ZLayer.succeed(requestEnv) ++
- ZLayer.succeed(responseEnv) ++
- ZLayer.succeed(jdbcEnv)
- )
- )
- .getOrThrowFiberFailure()
- }
- }
-
- override def init: Unit = {
- unsafeRun(null, null)(Database.init)
- }
-
- override def service(
- req: HttpServletRequest,
- res: HttpServletResponse
- ): Unit = {
- try {
- unsafeRun(req, res) {
- Request.route {
- case "GET" :: Nil => Services.getMessages
- case "POST" :: Nil => Services.addMessage
- case _ => Response.setStatus(404)
- }
- }
- } catch {
- case t: Throwable =>
- t.printStackTrace
- res.setStatus(500)
- }
- }
-}
diff --git a/examples/zio/src/main/scala/package.scala b/examples/zio/src/main/scala/package.scala
deleted file mode 100644
index 298ea354..00000000
--- a/examples/zio/src/main/scala/package.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-trait WithConnection {
- def connection: java.sql.Connection
-}
-
-trait WithRequest {
- def request: javax.servlet.http.HttpServletRequest
-}
-
-trait WithResponse {
- def response: javax.servlet.http.HttpServletResponse
-}
-
-object `package` {
-
- import zio.ZIO
-
- type DB[A] = ZIO[WithConnection, Throwable, A]
- type Req[A] = ZIO[WithRequest, Throwable, A]
- type Res[A] = ZIO[WithResponse, Throwable, A]
-}
diff --git a/examples/zio/src/main/webapp/WEB-INF/web.xml b/examples/zio/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index cfbb3811..00000000
--- a/examples/zio/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
- ZioServlet
- ZioServlet
- true
-
-
-
- ZioServlet
- /*
-
-
-
diff --git a/examples/zio/src/test/scala/Http.scala b/examples/zio/src/test/scala/Http.scala
deleted file mode 100644
index b922e744..00000000
--- a/examples/zio/src/test/scala/Http.scala
+++ /dev/null
@@ -1,60 +0,0 @@
-import java.net._
-import scala.collection.JavaConverters._
-import scala.io.Source
-
-case class Response(
- status: Int,
- headers: Map[String, String],
- body: String
-)
-
-object Request {
-
- def apply(
- method: String,
- url: String,
- headers: Map[String, String],
- body: Option[String]
- ): Response = {
-
- val c =
- new URL(url)
- .openConnection()
- .asInstanceOf[HttpURLConnection]
-
- c.setInstanceFollowRedirects(false)
- c.setRequestMethod(method)
- c.setDoInput(true)
- c.setDoOutput(body.isDefined)
-
- headers foreach { case (k, v) =>
- c.setRequestProperty(k, v)
- }
-
- body foreach { b =>
- c.getOutputStream.write(b.getBytes("UTF-8"))
- }
-
- val response =
- Response(
- status = c.getResponseCode(),
- headers = c
- .getHeaderFields()
- .asScala
- .filter({ case (k, _) => k != null })
- .map({ case (k, v) => (k, v.asScala.mkString(",")) })
- .toMap - "Date" - "Content-Length" - "Server",
- body = Source.fromInputStream {
- if (c.getResponseCode() < 400) {
- c.getInputStream
- } else {
- c.getErrorStream
- }
- }.mkString
- )
-
- c.disconnect()
-
- response
- }
-}
diff --git a/examples/zio/src/test/scala/TestSuite.scala b/examples/zio/src/test/scala/TestSuite.scala
deleted file mode 100644
index 1f65c5d0..00000000
--- a/examples/zio/src/test/scala/TestSuite.scala
+++ /dev/null
@@ -1,54 +0,0 @@
-import org.scalatest._
-
-class TestSuite extends FunSuite with Matchers {
-
- test("no messages yet") {
- Request(
- method = "GET",
- url = "http://localhost:8080/",
- headers = Map.empty,
- body = None
- ) shouldBe {
- Response(
- status = 200,
- headers = Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |""".stripMargin
- )
- }
- }
-
- test("add a message") {
- Request(
- method = "POST",
- url = "http://localhost:8080/",
- headers = Map.empty,
- body = Some("name=jdoe&message=Howdy!")
- ) shouldBe {
- Response(
- status = 302,
- headers = Map("Location" -> "http://localhost:8080/"),
- body = ""
- )
- }
- }
-
- test("retrieve the message") {
- Request(
- method = "GET",
- url = "http://localhost:8080/",
- headers = Map.empty,
- body = None
- ) shouldBe {
- Response(
- status = 200,
- headers = Map("Content-Type" -> "text/html;charset=utf-8"),
- body = """|
- |""".stripMargin
- )
- }
- }
-}
diff --git a/shell.nix b/shell.nix
index 0d21993c..3d4d62d0 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,6 +1,6 @@
{ pkgs ? import {} }:
let
- jdk = pkgs.jdk8;
+ jdk = pkgs.jdk11;
in
pkgs.mkShell {
nativeBuildInputs = [
diff --git a/src/template/build.sbt b/src/template/build.sbt
index 54b6c084..a1beeb0a 100644
--- a/src/template/build.sbt
+++ b/src/template/build.sbt
@@ -2,7 +2,7 @@ libraryDependencies += "org.typelevel" %% "cats-effect" % "3.5.4"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
libraryDependencies += "com.h2database" % "h2" % "2.2.224"
-libraryDependencies += "jakarta.servlet" % "jakarta.servlet-api" % "6.0.0" % "provided"
+libraryDependencies += "jakarta.servlet" % "jakarta.servlet-api" % "6.0.0" % Provided
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5"
libraryDependencies += "ch.qos.logback" % "logback-classic" % "1.5.8"
diff --git a/src/template/project/plugins.sbt b/src/template/project/plugins.sbt
index bc97c43d..da29e13c 100644
--- a/src/template/project/plugins.sbt
+++ b/src/template/project/plugins.sbt
@@ -1,3 +1,3 @@
-addSbtPlugin("com.earldouglas" % "xsbt-web-plugin" % "0.1.0-SNAPSHOT")
+addSbtPlugin("com.earldouglas" % "sbt-war" % "0.1.0-SNAPSHOT")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2")
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.12.1")