1
0
mirror of https://github.com/octoleo/plantuml-server.git synced 2024-12-22 00:38:54 +00:00

update jetty and tomcat to latest version

This commit is contained in:
Florian 2021-10-15 15:11:55 +02:00 committed by arnaudroques
parent b1b7dfb84b
commit 9cb9cec6ca
30 changed files with 1693 additions and 611 deletions

78
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,78 @@
name: Docker
on:
workflow_run:
workflows:
- Main
types:
- completed
jobs:
build:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success'
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Docker tomcat meta
id: docker_meta_tomcat
uses: crazy-max/ghaction-docker-meta@v3
with:
flavor: |
latest=false
prefix=
suffix=
images: plantuml/plantuml-server
tags: |
type=semver,pattern=tomcat-{{raw}}
type=raw,value=tomcat
- name: Docker jetty meta
id: docker_meta_jetty
uses: crazy-max/ghaction-docker-meta@v3
with:
flavor: |
latest=true
prefix=
suffix=
images: plantuml/plantuml-server
tags: |
type=semver,pattern={{raw}}
type=semver,pattern=jetty-{{raw}}
type=raw,value=jetty
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build & push tomcat
id: docker_build_tomcat
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.tomcat
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta_tomcat.outputs.tags }}
labels: ${{ steps.docker_meta_tomcat.outputs.labels }}
- name: Build & push jetty
id: docker_build_jetty
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.jetty
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta_jetty.outputs.tags }}
labels: ${{ steps.docker_meta_jetty.outputs.labels }}

View File

@ -6,7 +6,7 @@ on:
- "v*"
jobs:
build:
build-jdk11:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -15,87 +15,98 @@ jobs:
- uses: actions/setup-java@v2
with:
distribution: "adopt"
java-version: "8"
distribution: "zulu"
java-version: 11
check-latest: true
cache: "maven"
- name: build with maven
run: mvn --batch-mode --define java.net.useSystemProxies=true package
- name: get tag name
id: version
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/*/}
- name: build with maven
run: mvn --batch-mode --define java.net.useSystemProxies=true package
- name: create renamed build
run: cp target/plantuml.war target/plantuml-${{ steps.version.outputs.VERSION }}.war
- name: build with maven (including the apache-jsp artifact)
run: mvn --batch-mode --define java.net.useSystemProxies=true -Dapache-jsp.scope=compile package
- name: create renamed build (including the apache-jsp artifact)
run: cp target/plantuml.war target/plantuml-jsp-${{ steps.version.outputs.VERSION }}.war
- name: temporarily save generated war files
uses: actions/upload-artifact@v2
with:
name: war-jre11
path: target/plantuml*-${{ steps.version.outputs.VERSION }}.war
build-jdk8:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-java@v2
with:
distribution: "zulu"
java-version: 8
check-latest: true
cache: "maven"
- name: get tag name
id: version
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/*/}
- name: Remove test code (not java 8 compatible)
run: rm -rf src/test
- name: build with maven
run: mvn --batch-mode -f pom.jdk8.xml --define java.net.useSystemProxies=true package
- name: create renamed build
run: cp target/plantuml.war target/plantuml-jre8-${{ steps.version.outputs.VERSION }}.war
- name: build with maven (including the apache-jsp artifact)
run: mvn --batch-mode -f pom.jdk8.xml --define java.net.useSystemProxies=true -Dapache-jsp.scope=compile package
- name: create renamed build (including the apache-jsp artifact)
run: cp target/plantuml.war target/plantuml-jre8-jsp-${{ steps.version.outputs.VERSION }}.war
- name: temporarily save generated war files
uses: actions/upload-artifact@v2
with:
name: war-jre8
path: target/plantuml*-${{ steps.version.outputs.VERSION }}.war
publish-releases:
runs-on: ubuntu-latest
needs:
- build-jdk11
- build-jdk8
steps:
- name: retrieve generated war files (jre8)
uses: actions/download-artifact@v2
with:
name: war-jre8
path: artifacts
- name: retrieve generated war files (jre11)
uses: actions/download-artifact@v2
with:
name: war-jre11
path: artifacts
- name: display structure of downloaded files
run: ls -lah artifacts
- name: upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: target/plantuml-${{ steps.version.outputs.VERSION }}.war
asset_name: plantuml-${{ steps.version.outputs.VERSION }}.war
file: artifacts/plantuml*.war
tag: ${{ github.ref }}
overwrite: true
- name: Docker tomcat meta
id: docker_meta_tomcat
uses: crazy-max/ghaction-docker-meta@v3
with:
flavor: |
latest=false
prefix=
suffix=
images: plantuml/plantuml-server
tags: |
type=semver,pattern=tomcat-{{raw}}
type=raw,value=tomcat
- name: Docker jetty meta
id: docker_meta_jetty
uses: crazy-max/ghaction-docker-meta@v3
with:
flavor: |
latest=true
prefix=
suffix=
images: plantuml/plantuml-server
tags: |
type=semver,pattern={{raw}}
type=semver,pattern=jetty-{{raw}}
type=raw,value=jetty
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build & push tomcat
id: docker_build_tomcat
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.tomcat
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta_tomcat.outputs.tags }}
labels: ${{ steps.docker_meta_tomcat.outputs.labels }}
- name: Build & push jetty
id: docker_build_jetty
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile.jetty
platforms: linux/amd64
push: true
tags: ${{ steps.docker_meta_jetty.outputs.tags }}
labels: ${{ steps.docker_meta_jetty.outputs.labels }}
file_glob: true

View File

@ -19,8 +19,8 @@ jobs:
- uses: actions/setup-java@v2
with:
distribution: "adopt"
java-version: "8"
distribution: "zulu"
java-version: 11
check-latest: true
cache: "maven"

View File

@ -5,7 +5,7 @@ on:
- pull_request
jobs:
test-mvn-livecycle:
test-java-8-war-generation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@ -14,65 +14,110 @@ jobs:
- uses: actions/setup-java@v2
with:
distribution: "adopt"
java-version: "8"
distribution: "zulu"
java-version: 8
check-latest: true
cache: "maven"
- name: Remove test code (not java 8 compatible)
run: rm -rf src/test
- name: Generate war file (including apache-jsp artifact)
run: mvn --batch-mode -f pom.jdk8.xml -D java.net.useSystemProxies=true -Dapache-jsp.scope=compile clean package
- name: Generate war file
run: mvn --batch-mode -f pom.jdk8.xml -D java.net.useSystemProxies=true clean package
- name: temporarily save generated files
uses: actions/upload-artifact@v2
with:
name: war-jre8
path: target/plantuml.war
retention-days: 1
test-java-8-war:
runs-on: ubuntu-latest
needs: test-java-8-war-generation
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: retrieve generated files (jre8)
uses: actions/download-artifact@v2
with:
name: war-jre8
path: artifacts
- uses: actions/setup-java@v2
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Prepare jetty-runner tests
run: mvn --batch-mode clean package
- name: Start jetty server over jetty-runner
run: java -jar target/dependency/jetty-runner.jar --config src/main/config/jetty.xml --path /plantuml artifacts/plantuml.war &
- name: Wait 5 seconds (to let jetty-runner start the jetty server)
run: sleep 5s
- name: Run tests against "mvn jetty:run" server
run: mvn --batch-mode test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
test-mvn-livecycle:
runs-on: ubuntu-latest
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-java@v2
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Lifecycle - Step 1/8 - mvn clean
run: mvn clean
run: mvn --batch-mode clean
- name: Lifecycle - Step 2/8 - mvn validate
run: mvn validate
run: mvn --batch-mode validate
- name: Lifecycle - Step 3/8 - mvn compile
run: mvn compile
run: mvn --batch-mode compile
- name: Lifecycle - Step 4/8 - mvn test (with skipTests=true)
run: mvn test
run: mvn --batch-mode test
- name: Lifecycle - Step 5/8 - mvn package
run: mvn package
run: mvn --batch-mode package
- name: Lifecycle - Step 6/8 - mvn verify
run: mvn verify
run: mvn --batch-mode verify
- name: Lifecycle - Step 7/8 - mvn install
run: mvn install
run: mvn --batch-mode install
- name: Lifecycle - Step 8/8 - mvn site
run: mvn site
run: mvn --batch-mode site
# test-embedded:
# runs-on: ubuntu-latest
# needs: test-mvn-livecycle
# steps:
# - uses: actions/checkout@v2
# with:
# fetch-depth: 0
# - uses: actions/setup-java@v2
# with:
# distribution: "adopt"
# java-version: "8"
# check-latest: true
# cache: "maven"
# - name: Prepare embedded tests - Step 1/3 - mvn clean
# run: mvn clean
# - name: Prepare embedded tests - Step 2/3 - mvn compile
# run: mvn compile
# - name: Prepare embedded tests - Step 3/3 - mvn test (with skipTests=true)
# run: mvn test
# - name: Run tests against jetty embedded server
# run: mvn test -DskipTests=false
test-jetty:
test-embedded:
runs-on: ubuntu-latest
needs: test-mvn-livecycle
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
@ -80,19 +125,94 @@ jobs:
- uses: actions/setup-java@v2
with:
distribution: "adopt"
java-version: "8"
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Prepare external tests - Step 1/3 - mvn clean
run: mvn clean
- name: Run tests against jetty embedded server
run: mvn --batch-mode clean test -DskipTests=false
- name: Prepare external tests - Step 2/3 - mvn compile
run: mvn compile
test-mvn-jetty-run:
runs-on: ubuntu-latest
needs: test-mvn-livecycle
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Prepare external tests - Step 3/3 - mvn test (with skipTests=true)
run: mvn test
- uses: actions/setup-java@v2
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Prepare "mvn jetty:run" tests
run: mvn --batch-mode clean test
- name: Start jetty server over maven
run: mvn --batch-mode jetty:run &
- name: Wait 10 seconds (to let maven start the jetty server)
run: sleep 10s
- name: Run tests against "mvn jetty:run" server
run: mvn --batch-mode test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
test-jetty-runner:
runs-on: ubuntu-latest
needs: test-mvn-livecycle
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-java@v2
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Prepare jetty-runner tests
run: mvn --batch-mode clean package
- name: Start jetty server over jetty-runner
run: java -jar target/dependency/jetty-runner.jar --config src/main/config/jetty.xml --path /plantuml target/plantuml.war &
- name: Wait 5 seconds (to let jetty-runner start the jetty server)
run: sleep 5s
- name: Run tests against "mvn jetty:run" server
run: mvn --batch-mode test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
test-jetty:
runs-on: ubuntu-latest
needs: test-mvn-livecycle
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: actions/setup-java@v2
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Prepare external tests
run: mvn --batch-mode clean test
- name: Build the jetty docker stack
run: |
@ -103,11 +223,14 @@ jobs:
run: docker ps
- name: run tests against jetty docker image
run: mvn test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
run: mvn --batch-mode test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
test-tomcat:
runs-on: ubuntu-latest
needs: test-mvn-livecycle
strategy:
matrix:
java-version: [ 11, 17 ]
steps:
- uses: actions/checkout@v2
with:
@ -115,19 +238,13 @@ jobs:
- uses: actions/setup-java@v2
with:
distribution: "adopt"
java-version: "8"
distribution: "zulu"
java-version: ${{ matrix.java-version }}
check-latest: true
cache: "maven"
- name: Prepare external tests - Step 1/3 - mvn clean
run: mvn clean
- name: Prepare external tests - Step 2/3 - mvn compile
run: mvn compile
- name: Prepare external tests - Step 3/3 - mvn test (with skipTests=true)
run: mvn test
- name: Prepare external tests
run: mvn --batch-mode clean test
- name: Build the tomcat docker stack
run: |
@ -138,4 +255,4 @@ jobs:
run: docker ps
- name: run tests against tomcat docker image
run: mvn test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
run: mvn --batch-mode test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"

View File

@ -14,7 +14,9 @@
"servlets",
"startditaa",
"startuml",
"utxt"
"utxt",
"ghaction",
"buildx"
],
"cSpell.allowCompoundWords": true
}

View File

@ -8,7 +8,12 @@ RUN mvn --batch-mode --define java.net.useSystemProxies=true package
########################################################################################
FROM jetty:9.4-jre11-slim
FROM jetty:11.0.7-jre11-slim
# Proxy and OldProxy need empty path segments support in URIs
# Hence: allow AMBIGUOUS_EMPTY_SEGMENT
# Changes are only active if `/generate-jetty-start.sh` is called!
RUN sed -i 's/# jetty\.httpConfig\.uriCompliance=DEFAULT/jetty.httpConfig.uriCompliance=DEFAULT,AMBIGUOUS_EMPTY_SEGMENT/g' /var/lib/jetty/start.d/server.ini
USER root
RUN apt-get update && \

View File

@ -4,11 +4,11 @@ COPY pom.xml /app/
COPY src/main /app/src/main/
WORKDIR /app
RUN mvn --batch-mode --define java.net.useSystemProxies=true package
RUN mvn --batch-mode --define java.net.useSystemProxies=true -Dapache-jsp.scope=compile package
########################################################################################
FROM tomcat:9.0-jdk11-openjdk-slim
FROM tomcat:10-jdk11-openjdk-slim
RUN apt-get update && \
apt-get install -y --no-install-recommends \

View File

@ -18,7 +18,7 @@ To know more about PlantUML, please visit https://plantuml.com.
## Requirements
- jre/jdk 1.6.0 or above
- jre/jdk 11 or above
- apache maven 3.0.2 or above
@ -36,7 +36,7 @@ In this way the server is run on an embedded jetty server.
You can specify the port at which it runs:
```sh
mvn jetty:run -Djetty.port=9999
mvn jetty:run -Djetty.http.port=9999
```
@ -74,18 +74,27 @@ And run `docker-compose up`. This will start a modified version of the image usi
You can apply some option to your PlantUML server with environment variable.
If you run the directly the jar, you can pass the option with `-D` flag
If you run the directly the jar:
```sh
java -D THE_ENV_VARIABLE=THE_ENV_VALUE -Djetty.contextpath=/ -jar target/dependency/jetty-runner.jar target/plantuml.war
# NOTE: jetty-runner is deprecated.
# build war file and jetty-runner
mvn package
# start directly
# java $JVM_ARGS -jar jetty-runner.jar $JETTY_ARGS
java -jar target/dependency/jetty-runner.jar --config src/main/config/jetty.xml --port 9999 --path /plantuml target/plantuml.war
# see help for more possible options
java -jar target/dependency/jetty-runner.jar --help
```
or
Note: `--config src/main/config/jetty.xml` is only necessary if you need support for empty path segments in URLs (e.g. for the old proxy)
Alternatively, start over maven and pass the option with `-D` flag
```sh
mvn jetty:run -D THE_ENV_VARIABLE=THE_ENV_VALUE -Djetty.port=9999
mvn jetty:run -D THE_ENV_VARIABLE=THE_ENV_VALUE -Djetty.http.port=9999
```
If you use docker, you can use the `-e` flag:
```sh
docker run -d -p 8080:8080 -e THE_ENV_VARIABLE=THE_ENV_VALUE plantuml/plantuml-server:jetty
docker run -d -p 9999:8080 -e THE_ENV_VARIABLE=THE_ENV_VALUE plantuml/plantuml-server:jetty
```
You can set all the following variables:
@ -115,7 +124,7 @@ So, you can use following command to create a self-contained docker image that w
*Note: Generate the WAR (instructions further below) prior to running "docker build"*
```sh
docker image build -t plantuml-server:local .
docker image build -f Dockerfile.jetty -t plantuml-server:local .
docker run -d -p 8080:8080 plantuml-server:local
```
The server is now listening to [http://localhost:8080](http://localhost:8080).
@ -126,9 +135,18 @@ You may specify the port in `-p` Docker command line argument.
## How to generate the war
To build the war, just run:
```sh
mvn package
```
at the root directory of the project to produce plantuml.war in the target/ directory.
NOTE: If you want that the generated war includes the `apache-jsp` artifact run:
```sh
mvn package -Dapache-jsp.scope=compile
```
If you want to generate the war with java 8 as target just remove the src/test directory and use `pom.jdk8.xml`.
```sh
rm -rf src/test
mvn package -f pom.jdk8.xml [-Dapache-jsp.scope=compile]
```

509
pom.jdk8.xml Normal file
View File

@ -0,0 +1,509 @@
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>
<groupId>org.sourceforge.plantuml</groupId>
<artifactId>plantumlservlet</artifactId>
<version>1-SNAPSHOT</version>
<packaging>war</packaging>
<name>PlantUML Servlet</name>
<url>https://plantuml.github.io/plantuml-server/index.html</url>
<properties>
<java.version>8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!--
Skip tests by default.
Run tests manually:
- mvn test -DskipTests=false
- mvn test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
-->
<skipTests>true</skipTests>
<!--
This artifact is required for:
1. EmbeddedJettyServer -> scope: test
2. Tomcat docker image -> scope: compile
BUT: Jetty docker image as well as jetty-runner will crash on runtime if
this artifact is included because it's already provided so that the
artifact would apear multiple times on the classpath.
You can test it via: `mvn jetty:run [-Dapache-jsp.scope=compile]`
Error: java.util.ServiceConfigurationError: org.apache.juli.logging.Log: org.eclipse.jetty.apache.jsp.JuliLog not a subtype
HENCE: Default is the "test" scope and for Tomcat docker image building add:
-Dapache-jsp.scope=compile
-->
<apache-jsp.scope>test</apache-jsp.scope>
<maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
<timestamp>${maven.build.timestamp}</timestamp>
<wtp.version>1.5</wtp.version>
<wtp.contextName>plantuml</wtp.contextName>
<jetty.http.port>8080</jetty.http.port>
<jetty.contextpath>/${wtp.contextName}</jetty.contextpath>
<!-- main versions -->
<plantuml.version>1.2021.12</plantuml.version>
<!-- Please keep the jetty version identical with the docker image -->
<jetty.version>11.0.7</jetty.version>
<codemirror.version>5.63.0</codemirror.version>
<slf4j.version>1.7.32</slf4j.version>
<!-- dependencies -->
<jstl.version>1.2</jstl.version>
<apache-jsp.version>${jetty.version}</apache-jsp.version>
<jetty-annotations.version>${jetty.version}</jetty-annotations.version>
<glassfish-jstl.version>${jetty.version}</glassfish-jstl.version>
<batik-all.version>1.14</batik-all.version>
<!-- jlatexmath -->
<jlatexmath.version>1.0.7</jlatexmath.version>
<jlatexmath-font-greek.version>${jlatexmath.version}</jlatexmath-font-greek.version>
<jlatexmath-font-cyrillic.version>${jlatexmath.version}</jlatexmath-font-cyrillic.version>
<!-- Logging -->
<slf4j-log4j12.version>${slf4j.version}</slf4j-log4j12.version>
<slf4j-api.version>${slf4j.version}</slf4j-api.version>
<!-- Testing -->
<junit.version>4.13.2</junit.version>
<htmlunit.version>2.53.0</htmlunit.version>
<jetty-server.version>${jetty.version}</jetty-server.version>
<!-- build plugin management -->
<!-- lock down plugins versions to avoid using Maven defaults -->
<maven-clean-plugin.version>3.1.0</maven-clean-plugin.version>
<maven-dependency-plugin.version>3.2.0</maven-dependency-plugin.version>
<maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<versions-maven-plugin.version>2.8.1</versions-maven-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
<maven-install-plugin.version>2.5.2</maven-install-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-site-plugin.version>3.9.1</maven-site-plugin.version>
<maven-project-info-reports-plugin.version>3.1.2</maven-project-info-reports-plugin.version>
<maven-checkstyle-plugin.version>3.1.2</maven-checkstyle-plugin.version>
<checkstyle.version>9.0.1</checkstyle.version>
<!-- plugins -->
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
<jetty-runner.version>${jetty.version}</jetty-runner.version>
<jetty-maven-plugin.version>${jetty.version}</jetty-maven-plugin.version>
<duplicate-finder-maven-plugin.version>1.5.0</duplicate-finder-maven-plugin.version>
<maven-javadoc-plugin.version>3.3.1</maven-javadoc-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId>
<version>${plantuml.version}</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>codemirror</artifactId>
<version>${codemirror.version}</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>${apache-jsp.version}</version>
<scope>${apache-jsp.scope}</scope>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-jakarta-servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-schemas</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${jetty-annotations.version}</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-jakarta-servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<!-- batik-all generally tends to provide duplicate resources on the classpath -->
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>${batik-all.version}</version>
<type>pom</type>
</dependency>
<!-- jlatexmath -->
<dependency>
<groupId>org.scilab.forge</groupId>
<artifactId>jlatexmath</artifactId>
<version>${jlatexmath.version}</version>
</dependency>
<dependency>
<groupId>org.scilab.forge</groupId>
<artifactId>jlatexmath-font-greek</artifactId>
<version>${jlatexmath-font-greek.version}</version>
</dependency>
<dependency>
<groupId>org.scilab.forge</groupId>
<artifactId>jlatexmath-font-cyrillic</artifactId>
<version>${jlatexmath-font-cyrillic.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>${htmlunit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty-server.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-jakarta-servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<finalName>plantuml</finalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>${maven-clean-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>${maven-resources-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>${maven-install-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>${maven-deploy-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>${maven-site-plugin.version}</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${maven-project-info-reports-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>${checkstyle.version}</version>
</dependency>
</dependencies>
<configuration>
<configLocation>${basedir}/src/main/config/checkstyle.xml</configLocation>
<linkXRef>false</linkXRef>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>${versions-maven-plugin.version}</version>
<configuration>
<outputFile>${project.build.directory}/outdated-dependencies.txt</outputFile>
<rulesUri>file:///${basedir}/src/main/config/rules.xml</rulesUri>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<skipTests>${skipTests}</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>${maven-site-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<executions>
<execution>
<?m2e execute onConfiguration,onIncremental?>
<phase>validate</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>${versions-maven-plugin.version}</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>display-property-updates</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
<version>${duplicate-finder-maven-plugin.version}</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<ignoredResourcePatterns>
<ignoredResourcePattern>^about\.html$</ignoredResourcePattern>
<ignoredResourcePattern>^license/LICENSE\.dom-software\.txt$</ignoredResourcePattern>
<ignoredResourcePattern>^org/apache/batik/apps/rasterizer/resources/rasterizer\.policy$</ignoredResourcePattern>
</ignoredResourcePatterns>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<configuration>
<show>private</show>
<nohelp>true</nohelp>
<source>${java.version}</source>
<failOnWarnings>true</failOnWarnings>
</configuration>
</plugin>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<?m2e execute onConfiguration,onIncremental?>
<!-- To provide webjars for the embedded jetty server for junit tests -->
<id>unpack-resources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.webjars.npm</groupId>
<artifactId>codemirror</artifactId>
<version>${codemirror.version}</version>
<includes>**/lib/*.js,**/lib/*.css</includes>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-runner</artifactId>
<version>${jetty-runner.version}</version>
<destFileName>jetty-runner.jar</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<wtpversion>${wtp.version}</wtpversion>
<wtpContextName>${wtp.contextName}</wtpContextName>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
<!-- jetty.xml
Only necessary to support old proxy.
The old proxy needs empty path segments support in URIs.
Hence: allow AMBIGUOUS_EMPTY_SEGMENT
-->
<jettyXmls>${basedir}/src/main/config/jetty.xml</jettyXmls>
<scanIntervalSeconds>5</scanIntervalSeconds>
<webApp>
<contextPath>${jetty.contextpath}</contextPath>
</webApp>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<webResources>
<resource>
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>*.jspf</include>
</includes>
<filtering>true</filtering>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>${maven-project-info-reports-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>index</report>
<report>dependencies</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>${versions-maven-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<!-- <report>dependency-updates-report</report> -->
<!-- <report>plugin-updates-report</report> -->
<report>property-updates-report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven-javadoc-plugin.version}</version>
<reportSets>
<reportSet>
<id>html</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>${maven-checkstyle-plugin.version}</version>
<reportSets>
<reportSet>
<reports>
<report>checkstyle</report>
<report>checkstyle-aggregate</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</project>

173
pom.xml
View File

@ -15,7 +15,7 @@
<url>https://plantuml.github.io/plantuml-server/index.html</url>
<properties>
<java.version>8</java.version>
<java.version>11</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -29,31 +29,53 @@
-->
<skipTests>true</skipTests>
<!--
This artifact is required for:
1. EmbeddedJettyServer -> scope: test
2. Tomcat docker image -> scope: compile
BUT: Jetty docker image as well as jetty-runner will crash on runtime if
this artifact is included because it's already provided so that the
artifact would apear multiple times on the classpath.
You can test it via: `mvn jetty:run [-Dapache-jsp.scope=compile]`
Error: java.util.ServiceConfigurationError: org.apache.juli.logging.Log: org.eclipse.jetty.apache.jsp.JuliLog not a subtype
HENCE: Default is the "test" scope and for Tomcat docker image building add:
-Dapache-jsp.scope=compile
-->
<apache-jsp.scope>test</apache-jsp.scope>
<maven.build.timestamp.format>yyyyMMdd-HHmm</maven.build.timestamp.format>
<timestamp>${maven.build.timestamp}</timestamp>
<wtp.version>1.5</wtp.version>
<wtp.contextName>plantuml</wtp.contextName>
<jetty.port>8080</jetty.port>
<jetty.http.port>8080</jetty.http.port>
<jetty.contextpath>/${wtp.contextName}</jetty.contextpath>
<!-- main versions -->
<plantuml.version>1.2021.12</plantuml.version>
<jetty.version>8.0.4.v20111024</jetty.version>
<!-- Please keep the jetty version identical with the docker image -->
<jetty.version>11.0.7</jetty.version>
<codemirror.version>5.63.0</codemirror.version>
<slf4j.version>1.7.32</slf4j.version>
<!-- dependencies -->
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<apache-jsp.version>${jetty.version}</apache-jsp.version>
<jetty-annotations.version>${jetty.version}</jetty-annotations.version>
<glassfish-jstl.version>${jetty.version}</glassfish-jstl.version>
<batik-all.version>1.14</batik-all.version>
<!-- jlatexmath -->
<jlatexmath.version>1.0.7</jlatexmath.version>
<jlatexmath-font-greek.version>${jlatexmath.version}</jlatexmath-font-greek.version>
<jlatexmath-font-cyrillic.version>${jlatexmath.version}</jlatexmath-font-cyrillic.version>
<!-- Logging -->
<slf4j-log4j12.version>${slf4j.version}</slf4j-log4j12.version>
<slf4j-api.version>${slf4j.version}</slf4j-api.version>
<!-- Testing -->
<junit.version>4.13.2</junit.version>
<htmlunit.version>2.53.0</htmlunit.version>
<jetty-server.version>${jetty.version}</jetty-server.version>
<!-- build plugin management -->
<!-- lock down plugins versions to avoid using Maven defaults -->
@ -73,9 +95,9 @@
<!-- plugins -->
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
<!-- <jetty-runner.version>${jetty.version}</jetty-runner.version> -->
<jetty-runner.version>8.1.9.v20130131</jetty-runner.version>
<jetty-runner.version>${jetty.version}</jetty-runner.version>
<jetty-maven-plugin.version>${jetty.version}</jetty-maven-plugin.version>
<duplicate-finder-maven-plugin.version>1.5.0</duplicate-finder-maven-plugin.version>
<maven-javadoc-plugin.version>3.3.1</maven-javadoc-plugin.version>
</properties>
@ -85,26 +107,29 @@
<artifactId>plantuml</artifactId>
<version>${plantuml.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>codemirror</artifactId>
<version>${codemirror.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jsp</artifactId>
<version>${apache-jsp.version}</version>
<scope>${apache-jsp.scope}</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${jetty-annotations.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<!-- batik-all generally tends to provide duplicate resources on the classpath -->
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-all</artifactId>
<version>${batik-all.version}</version>
<type>pom</type>
</dependency>
<!-- jlatexmath -->
<dependency>
@ -122,6 +147,17 @@
<artifactId>jlatexmath-font-cyrillic</artifactId>
<version>${jlatexmath-font-cyrillic.version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j-log4j12.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<!-- Testing -->
<dependency>
<groupId>junit</groupId>
@ -136,15 +172,9 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.aggregate</groupId>
<artifactId>jetty-all</artifactId>
<version>${jetty.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1-glassfish</artifactId>
<version>2.1.v20100127</version>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty-server.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
@ -273,6 +303,26 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.basepom.maven</groupId>
<artifactId>duplicate-finder-maven-plugin</artifactId>
<version>${duplicate-finder-maven-plugin.version}</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
<configuration>
<ignoredResourcePatterns>
<ignoredResourcePattern>^about\.html$</ignoredResourcePattern>
<ignoredResourcePattern>^license/LICENSE\.dom-software\.txt$</ignoredResourcePattern>
<ignoredResourcePattern>^org/apache/batik/apps/rasterizer/resources/rasterizer\.policy$</ignoredResourcePattern>
</ignoredResourcePatterns>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
@ -285,36 +335,29 @@
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<wtpversion>${wtp.version}</wtpversion>
<wtpContextName>${wtp.contextName}</wtpContextName>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
<scanIntervalSeconds>5</scanIntervalSeconds>
<webApp>
<contextPath>${jetty.contextpath}</contextPath>
</webApp>
<systemProperties>
<systemProperty>
<name>jetty.port</name>
<value>${jetty.port}</value>
</systemProperty>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin.version}</version>
<executions>
<execution>
<?m2e execute onConfiguration,onIncremental?>
<!-- To provide webjars for the embedded jetty server for junit tests -->
<id>unpack-resources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.webjars.npm</groupId>
<artifactId>codemirror</artifactId>
<version>${codemirror.version}</version>
<includes>**/lib/*.js,**/lib/*.css</includes>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<phase>package</phase>
<goals>
@ -323,7 +366,7 @@
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-runner</artifactId>
<version>${jetty-runner.version}</version>
<destFileName>jetty-runner.jar</destFileName>
@ -333,6 +376,32 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<wtpversion>${wtp.version}</wtpversion>
<wtpContextName>${wtp.contextName}</wtpContextName>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty-maven-plugin.version}</version>
<configuration>
<!-- jetty.xml
Only necessary to support old proxy.
The old proxy needs empty path segments support in URIs.
Hence: allow AMBIGUOUS_EMPTY_SEGMENT
-->
<jettyXmls>${basedir}/src/main/config/jetty.xml</jettyXmls>
<scanIntervalSeconds>5</scanIntervalSeconds>
<webApp>
<contextPath>${jetty.contextpath}</contextPath>
</webApp>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
@ -340,7 +409,7 @@
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>*.jspf</include>
</includes>

77
src/main/config/jetty.xml Normal file
View File

@ -0,0 +1,77 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd">
<!-- =============================================================== -->
<!-- Configure a Jetty Server instance with an ID "Server" -->
<!-- Other configuration files may also configure the "Server" -->
<!-- ID, in which case they are adding configuration to the same -->
<!-- instance. If other configuration have a different ID, they -->
<!-- will create and configure another instance of Jetty. -->
<!-- Consult the javadoc of o.e.j.server.Server for all -->
<!-- configuration that may be set here. -->
<!-- =============================================================== -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- =========================================================== -->
<!-- Http Configuration. -->
<!-- This is a common configuration instance used by all -->
<!-- connectors that can carry HTTP semantics (HTTP, HTTPS, etc.)-->
<!-- It configures the non wire protocol aspects of the HTTP -->
<!-- semantic. -->
<!-- -->
<!-- This configuration is only defined here and is used by -->
<!-- reference from other XML files such as jetty-http.xml, -->
<!-- jetty-https.xml and other configuration files which -->
<!-- instantiate the connectors. -->
<!-- -->
<!-- Consult the javadoc of o.e.j.server.HttpConfiguration -->
<!-- for all configuration that may be set here. -->
<!-- =========================================================== -->
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<Set name="secureScheme" property="jetty.httpConfig.secureScheme"/>
<Set name="securePort" property="jetty.httpConfig.securePort"/>
<Set name="outputBufferSize" property="jetty.httpConfig.outputBufferSize"/>
<Set name="outputAggregationSize" property="jetty.httpConfig.outputAggregationSize"/>
<Set name="requestHeaderSize" property="jetty.httpConfig.requestHeaderSize"/>
<Set name="responseHeaderSize" property="jetty.httpConfig.responseHeaderSize"/>
<Set name="sendServerVersion" property="jetty.httpConfig.sendServerVersion"/>
<Set name="sendDateHeader"><Property name="jetty.httpConfig.sendDateHeader" default="false"/></Set>
<Set name="headerCacheSize" property="jetty.httpConfig.headerCacheSize"/>
<Set name="delayDispatchUntilContent" property="jetty.httpConfig.delayDispatchUntilContent"/>
<Set name="maxErrorDispatches" property="jetty.httpConfig.maxErrorDispatches"/>
<Set name="persistentConnectionsEnabled" property="jetty.httpConfig.persistentConnectionsEnabled"/>
<Set name="httpCompliance"><Call class="org.eclipse.jetty.http.HttpCompliance" name="from"><Arg><Property name="jetty.httpConfig.compliance" deprecated="jetty.http.compliance" default="RFC7230"/></Arg></Call></Set>
<!-- Changed from "SAFE" to "DEFAULT,AMBIGUOUS_EMPTY_SEGMENT" -->
<Set name="uriCompliance"><Call class="org.eclipse.jetty.http.UriCompliance" name="from"><Arg><Property name="jetty.httpConfig.uriCompliance" default="DEFAULT,AMBIGUOUS_EMPTY_SEGMENT"/></Arg></Call></Set>
<Set name="requestCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.requestCookieCompliance" default="RFC6265"/></Arg></Call></Set>
<Set name="responseCookieCompliance"><Call class="org.eclipse.jetty.http.CookieCompliance" name="valueOf"><Arg><Property name="jetty.httpConfig.responseCookieCompliance" default="RFC6265"/></Arg></Call></Set>
<Set name="relativeRedirectAllowed"><Property name="jetty.httpConfig.relativeRedirectAllowed" default="false"/></Set>
<Set name="useInputDirectByteBuffers" property="jetty.httpConfig.useInputDirectByteBuffers"/>
<Set name="useOutputDirectByteBuffers" property="jetty.httpConfig.useOutputDirectByteBuffers"/>
</New>
<New id="httpConnectionFactory" class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="httpConfig" /></Arg>
</New>
<New id="httpConnector" class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server"><Ref refid="Server" /></Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<Ref refid="httpConnectionFactory" />
</Item>
</Array>
</Arg>
<!-- Change port according to property. Default is 8080 -->
<Set name="port"><Property name="jetty.http.port" deprecated="jetty.port" default="8080" /></Set>
</New>
<!-- =========================================================== -->
<!-- Add http Connector -->
<!-- =========================================================== -->
<Call name="addConnector">
<Arg><Ref refid="httpConnector" /></Arg>
</Call>
</Configure>

View File

@ -26,10 +26,11 @@ package net.sourceforge.plantuml.servlet;
import java.io.IOException;
import javax.imageio.IIOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;

View File

@ -23,30 +23,30 @@
*/
package net.sourceforge.plantuml.servlet;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.ByteArrayOutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.BlockUml;
import net.sourceforge.plantuml.ErrorUml;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.NullOutputStream;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.code.Base64Coder;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.DiagramDescription;
import net.sourceforge.plantuml.core.ImageData;
import net.sourceforge.plantuml.version.Version;
import net.sourceforge.plantuml.error.PSystemError;
import net.sourceforge.plantuml.ErrorUml;
import net.sourceforge.plantuml.version.Version;
/**
* Delegates the diagram generation from the UML source and the filling of the HTTP response with the diagram in the

View File

@ -23,15 +23,16 @@
*/
package net.sourceforge.plantuml.servlet;
import net.sourceforge.plantuml.syntax.LanguageDescriptor;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintStream;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.syntax.LanguageDescriptor;
/**
* Servlet used to inspect the language keywords of the running PlantUML server.
* Same as {@code java -jar plantuml.jar -language}

View File

@ -26,10 +26,11 @@ package net.sourceforge.plantuml.servlet;
import java.io.IOException;
import javax.imageio.IIOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;

View File

@ -31,10 +31,10 @@ import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;

View File

@ -31,17 +31,20 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.HttpsURLConnection;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.api.PlantumlUtils;
import net.sourceforge.plantuml.code.Transcoder;
import net.sourceforge.plantuml.code.TranscoderUtil;
import net.sourceforge.plantuml.png.MetadataTag;
import net.sourceforge.plantuml.servlet.utility.Configuration;
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
/**
* Original idea from Achim Abeling for Confluence macro.
@ -81,62 +84,36 @@ public class PlantUmlServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
String text = request.getParameter("text");
String metadata = request.getParameter("metadata");
if (metadata != null) {
InputStream img = null;
try {
img = getImage(new URL(metadata));
MetadataTag metadataTag = new MetadataTag(img, "plantuml");
String data = metadataTag.getData();
if (data != null) {
text = data;
}
} finally {
if (img != null) {
img.close();
}
}
}
try {
text = getTextFromUrl(request, text);
} catch (Exception e) {
e.printStackTrace();
}
// textual diagram source
final String text = getText(request).trim();
// no Text form has been submitted
if (text == null || text.trim().isEmpty()) {
if (text.isEmpty()) {
redirectNow(request, response, DEFAULT_ENCODED_TEXT);
return;
}
final String encoded = getTranscoder().encode(text);
request.setAttribute("decoded", text);
request.setAttribute("encoded", encoded);
// check if an image map is necessary
if (text != null && PlantumlUtils.hasCMapData(text)) {
request.setAttribute("mapneeded", Boolean.TRUE);
}
// forward to index.jsp
prepareRequestForDispatch(request, text);
final RequestDispatcher dispatcher = request.getRequestDispatcher("/index.jsp");
dispatcher.forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
protected void doPost(
HttpServletRequest request,
HttpServletResponse response
) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String text = request.getParameter("text");
String encoded = DEFAULT_ENCODED_TEXT;
// encoded diagram source
String encoded;
try {
text = getTextFromUrl(request, text);
String text = getText(request).trim();
encoded = getTranscoder().encode(text);
} catch (Exception e) {
encoded = DEFAULT_ENCODED_TEXT;
e.printStackTrace();
}
@ -144,16 +121,59 @@ public class PlantUmlServlet extends HttpServlet {
}
/**
* Get textual diagram source from URL.
* Get textual diagram.
* Search for textual diagram in following order:
* 1. URL {@link PlantUmlServlet.getTextFromUrl}
* 2. metadata
* 3. request parameter "text"
*
* @param request http request which contains the source URL
* @param text fallback textual diagram source
* @param request http request
*
* @return if successful textual diagram source from URL; otherwise fallback {@code text}
* @return if successful textual diagram source; otherwise empty string
*
* @throws IOException if an input or output exception occurred
*/
private String getTextFromUrl(HttpServletRequest request, String text) throws IOException {
private String getText(final HttpServletRequest request) throws IOException {
String text;
// 1. URL
try {
text = getTextFromUrl(request);
if (text != null && !text.isEmpty()) {
return text;
}
} catch (Exception e) {
e.printStackTrace();
}
// 2. metadata
String metadata = request.getParameter("metadata");
if (metadata != null) {
try (InputStream img = getImage(new URL(metadata))) {
MetadataTag metadataTag = new MetadataTag(img, "plantuml");
String data = metadataTag.getData();
if (data != null) {
return data;
}
}
}
// 3. request parameter text
text = request.getParameter("text");
if (text != null && !text.isEmpty()) {
return text;
}
// nothing found
return "";
}
/**
* Get textual diagram source from URL.
*
* @param request http request which contains the source URL
*
* @return if successful textual diagram source from URL; otherwise empty string
*
* @throws IOException if an input or output exception occurred
*/
private String getTextFromUrl(HttpServletRequest request) throws IOException {
final Matcher recoverUml = RECOVER_UML_PATTERN.matcher(
request.getRequestURI().substring(request.getContextPath().length())
);
@ -171,8 +191,75 @@ public class PlantUmlServlet extends HttpServlet {
}
return getTranscoder().decode(url);
}
// fallback
return text;
// nothing found
return "";
}
/**
* Prepare request for dispatch and get request dispatcher.
*
* @param request http request which will be further prepared for dispatch
* @param text textual diagram source
*
* @throws IOException if an input or output exception occurred
*/
private void prepareRequestForDispatch(HttpServletRequest request, String text) throws IOException {
// diagram sources
final String encoded = getTranscoder().encode(text);
request.setAttribute("decoded", text);
request.setAttribute("encoded", encoded);
// properties
request.setAttribute("showSocialButtons", Configuration.get("SHOW_SOCIAL_BUTTONS"));
request.setAttribute("showGithubRibbon", Configuration.get("SHOW_GITHUB_RIBBON"));
// URL base
final String hostpath = getHostpath(request);
request.setAttribute("hostpath", hostpath);
// image URLs
final boolean hasImg = !text.isEmpty();
request.setAttribute("hasImg", hasImg);
request.setAttribute("imgurl", hostpath + "/png/" + encoded);
request.setAttribute("svgurl", hostpath + "/svg/" + encoded);
request.setAttribute("txturl", hostpath + "/txt/" + encoded);
request.setAttribute("mapurl", hostpath + "/map/" + encoded);
// map for diagram source if necessary
final boolean hasMap = PlantumlUtils.hasCMapData(text);
request.setAttribute("hasMap", hasMap);
String map = "";
if (hasMap) {
try {
map = UmlExtractor.extractMap(text);
} catch (Exception e) {
e.printStackTrace();
}
}
request.setAttribute("map", map);
}
/**
* Get hostpath (URL base) from request.
*
* @param request http request
*
* @return hostpath
*/
private String getHostpath(final HttpServletRequest request) {
// port
String port = "";
if (
(request.getScheme() == "http" && request.getServerPort() != 80)
||
(request.getScheme() == "https" && request.getServerPort() != 443)
) {
port = ":" + request.getServerPort();
}
// scheme
String scheme = request.getScheme();
final String forwardedProto = request.getHeader("x-forwarded-proto");
if (forwardedProto != null && !forwardedProto.isEmpty()) {
scheme = forwardedProto;
}
// hostpath
return scheme + "://" + request.getServerName() + port + request.getContextPath();
}
/**

View File

@ -29,11 +29,17 @@ import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.cert.Certificate;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.imageio.IIOException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.BlockUml;
import net.sourceforge.plantuml.FileFormat;
@ -42,13 +48,6 @@ import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.UmlSource;
import java.security.cert.Certificate;
import java.util.List;
import javax.imageio.IIOException;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLPeerUnverifiedException;
/**
* Proxy servlet of the webapp.
* This servlet retrieves the diagram source of a web resource (web html page)

View File

@ -23,20 +23,21 @@
*/
package net.sourceforge.plantuml.servlet;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
import javax.imageio.IIOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.IIOException;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.servlet.utility.UmlExtractor;
/**
* Common service servlet to produce diagram from compressed UML source contained in the end part of the requested URI.
*/

View File

@ -1,53 +0,0 @@
/* ========================================================================
* PlantUML : a free UML diagram generator
* ========================================================================
*
* Project Info: https://plantuml.com
*
* This file is part of PlantUML.
*
* PlantUML is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* PlantUML distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*/
package net.sourceforge.plantuml.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Welcome servlet of the webapp.
* Displays the sample Bob and Alice sequence diagram.
*/
@SuppressWarnings("SERIAL")
public class Welcome extends HttpServlet {
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// set the sample
request.setAttribute("decoded", "Bob -> Alice : hello");
request.setAttribute("encoded", "SyfFKj2rKt3CoKnELR1Io4ZDoSa70000");
// forward to index.jsp
RequestDispatcher dispatcher = request.getRequestDispatcher("/index.jsp");
dispatcher.forward(request, response);
}
}

View File

@ -85,10 +85,10 @@ public final class Configuration {
* @return true if the value is "on"
*/
public static boolean get(final String key) {
if (instance.config.getProperty(key) == null) {
if (get().getProperty(key) == null) {
return false;
}
return instance.config.getProperty(key).startsWith("on");
return get().getProperty(key).startsWith("on");
}
}

View File

@ -27,9 +27,14 @@ import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import net.sourceforge.plantuml.FileFormat;
import net.sourceforge.plantuml.FileFormatOption;
import net.sourceforge.plantuml.OptionFlags;
import net.sourceforge.plantuml.SourceStringReader;
import net.sourceforge.plantuml.code.Transcoder;
import net.sourceforge.plantuml.code.TranscoderUtil;
import net.sourceforge.plantuml.core.Diagram;
import net.sourceforge.plantuml.core.ImageData;
/**
* Utility class to extract the UML source from the compressed UML source contained in the end part
@ -84,4 +89,36 @@ public abstract class UmlExtractor {
return uml;
}
/**
* Get image map from uml.
*
* @param uml textual diagram source
*
* @return image map of the diagram in HTML format if the image has some position information; otherwise `null`
*
* @throws IOException if an input or output exception occurred
*/
public static String extractMap(final String uml) throws IOException {
return extractMap(uml, FileFormat.PNG);
}
/**
* Get image map from uml.
*
* @param uml textual diagram source
* @param fileFormat underlying file format of uml image
*
* @return image map of the diagram in HTML format if the image has some position information; otherwise `null`
*
* @throws IOException if an input or output exception occurred
*/
public static String extractMap(final String uml, final FileFormat fileFormat) throws IOException {
Diagram diagram = new SourceStringReader(uml).getBlocks().get(0).getDiagram();
ImageData map = diagram.exportDiagram(new NullOutputStream(), 0, new FileFormatOption(fileFormat, false));
if (map.containsCMapData()) {
return map.getCMapData("plantuml");
}
return null;
}
}

View File

@ -0,0 +1,6 @@
# Logger configuration file
#
log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yy-MM-dd HH:mm:ss:SSS} %5p %t %c{2}:%L - %m%n

View File

@ -1,150 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>plantuml</display-name>
<context-param>
<param-name>org.eclipse.jetty.servlet.Default.welcomeServlets</param-name>
<param-value>exact</param-value>
</context-param>
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
<init-param>
<param-name>compilerSourceVM</param-name>
<param-value>1.7</param-value>
</init-param>
<init-param>
<param-name>compilerTargetVM</param-name>
<param-value>1.7</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>plantumlservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.PlantUmlServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>welcome</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.Welcome</servlet-class>
</servlet>
<servlet>
<servlet-name>imgservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.ImgServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>svgservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.SvgServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>epsservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.EpsServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>epstextservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.EpsTextServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>base64servlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.Base64Servlet</servlet-class>
</servlet>
<servlet>
<servlet-name>asciiservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.AsciiServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>proxyservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.ProxyServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>oldproxyservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.OldProxyServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>mapservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.MapServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>checkservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.CheckSyntaxServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>languageservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.LanguageServlet</servlet-class>
</servlet>
<!-- Patterns of the servlet -->
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/uml/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/form</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>imgservlet</servlet-name>
<url-pattern>/png/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>imgservlet</servlet-name>
<url-pattern>/img/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>svgservlet</servlet-name>
<url-pattern>/svg/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>epsservlet</servlet-name>
<url-pattern>/eps/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>epstextservlet</servlet-name>
<url-pattern>/epstext/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>base64servlet</servlet-name>
<url-pattern>/base64/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>asciiservlet</servlet-name>
<url-pattern>/txt/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>checkservlet</servlet-name>
<url-pattern>/check/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>mapservlet</servlet-name>
<url-pattern>/map/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/start/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>oldproxyservlet</servlet-name>
<url-pattern>/proxy/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>proxyservlet</servlet-name>
<url-pattern>/proxy</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>languageservlet</servlet-name>
<url-pattern>/language</url-pattern>
</servlet-mapping>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<welcome-file-list>
<welcome-file>welcome</welcome-file>
</welcome-file-list>
<web-app
xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:web="https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
>
<!-- ========================================================== -->
<!-- General -->
<!-- ========================================================== -->
<!-- Name the application -->
<display-name>PlantUML</display-name>
<description>PlantUML Online Server</description>
<!-- This app is cluster-ready -->
<distributable />
<!-- Set timeout to 120 minutes -->
<session-config>
<session-timeout>120</session-timeout>
</session-config>
<!-- ========================================================== -->
<!-- Custom Tag Libraries -->
<!-- ========================================================== -->
<!-- Taglib declarations are no longer required since JSP 2.0, see Removing taglib from web.xml -->
<!-- The <taglib> did not need to be a child of <jsp-config> in earlier versions but is required as of Tomcat 7 -->
<!-- Note that you can only have one <jsp-config> element per web.xml -->
<!--
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/lib/c.tld</taglib-location>
</taglib>
</jsp-config>
-->
<!-- ========================================================== -->
<!-- Context Parameters -->
<!-- ========================================================== -->
<context-param>
<param-name>org.eclipse.jetty.servlet.Default.welcomeServlets</param-name>
<param-value>exact</param-value>
</context-param>
<!-- ========================================================== -->
<!-- Servlets -->
<!-- ========================================================== -->
<servlet>
<servlet-name>jsp</servlet-name>
<servlet-class>org.eclipse.jetty.jsp.JettyJspServlet</servlet-class>
<init-param>
<param-name>compilerSourceVM</param-name>
<param-value>1.7</param-value>
</init-param>
<init-param>
<param-name>compilerTargetVM</param-name>
<param-value>1.7</param-value>
</init-param>
</servlet>
<servlet>
<servlet-name>plantumlservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.PlantUmlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/uml/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/form</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>plantumlservlet</servlet-name>
<url-pattern>/start/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>imgservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.ImgServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>imgservlet</servlet-name>
<url-pattern>/png/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>imgservlet</servlet-name>
<url-pattern>/img/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>svgservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.SvgServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>svgservlet</servlet-name>
<url-pattern>/svg/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>epsservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.EpsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>epsservlet</servlet-name>
<url-pattern>/eps/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>epstextservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.EpsTextServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>epstextservlet</servlet-name>
<url-pattern>/epstext/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>base64servlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.Base64Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>base64servlet</servlet-name>
<url-pattern>/base64/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>asciiservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.AsciiServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>asciiservlet</servlet-name>
<url-pattern>/txt/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>proxyservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.ProxyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>proxyservlet</servlet-name>
<url-pattern>/proxy</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>oldproxyservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.OldProxyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>oldproxyservlet</servlet-name>
<url-pattern>/proxy/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>mapservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.MapServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mapservlet</servlet-name>
<url-pattern>/map/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>checkservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.CheckSyntaxServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>checkservlet</servlet-name>
<url-pattern>/check/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>languageservlet</servlet-name>
<servlet-class>net.sourceforge.plantuml.servlet.LanguageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>languageservlet</servlet-name>
<url-pattern>/language</url-pattern>
</servlet-mapping>
<!-- ========================================================== -->
<!-- Error Handler -->
<!-- ========================================================== -->
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<!-- ========================================================== -->
<!-- Welcome Files -->
<!-- ========================================================== -->
<welcome-file-list>
<welcome-file>welcome</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -1,12 +1,21 @@
<%@ page isErrorPage="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8" session="false" %>
<c:set var="contextroot" value="${pageContext.request.contextPath}" />
<c:if test="${(pageContext.request.scheme == 'http' && pageContext.request.serverPort != 80) ||
(pageContext.request.scheme == 'https' && pageContext.request.serverPort != 443) }">
<c:set var="port" value=":${pageContext.request.serverPort}" />
</c:if>
<c:set var="scheme" value="${(not empty header['x-forwarded-proto']) ? header['x-forwarded-proto'] : pageContext.request.scheme}" />
<c:set var="hostpath" value="${scheme}://${pageContext.request.serverName}${port}${contextroot}" />
<%
String contextroot = request.getContextPath();
String port = "";
if (
(request.getScheme() == "http" && request.getServerPort() != 80)
||
(request.getScheme() == "https" && request.getServerPort() != 443)
) {
port = ":" + request.getServerPort();
}
String scheme = request.getScheme();
if (request.getHeader("x-forwarded-proto") != null && request.getHeader("x-forwarded-proto") != "") {
scheme = request.getHeader("x-forwarded-proto");
}
String hostpath = scheme + "://" + request.getServerName() + port + contextroot;
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
@ -15,23 +24,23 @@
<meta http-equiv="expires" content="0" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache, must-revalidate" />
<link rel="stylesheet" href="${hostpath}/plantuml.css" type="text/css"/>
<link rel="icon" href="${hostpath}/favicon.ico" type="image/x-icon"/>
<link rel="shortcut icon" href="${hostpath}/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="<%= hostpath %>/plantuml.css" type="text/css"/>
<link rel="icon" href="<%= hostpath %>/favicon.ico" type="image/x-icon"/>
<link rel="shortcut icon" href="<%= hostpath %>/favicon.ico" type="image/x-icon"/>
<title>PlantUMLServer Error</title>
</head>
<body>
<p>
Sorry, but things didn't work out as planned.
</p>
<hr/>
<jsp:useBean id="now" class="java.util.Date" />
<ul>
<li><%=now.toString() %></li>
<li>Request that failed: <%=pageContext.getErrorData().getRequestURI() %></li>
<li>Status code: <%=pageContext.getErrorData().getStatusCode() %></li>
<li>Exception: <%=pageContext.getErrorData().getThrowable() %></li>
</ul>
<hr/>
<p>
Sorry, but things didn't work out as planned.
</p>
<hr/>
<jsp:useBean id="now" class="java.util.Date" />
<ul>
<li><%= now.toString() %></li>
<li>Request that failed: <%= pageContext.getErrorData().getRequestURI() %></li>
<li>Status code: <%= pageContext.getErrorData().getStatusCode() %></li>
<li>Exception: <%= pageContext.getErrorData().getThrowable() %></li>
</ul>
<hr/>
</body>
</html>

View File

@ -1,5 +1,4 @@
<div id="footer">
<p>PlantUML Server ${timestamp} / version <%= net.sourceforge.plantuml.version.Version.version() %>
</p>
<p>PlantUML Server Version <%= net.sourceforge.plantuml.version.Version.version() %>
</p>
</div>

View File

@ -1,22 +1,24 @@
<%@ page info="index" contentType="text/html; charset=utf-8" pageEncoding="utf-8" session="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="cfg" value="${applicationScope['cfg']}" />
<c:set var="contextroot" value="${pageContext.request.contextPath}" />
<c:if test="${(pageContext.request.scheme == 'http' && pageContext.request.serverPort != 80) ||
(pageContext.request.scheme == 'https' && pageContext.request.serverPort != 443) }">
<c:set var="port" value=":${pageContext.request.serverPort}" />
</c:if>
<c:set var="scheme" value="${(not empty header['x-forwarded-proto']) ? header['x-forwarded-proto'] : pageContext.request.scheme}" />
<c:set var="hostpath" value="${scheme}://${pageContext.request.serverName}${port}${contextroot}" />
<c:if test="${!empty encoded}">
<c:set var="imgurl" value="${hostpath}/png/${encoded}" />
<c:set var="svgurl" value="${hostpath}/svg/${encoded}" />
<c:set var="txturl" value="${hostpath}/txt/${encoded}" />
<c:if test="${!empty mapneeded}">
<c:set var="mapurl" value="${hostpath}/map/${encoded}" />
</c:if>
</c:if>
<%
// diagram sources
String decoded = request.getAttribute("decoded").toString();
String encoded = request.getAttribute("encoded").toString();
// properties
boolean showSocialButtons = (boolean)request.getAttribute("showSocialButtons");
boolean showGithubRibbon = (boolean)request.getAttribute("showGithubRibbon");
// URL base
String hostpath = request.getAttribute("hostpath").toString();
// image URLs
boolean hasImg = (boolean)request.getAttribute("hasImg");
String imgurl = request.getAttribute("imgurl").toString();
String svgurl = request.getAttribute("svgurl").toString();
String txturl = request.getAttribute("txturl").toString();
String mapurl = request.getAttribute("mapurl").toString();
// map for diagram source if necessary
boolean hasMap = (boolean)request.getAttribute("hasMap");
String map = request.getAttribute("map").toString();
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
@ -25,73 +27,67 @@
<meta http-equiv="expires" content="0" />
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-cache, must-revalidate" />
<link rel="icon" href="${hostpath}/favicon.ico" type="image/x-icon"/>
<link rel="shortcut icon" href="${hostpath}/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="${hostpath}/plantuml.css" />
<link rel="stylesheet" href="${hostpath}/webjars/codemirror/5.63.0/lib/codemirror.css" />
<script src="${hostpath}/webjars/codemirror/5.63.0/lib/codemirror.js"></script>
<link rel="icon" href="<%= hostpath %>/favicon.ico" type="image/x-icon"/>
<link rel="shortcut icon" href="<%= hostpath %>/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="<%= hostpath %>/plantuml.css" />
<link rel="stylesheet" href="<%= hostpath %>/webjars/codemirror/5.63.0/lib/codemirror.css" />
<script src="<%= hostpath %>/webjars/codemirror/5.63.0/lib/codemirror.js"></script>
<script>
window.onload = function() {
document.myCodeMirror = CodeMirror.fromTextArea(
document.getElementById("text"),
{lineNumbers: true}
{ lineNumbers: true }
);
};
</script>
<title>PlantUMLServer</title>
</head>
<body>
<div id="header">
<%-- PAGE TITLE --%>
<h1>PlantUML Server</h1>
<c:if test="${cfg['SHOW_SOCIAL_BUTTONS'] eq 'on' }">
<%@ include file="resource/socialbuttons1.html" %>
</c:if>
<c:if test="${cfg['SHOW_GITHUB_RIBBON'] eq 'on' }">
<%@ include file="resource/githubribbon.html" %>
</c:if>
<p>Create your <a href="https://plantuml.com">PlantUML</a> diagrams directly in your browser !</p>
</div>
<div id="content">
<%-- CONTENT --%>
<form method="post" accept-charset="UTF-8" action="${contextroot}/form">
<p>
<textarea id="text" name="text" cols="120" rows="10"><c:out value="${decoded}"/></textarea>
<input type="submit" />
</p>
</form>
<hr/>
<p>You can enter here a previously generated URL:</p>
<form method="post" action="${contextroot}/form">
<p>
<input name="url" type="text" size="150" value="${imgurl}" />
<br/>
<input type="submit"/>
</p>
</form>
<c:if test="${!empty imgurl}">
<div id="header">
<%-- PAGE TITLE --%>
<h1>PlantUML Server</h1>
<% if (showSocialButtons) { %>
<%@ include file="resource/socialbuttons1.html" %>
<% } %>
<% if (showGithubRibbon) { %>
<%@ include file="resource/githubribbon.html" %>
<% } %>
<p>Create your <a href="https://plantuml.com">PlantUML</a> diagrams directly in your browser!</p>
</div>
<div id="content">
<%-- CONTENT --%>
<form method="post" accept-charset="utf-8" action="<%= hostpath %>/form">
<p>
<textarea id="text" name="text" cols="120" rows="10"><%= decoded %></textarea>
<input type="submit" />
</p>
</form>
<hr/>
<a href="${svgurl}">View as SVG</a>&nbsp;
<a href="${txturl}">View as ASCII Art</a>&nbsp;
<c:if test="${!empty mapurl}">
<a href="${mapurl}">View Map Data</a>
</c:if>
<c:if test="${cfg['SHOW_SOCIAL_BUTTONS'] == 'on' }">
<%@ include file="resource/socialbuttons2.jspf" %>
</c:if>
<p id="diagram">
<c:choose>
<c:when test="${!empty mapurl}">
<img src="${imgurl}" alt="PlantUML diagram" />
</c:when>
<c:otherwise>
<img src="${imgurl}" alt="PlantUML diagram" />
</c:otherwise>
</c:choose>
</p>
</c:if>
</div>
<%-- FOOTER --%>
<%@ include file="footer.jspf" %>
<p>You can enter here a previously generated URL:</p>
<form method="post" action="<%= hostpath %>/form">
<p>
<input name="url" type="text" size="150" value="<%= imgurl %>" />
<br/>
<input type="submit"/>
</p>
</form>
<% if (hasImg) { %>
<hr/>
<a href="<%= svgurl %>">View as SVG</a>&nbsp;
<a href="<%= txturl %>">View as ASCII Art</a>&nbsp;
<% if (hasMap) { %>
<a href="<%= mapurl %>">View Map Data</a>
<% } %>
<% if (showSocialButtons) { %>
<%@ include file="resource/socialbuttons2.jspf" %>
<% } %>
<p id="diagram">
<img src="<%= imgurl %>" alt="PlantUML diagram" />
<%= map %>
</p>
<% } %>
</div>
<%-- FOOTER --%>
<%@ include file="footer.jspf" %>
</body>
</html>

View File

@ -183,10 +183,10 @@ public class TestForm extends WebappTestCase {
HtmlImage img = page.getFirstByXPath("//img[contains(@alt, 'PlantUML diagram')]");
assertNotEquals(0, img.getImageReader().getHeight(0)); // 131
assertNotEquals(0, img.getImageReader().getWidth(0)); // 231
// TODO: Ensure the image map is present
//DomElement map = page.getElementById("plantuml_map");
//assertNotNull(map);
//assertEquals(1, map.getChildElementCount());
// Ensure the image map is present
DomElement map = page.getElementById("plantuml_map");
assertNotNull(map);
assertEquals(1, map.getChildElementCount());
}
}

View File

@ -8,6 +8,9 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import junit.framework.TestCase;
import net.sourceforge.plantuml.servlet.server.EmbeddedJettyServer;
import net.sourceforge.plantuml.servlet.server.ExternalServer;
@ -16,6 +19,8 @@ import net.sourceforge.plantuml.servlet.server.ServerUtils;
public abstract class WebappTestCase extends TestCase {
protected final Logger logger;
private final ServerUtils serverUtils;
public WebappTestCase() {
@ -24,24 +29,26 @@ public abstract class WebappTestCase extends TestCase {
public WebappTestCase(String name) {
super(name);
logger = LoggerFactory.getLogger(this.getClass());
String uri = System.getProperty("system.test.server", "");
//uri = "http://localhost:8080/plantuml";
if (!uri.isEmpty()) {
// mvn test -DskipTests=false -DargLine="-Dsystem.test.server=http://localhost:8080/plantuml"
System.out.println("Test against external server: " + uri);
logger.info("Test against external server: " + uri);
serverUtils = new ExternalServer(uri);
return;
}
// mvn test -DskipTests=false
System.out.println("Test against embedded jetty server.");
logger.info("Test against embedded jetty server.");
serverUtils = new EmbeddedJettyServer();
}
@Override
public void setUp() throws Exception {
serverUtils.startServer();
logger.info(getServerUrl());
}
@Override

View File

@ -1,19 +1,51 @@
package net.sourceforge.plantuml.servlet.server;
import java.net.InetSocketAddress;
import java.util.EnumSet;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.http.UriCompliance;
import org.eclipse.jetty.http.UriCompliance.Violation;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.WebAppContext;
public class EmbeddedJettyServer implements ServerUtils {
private static final String contextPath = "/plantuml";
private Server server;
public EmbeddedJettyServer() {
server = new Server(new InetSocketAddress("127.0.0.1", 0));
server.addBean(new WebAppContext(server, "src/main/webapp", "/plantuml"));
server = new Server();
ServerConnector connector = new ServerConnector(server);
// Proxy and OldProxy need empty path segments support in URIs
// Hence: allow AMBIGUOUS_EMPTY_SEGMENT
UriCompliance uriCompliance = UriCompliance.from(EnumSet.of(Violation.AMBIGUOUS_EMPTY_SEGMENT));
connector.getConnectionFactory(HttpConnectionFactory.class)
.getHttpConfiguration()
.setUriCompliance(uriCompliance);
server.addConnector(connector);
// PlantUML server web application
WebAppContext context = new WebAppContext(server, "src/main/webapp", EmbeddedJettyServer.contextPath);
// Add static webjars resource files
// The maven-dependency-plugin in the pom.xml provides these files.
WebAppContext res = new WebAppContext(
server,
"target/classes/META-INF/resources/webjars",
EmbeddedJettyServer.contextPath + "/webjars"
);
// Create server handler
HandlerList handlers = new HandlerList();
handlers.addHandler(res); // provides: /plantuml/webjars
handlers.addHandler(context); // provides: /plantuml
handlers.addHandler(new DefaultHandler()); // provides: /
server.setHandler(handlers);
}
public void startServer() throws Exception {
@ -25,8 +57,12 @@ public class EmbeddedJettyServer implements ServerUtils {
}
public String getServerUrl() {
Connector connector = server.getConnectors()[0];
return String.format("http://%s:%d/plantuml", connector.getHost(), connector.getLocalPort());
return String.format(
"%s://%s%s",
server.getURI().getScheme(),
server.getURI().getAuthority(),
EmbeddedJettyServer.contextPath
);
}
}