Compare commits

..

No commits in common. "master" and "1.0.4" have entirely different histories.

64 changed files with 3063 additions and 1651 deletions

View file

@ -1,42 +1,37 @@
version: 2.1
version: 2
jobs:
build:
docker:
- image: circleci/openjdk:8-jdk
working_directory: ~/repo
environment:
JVM_OPTS: -Xmx3200m
TERM: dumb
commands:
build_and_test:
parameters:
reports-dir:
type: string
default: "build/reports/test_results"
steps:
- checkout
- restore_cache:
keys:
- gradle-dependencies-{{ checksum "build.gradle" }}
# fallback to using the latest cache if no exact match is found
- gradle-dependencies-
- run:
name: Download dependencies
command: ./bld download
name: Gradle Dependencies
command: ./gradlew dependencies
- save_cache:
paths: ~/.m2
key: gradle-dependencies-{{ checksum "build.gradle" }}
- run:
name: Compile source
command: ./bld compile
- run:
name: Run tests
command: ./bld jacoco -reports-dir=<< parameters.reports-dir >>
- store_test_results:
path: << parameters.reports-dir >>
name: Run All Checks
command: ./gradlew check
- store_artifacts:
path: build/reports/jacoco/test/html
jobs:
bld_jdk17:
docker:
- image: cimg/openjdk:17.0
steps:
- build_and_test
bld_jdk21:
docker:
- image: cimg/openjdk:21.0
steps:
- build_and_test
workflows:
bld:
jobs:
- bld_jdk17
- bld_jdk21
path: build/reports/
destination: reports
- store_test_results:
path: build/reports/

View file

@ -1,53 +0,0 @@
name: bld-ci
on: [ push, pull_request, workflow_dispatch ]
jobs:
build-bld-project:
env:
COVERAGE_JDK: "17"
strategy:
matrix:
java-version: [ 17, 21, 24 ]
os: [ ubuntu-latest, windows-latest, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout source repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v4
with:
distribution: "zulu"
java-version: ${{ matrix.java-version }}
- name: Download dependencies
run: ./bld download
- name: Compile source
run: ./bld compile
- name: Run tests
run: ./bld jacoco
- name: Remove pom.xml
if: success() && matrix.java-version == env.COVERAGE_JDK && matrix.os == 'ubuntu-latest'
run: rm -rf pom.xml
- name: SonarCloud Scan
uses: sonarsource/sonarcloud-github-action@master
if: success() && matrix.java-version == env.COVERAGE_JDK && matrix.os == 'ubuntu-latest'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
if: success() && matrix.java-version == env.COVERAGE_JDK && matrix.os == 'ubuntu-latest'
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View file

@ -1 +0,0 @@
future-release=1.1.2

81
.gitignore vendored
View file

@ -1,58 +1,25 @@
.gradle
**/.idea/dictionaries
**/.idea/gradle.xml
**/.idea/libraries
**/.idea/tasks.xml
**/.idea/workspace.xml
*.iws
.DS_Store
build
lib/bld/**
!lib/bld/bld-wrapper.properties
!lib/bld/bld-wrapper.jar
lib/compile/
lib/runtime/
lib/standalone/
lib/test/
# IDEA ignores
# User-specific
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# AWS User-specific
.idea/**/aws.xml
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# SonarLint plugin
.idea/sonarlint/
# Editor-based Rest Client
.idea/httpRequests
target
local.properties
.classpath
.gradle
.nb-gradle
.project
.settings
/bin
/build
/deploy
/dist
/gen
/gradle.properties
/local.properties
/out
/proguard-project.txt
/project.properties
/test-output
Thumbs.db
ehthumbs.db

9
.idea/HttpStatus.iml generated Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

29
.idea/app.iml generated
View file

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/main" />
<output-test url="file://$MODULE_DIR$/build/test" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/src/main/resources/templates" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="RUNTIME">
<library>
<CLASSES>
<root url="file://$MODULE_DIR$/src/main/resources/templates" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="compile" level="project" />
<orderEntry type="library" scope="RUNTIME" name="runtime" level="project" />
<orderEntry type="library" scope="TEST" name="test" level="project" />
</component>
</module>

14
.idea/bld.iml generated
View file

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/build/bld" />
<output-test url="file://$MODULE_DIR$/build/bld" />
<exclude-output />
<content url="file://$MODULE_DIR$/src/bld">
<sourceFolder url="file://$MODULE_DIR$/src/bld/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="bld" level="project" />
</component>
</module>

6
.idea/bld.xml generated
View file

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="BldConfiguration">
<events />
</component>
</project>

16
.idea/checkstyle-idea.xml generated Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="checkstyle-version" value="8.19" />
<entry key="copy-libs" value="true" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnly" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
</project>

View file

@ -1,5 +0,0 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
</state>
</component>

View file

@ -1,6 +0,0 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="&amp;#36;file.fileName&#10;&#10;Copyright 2015-&amp;#36;today.year Erik C. Thauvin (erik@thauvin.net)&#10;All rights reserved.&#10;&#10;Redistribution and use in source and binary forms, with or without&#10;modification, are permitted provided that the following conditions are met:&#10;&#10; Redistributions of source code must retain the above copyright notice, this&#10; list of conditions and the following disclaimer.&#10;&#10; Redistributions in binary form must reproduce the above copyright notice,&#10; this list of conditions and the following disclaimer in the documentation&#10; and/or other materials provided with the distribution.&#10;&#10; Neither the name of this project nor the names of its contributors may be&#10; used to endorse or promote products derived from this software without&#10; specific prior written permission.&#10;&#10;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;&#10;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&#10;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE&#10;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE&#10;FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL&#10;DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR&#10;SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER&#10;CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,&#10;OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE&#10;OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." />
<option name="myName" value="Erik's Copyright Notice" />
</copyright>
</component>

View file

@ -1,3 +0,0 @@
<component name="CopyrightManager">
<settings default="Erik's Copyright Notice" />
</component>

View file

@ -1,8 +1,59 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavadocDeclaration" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ADDITIONAL_TAGS" value="created" />
<inspection_tool class="AndroidLintNewerVersionAvailable" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FieldMayBeFinal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="FieldNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
<extension name="InstanceVariableNamingConvention" enabled="true">
<option name="m_regex" value="^[a-z][a-z0-9][a-zA-Z0-9]*$" />
<option name="m_minLength" value="2" />
<option name="m_maxLength" value="32" />
</extension>
</inspection_tool>
<inspection_tool class="GroovyVariableCanBeFinal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="created" />
</inspection_tool>
<inspection_tool class="LiteralAsArgToStringEquals" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="LocalCanBeFinal" enabled="true" level="WARNING" enabled_by_default="true">
<option name="REPORT_VARIABLES" value="true" />
<option name="REPORT_PARAMETERS" value="true" />
<option name="REPORT_CATCH_PARAMETERS" value="false" />
</inspection_tool>
<inspection_tool class="NonFinalUtilityClass" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="UnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WeakerAccess" enabled="false" level="WARNING" enabled_by_default="false">
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="true" />
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
</inspection_tool>
</profile>
</component>

View file

@ -1,18 +0,0 @@
<component name="libraryTable">
<library name="bld">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/bld" />
<root url="jar://$USER_HOME$/.bld/dist/bld-2.2.1-sources.jar!/" />
</SOURCES>
<excluded>
<root url="jar://$PROJECT_DIR$/lib/bld/bld-wrapper.jar!/" />
</excluded>
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" />
<jarDirectory url="file://$PROJECT_DIR$/lib/bld" recursive="false" type="SOURCES" />
</library>
</component>

View file

@ -1,13 +0,0 @@
<component name="libraryTable">
<library name="compile">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/compile" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/compile" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -1,14 +0,0 @@
<component name="libraryTable">
<library name="runtime">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
<root url="file://$PROJECT_DIR$/src/main/resources" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/runtime" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/runtime" recursive="true" type="SOURCES" />
</library>
</component>

View file

@ -1,14 +0,0 @@
<component name="libraryTable">
<library name="test">
<CLASSES>
<root url="file://$PROJECT_DIR$/lib/test" />
<root url="file://$PROJECT_DIR$/src/test/resources" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/lib/test" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" />
<jarDirectory url="file://$PROJECT_DIR$/lib/test" recursive="true" type="SOURCES" />
</library>
</component>

25
.idea/misc.xml generated
View file

@ -1,25 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<pattern value="net.thauvin.erik.httpstatus.HttpStatusBuild" />
<pattern value="net.thauvin.erik.httpstatus.HttpStatusBuild" method="pmd" />
<pattern value="net.thauvin.erik.httpstatus.HttpStatusBuild" method="jacoco" />
<pattern value="net.thauvin.erik.httpstatus.taglibs.ReasonTag" method="setCode" />
<pattern value="net.thauvin.erik.httpstatus.HttpStatusBuild" method="pmdCli" />
</component>
<component name="PDMPlugin">
<option name="customRuleSets">
<list>
<option value="K:\java\semver\config\pmd.xml" />
<option value="$PROJECT_DIR$/../bld-pitest/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-jacoco-report/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-checkstyle/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-exec/config/pmd.xml" />
<option value="$PROJECT_DIR$/../bld-testng/config/pmd.xml" />
</list>
</option>
<option name="skipTestSources" value="false" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build" />
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>

3
.idea/modules.xml generated
View file

@ -2,8 +2,7 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/app.iml" filepath="$PROJECT_DIR$/.idea/app.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/bld.iml" filepath="$PROJECT_DIR$/.idea/bld.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/HttpStatus.iml" filepath="$PROJECT_DIR$/.idea/HttpStatus.iml" />
</modules>
</component>
</project>

26
.idea/modules/httpstatus.iml generated Normal file
View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="httpstatus" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="net.thauvin.erik.httpstatus" external.system.module.version="1.0.4" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/../../out/production/classes" />
<output-test url="file://$MODULE_DIR$/../../out/test/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../..">
<sourceFolder url="file://$MODULE_DIR$/../../src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/../../src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/../../src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/../../.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../build" />
<excludeFolder url="file://$MODULE_DIR$/../../out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.github.spotbugs:spotbugs-annotations:3.1.12" level="project" />
<orderEntry type="library" name="Gradle: javax.servlet:javax.servlet-api:4.0.1" level="project" />
<orderEntry type="library" name="Gradle: javax.servlet.jsp:jsp-api:2.2.1-b03" level="project" />
<orderEntry type="library" scope="PROVIDED" name="Gradle: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.testng:testng:6.14.3" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: com.beust:jcommander:1.72" level="project" />
<orderEntry type="library" scope="TEST" name="Gradle: org.apache-extras.beanshell:bsh:2.0b6" level="project" />
</component>
</module>

View file

@ -1,9 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Run Tests" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="net.thauvin.erik.httpstatus.HttpStatusTest" />
<module name="app" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

2
.idea/vcs.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

17
.travis.yml Normal file
View file

@ -0,0 +1,17 @@
language: java
jdk:
- oraclejdk8
addons:
sonarcloud:
organization: "ethauvin-github"
before_install:
- chmod +x gradlew
after_success:
- |
if [ "${TRAVIS_TEST_RESULT}" == 0 ]; then
./gradlew sonarqube
fi

11
.vscode/launch.json vendored
View file

@ -1,11 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Run Tests",
"request": "launch",
"mainClass": "net.thauvin.erik.httpstatus.HttpStatusTest"
}
]
}

14
.vscode/settings.json vendored
View file

@ -1,14 +0,0 @@
{
"java.project.sourcePaths": [
"src/main/java",
"src/main/resources",
"src/test/java",
"src/bld/java",
"src/bld/resources"
],
"java.configuration.updateBuildConfiguration": "automatic",
"java.project.referencedLibraries": [
"${HOME}/.bld/dist/bld-2.2.1.jar",
"lib/**/*.jar",
]
}

View file

@ -1,62 +0,0 @@
# Changelog
## [1.1.1](https://github.com/ethauvin/httpstatus/tree/1.1.1) (2024-06-07)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.1.0...1.1.1)
**Implemented enhancements:**
- Sort command line output [\#10](https://github.com/ethauvin/HttpStatus/issues/10)
- Update reasons properties status codes [\#9](https://github.com/ethauvin/HttpStatus/issues/9)
## [1.1.0](https://github.com/ethauvin/httpstatus/tree/1.1.0) (2023-09-29)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.0.5...1.1.0)
**Implemented enhancements:**
- Print status code by response classes [\#8](https://github.com/ethauvin/HttpStatus/issues/8)
- Move to Jakarta EE [\#7](https://github.com/ethauvin/HttpStatus/issues/7)
- Only use XML character entities in Utils.escapeXml\(\) [\#6](https://github.com/ethauvin/HttpStatus/issues/6)
- Implement a StatusCode bean to check the status code. [\#5](https://github.com/ethauvin/HttpStatus/issues/5)
## [1.0.5](https://github.com/ethauvin/httpstatus/tree/1.0.5) (2021-03-20)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.0.4...1.0.5)
**Implemented enhancements:**
- Retrieve the error message from the request, if available. [\#4](https://github.com/ethauvin/HttpStatus/issues/4)
- Add Unofficial Codes [\#3](https://github.com/ethauvin/HttpStatus/issues/3)
## [1.0.4](https://github.com/ethauvin/httpstatus/tree/1.0.4) (2019-05-08)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.0.3...1.0.4)
**Implemented enhancements:**
- Implement all INA HTTP status codes [\#1](https://github.com/ethauvin/HttpStatus/issues/1)
**Fixed bugs:**
- hs:reason always outputs the default value. [\#2](https://github.com/ethauvin/HttpStatus/issues/2)
## [1.0.3](https://github.com/ethauvin/httpstatus/tree/1.0.3) (2016-01-22)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.0.2...1.0.3)
## [1.0.2](https://github.com/ethauvin/httpstatus/tree/1.0.2) (2016-01-21)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.0.1...1.0.2)
## [1.0.1](https://github.com/ethauvin/httpstatus/tree/1.0.1) (2015-12-16)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/1.0...1.0.1)
## [1.0](https://github.com/ethauvin/httpstatus/tree/1.0) (2015-12-04)
[Full Changelog](https://github.com/ethauvin/httpstatus/compare/ad982eff1b27c31b54df4abae00ac2d4065543d6...1.0)
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*

533
HttpStatus.ipr Normal file
View file

@ -0,0 +1,533 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="LOCAL_FILE:K:/java/HttpStatus/config/checkstyle/checkstyle.xml:Erik's Checks" />
<entry key="checkstyle-version" value="8.19" />
<entry key="copy-libs" value="true" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="location-2" value="LOCAL_FILE:K:/java/HttpStatus/config/checkstyle/checkstyle.xml:Erik's Checks" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnlyWithTests" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
<component name="ClientPropertiesManager">
<properties class="javax.swing.AbstractButton">
<property name="hideActionText" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JComponent">
<property name="html.disable" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JEditorPane">
<property name="JEditorPane.w3cLengthUnits" class="java.lang.Boolean" />
<property name="JEditorPane.honorDisplayProperties" class="java.lang.Boolean" />
<property name="charset" class="java.lang.String" />
</properties>
<properties class="javax.swing.JList">
<property name="List.isFileList" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JPasswordField">
<property name="JPasswordField.cutCopyAllowed" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JSlider">
<property name="Slider.paintThumbArrowShape" class="java.lang.Boolean" />
<property name="JSlider.isFilled" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JTable">
<property name="Table.isFileList" class="java.lang.Boolean" />
<property name="JTable.autoStartsEdit" class="java.lang.Boolean" />
<property name="terminateEditOnFocusLost" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JToolBar">
<property name="JToolBar.isRollover" class="java.lang.Boolean" />
</properties>
<properties class="javax.swing.JTree">
<property name="JTree.lineStyle" class="java.lang.String" />
</properties>
<properties class="javax.swing.text.JTextComponent">
<property name="caretAspectRatio" class="java.lang.Double" />
<property name="caretWidth" class="java.lang.Integer" />
</properties>
</component>
<component name="CopyrightManager" default="">
<copyright>
<option name="myName" value="Erik's Copyright Notice" />
<option name="notice" value="&amp;#36;file.fileName&#10;&#10;Copyright (c) 2015-&amp;#36;today.year, Erik C. Thauvin (erik@thauvin.net)&#10;All rights reserved.&#10;&#10;Redistribution and use in source and binary forms, with or without&#10;modification, are permitted provided that the following conditions are met:&#10;&#10; Redistributions of source code must retain the above copyright notice, this&#10; list of conditions and the following disclaimer.&#10;&#10; Redistributions in binary form must reproduce the above copyright notice,&#10; this list of conditions and the following disclaimer in the documentation&#10; and/or other materials provided with the distribution.&#10;&#10; Neither the name of this project nor the names of its contributors may be&#10; used to endorse or promote products derived from this software without&#10; specific prior written permission.&#10;&#10;THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS &quot;AS IS&quot;&#10;AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE&#10;IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE&#10;DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE&#10;FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL&#10;DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR&#10;SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER&#10;CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,&#10;OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE&#10;OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." />
</copyright>
<module2copyright>
<element module="Source" copyright="Erik's Copyright Notice" />
</module2copyright>
<LanguageOptions name="__TEMPLATE__">
<option name="addBlankAfter" value="false" />
</LanguageOptions>
</component>
<component name="DependencyValidationManager">
<scope name="Copyright" pattern="file[httpstatus]:src/main/java//*.java||file[httpstatus]:src/test/java//*.java||file:src/main/resources/META-INF/httpstatus.tld||file[httpstatus]:src/main/resources//*.tld||file:LICENSE.txt" />
</component>
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
<component name="GradleLocalSettings">
<option name="modificationStamps">
<map>
<entry key="K:/GitHub/CompileOnlyPlugin" value="2933943731758" />
<entry key="K:/ect/groovy/SshotCleaner" value="2892856534549" />
<entry key="K:/ect/java/Captcha" value="2894636758390" />
<entry key="K:/ect/java/FileSplitter" value="2846829504112" />
<entry key="K:/ect/java/GZIPFilter" value="2894567636586" />
<entry key="K:/ect/java/Lotto" value="2894619520256" />
<entry key="K:/ect/java/SshotCleaner" value="1446415498070" />
<entry key="K:/ect/java/TorrentCleaner" value="2894593616839" />
<entry key="K:/ect/java/click" value="2894595659515" />
<entry key="K:/ect/java/iFit2Workout" value="2894645931218" />
<entry key="K:/imacination/jtalk" value="2865986493991" />
<entry key="$PROJECT_DIR$/../DataProviderTest" value="2935655621669" />
<entry key="$PROJECT_DIR$" value="2921271906937" />
<entry key="$PROJECT_DIR$/../SemanticVersion" value="2905451385982" />
<entry key="$PROJECT_DIR$/../mobibot" value="2865248599040" />
<entry key="$PROJECT_DIR$/../semver" value="2921872379706" />
</map>
</option>
<option name="externalProjectsViewState">
<projects_view />
</option>
</component>
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="LOCAL" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="C:/gradle" />
<option name="gradleJvm" value="#JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useAutoImport" value="true" />
</GradleProjectSettings>
</option>
</component>
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<option name="myLocal" value="true" />
<inspection_tool class="FieldMayBeFinal" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="created" />
</inspection_tool>
<inspection_tool class="LocalCanBeFinal" enabled="true" level="WARNING" enabled_by_default="true">
<option name="REPORT_VARIABLES" value="true" />
<option name="REPORT_PARAMETERS" value="false" />
<option name="REPORT_CATCH_PARAMETERS" value="false" />
</inspection_tool>
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
<inspection_tool class="UnnecessarySemicolon" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="WeakerAccess" enabled="true" level="WARNING" enabled_by_default="true">
<option name="SUGGEST_PACKAGE_LOCAL_FOR_MEMBERS" value="true" />
<option name="SUGGEST_PACKAGE_LOCAL_FOR_TOP_CLASSES" value="false" />
<option name="SUGGEST_PRIVATE_FOR_INNERS" value="false" />
</inspection_tool>
</profile>
<version value="1.0" />
</component>
<component name="MavenImportPreferences">
<option name="generalSettings">
<MavenGeneralSettings>
<option name="mavenHome" value="Bundled (Maven 3)" />
</MavenGeneralSettings>
</option>
</component>
<component name="PDMPlugin">
<option name="customRuleSets">
<list>
<option value="K:\java\HttpStatus\config\pmd.xml" />
</list>
</option>
<option name="options">
<map>
<entry key="Encoding" value="" />
<entry key="Target JDK" value="1.8" />
</map>
</option>
</component>
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
<component name="ProjectCodeStyleConfiguration">
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Erik's Code Style" />
</component>
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State>
<id />
</State>
<State>
<id>Android Lint</id>
</State>
<State>
<id>Java</id>
</State>
<State>
<id>Portability issuesJava</id>
</State>
</expanded-state>
</profile-state>
</entry>
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="false">
<OptionsSetting value="true" id="Add" />
<OptionsSetting value="true" id="Remove" />
<OptionsSetting value="true" id="Checkout" />
<OptionsSetting value="true" id="Update" />
<OptionsSetting value="true" id="Status" />
<OptionsSetting value="true" id="Edit" />
<ConfirmationsSetting value="0" id="Add" />
<ConfirmationsSetting value="0" id="Remove" />
</component>
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/httpstatus.iml" filepath="$PROJECT_DIR$/.idea/modules/httpstatus.iml" group="httpstatus" />
</modules>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="12" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="PropertiesComponent">
<property name="GoToClass.includeLibraries" value="false" />
<property name="GoToClass.toSaveIncludeLibraries" value="false" />
<property name="GoToFile.includeJavaFiles" value="false" />
<property name="MemberChooser.sorted" value="false" />
<property name="MemberChooser.showClasses" value="true" />
<property name="MemberChooser.copyJavadoc" value="false" />
<property name="settings.editor.selected.configurable" value="Errors" />
<property name="settings.editor.splitter.proportion" value="0.2" />
</component>
<component name="RunManager">
<configuration default="true" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType" factoryName="Plugin">
<module name="" />
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxPermSize=250m -ea" />
<option name="PROGRAM_PARAMETERS" />
<method />
</configuration>
<configuration default="true" type="Applet" factoryName="Applet">
<option name="WIDTH" value="400" />
<option name="HEIGHT" value="300" />
<option name="POLICY_FILE" value="$APPLICATION_HOME_DIR$/bin/appletviewer.policy" />
<module />
<method />
</configuration>
<configuration default="true" type="Application" factoryName="Application">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" />
<option name="VM_PARAMETERS" />
<option name="PROGRAM_PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="ENABLE_SWING_INSPECTOR" value="false" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<module name="" />
<envs />
<method />
</configuration>
<configuration default="true" type="JUnit" factoryName="JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$MODULE_DIR$" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>
<configuration default="true" type="Remote" factoryName="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" value="javadebug" />
<option name="HOST" value="localhost" />
<option name="PORT" value="5005" />
<method />
</configuration>
<configuration default="true" type="TestNG" factoryName="TestNG">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="SUITE_NAME" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" />
<option name="METHOD_NAME" />
<option name="GROUP_NAME" />
<option name="TEST_OBJECT" value="CLASS" />
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="OUTPUT_DIRECTORY" />
<option name="ANNOTATION_TYPE" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<option name="USE_DEFAULT_REPORTERS" value="false" />
<option name="PROPERTIES_FILE" />
<envs />
<properties />
<listeners />
<method />
</configuration>
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
<component name="libraryTable">
<library name="Gradle: com.beust:jcommander:1.72">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.beust/jcommander/1.72/6375e521c1e11d6563d4f25a07ce124ccf8cd171/jcommander-1.72.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.beust/jcommander/1.72/7ef123d5dfb6f839b41265648ff1be34982d50f8/jcommander-1.72-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: com.github.spotbugs:spotbugs-annotations:3.1.12">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.spotbugs/spotbugs-annotations/3.1.12/ba2c77a05091820668987292f245f3b089387bfa/spotbugs-annotations-3.1.12.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.github.spotbugs/spotbugs-annotations/3.1.12/1d7b1099a4318469157e2172e0559ce0c5b2a85b/spotbugs-annotations-3.1.12-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: com.google.code.findbugs:jsr305:3.0.2">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/25ea2e8b0c338a877313bd4672d3fe056ea78f0d/jsr305-3.0.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.findbugs/jsr305/3.0.2/b19b5927c2c25b6c70f093767041e641ae0b1b35/jsr305-3.0.2-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: javax.servlet.jsp:jsp-api:2.2.1-b03">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.servlet.jsp/jsp-api/2.2.1-b03/c7205b380e9ceb4b96745656755f31f76ae01b74/jsp-api-2.2.1-b03.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.servlet.jsp/jsp-api/2.2.1-b03/5ee3f521021fd5d8c0a89a208a228c1ab10ef854/jsp-api-2.2.1-b03-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: javax.servlet:javax.servlet-api:4.0.1">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.servlet/javax.servlet-api/4.0.1/a27082684a2ff0bf397666c3943496c44541d1ca/javax.servlet-api-4.0.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/javax.servlet/javax.servlet-api/4.0.1/49a9da44db6e6b5f44ce15ddfcfe2b6666151b25/javax.servlet-api-4.0.1-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.apache-extras.beanshell:bsh:2.0b6">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache-extras.beanshell/bsh/2.0b6/fb418f9b33a0b951e9a2978b4b6ee93b2707e72f/bsh-2.0b6.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apache-extras.beanshell/bsh/2.0b6/76a65f674e8f2df409934824c49ca338987c63ae/bsh-2.0b6-sources.jar!/" />
</SOURCES>
</library>
<library name="Gradle: org.testng:testng:6.14.3">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.testng/testng/6.14.3/d24515dc253e77e54b73df97e1fb2eb7faf34fdd/testng-6.14.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.testng/testng/6.14.3/bfd2538501a129a142fe8366169c48b91609dc0b/testng-6.14.3-sources.jar!/" />
</SOURCES>
</library>
</component>
<component name="masterDetails">
<states>
<state key="ProjectJDKs.UI">
<settings>
<last-edited>1.8.x</last-edited>
<splitter-proportions>
<option name="proportions">
<list>
<option value="0.19944212" />
</list>
</option>
</splitter-proportions>
</settings>
</state>
</states>
</component>
</project>

View file

@ -1,4 +1,4 @@
Copyright (c) 2015-2025, Erik C. Thauvin (erik@thauvin.net)
Copyright (c) 2015-2019, Erik C. Thauvin (erik@thauvin.net)
All rights reserved.
Redistribution and use in source and binary forms, with or without

424
README.md
View file

@ -1,37 +1,11 @@
# HttpStatus JSP Tag Library
# HttpStatus JSP Tag Library
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
[![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
[![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld)
[![Release](https://img.shields.io/github/release/ethauvin/httpstatus.svg)](https://github.com/ethauvin/httpstatus/releases/latest)
[![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/net.thauvin.erik.httpstatus/httpstatus.svg?label=sanpshot&server=https%3A%2F%2Foss.sonatype.org)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/httpstatus/httpstatus/)
[![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik.httpstatus/httpstatus.svg?color=blue)](https://central.sonatype.com/artifact/net.thauvin.erik.httpstatus/httpstatus)
[![release](https://img.shields.io/github/release/ethauvin/httpstatus.svg)](https://github.com/ethauvin/httpstatus/releases/latest) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik.httpstatus/httpstatus/badge.svg)](https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik.httpstatus/httpstatus) [![Download](https://api.bintray.com/packages/ethauvin/maven/HttpStatus/images/download.svg)](https://bintray.com/ethauvin/maven/HttpStatus/_latestVersion)
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause) [![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/httpstatus/badge.svg?targetFile=build.gradle)](https://snyk.io/test/github/ethauvin/httpstatus?targetFile=build.gradle) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_HttpStatus&metric=alert_status)](https://sonarcloud.io/dashboard?id=ethauvin_HttpStatus)
[![Build Status](https://travis-ci.org/ethauvin/HttpStatus.svg?branch=master)](https://travis-ci.org/ethauvin/HttpStatus) [![Build status](https://ci.appveyor.com/api/projects/status/w5j4kul3w2rkigxb?svg=true)](https://ci.appveyor.com/project/ethauvin/httpstatus) [![CircleCI](https://circleci.com/gh/ethauvin/HttpStatus/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/HttpStatus/tree/master)
[![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/httpstatus/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/ethauvin/httpstatus?targetFile=pom.xml)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_HttpStatus&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ethauvin_HttpStatus)
[![GitHub CI](https://github.com/ethauvin/httpstatus/actions/workflows/bld.yml/badge.svg)](https://github.com/ethauvin/httpstatus/actions/workflows/bld.yml)
[![CircleCI](https://circleci.com/gh/ethauvin/HttpStatus/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/HttpStatus/tree/master)
A simple [JSP](http://www.oracle.com/technetwork/java/javaee/jsp/index.html) Tag Library to display the [code](#hscode), [reason](#hsreason), [cause](#hscode) and/or [message](#hsmessage) for [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) in JSP error pages.
## Table of Contents
- [Examples](#examples)
- [Usage](#usage)
- [Gradle](#gradle)
- [bld](#bld)
- [Maven](#maven)
- [JSP Tags](#jsp-tags)
- [hs:cause](#hscause)
- [hs:code](#hscode)
- [hs:message](#hsmessage)
- [hs:reason](#hsreason)
- [StatusCode Bean](#statuscode-bean)
- [Reasons](#reasons)
- [Command Line Usage](#command-line-usage)
- [Contributing](#contributing)
## Examples
A simple [JSP](http://www.oracle.com/technetwork/java/javaee/jsp/index.html) Tag Library to display the [code](#hscode), [reason](#hsreason) and/or [cause](#hscode) for [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) in JSP error pages.
For example:
@ -43,7 +17,6 @@ For example:
</head>
<h1><hs:reason default="Server Error"/></h1>
Cause: <pre><hs:cause default="Unable to complete your request."/></pre>
Message: <pre><hs:message default="A server error has occured."/></pre>
...
```
@ -54,53 +27,11 @@ or
<%= Reasons.getReasonPhrase(pageContext.getErrorData().getStatusCode()) %>
```
would display on a [501 status code](https://www.rfc-editor.org/rfc/rfc9110.html#name-501-not-implemented):
would display on a [501 status code](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2):
```console
Not Implemented
```
Not Implemented
## Usage
### [Gradle](https://gradle.org/)
Include the following in your `build.gradle` file:
```gradle
repositories {
mavenCentral()
}
dependencies {
implementation 'net.thauvin.erik.httpstatus:httpstatus:1.1.1'
}
```
### [bld](https://rife2.com/bld)
Include the following in your `bld` build file:
```java
scope(compile).include(
dependency("net.thauvin.erik.httpstatus","httpstatus", version(1, 1, 0))
);
```
### [Maven](http://maven.apache.org/)
As a `Maven` artifact:
```xml
<dependency>
<groupId>net.thauvin.erik.httpstatus</groupId>
<artifactId>httpstatus</artifactId>
<version>1.1.1</version>
</dependency>
```
## JSP Tags
### hs:cause
## hs:cause
The `<hs:cause/>` tag displays the cause of current HTTP status code, if any. A shorthand for:
@ -110,262 +41,157 @@ The `<hs:cause/>` tag displays the cause of current HTTP status code, if any. A
Optional attributes are:
| Attribute | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `default` | The fallback value to output, if no cause is |
| `escapeXml` | Converts &lt;, &gt;, &amp;, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default. |
### hs:code
Attribute | Description
----------- | -------------------------------------------------------------------------------------------
`default` | The fallback value to output, if no cause is available.
`escapeXml` | Converts &lt;, &gt;, &amp;, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default.
## hs:code
The `<hs:code/>` tag displays the current HTTP status code, if any. A shorthand for:
```jsp
<%= pageContext.getErrorData().getStatusCode() %>
```
### hs:message
## hs:reason
The `<hs:message/>` tag displays the current error message, if any. A shorthand for:
The `<hs:reason/>` tag displays the reason for a HTTP status code, if any. Optional attributes are:
```jsp
<%= request.getAttribute("javax.servlet.error.message") %>
```
Attribute | Description
----------- | -------------------------------------------------------------------------------------------
`code` | The HTTP status error code. If not specified the current status code is used.
`default` | The fallback value to output, if no reason is available.
`escapeXml` | Converts &lt;, &gt;, &amp;, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default.
Optional attributes are:
The reasons are defined in a [ResourceBundle](http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html) properties as follows:
| Attribute | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `default` | The fallback value to output, if no error message is available. |
| `escapeXml` | Converts &lt;, &gt;, &amp;, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default. |
Status Code | Reason
----------- | -----------------------------------
`100` | Continue
`101` | Switching Protocols
`102` | Processing
`103` | Early Hints
`200` | OK
`201` | Created
`202` | Accepted
`203` | Non-Authoritative Information
`204` | No Content
`205` | Reset Content
`206` | Partial Content
`207` | Multi-Status
`208` | Already Reported
`226` | IM Used
`300` | Multiple Choices
`301` | Moved Permanently
`302` | Found/Moved Temporarily
`303` | See Other
`304` | Not Modified
`305` | Use Proxy
`306` | Switch Proxy
`307` | Temporary Redirect
`308` | Permanent Redirect
`400` | Bad Request
`401` | Unauthorized
`402` | Payment Required
`403` | Forbidden
`404` | Not Found
`405` | Method Not Allowed
`406` | Not Acceptable
`407` | Proxy Authentication Required
`408` | Request Timeout
`409` | Conflict
`410` | Gone
`411` | Length Required
`412` | Precondition Failed
`413` | Request Entity/Payload Too Large
`414` | Request-URI Too Long
`415` | Unsupported Media Type
`416` | Requested Range Not Satisfiable
`417` | Expectation Failed
`418` | I'm A Teapot
`419` | Insufficient Space on Resource
`420` | Method Failure
`421` | Misdirected Request
`422` | Unprocessable Entity
`423` | Locked
`424` | Failed Dependency
`426` | Upgrade Required
`428` | Precondition Required
`429` | Too Many Requests
`431` | Request Header Fields Too Large
`440` | Login Timeout
`444` | No Response
`449` | Retry With
`450` | Blocked by Windows Parental Controls
`451` | Unavailable For Legal Reasons
`494` | Request Header Too Large
`495` | Cert Error
`496` | No Cert
`497` | HTTP to HTTPS
`498` | Token Expired/Invalid
`499` | Client Closed Request
`500` | Internal Server Error
`501` | Not Implemented
`502` | Bad Gateway
`503` | Service Unavailable
`504` | Gateway Timeout
`505` | HTTP Version Not Supported
`506` | Variant Also Negotiates
`507` | Insufficient Storage
`508` | Loop Detected
`509` | Bandwidth Limit Exceeded
`510` | Not Extended
`511` | Network Authentication Required
`520` | Unknown Error
`522` | Origin Connection Time-out
`598` | Network Read Timeout Error
`599` | Network Connect Timeout Error
### hs:reason
## Usage with [Gradle](https://gradle.org/) or [Maven](http://maven.apache.org/)
Include the following in your `build.gradle` file:
The `<hs:reason/>` tag displays the reason for an HTTP status code, if any. Optional attributes are:
| Attribute | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `default` | The fallback value to output, if no reason is available. |
| `code` | The HTTP status error code. If not specified the current status code is used. |
| `escapeXml` | Converts &lt;, &gt;, &amp;, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default. |
## StatusCode Bean
The `StatusCode` bean can be used to check the class of the status code error. For example, using the JSTL:
```jsp
<%@ taglib prefix="hs" uri="http://erik.thauvin.net/taglibs/httpstatus" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="statusCode" class="net.thauvin.erik.httpstatus.StatusCode"/>
<c:set target="${statusCode}" property="code"><hs:code/></c:set>
<c:choose>
<c:when test="${statusCode.isClientError()}">
An error occurred on your side. (<hs:reason/>)
</c:when>
<c:otherwise>
An error occurred on our side. (<hs:message/>)
</c:otherwise>
</c:choose>
```
or in a Servlet:
```java
import net.thauvin.erik.httpstatus.StatusCode;
public class ExampleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) {
var statusCode = new StatusCode(
(Integer) request.getAttribute("javax.servlet.error.status_code"));
if (statusCode.isError()) {
if (statusCode.isServerError()) {
var reason = statusCode.getReason();
} else {
// ...
}
}
}
```gradle
dependencies {
compile 'net.thauvin.erik.httpstatus:httpstatus:1.0.4'
}
```
The `StatusCode` bean methods are:
or as a Maven artifact:
| Method | Description |
| --------------- | -------------------------------------------------------------------- |
| `getReason` | Returns the reason for the status code (eg: `Internal Server Error`) |
| `isClientError` | Checks if the status code is a client error. |
| `isError` | Checks if the status code is a server or client error. |
| `isInfo` | Checks if the status code is informational. |
| `isRedirect` | Checks if the status code is a redirect. |
| `isServerError` | Checks if the status code is a server error. |
| `isSuccess` | Checks if the status code is a success. (`OK`) |
| `isValid` | Checks if the status code is valid. |
## Reasons
The reasons are defined in a [ResourceBundle](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ResourceBundle.html) properties as follows:
| Status Code | Reason |
| ----------- | ---------------------------------------------------------- |
| `100` | Continue |
| `101` | Switching Protocols |
| `102` | Processing |
| `103` | Early Hints |
| `110` | Response is Stale |
| `111` | Revalidation Failed |
| `112` | Disconnected Operation |
| `113` | Heuristic Expiration |
| `199` | Miscellaneous Warning |
| `200` | OK |
| `201` | Created |
| `202` | Accepted |
| `203` | Non-Authoritative Information |
| `204` | No Content |
| `205` | Reset Content |
| `206` | Partial Content |
| `207` | Multi-Status |
| `208` | Already Reported |
| `214` | Transformation Applied |
| `218` | This is fine |
| `226` | IM Used |
| `299` | Miscellaneous Persistent Warning |
| `300` | Multiple Choices |
| `301` | Moved Permanently |
| `302` | Found/Moved Temporarily |
| `303` | See Other |
| `304` | Not Modified |
| `305` | Use Proxy |
| `306` | Unused |
| `307` | Temporary Redirect |
| `308` | Permanent Redirect |
| `400` | Bad Request |
| `401` | Unauthorized |
| `402` | Payment Required |
| `403` | Forbidden |
| `404` | Not Found |
| `405` | Method Not Allowed |
| `406` | Not Acceptable |
| `407` | Proxy Authentication Required |
| `408` | Request Timeout |
| `409` | Conflict |
| `410` | Gone |
| `411` | Length Required |
| `412` | Precondition Failed |
| `413` | Payload Too Large |
| `414` | URI Too Long |
| `415` | Unsupported Media Type |
| `416` | Range Not Satisfiable |
| `417` | Expectation Failed |
| `418` | I'm A Teapot |
| `419` | Insufficient Space on Resource |
| `420` | Method Failure |
| `421` | Misdirected Request |
| `422` | Unprocessable Content |
| `423` | Locked |
| `424` | Failed Dependency |
| `425` | Too Early |
| `426` | Upgrade Required |
| `428` | Precondition Required |
| `429` | Too Many Requests |
| `430` | Request Header Fields Too Large |
| `431` | Request Header Fields Too Large |
| `440` | Login Timeout |
| `444` | No Response |
| `449` | Retry With |
| `450` | Blocked by Windows Parental Controls |
| `451` | Unavailable For Legal Reasons |
| `460` | Client Closed Connection Before Load Balancer Idle Timeout |
| `463` | X-Forwarded-For Header with More than 30 IP Addresses |
| `494` | Request Header Too Large |
| `495` | SSL Certificate Error |
| `496` | SSL Certificate Required |
| `497` | HTTP Request Sent to HTTPS Port |
| `498` | Token Expired/Invalid |
| `499` | Client Closed Request |
| `500` | Internal Server Error |
| `501` | Not Implemented |
| `502` | Bad Gateway |
| `503` | Service Unavailable |
| `504` | Gateway Timeout |
| `505` | HTTP Version Not Supported |
| `506` | Variant Also Negotiates |
| `507` | Insufficient Storage |
| `508` | Loop Detected |
| `509` | Bandwidth Limit Exceeded |
| `510` | Not Extended |
| `511` | Network Authentication Required |
| `520` | Unknown Error |
| `521` | Web Server Is Down |
| `522` | Connection Timed Out |
| `523` | Origin Is Unreachable |
| `524` | A Timeout Occurred |
| `525` | SSL Handshake Failed |
| `526` | Invalid SSL Certificate |
| `527` | Railgun Error |
| `529` | Site is overloaded |
| `530` | Site is frozen |
| `540` | Temporarily Disabled |
| `561` | Unauthorized |
| `598` | Network Read Timeout Error |
| `599` | Network Connect Timeout Error |
| `783` | Unexpected Token |
```xml
<dependency>
<groupId>net.thauvin.erik.httpstatus</groupId>
<artifactId>httpstatus</artifactId>
<version>1.0.4</version>
</dependency>
```
## Command Line Usage
You can query the reason phrase for status codes as follows:
```console
$ java -jar httpstatus-1.1.1.jar 404 500
```sh
$ java -jar httpstatus-1.0.4.jar 404 500
404: Not Found
500: Internal Server Error
```
If no status code is specified, all will be printed:
```console
$ java -jar httpstatus-1.1.1.jar
```sh
$ java -jar httpstatus-1.0.4.jar
100: Continue
101: Switching Protocols
102: Processing
103: Early Hints
110: Response is Stale
111: Revalidation Failed
112: Disconnected Operation
113: Heuristic Expiration
199: Miscellaneous Warning
200: OK
201: Created
202: Accepted
203: Non-Authoritative Information
204: No Content
205: Reset Content
206: Partial Content
207: Multi-Status
208: Already Reported
226: IM Used
...
```
You can also print status codes by [response classes](https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes):
```console
$ java -jar httpstatus-1.1.1.jar 2xx
200: OK
201: Created
202: Accepted
203: Non-Authoritative Information
...
```
## Contributing
If you want to contribute to this project, all you have to do is clone the GitHub
repository:
```console
git clone git@github.com:ethauvin/HttpStatus.git
```
Then use [bld](https://rife2.com/bld) to build:
```console
cd HttpStatus
./bld compile
```
The project has an [IntelliJ IDEA](https://www.jetbrains.com/idea/) project structure. You can just open it after all
the dependencies were downloaded and peruse the code.

26
appveyor.yml Normal file
View file

@ -0,0 +1,26 @@
version: "{branch} {build}"
skip_tags: true
build:
verbosity: detailed
build_script:
- gradlew.bat assemble --info --no-daemon
test_script:
- gradlew.bat check --info --no-daemon
branches:
only:
- master
cache:
- C:\Users\appveyor\.gradle
environment:
matrix:
- JAVA_HOME: C:\Program Files\Java\jdk1.8.0
- JAVA_HOME: C:\Program Files (x86)\Java\jdk1.8.0
matrix:
fast_finish: true

2
bld
View file

@ -1,2 +0,0 @@
#!/usr/bin/env sh
java -jar "$(dirname "$0")/lib/bld/bld-wrapper.jar" "$0" --build net.thauvin.erik.httpstatus.HttpStatusBuild "$@"

View file

@ -1,4 +0,0 @@
@echo off
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
java -jar "%DIRNAME%/lib/bld/bld-wrapper.jar" "%0" --build net.thauvin.erik.httpstatus.HttpStatusBuild %*

247
build.gradle Normal file
View file

@ -0,0 +1,247 @@
plugins {
id 'checkstyle'
id 'java'
id 'jacoco'
id 'idea'
id 'application'
id 'maven'
id 'maven-publish'
id 'pmd'
id 'com.jfrog.bintray' version '1.8.4'
id 'com.github.ben-manes.versions' version '0.21.0'
id 'net.thauvin.erik.gradle.semver' version '1.0.0'
id 'com.github.spotbugs' version '1.7.1'
id 'org.sonarqube' version '2.7'
}
import com.github.spotbugs.SpotBugsTask
import org.apache.tools.ant.taskdefs.condition.Os
defaultTasks 'deploy'
def deployDir = 'deploy'
def mavenName = 'HttpStatus'
def mavenDescription = 'HttpStatus JSP Tag Library'
def mavenUrl = 'https://github.com/ethauvin/HttpStatus'
def mavenLicense = 'The BSD 3-Clause License'
def mavenLicenseUrl = 'http://opensource.org/licenses/BSD-3-Clause'
def mavenScmCon = 'https://github.com/ethauvin/HttpStatus.git'
def mavenScmDevCon = 'git@github.com:ethauvin/HttpStatus.git'
def pkgLicenses = ['BSD 3-Clause']
def pkgIssueTrackerUrl = mavenUrl + '/issues'
def pkgLabels = ['jsp', 'tag library', 'http', 'status code', 'java']
group = 'net.thauvin.erik.httpstatus'
mainClassName = 'net.thauvin.erik.httpstatus.Reasons'
sourceCompatibility = 1.8
targetCompatibility = 1.8
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
repositories {
mavenLocal()
jcenter()
}
dependencies {
implementation 'javax.servlet:javax.servlet-api:4.0.1'
implementation 'javax.servlet.jsp:jsp-api:2.2.1-b03'
spotbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0'
spotbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.3.sb'
compileOnly 'com.github.spotbugs:spotbugs-annotations:3.1.12'
testCompileOnly 'com.github.spotbugs:spotbugs-annotations:3.1.12'
testImplementation 'org.testng:testng:6.14.3'
}
javadoc {
title = mavenDescription + ' ' + version
options.source = 8
options.tags = ['created']
options.author = true
options.links('https://docs.oracle.com/javase/8/docs/api/')
options.addStringOption('Xdoclint:none', '-quiet')
}
compileJava {
//options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation'
}
jar {
manifest.attributes('Main-Class': mainClassName)
}
clean {
doLast {
project.delete(fileTree(deployDir))
}
}
test {
useTestNG()
}
pmd {
ruleSetFiles = files("config/pmd.xml")
ruleSets = []
}
tasks.withType(SpotBugsTask) {
reports {
xml.enabled = false
html.enabled = true
}
excludeFilter = file("$projectDir/config/spotbugs/excludeFilter.xml")
}
tasks.withType(Checkstyle) {
reports {
xml.enabled = false
html.enabled = true
}
}
bintray {
user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
publications = ['MyPublication']
dryRun = false
pkg {
repo = 'maven'
name = mavenName
licenses = pkgLicenses
desc = mavenDescription
websiteUrl = mavenUrl
issueTrackerUrl = pkgIssueTrackerUrl
vcsUrl = mavenScmCon
labels = pkgLabels
publicDownloadNumbers = true
version {
gpg {
sign = true
}
}
}
}
bintrayUpload {
versionName = "$project.version"
versionDesc = "$mavenName $project.version"
versionVcsTag = "$project.version"
versionReleased = new Date()
}
task javadocJar(type: Jar, dependsOn: javadoc) {
group = 'Build'
description = 'Builds an archive of the javadoc docs.'
archiveClassifier = 'javadoc'
from javadoc.destinationDir
}
task sourcesJar(type: Jar) {
group = 'Build'
description = 'Builds an archive of the source code.'
archiveClassifier = 'sources'
from sourceSets.main.allSource
}
artifacts {
archives javadocJar
archives sourcesJar
}
publishing {
publications {
MyPublication(MavenPublication) {
from components.java
artifact sourcesJar
artifact javadocJar
groupId project.group
artifactId rootProject.name
pom {
name = mavenName
description = mavenDescription
url = mavenUrl
licenses {
license {
name = mavenLicense
url = mavenLicenseUrl
distribution = 'repo'
}
}
developers {
developer {
id = 'ethauvin'
name = 'Erik C. Thauvin'
email = 'erik@thauvin.net'
}
}
scm {
connection = 'scm:git:' + mavenScmCon
developerConnection = 'scm:git:' + mavenScmDevCon
url = mavenScmCon
}
}
}
}
}
task copyToDeploy(type: Copy) {
from(configurations.runtime) {
exclude 'javax.servlet-api-*.jar'
exclude 'jsp-api-*.jar'
}
from jar
into deployDir
}
task deploy(dependsOn: ['clean', 'build', 'copyToDeploy']) {
description = 'Copies all needed files to the ${deployDir} directory.'
group = 'Publishing'
outputs.dir deployDir
inputs.files copyToDeploy
mustRunAfter clean
}
task release(dependsOn: ['wrapper', 'deploy']) {
group = 'Publishing'
description = 'Releases new version.'
}
task pandoc(type: Exec) {
group = 'Documentation'
def pandoc_args = ['--from', 'gfm',
'--to', 'html5',
'--metadata', "pagetitle=$mavenDescription",
'-s',
'-c', 'github-pandoc.css',
'-o', 'docs/README.html',
'README.md']
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
commandLine(['cmd', '/c', 'pandoc'] + pandoc_args)
} else {
executable 'pandoc'
args pandoc_args
}
standardOutput = new ByteArrayOutputStream()
ext.output = {
return standardOutput.toString()
}
}
sonarqube {
properties {
property("sonar.projectKey", "ethauvin_HttpStatus")
property("sonar.sourceEncoding", "UTF-8")
}
}
tasks.sonarqube {
dependsOn("jacocoTestReport")
}

View file

@ -0,0 +1,267 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<!--
Checkstyle configuration that checks the Google coding conventions from Google Java Style
that can be found at https://google.github.io/styleguide/javaguide.html.
Checkstyle is very configurable. Be sure to read the documentation at
http://checkstyle.sf.net (or in your downloaded distribution).
To completely disable a check, just comment it out or delete it from the file.
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
-->
<module name="Checker">
<property name="charset" value="UTF-8"/>
<property name="severity" value="warning"/>
<property name="fileExtensions" value="java, properties, xml"/>
<!-- Excludes all 'module-info.java' files -->
<!-- See https://checkstyle.org/config_filefilters.html -->
<module name="BeforeExecutionExclusionFileFilter">
<property name="fileNamePattern" value="module\-info\.java$"/>
</module>
<!-- Checks for whitespace -->
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
<module name="FileTabCharacter">
<property name="eachLine" value="true"/>
</module>
<module name="SuppressWarningsFilter"/>
<module name="TreeWalker">
<module name="SuppressWarningsHolder"/>
<module name="OuterTypeFilename"/>
<module name="IllegalTokenText">
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
<property name="format"
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
<property name="message"
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
</module>
<module name="AvoidEscapedUnicodeCharacters">
<property name="allowEscapesForControlCharacters" value="true"/>
<property name="allowByTailComment" value="true"/>
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="LineLength">
<property name="max" value="120"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="AvoidStarImport"/>
<module name="OneTopLevelClass"/>
<module name="NoLineWrap"/>
<module name="EmptyBlock">
<property name="option" value="TEXT"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
</module>
<module name="NeedBraces"/>
<module name="LeftCurly"/>
<module name="RightCurly">
<property name="id" value="RightCurlySame"/>
<property name="tokens"
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
LITERAL_DO"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlyAlone"/>
<property name="option" value="alone"/>
<property name="tokens"
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
INSTANCE_INIT"/>
</module>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyLambdas" value="true"/>
<property name="allowEmptyMethods" value="true"/>
<property name="allowEmptyTypes" value="true"/>
<property name="allowEmptyLoops" value="true"/>
<message key="ws.notFollowed"
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
<message key="ws.notPreceded"
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
</module>
<module name="OneStatementPerLine"/>
<module name="MultipleVariableDeclarations"/>
<module name="ArrayTypeStyle"/>
<module name="MissingSwitchDefault"/>
<module name="FallThrough"/>
<module name="UpperEll"/>
<module name="ModifierOrder"/>
<module name="EmptyLineSeparator">
<property name="allowNoEmptyLineBetweenFields" value="true"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapDot"/>
<property name="tokens" value="DOT"/>
<property name="option" value="nl"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapComma"/>
<property name="tokens" value="COMMA"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<!-- ELLIPSIS is EOL until https://github.com/google/styleguide/issues/258 -->
<property name="id" value="SeparatorWrapEllipsis"/>
<property name="tokens" value="ELLIPSIS"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<!-- ARRAY_DECLARATOR is EOL until https://github.com/google/styleguide/issues/259 -->
<property name="id" value="SeparatorWrapArrayDeclarator"/>
<property name="tokens" value="ARRAY_DECLARATOR"/>
<property name="option" value="EOL"/>
</module>
<module name="SeparatorWrap">
<property name="id" value="SeparatorWrapMethodRef"/>
<property name="tokens" value="METHOD_REF"/>
<property name="option" value="nl"/>
</module>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
<message key="name.invalidPattern"
value="Package name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="TypeName">
<message key="name.invalidPattern"
value="Type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MemberName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
<message key="name.invalidPattern"
value="Member name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LambdaParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="CatchParameterName">
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="LocalVariableName">
<property name="tokens" value="VARIABLE_DEF"/>
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
<message key="name.invalidPattern"
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="ClassTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Class type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="MethodTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Method type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="InterfaceTypeParameterName">
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
<message key="name.invalidPattern"
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="NoFinalizer"/>
<module name="GenericWhitespace">
<message key="ws.followed"
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
<message key="ws.preceded"
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
<message key="ws.illegalFollow"
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
<message key="ws.notPreceded"
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
</module>
<module name="Indentation">
<property name="basicOffset" value="4"/>
<property name="braceAdjustment" value="0"/>
<property name="caseIndent" value="4"/>
<property name="throwsIndent" value="4"/>
<property name="lineWrappingIndentation" value="4"/>
<property name="arrayInitIndent" value="4"/>
</module>
<module name="AbbreviationAsWordInName">
<property name="ignoreFinal" value="false"/>
<property name="allowedAbbreviationLength" value="1"/>
</module>
<module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/>
<module name="CustomImportOrder">
<property name="customImportOrderRules"
value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/>
<property name="specialImportsRegExp" value="^javax\."/>
<property name="standardPackageRegExp" value="^java\."/>
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="false"/>
</module>
<module name="MethodParamPad"/>
<module name="NoWhitespaceBefore">
<property name="tokens"
value="COMMA, SEMI, POST_INC, POST_DEC, DOT, ELLIPSIS, METHOD_REF"/>
<property name="allowLineBreaks" value="true"/>
</module>
<module name="ParenPad"/>
<module name="OperatorWrap">
<property name="option" value="NL"/>
<property name="tokens"
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF "/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationMostCases"/>
<property name="tokens"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/>
</module>
<module name="AnnotationLocation">
<property name="id" value="AnnotationLocationVariables"/>
<property name="tokens" value="VARIABLE_DEF"/>
<property name="allowSamelineMultipleAnnotations" value="true"/>
</module>
<module name="NonEmptyAtclauseDescription"/>
<module name="JavadocTagContinuationIndentation"/>
<module name="SummaryJavadoc">
<property name="forbiddenSummaryFragments"
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
</module>
<module name="JavadocParagraph"/>
<module name="AtclauseOrder">
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
<property name="target"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
</module>
<module name="JavadocMethod">
<property name="scope" value="public"/>
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="minLineCount" value="2"/>
<property name="allowedAnnotations" value="Override, Test"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
</module>
<module name="MethodName">
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
<message key="name.invalidPattern"
value="Method name ''{0}'' must match pattern ''{1}''."/>
</module>
<module name="SingleLineJavadoc">
<property name="ignoreInlineTags" value="false"/>
</module>
<module name="EmptyCatchBlock">
<property name="exceptionVariableName" value="expected"/>
</module>
<module name="CommentsIndentation"/>
</module>
</module>

View file

@ -5,105 +5,250 @@
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>Erik's Ruleset</description>
<!-- BEST PRACTICES -->
<rule ref="category/java/bestpractices.xml">
<exclude name="AvoidPrintStackTrace"/>
<exclude name="GuardLogStatement"/>
<exclude name="UnitTestContainsTooManyAsserts"/>
<exclude name="UnitTestShouldUseTestAnnotation"/>
</rule>
<rule ref="category/java/bestpractices.xml/MissingOverride">
<properties>
<property name="violationSuppressXPath"
value="//MethodDeclaration[@Name='hashCode' or @Name='equals' or @Name='toString']"/>
</properties>
</rule>
<rule ref="category/java/bestpractices.xml/AvoidStringBufferField"/>
<rule ref="category/java/bestpractices.xml/AvoidUsingHardCodedIP"/>
<rule ref="category/java/bestpractices.xml/CheckResultSet"/>
<rule ref="category/java/bestpractices.xml/ConstantsInInterface"/>
<rule ref="category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt"/>
<rule ref="category/java/bestpractices.xml/ForLoopCanBeForeach"/>
<rule ref="category/java/bestpractices.xml/GuardLogStatement"/>
<rule ref="category/java/bestpractices.xml/LooseCoupling"/>
<rule ref="category/java/bestpractices.xml/MethodReturnsInternalArray"/>
<rule ref="category/java/bestpractices.xml/MissingOverride"/>
<rule ref="category/java/bestpractices.xml/PositionLiteralsFirstInCaseInsensitiveComparisons"/>
<rule ref="category/java/bestpractices.xml/PositionLiteralsFirstInComparisons"/>
<rule ref="category/java/bestpractices.xml/PreserveStackTrace"/>
<rule ref="category/java/bestpractices.xml/ReplaceEnumerationWithIterator"/>
<rule ref="category/java/bestpractices.xml/ReplaceHashtableWithMap"/>
<rule ref="category/java/bestpractices.xml/ReplaceVectorWithList"/>
<rule ref="category/java/bestpractices.xml/SwitchStmtsShouldHaveDefault"/>
<rule ref="category/java/bestpractices.xml/SystemPrintln"/>
<rule ref="category/java/bestpractices.xml/UnusedFormalParameter"/>
<rule ref="category/java/bestpractices.xml/UnusedImports"/>
<rule ref="category/java/bestpractices.xml/UnusedLocalVariable"/>
<rule ref="category/java/bestpractices.xml/UnusedPrivateField"/>
<rule ref="category/java/bestpractices.xml/UnusedPrivateMethod"/>
<rule ref="category/java/bestpractices.xml/UseAssertEqualsInsteadOfAssertTrue"/>
<rule ref="category/java/bestpractices.xml/UseAssertNullInsteadOfAssertTrue"/>
<rule ref="category/java/bestpractices.xml/UseAssertSameInsteadOfAssertTrue"/>
<rule ref="category/java/bestpractices.xml/UseAssertTrueInsteadOfAssertEquals"/>
<rule ref="category/java/bestpractices.xml/UseCollectionIsEmpty"/>
<rule ref="category/java/bestpractices.xml/UseVarargs"/>
<!-- CODE STYLE -->
<rule ref="category/java/codestyle.xml">
<exclude name="AtLeastOneConstructor"/>
<exclude name="ClassNamingConventions"/>
<exclude name="CommentDefaultAccessModifier"/>
<exclude name="ConfusingTernary"/>
<exclude name="FieldNamingConventions"/>
<exclude name="LocalVariableCouldBeFinal"/>
<exclude name="LongVariable"/>
<exclude name="MethodArgumentCouldBeFinal"/>
<exclude name="OnlyOneReturn"/>
<exclude name="PackageCase"/>
<exclude name="ShortClassName"/>
<exclude name="ShortMethodName"/>
<exclude name="ShortVariable"/>
<exclude name="UseExplicitTypes"/>
<exclude name="UseUnderscoresInNumericLiterals"/>
<exclude name="UselessParentheses"/>
</rule>
<!-- NAMING CONVENTIONS -->
<rule ref="category/java/codestyle.xml/FormalParameterNamingConventions"/>
<rule ref="category/java/codestyle.xml/GenericsNaming"/>
<rule ref="category/java/codestyle.xml/LocalVariableNamingConventions"/>
<rule ref="category/java/codestyle.xml/MethodNamingConventions"/>
<rule ref="category/java/codestyle.xml/PackageCase"/>
<!-- OTHER -->
<rule ref="category/java/codestyle.xml/AvoidDollarSigns"/>
<rule ref="category/java/codestyle.xml/AvoidProtectedFieldInFinalClass"/>
<rule ref="category/java/codestyle.xml/AvoidProtectedMethodInFinalClassNotExtending"/>
<rule ref="category/java/codestyle.xml/AvoidUsingNativeCode"/>
<rule ref="category/java/codestyle.xml/BooleanGetMethodName"/>
<rule ref="category/java/codestyle.xml/CallSuperInConstructor"/>
<rule ref="category/java/codestyle.xml/ControlStatementBraces"/>
<rule ref="category/java/codestyle.xml/DontImportJavaLang"/>
<rule ref="category/java/codestyle.xml/DuplicateImports"/>
<rule ref="category/java/codestyle.xml/EmptyMethodInAbstractClassShouldBeAbstract"/>
<rule ref="category/java/codestyle.xml/ExtendsObject"/>
<rule ref="category/java/codestyle.xml/FieldDeclarationsShouldBeAtStartOfClass"/>
<rule ref="category/java/codestyle.xml/ForLoopShouldBeWhileLoop"/>
<rule ref="category/java/codestyle.xml/IdenticalCatchBranches"/>
<rule ref="category/java/codestyle.xml/LocalVariableCouldBeFinal"/>
<rule ref="category/java/codestyle.xml/MethodArgumentCouldBeFinal"/>
<rule ref="category/java/codestyle.xml/NoPackage"/>
<rule ref="category/java/codestyle.xml/PrematureDeclaration"/>
<rule ref="category/java/codestyle.xml/TooManyStaticImports"/>
<rule ref="category/java/codestyle.xml/UnnecessaryAnnotationValueElement"/>
<rule ref="category/java/codestyle.xml/UnnecessaryConstructor"/>
<rule ref="category/java/codestyle.xml/UnnecessaryFullyQualifiedName"/>
<rule ref="category/java/codestyle.xml/UnnecessaryLocalBeforeReturn"/>
<rule ref="category/java/codestyle.xml/UnnecessaryReturn"/>
<rule ref="category/java/codestyle.xml/UselessQualifiedThis"/>
<rule ref="category/java/codestyle.xml/UnnecessaryImport">
<properties>
<property name="violationSuppressRegex" value="Unused (static|.*\.\*).*"/>
</properties>
</rule>
<!-- DESIGN -->
<rule ref="category/java/design.xml">
<exclude name="AvoidCatchingGenericException"/>
<exclude name="AvoidDeeplyNestedIfStmts"/>
<exclude name="AvoidUncheckedExceptionsInSignatures"/>
<exclude name="CognitiveComplexity"/>
<exclude name="CyclomaticComplexity"/>
<exclude name="ExcessiveParameterList"/>
<exclude name="ExcessivePublicCount"/>
<exclude name="GodClass"/>
<exclude name="LawOfDemeter"/>
<exclude name="LoosePackageCoupling"/>
<exclude name="NPathComplexity"/>
<exclude name="NcssCount"/>
<exclude name="TooManyFields"/>
<exclude name="TooManyMethods"/>
<exclude name="UseObjectForClearerAPI"/>
</rule>
<rule ref="category/java/design.xml/AbstractClassWithoutAnyMethod"/>
<rule ref="category/java/design.xml/AvoidRethrowingException"/>
<rule ref="category/java/design.xml/AvoidThrowingNewInstanceOfSameException"/>
<rule ref="category/java/design.xml/AvoidThrowingNullPointerException"/>
<rule ref="category/java/design.xml/AvoidThrowingRawExceptionTypes"/>
<rule ref="category/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/>
<rule ref="category/java/design.xml/CollapsibleIfStatements"/>
<rule ref="category/java/design.xml/CouplingBetweenObjects"/>
<rule ref="category/java/design.xml/DataClass"/>
<rule ref="category/java/design.xml/DoNotExtendJavaLangError"/>
<rule ref="category/java/design.xml/ExceptionAsFlowControl"/>
<rule ref="category/java/design.xml/ExcessivePublicCount"/>
<rule ref="category/java/design.xml/FinalFieldCouldBeStatic"/>
<rule ref="category/java/design.xml/ImmutableField"/>
<rule ref="category/java/design.xml/LogicInversion"/>
<rule ref="category/java/design.xml/SignatureDeclareThrowsException"/>
<rule ref="category/java/design.xml/SimplifiedTernary"/>
<rule ref="category/java/design.xml/SimplifyBooleanAssertion"/>
<rule ref="category/java/design.xml/SimplifyBooleanExpressions"/>
<rule ref="category/java/design.xml/SimplifyBooleanReturns"/>
<rule ref="category/java/design.xml/SimplifyConditional"/>
<rule ref="category/java/design.xml/SingularField"/>
<rule ref="category/java/design.xml/SwitchDensity"/>
<rule ref="category/java/design.xml/UselessOverridingMethod"/>
<rule ref="category/java/design.xml/UseUtilityClass"/>
<!-- DOCUMENTATION -->
<rule ref="category/java/documentation.xml">
<exclude name="CommentRequired"/>
<exclude name="CommentSize"/>
</rule>
<rule ref="category/java/documentation.xml/UncommentedEmptyConstructor"/>
<rule ref="category/java/documentation.xml/UncommentedEmptyMethodBody"/>
<!-- ERROR PRONE -->
<rule ref="category/java/errorprone.xml">
<exclude name="AssignmentInOperand"/>
<exclude name="AvoidCatchingNPE"/>
<exclude name="AvoidDuplicateLiterals"/>
<exclude name="AvoidFieldNameMatchingMethodName"/>
<exclude name="AvoidFieldNameMatchingTypeName"/>
<exclude name="AvoidLiteralsInIfCondition"/>
<exclude name="NullAssignment"/>
</rule>
<rule ref="category/java/errorprone.xml/AssignmentInOperand">
<properties>
<property name="allowWhile" value="true"/>
<property name="allowFor" value="true"/>
<property name="allowIf" value="true"/>
</properties>
</rule>
<rule ref="category/java/errorprone.xml/AvoidDuplicateLiterals">
<rule ref="category/java/errorprone.xml/AssignmentToNonFinalStatic"/>
<rule ref="category/java/errorprone.xml/AvoidAccessibilityAlteration"/>
<rule ref="category/java/errorprone.xml/AvoidAssertAsIdentifier"/>
<rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"/>
<rule ref="category/java/errorprone.xml/AvoidCallingFinalize"/>
<rule ref="category/java/errorprone.xml/AvoidCatchingThrowable"/>
<rule ref="category/java/errorprone.xml/AvoidDecimalLiteralsInBigDecimalConstructor"/>
<rule ref="category/java/errorprone.xml/AvoidDuplicateLiterals"/>
<rule ref="category/java/errorprone.xml/AvoidEnumAsIdentifier"/>
<rule ref="category/java/errorprone.xml/AvoidInstanceofChecksInCatchClause"/>
<rule ref="category/java/errorprone.xml/AvoidLosingExceptionInformation"/>
<rule ref="category/java/errorprone.xml/AvoidMultipleUnaryOperators"/>
<rule ref="category/java/errorprone.xml/AvoidUsingOctalValues"/>
<rule ref="category/java/errorprone.xml/BadComparison"/>
<rule ref="category/java/errorprone.xml/BrokenNullCheck"/>
<rule ref="category/java/errorprone.xml/CallSuperFirst"/>
<rule ref="category/java/errorprone.xml/CallSuperLast"/>
<rule ref="category/java/errorprone.xml/CheckSkipResult"/>
<rule ref="category/java/errorprone.xml/ClassCastExceptionWithToArray"/>
<rule ref="category/java/errorprone.xml/CloneMethodMustBePublic"/>
<rule ref="category/java/errorprone.xml/CloneMethodMustImplementCloneable"/>
<rule ref="category/java/errorprone.xml/CloneMethodReturnTypeMustMatchClassName"/>
<rule ref="category/java/errorprone.xml/CloneThrowsCloneNotSupportedException"/>
<rule ref="category/java/errorprone.xml/CloseResource"/>
<rule ref="category/java/errorprone.xml/CompareObjectsWithEquals"/>
<rule ref="category/java/errorprone.xml/ConstructorCallsOverridableMethod"/>>
<rule ref="category/java/errorprone.xml/DoNotCallGarbageCollectionExplicitly"/>
<rule ref="category/java/errorprone.xml/DoNotExtendJavaLangThrowable"/>
<rule ref="category/java/errorprone.xml/DoNotHardCodeSDCard"/>
<rule ref="category/java/errorprone.xml/DoNotThrowExceptionInFinally"/>
<rule ref="category/java/errorprone.xml/DontImportSun"/>
<rule ref="category/java/errorprone.xml/DontUseFloatTypeForLoopIndices"/>
<rule ref="category/java/errorprone.xml/EqualsNull"/>
<rule ref="category/java/errorprone.xml/FinalizeDoesNotCallSuperFinalize"/>
<rule ref="category/java/errorprone.xml/FinalizeOnlyCallsSuperFinalize"/>
<rule ref="category/java/errorprone.xml/FinalizeOverloaded"/>
<rule ref="category/java/errorprone.xml/FinalizeShouldBeProtected"/>
<rule ref="category/java/errorprone.xml/IdempotentOperations"/>
<rule ref="category/java/errorprone.xml/ImportFromSamePackage"/>
<rule ref="category/java/errorprone.xml/InstantiationToGetClass"/>
<rule ref="category/java/errorprone.xml/InvalidSlf4jMessageFormat"/>
<rule ref="category/java/errorprone.xml/JumbledIncrementer"/>
<rule ref="category/java/errorprone.xml/JUnitSpelling"/>
<rule ref="category/java/errorprone.xml/JUnitStaticSuite"/>
<rule ref="category/java/errorprone.xml/LoggerIsNotStaticFinal"/>
<rule ref="category/java/errorprone.xml/MethodWithSameNameAsEnclosingClass"/>
<rule ref="category/java/errorprone.xml/MisplacedNullCheck"/>
<rule ref="category/java/errorprone.xml/MissingBreakInSwitch"/>
<rule ref="category/java/errorprone.xml/MissingSerialVersionUID"/>
<rule ref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"/>
<rule ref="category/java/errorprone.xml/MoreThanOneLogger"/>
<rule ref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement"/>
<rule ref="category/java/errorprone.xml/NonStaticInitializer"/>
<rule ref="category/java/errorprone.xml/NullAssignment"/>
<rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/>
<rule ref="category/java/errorprone.xml/ProperCloneImplementation"/>
<rule ref="category/java/errorprone.xml/ProperLogger"/>
<rule ref="category/java/errorprone.xml/ReturnEmptyArrayRatherThanNull"/>
<rule ref="category/java/errorprone.xml/ReturnFromFinallyBlock"/>
<rule ref="category/java/errorprone.xml/SimpleDateFormatNeedsLocale"/>
<rule ref="category/java/errorprone.xml/SingleMethodSingleton"/>
<rule ref="category/java/errorprone.xml/SingletonClassReturningNewInstance"/>
<rule ref="category/java/errorprone.xml/StaticEJBFieldShouldBeFinal"/>
<rule ref="category/java/errorprone.xml/StringBufferInstantiationWithChar"/>
<rule ref="category/java/errorprone.xml/SuspiciousEqualsMethodName"/>
<rule ref="category/java/errorprone.xml/SuspiciousHashcodeMethodName"/>
<rule ref="category/java/errorprone.xml/SuspiciousOctalEscape"/>
<rule ref="category/java/errorprone.xml/TestClassWithoutTestCases"/>
<rule ref="category/java/errorprone.xml/UnconditionalIfStatement"/>
<rule ref="category/java/errorprone.xml/UnnecessaryBooleanAssertion"/>
<rule ref="category/java/errorprone.xml/UnnecessaryCaseChange"/>
<rule ref="category/java/errorprone.xml/UnnecessaryConversionTemporary"/>
<rule ref="category/java/errorprone.xml/UnusedNullCheckInEquals"/>
<rule ref="category/java/errorprone.xml/UseCorrectExceptionLogging"/>
<rule ref="category/java/errorprone.xml/UseEqualsToCompareStrings"/>
<rule ref="category/java/errorprone.xml/UselessOperationOnImmutable"/>
<rule ref="category/java/errorprone.xml/UseLocaleWithCaseConversions"/>
<rule ref="category/java/errorprone.xml/EmptyCatchBlock">
<properties>
<property name="skipAnnotations" value="true"/>
<property name="allowExceptionNameRegex">
<value>^ignore$</value>
</property>
</properties>
</rule>
<rule ref="category/java/errorprone.xml/EmptyFinalizer"/>
<rule ref="category/java/errorprone.xml/EmptyFinallyBlock"/>
<rule ref="category/java/errorprone.xml/EmptyIfStmt"/>
<rule ref="category/java/errorprone.xml/EmptyInitializer"/>
<rule ref="category/java/errorprone.xml/EmptyStatementBlock"/>
<rule ref="category/java/errorprone.xml/EmptyStatementNotInLoop"/>
<rule ref="category/java/errorprone.xml/EmptySwitchStatements"/>
<rule ref="category/java/errorprone.xml/EmptySynchronizedBlock"/>
<rule ref="category/java/errorprone.xml/EmptyTryBlock"/>
<rule ref="category/java/errorprone.xml/EmptyWhileStmt"/>
<!-- MULTITHREADING -->
<rule ref="category/java/multithreading.xml">
</rule>
<rule ref="category/java/multithreading.xml/AvoidSynchronizedAtMethodLevel"/>
<rule ref="category/java/multithreading.xml/AvoidThreadGroup"/>
<rule ref="category/java/multithreading.xml/AvoidUsingVolatile"/>
<rule ref="category/java/multithreading.xml/DontCallThreadRun"/>
<rule ref="category/java/multithreading.xml/DoubleCheckedLocking"/>
<rule ref="category/java/multithreading.xml/NonThreadSafeSingleton"/>
<rule ref="category/java/multithreading.xml/UseConcurrentHashMap"/>
<rule ref="category/java/multithreading.xml/UseNotifyAllInsteadOfNotify"/>
<!-- PERFORMANCE -->
<rule ref="category/java/performance.xml">
</rule>
<rule ref="category/java/performance.xml/AddEmptyString"/>
<rule ref="category/java/performance.xml/AppendCharacterWithChar"/>
<rule ref="category/java/performance.xml/AvoidArrayLoops"/>
<rule ref="category/java/performance.xml/AvoidFileStream"/>
<rule ref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops"/>
<rule ref="category/java/performance.xml/AvoidUsingShortType"/>
<rule ref="category/java/performance.xml/BigIntegerInstantiation"/>
<rule ref="category/java/performance.xml/BooleanInstantiation"/>
<rule ref="category/java/performance.xml/ByteInstantiation"/>
<rule ref="category/java/performance.xml/ConsecutiveAppendsShouldReuse"/>
<rule ref="category/java/performance.xml/ConsecutiveLiteralAppends"/>
<rule ref="category/java/performance.xml/InefficientEmptyStringCheck"/>
<rule ref="category/java/performance.xml/InefficientStringBuffering"/>
<rule ref="category/java/performance.xml/InsufficientStringBufferDeclaration"/>
<rule ref="category/java/performance.xml/IntegerInstantiation"/>
<rule ref="category/java/performance.xml/LongInstantiation"/>
<rule ref="category/java/performance.xml/OptimizableToArrayCall"/>
<rule ref="category/java/performance.xml/RedundantFieldInitializer"/>
<rule ref="category/java/performance.xml/SimplifyStartsWith"/>
<rule ref="category/java/performance.xml/ShortInstantiation"/>
<rule ref="category/java/performance.xml/StringInstantiation"/>
<rule ref="category/java/performance.xml/StringToString"/>
<rule ref="category/java/performance.xml/TooFewBranchesForASwitchStatement"/>
<rule ref="category/java/performance.xml/UnnecessaryWrapperObjectCreation"/>
<rule ref="category/java/performance.xml/UseArrayListInsteadOfVector"/>
<rule ref="category/java/performance.xml/UseArraysAsList"/>
<rule ref="category/java/performance.xml/UseIndexOfChar"/>
<rule ref="category/java/performance.xml/UselessStringValueOf"/>
<rule ref="category/java/performance.xml/UseStringBufferForStringAppends"/>
<rule ref="category/java/performance.xml/UseStringBufferLength"/>
<!-- SECURITY -->
<rule ref="category/java/security.xml">
</rule>
<rule ref="category/java/security.xml/HardCodedCryptoKey"/>
<rule ref="category/java/security.xml/InsecureCryptoIv"/>
</ruleset>

View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter
xmlns="https://github.com/spotbugs/filter/3.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/spotbugs/filter/3.0.0 https://raw.githubusercontent.com/spotbugs/spotbugs/3.1.0/spotbugs/etc/findbugsfilter.xsd">
<!-- <Match>
<Package name="com.foobar.*"/>
<Class name="com.foobar.MyClass"/>
<Or>
<Method name="someMethod"/>
<Method name="someOtherMethod"/>
</Or>
<Bug pattern="DLS_DEAD_LOCAL_STORE"/>
<Confidence value="2"/>
</Match>-->
</FindBugsFilter>

514
docs/README.html Normal file
View file

@ -0,0 +1,514 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>HttpStatus JSP Tag Library</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
</style>
<style>
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
{ position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
{ content: attr(title);
position: relative; left: -1em; text-align: right; vertical-align: baseline;
border: none; pointer-events: all; display: inline-block;
-webkit-touch-callout: none; -webkit-user-select: none;
-khtml-user-select: none; -moz-user-select: none;
-ms-user-select: none; user-select: none;
padding: 0 4px; width: 4em;
color: #aaaaaa;
}
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa; padding-left: 4px; }
div.sourceCode
{ }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
</style>
<link rel="stylesheet" href="github-pandoc.css" />
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<h1 id="httpstatus-jsp-tag-library">HttpStatus JSP Tag Library</h1>
<p><a href="https://github.com/ethauvin/httpstatus/releases/latest"><img src="https://img.shields.io/github/release/ethauvin/httpstatus.svg" alt="release" /></a> <a href="https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik.httpstatus/httpstatus"><img src="https://maven-badges.herokuapp.com/maven-central/net.thauvin.erik.httpstatus/httpstatus/badge.svg" alt="Maven Central" /></a> <a href="https://bintray.com/ethauvin/maven/HttpStatus/_latestVersion"><img src="https://api.bintray.com/packages/ethauvin/maven/HttpStatus/images/download.svg" alt="Download" /></a><br />
<a href="http://opensource.org/licenses/BSD-3-Clause"><img src="https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square" alt="License (3-Clause BSD)" /></a> <a href="https://snyk.io/test/github/ethauvin/httpstatus?targetFile=build.gradle"><img src="https://snyk.io/test/github/ethauvin/httpstatus/badge.svg?targetFile=build.gradle" alt="Known Vulnerabilities" /></a> <a href="https://sonarcloud.io/dashboard?id=ethauvin_HttpStatus"><img src="https://sonarcloud.io/api/project_badges/measure?project=ethauvin_HttpStatus&amp;metric=alert_status" alt="Quality Gate Status" /></a><br />
<a href="https://travis-ci.org/ethauvin/HttpStatus"><img src="https://travis-ci.org/ethauvin/HttpStatus.svg?branch=master" alt="Build Status" /></a> <a href="https://ci.appveyor.com/project/ethauvin/httpstatus"><img src="https://ci.appveyor.com/api/projects/status/w5j4kul3w2rkigxb?svg=true" alt="Build status" /></a> <a href="https://circleci.com/gh/ethauvin/HttpStatus/tree/master"><img src="https://circleci.com/gh/ethauvin/HttpStatus/tree/master.svg?style=shield" alt="CircleCI" /></a></p>
<p>A simple <a href="http://www.oracle.com/technetwork/java/javaee/jsp/index.html">JSP</a> Tag Library to display the <a href="#hscode">code</a>, <a href="#hsreason">reason</a> and/or <a href="#hscode">cause</a> for <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP status codes</a> in JSP error pages.</p>
<p>For example:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode jsp"><code class="sourceCode jsp"><a class="sourceLine" id="cb1-1" title="1">&lt;%@ page<span class="ot"> isErrorPage</span>=<span class="st">&quot;true&quot;</span><span class="ot"> </span>%&gt;</a>
<a class="sourceLine" id="cb1-2" title="2">&lt;%@ taglib<span class="ot"> prefix</span>=<span class="st">&quot;hs&quot;</span><span class="ot"> uri</span>=<span class="st">&quot;http://erik.thauvin.net/taglibs/httpstatus&quot;</span><span class="ot"> </span>%&gt;</a>
<a class="sourceLine" id="cb1-3" title="3">&lt;html&gt;&lt;head&gt;</a>
<a class="sourceLine" id="cb1-4" title="4">&lt;title&gt;<span class="kw">&lt;hs:code/&gt;</span> <span class="kw">&lt;hs:reason</span><span class="ot"> default</span>=<span class="dt">&quot;Server Error&quot;</span><span class="kw">/&gt;</span>&lt;/title&gt;</a>
<a class="sourceLine" id="cb1-5" title="5">&lt;/head&gt;</a>
<a class="sourceLine" id="cb1-6" title="6">&lt;h1&gt;<span class="kw">&lt;hs:reason</span><span class="ot"> default</span>=<span class="dt">&quot;Server Error&quot;</span><span class="kw">/&gt;</span>&lt;/h1&gt;</a>
<a class="sourceLine" id="cb1-7" title="7">Cause: &lt;pre&gt;<span class="kw">&lt;hs:cause</span><span class="ot"> default</span>=<span class="dt">&quot;Unable to complete your request.&quot;</span><span class="kw">/&gt;</span>&lt;/pre&gt;</a>
<a class="sourceLine" id="cb1-8" title="8">...</a></code></pre></div>
<p>or</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode jsp"><code class="sourceCode jsp"><a class="sourceLine" id="cb2-1" title="1">&lt;%@ page<span class="ot"> isErrorPage</span>=<span class="st">&quot;true&quot;</span><span class="ot"> import</span>=<span class="st">&quot;net.thauvin.erik.httpstatus.Reasons&quot;</span><span class="ot"> </span>%&gt;</a>
<a class="sourceLine" id="cb2-2" title="2">&lt;%= Reasons.getReasonPhrase(pageContext.getErrorData().getStatusCode()) %&gt;</a></code></pre></div>
<p>would display on a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.2">501 status code</a>:</p>
<pre><code>Not Implemented
</code></pre>
<h2 id="hscause">hs:cause</h2>
<p>The <code>&lt;hs:cause/&gt;</code> tag displays the cause of current HTTP status code, if any. A shorthand for:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode jsp"><code class="sourceCode jsp"><a class="sourceLine" id="cb4-1" title="1">&lt;%= pageContext.getErrorData().getThrowable().getCause().getLocalizedMessage() %&gt;</a></code></pre></div>
<p>Optional attributes are:</p>
<table>
<thead>
<tr class="header">
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>default</code></td>
<td>The fallback value to output, if no cause is available.</td>
</tr>
<tr class="even">
<td><code>escapeXml</code></td>
<td>Converts &lt;, &gt;, &amp;, ', " to their corresponding <a href="http://dev.w3.org/html5/html-author/charref">entity codes</a>. Value is <code>true</code> by default.</td>
</tr>
</tbody>
</table>
<h2 id="hscode">hs:code</h2>
<p>The <code>&lt;hs:code/&gt;</code> tag displays the current HTTP status code, if any. A shorthand for:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode jsp"><code class="sourceCode jsp"><a class="sourceLine" id="cb5-1" title="1">&lt;%= pageContext.getErrorData().getStatusCode() %&gt;</a></code></pre></div>
<h2 id="hsreason">hs:reason</h2>
<p>The <code>&lt;hs:reason/&gt;</code> tag displays the reason for a HTTP status code, if any. Optional attributes are:</p>
<table>
<thead>
<tr class="header">
<th>Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>code</code></td>
<td>The HTTP status error code. If not specified the current status code is used.</td>
</tr>
<tr class="even">
<td><code>default</code></td>
<td>The fallback value to output, if no reason is available.</td>
</tr>
<tr class="odd">
<td><code>escapeXml</code></td>
<td>Converts &lt;, &gt;, &amp;, ', " to their corresponding <a href="http://dev.w3.org/html5/html-author/charref">entity codes</a>. Value is <code>true</code> by default.</td>
</tr>
</tbody>
</table>
<p>The reasons are defined in a <a href="http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html">ResourceBundle</a> properties as follows:</p>
<table>
<thead>
<tr class="header">
<th>Status Code</th>
<th>Reason</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td><code>100</code></td>
<td>Continue</td>
</tr>
<tr class="even">
<td><code>101</code></td>
<td>Switching Protocols</td>
</tr>
<tr class="odd">
<td><code>102</code></td>
<td>Processing</td>
</tr>
<tr class="even">
<td><code>103</code></td>
<td>Early Hints</td>
</tr>
<tr class="odd">
<td><code>200</code></td>
<td>OK</td>
</tr>
<tr class="even">
<td><code>201</code></td>
<td>Created</td>
</tr>
<tr class="odd">
<td><code>202</code></td>
<td>Accepted</td>
</tr>
<tr class="even">
<td><code>203</code></td>
<td>Non-Authoritative Information</td>
</tr>
<tr class="odd">
<td><code>204</code></td>
<td>No Content</td>
</tr>
<tr class="even">
<td><code>205</code></td>
<td>Reset Content</td>
</tr>
<tr class="odd">
<td><code>206</code></td>
<td>Partial Content</td>
</tr>
<tr class="even">
<td><code>207</code></td>
<td>Multi-Status</td>
</tr>
<tr class="odd">
<td><code>208</code></td>
<td>Already Reported</td>
</tr>
<tr class="even">
<td><code>226</code></td>
<td>IM Used</td>
</tr>
<tr class="odd">
<td><code>300</code></td>
<td>Multiple Choices</td>
</tr>
<tr class="even">
<td><code>301</code></td>
<td>Moved Permanently</td>
</tr>
<tr class="odd">
<td><code>302</code></td>
<td>Found/Moved Temporarily</td>
</tr>
<tr class="even">
<td><code>303</code></td>
<td>See Other</td>
</tr>
<tr class="odd">
<td><code>304</code></td>
<td>Not Modified</td>
</tr>
<tr class="even">
<td><code>305</code></td>
<td>Use Proxy</td>
</tr>
<tr class="odd">
<td><code>306</code></td>
<td>Switch Proxy</td>
</tr>
<tr class="even">
<td><code>307</code></td>
<td>Temporary Redirect</td>
</tr>
<tr class="odd">
<td><code>308</code></td>
<td>Permanent Redirect</td>
</tr>
<tr class="even">
<td><code>400</code></td>
<td>Bad Request</td>
</tr>
<tr class="odd">
<td><code>401</code></td>
<td>Unauthorized</td>
</tr>
<tr class="even">
<td><code>402</code></td>
<td>Payment Required</td>
</tr>
<tr class="odd">
<td><code>403</code></td>
<td>Forbidden</td>
</tr>
<tr class="even">
<td><code>404</code></td>
<td>Not Found</td>
</tr>
<tr class="odd">
<td><code>405</code></td>
<td>Method Not Allowed</td>
</tr>
<tr class="even">
<td><code>406</code></td>
<td>Not Acceptable</td>
</tr>
<tr class="odd">
<td><code>407</code></td>
<td>Proxy Authentication Required</td>
</tr>
<tr class="even">
<td><code>408</code></td>
<td>Request Timeout</td>
</tr>
<tr class="odd">
<td><code>409</code></td>
<td>Conflict</td>
</tr>
<tr class="even">
<td><code>410</code></td>
<td>Gone</td>
</tr>
<tr class="odd">
<td><code>411</code></td>
<td>Length Required</td>
</tr>
<tr class="even">
<td><code>412</code></td>
<td>Precondition Failed</td>
</tr>
<tr class="odd">
<td><code>413</code></td>
<td>Request Entity/Payload Too Large</td>
</tr>
<tr class="even">
<td><code>414</code></td>
<td>Request-URI Too Long</td>
</tr>
<tr class="odd">
<td><code>415</code></td>
<td>Unsupported Media Type</td>
</tr>
<tr class="even">
<td><code>416</code></td>
<td>Requested Range Not Satisfiable</td>
</tr>
<tr class="odd">
<td><code>417</code></td>
<td>Expectation Failed</td>
</tr>
<tr class="even">
<td><code>418</code></td>
<td>I'm A Teapot</td>
</tr>
<tr class="odd">
<td><code>419</code></td>
<td>Insufficient Space on Resource</td>
</tr>
<tr class="even">
<td><code>420</code></td>
<td>Method Failure</td>
</tr>
<tr class="odd">
<td><code>421</code></td>
<td>Misdirected Request</td>
</tr>
<tr class="even">
<td><code>422</code></td>
<td>Unprocessable Entity</td>
</tr>
<tr class="odd">
<td><code>423</code></td>
<td>Locked</td>
</tr>
<tr class="even">
<td><code>424</code></td>
<td>Failed Dependency</td>
</tr>
<tr class="odd">
<td><code>426</code></td>
<td>Upgrade Required</td>
</tr>
<tr class="even">
<td><code>428</code></td>
<td>Precondition Required</td>
</tr>
<tr class="odd">
<td><code>429</code></td>
<td>Too Many Requests</td>
</tr>
<tr class="even">
<td><code>431</code></td>
<td>Request Header Fields Too Large</td>
</tr>
<tr class="odd">
<td><code>440</code></td>
<td>Login Timeout</td>
</tr>
<tr class="even">
<td><code>444</code></td>
<td>No Response</td>
</tr>
<tr class="odd">
<td><code>449</code></td>
<td>Retry With</td>
</tr>
<tr class="even">
<td><code>450</code></td>
<td>Blocked by Windows Parental Controls</td>
</tr>
<tr class="odd">
<td><code>451</code></td>
<td>Unavailable For Legal Reasons</td>
</tr>
<tr class="even">
<td><code>494</code></td>
<td>Request Header Too Large</td>
</tr>
<tr class="odd">
<td><code>495</code></td>
<td>Cert Error</td>
</tr>
<tr class="even">
<td><code>496</code></td>
<td>No Cert</td>
</tr>
<tr class="odd">
<td><code>497</code></td>
<td>HTTP to HTTPS</td>
</tr>
<tr class="even">
<td><code>498</code></td>
<td>Token Expired/Invalid</td>
</tr>
<tr class="odd">
<td><code>499</code></td>
<td>Client Closed Request</td>
</tr>
<tr class="even">
<td><code>500</code></td>
<td>Internal Server Error</td>
</tr>
<tr class="odd">
<td><code>501</code></td>
<td>Not Implemented</td>
</tr>
<tr class="even">
<td><code>502</code></td>
<td>Bad Gateway</td>
</tr>
<tr class="odd">
<td><code>503</code></td>
<td>Service Unavailable</td>
</tr>
<tr class="even">
<td><code>504</code></td>
<td>Gateway Timeout</td>
</tr>
<tr class="odd">
<td><code>505</code></td>
<td>HTTP Version Not Supported</td>
</tr>
<tr class="even">
<td><code>506</code></td>
<td>Variant Also Negotiates</td>
</tr>
<tr class="odd">
<td><code>507</code></td>
<td>Insufficient Storage</td>
</tr>
<tr class="even">
<td><code>508</code></td>
<td>Loop Detected</td>
</tr>
<tr class="odd">
<td><code>509</code></td>
<td>Bandwidth Limit Exceeded</td>
</tr>
<tr class="even">
<td><code>510</code></td>
<td>Not Extended</td>
</tr>
<tr class="odd">
<td><code>511</code></td>
<td>Network Authentication Required</td>
</tr>
<tr class="even">
<td><code>520</code></td>
<td>Unknown Error</td>
</tr>
<tr class="odd">
<td><code>522</code></td>
<td>Origin Connection Time-out</td>
</tr>
<tr class="even">
<td><code>598</code></td>
<td>Network Read Timeout Error</td>
</tr>
<tr class="odd">
<td><code>599</code></td>
<td>Network Connect Timeout Error</td>
</tr>
</tbody>
</table>
<h2 id="usage-with-gradle-or-maven">Usage with <a href="https://gradle.org/">Gradle</a> or <a href="http://maven.apache.org/">Maven</a></h2>
<p>Include the following in your <code>build.gradle</code> file:</p>
<pre class="gradle"><code>dependencies {
compile &#39;net.thauvin.erik.httpstatus:httpstatus:1.0.4&#39;
}
</code></pre>
<p>or as a Maven artifact:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode xml"><code class="sourceCode xml"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">&lt;dependency&gt;</span></a>
<a class="sourceLine" id="cb7-2" title="2"> <span class="kw">&lt;groupId&gt;</span>net.thauvin.erik.httpstatus<span class="kw">&lt;/groupId&gt;</span></a>
<a class="sourceLine" id="cb7-3" title="3"> <span class="kw">&lt;artifactId&gt;</span>httpstatus<span class="kw">&lt;/artifactId&gt;</span></a>
<a class="sourceLine" id="cb7-4" title="4"> <span class="kw">&lt;version&gt;</span>1.0.4<span class="kw">&lt;/version&gt;</span></a>
<a class="sourceLine" id="cb7-5" title="5"><span class="kw">&lt;/dependency&gt;</span></a></code></pre></div>
<h2 id="command-line-usage">Command Line Usage</h2>
<p>You can query the reason phrase for status codes as follows:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><a class="sourceLine" id="cb8-1" title="1">$ <span class="ex">java</span> -jar httpstatus-1.0.4.jar 404 500</a>
<a class="sourceLine" id="cb8-2" title="2"><span class="ex">404</span>: Not Found</a>
<a class="sourceLine" id="cb8-3" title="3"><span class="ex">500</span>: Internal Server Error</a></code></pre></div>
<p>If no status code is specified, all will be printed:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode sh"><code class="sourceCode bash"><a class="sourceLine" id="cb9-1" title="1">$ <span class="ex">java</span> -jar httpstatus-1.0.4.jar</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="ex">100</span>: Continue</a>
<a class="sourceLine" id="cb9-3" title="3"><span class="ex">101</span>: Switching Protocols</a>
<a class="sourceLine" id="cb9-4" title="4"><span class="ex">102</span>: Processing</a>
<a class="sourceLine" id="cb9-5" title="5"><span class="ex">103</span>: Early Hints</a>
<a class="sourceLine" id="cb9-6" title="6"><span class="ex">200</span>: OK</a>
<a class="sourceLine" id="cb9-7" title="7"><span class="ex">201</span>: Created</a>
<a class="sourceLine" id="cb9-8" title="8"><span class="ex">202</span>: Accepted</a>
<a class="sourceLine" id="cb9-9" title="9"><span class="ex">203</span>: Non-Authoritative Information</a>
<a class="sourceLine" id="cb9-10" title="10"><span class="ex">204</span>: No Content</a>
<a class="sourceLine" id="cb9-11" title="11"><span class="ex">205</span>: Reset Content</a>
<a class="sourceLine" id="cb9-12" title="12"><span class="ex">206</span>: Partial Content</a>
<a class="sourceLine" id="cb9-13" title="13"><span class="ex">207</span>: Multi-Status</a>
<a class="sourceLine" id="cb9-14" title="14"><span class="ex">208</span>: Already Reported</a>
<a class="sourceLine" id="cb9-15" title="15"><span class="ex">226</span>: IM Used</a>
<a class="sourceLine" id="cb9-16" title="16"><span class="ex">...</span></a></code></pre></div>
</body>
</html>

425
docs/github-pandoc.css Normal file

File diff suppressed because one or more lines are too long

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

188
gradlew vendored Executable file
View file

@ -0,0 +1,188 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

100
gradlew.bat vendored Normal file
View file

@ -0,0 +1,100 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

Binary file not shown.

View file

@ -1,7 +0,0 @@
bld.downloadExtensionJavadoc=false
bld.downloadExtensionSources=true
bld.downloadLocation=
bld.extension-jacoco=com.uwyn.rife2:bld-jacoco-report:0.9.10
bld.extension-pmd=com.uwyn.rife2:bld-pmd:1.2.3
bld.repositories=MAVEN_CENTRAL,RIFE2_RELEASES,MAVEN_LOCAL,RIFE2_SNAPSHOTS
bld.version=2.2.1

50
pom.xml
View file

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>net.thauvin.erik.httpstatus</groupId>
<artifactId>httpstatus</artifactId>
<version>1.1.2-SNAPSHOT</version>
<name>HttpStatus</name>
<description>Tag library to display the code, reason, cause and/or message for HTTP status codes in JSP error pages</description>
<url>https://github.com/ethauvin/HttpStatus</url>
<licenses>
<license>
<name>The BSD 3-Clause License</name>
<url>https://opensource.org/licenses/BSD-3-Clause</url>
</license>
</licenses>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>4.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>6.0.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<developers>
<developer>
<id>ethauvin</id>
<name>Erik C. Thauvin</name>
<email>erik@thauvin.net</email>
<url>https://erik.thauvin.net/</url>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/ethauvin/HttpStatus.git</connection>
<developerConnection>scm:git:git@github.com:ethauvin/HttpStatus.git</developerConnection>
<url>https://github.com/ethauvin/HttpStatus</url>
</scm>
</project>

19
settings.gradle Normal file
View file

@ -0,0 +1,19 @@
/*
* This settings file was auto generated by the Gradle buildInit task
* by 'erik' at '12/2/15 1:19 PM' with Gradle 2.9
*
* The settings file is used to specify which projects to include in your build.
* In a single project build this file can be empty or even removed.
*
* Detailed information about configuring a multi-project build in Gradle can be found
* in the user guide at https://docs.gradle.org/2.9/userguide/multi_project_builds.html
*/
/*
// To declare projects as part of a multi-project build use the 'include' method
include 'shared'
include 'api'
include 'services:webservice'
*/
rootProject.name = 'httpstatus'

View file

@ -1,7 +0,0 @@
sonar.organization=ethauvin-github
sonar.projectKey=ethauvin_HttpStatus
sonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml
sonar.sources=src/main/java/
sonar.tests=src/test/java/
sonar.java.binaries=build/main,build/test
sonar.java.libraries=lib/compile/*.jar

View file

@ -1,157 +0,0 @@
/*
* HttpStatusBuild.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.httpstatus;
import rife.bld.BuildCommand;
import rife.bld.Project;
import rife.bld.extension.JacocoReportOperation;
import rife.bld.extension.PmdOperation;
import rife.bld.publish.*;
import rife.tools.exceptions.FileUtilsErrorException;
import java.io.File;
import java.util.List;
import java.util.jar.Attributes;
import static rife.bld.dependencies.Repository.*;
import static rife.bld.dependencies.Scope.compile;
import static rife.bld.dependencies.Scope.test;
import static rife.bld.operations.JavadocOptions.DocLinkOption.NO_MISSING;
public class HttpStatusBuild extends Project {
final PmdOperation pmdOp = new PmdOperation()
.fromProject(this)
.failOnViolation(true)
.ruleSets("config/pmd.xml");
public HttpStatusBuild() {
pkg = "net.thauvin.erik.httpstatus";
name = "HttpStatus";
version = version(1, 1, 2, "SNAPSHOT");
var description = "Tag library to display the code, reason, cause and/or message for HTTP status codes in JSP error pages";
var url = "https://github.com/ethauvin/HttpStatus";
mainClass = "net.thauvin.erik.httpstatus.Reasons";
javaRelease = 17;
downloadSources = true;
autoDownloadPurge = true;
repositories = List.of(MAVEN_CENTRAL, SONATYPE_SNAPSHOTS);
scope(compile)
.include(dependency("jakarta.servlet", "jakarta.servlet-api", version(6, 1, 0)))
.include(dependency("jakarta.servlet.jsp", "jakarta.servlet.jsp-api", version(4, 0, 0)))
.include(dependency("jakarta.el", "jakarta.el-api", version(6, 0, 1)));
scope(test)
.include(dependency("org.assertj", "assertj-core", version(3, 27, 3)))
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 12, 2)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 12, 2)));
jarOperation().manifestAttribute(Attributes.Name.MAIN_CLASS, pkg + '.' + "Reasons");
javadocOperation().javadocOptions()
.docTitle(description + ' ' + version.toString())
.docLint(NO_MISSING)
.link("https://jakarta.ee/specifications/platform/9/apidocs/");
publishOperation()
.repository(version.isSnapshot() ? repository(SONATYPE_SNAPSHOTS_LEGACY.location())
.withCredentials(property("sonatype.user"), property("sonatype.password"))
: repository(SONATYPE_RELEASES_LEGACY.location())
.withCredentials(property("sonatype.user"), property("sonatype.password")))
.repository(repository("github"))
.info(new PublishInfo()
.groupId(pkg)
.artifactId(name.toLowerCase())
.name(name)
.version(version)
.description(description)
.url(url)
.developer(new PublishDeveloper()
.id("ethauvin")
.name("Erik C. Thauvin")
.email("erik@thauvin.net")
.url("https://erik.thauvin.net/")
)
.license(new PublishLicense()
.name("The BSD 3-Clause License")
.url("https://opensource.org/licenses/BSD-3-Clause")
)
.scm(new PublishScm()
.connection("scm:git:" + url + ".git")
.developerConnection("scm:git:git@github.com:ethauvin/" + name + ".git")
.url(url))
.signKey(property("sign.key"))
.signPassphrase(property("sign.passphrase")));
}
public static void main(String[] args) {
new HttpStatusBuild().start(args);
}
@BuildCommand(summary = "Generates JaCoCo Reports")
public void jacoco() throws Exception {
new JacocoReportOperation()
.fromProject(this)
.execute();
}
@BuildCommand(summary = "Runs PMD analysis")
public void pmd() throws Exception {
pmdOp.execute();
}
@BuildCommand(value = "pmd-cli", summary = "Runs PMD analysis (CLI)")
public void pmdCli() throws Exception {
pmdOp.includeLineNumber(false).execute();
}
private void pomRoot() throws FileUtilsErrorException {
PomBuilder.generateInto(publishOperation().fromProject(this).info(), dependencies(),
new File(workDirectory, "pom.xml"));
}
@Override
public void publish() throws Exception {
super.publish();
pomRoot();
}
@Override
public void publishLocal() throws Exception {
super.publishLocal();
pomRoot();
}
}

View file

@ -1,7 +1,7 @@
/*
* Reasons.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,8 +32,11 @@
package net.thauvin.erik.httpstatus;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
@ -41,7 +44,7 @@ import java.util.concurrent.ConcurrentHashMap;
* Populates the {@link #REASON_PHRASES reason phrases} map from {@link #BUNDLE_BASENAME bundle properties}, and
* implements accessor methods.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-02
* @since 1.0
*/
@ -57,8 +60,8 @@ public final class Reasons {
// Initializes the reason phrases map.
static {
var bundle = ResourceBundle.getBundle(BUNDLE_BASENAME);
for (var key : bundle.keySet()) {
final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_BASENAME);
for (final String key : bundle.keySet()) {
REASON_PHRASES.put(key, bundle.getString(key));
}
}
@ -76,7 +79,7 @@ public final class Reasons {
* @param statusCode The status code.
* @return The reason phrase, or <code>null</code>.
*/
public static String getReasonPhrase(int statusCode) {
public static String getReasonPhrase(final int statusCode) {
return getReasonPhrase(Integer.toString(statusCode));
}
@ -86,36 +89,31 @@ public final class Reasons {
* @param statusCode The status code.
* @return The reason phrase, or <code>null</code>.
*/
public static String getReasonPhrase(String statusCode) {
@SuppressWarnings({"WeakerAccess"})
public static String getReasonPhrase(final String statusCode) {
return REASON_PHRASES.get(statusCode);
}
/**
* Prints the reason phrase for the given status code(s).
*
* @param args The status code(s) or response class(es), prints all if none.
* @param args The status code(s), prints all if none.
*/
@SuppressWarnings("PMD.SystemPrintln")
public static void main(String... args) {
var keys = new TreeSet<>(REASON_PHRASES.keySet());
@SuppressFBWarnings("MUI_CONTAINSKEY_BEFORE_GET")
public static void main(final String... args) {
if (args.length >= 1) {
for (var arg : args) {
if (arg.endsWith("xx")) { // e.g.: 2xx
var responseClass = arg.charAt(0);
keys.forEach(k -> {
if (k.charAt(0) == responseClass) {
System.out.println(k + ": " + REASON_PHRASES.get(k));
}
});
} else { // e.g.: 404
var value = REASON_PHRASES.get(arg);
if (value != null) {
System.out.println(arg + ": " + value);
}
for (final String key : args) {
if (REASON_PHRASES.containsKey(key)) {
System.out.println(key + ": " + REASON_PHRASES.get(key));
}
}
} else { // Print all
keys.forEach(k -> System.out.println(k + ": " + REASON_PHRASES.get(k)));
} else {
final SortedSet<String> keys = new TreeSet<>(REASON_PHRASES.keySet());
for (final String key : keys) {
System.out.println(key + ": " + REASON_PHRASES.get(key));
}
System.out.println("Total: " + REASON_PHRASES.size());
}
}

View file

@ -1,153 +0,0 @@
/*
* StatusCode.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.httpstatus;
import java.io.Serial;
import java.io.Serializable;
/**
* The <code>StatusCode</code> bean implements methods to check the class of an HTTP status code.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @since 1.1.0
*/
public class StatusCode implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private int code;
/**
* Creates a new StatusCode object.
*/
public StatusCode() {
// Default constructor.
}
/**
* Creates a new StatusCode object.
*
* @param code The status code.
*/
public StatusCode(int code) {
this.code = code;
}
/**
* Returns the status code.
*/
public int getCode() {
return code;
}
/**
* Returns the reason for the status code.
*
* @return The reason, or <code>null</code>.
* @see Reasons#getReasonPhrase(int)
*/
public String getReason() {
return Reasons.getReasonPhrase(code);
}
/**
* Checks if the status code is a client error. (eg: <code>Internal Server Error</code>)
*
* @return <code>true</code> if the status code is a client error, <code>false</code> otherwise.
*/
public boolean isClientError() {
return code >= 400 && code < 500;
}
/**
* Checks if the status code is a client or server error.
*
* @return <code>true</code> if the status code is an error, <code>false</code> otherwise.
*/
public boolean isError() {
return code >= 400 && code < 600;
}
/**
* Checks if the status code is informational.
*
* @return <code>true</code> if the status code is informational, <code>false</code> otherwise.
*/
public boolean isInfo() {
return code >= 100 && code < 200;
}
/**
* Checks if the status code is a redirect.
*
* @return <code>true</code> if the status code is a redirect, <code>false</code> otherwise.
*/
public boolean isRedirect() {
return code >= 300 && code < 400;
}
/**
* Checks if the status code is a server error.
*
* @return <code>true</code> if the status code is a server error, <code>false</code> otherwise.
*/
public boolean isServerError() {
return code >= 500 && code < 600;
}
/**
* Checks if the status code is a (<code>OK</code>) success.
*
* @return <code>true</code> if the status code is a success, <code>false</code> otherwise.
*/
public boolean isSuccess() {
return code >= 200 && code < 300;
}
/**
* Checks if the status code is valid.
*
* @return <code>true</code> if the status code is valid, <code>false</code> otherwise.
*/
public boolean isValid() {
return code == 783 || (code >= 100 && code < 600);
}
/**
* Sets the status code.
*
* @param code The HTTP status code.
*/
public void setCode(int code) {
this.code = code;
}
}

View file

@ -1,7 +1,7 @@
/*
* Utils.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,11 +38,12 @@ import java.io.Writer;
/**
* The <code>Utils</code> class implements a collection of utility methods used throughout this project.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-03
* @since 1.0
*/
public final class Utils {
/**
* Disables the default constructor.
*
@ -59,18 +60,30 @@ public final class Utils {
* @param value The string value to convert.
* @return The converted string value.
*/
public static String escapeXml(String value) {
var escaped = new StringBuilder();
public static String escapeXml(final String value) {
final StringBuilder escaped = new StringBuilder();
for (var i = 0; i < value.length(); i++) {
var c = value.charAt(i);
for (int i = 0; i < value.length(); i++) {
final char c = value.charAt(i);
switch (c) {
case '<' -> escaped.append("&lt;");
case '>' -> escaped.append("&gt;");
case '&' -> escaped.append("&amp;");
case '\'' -> escaped.append("&apos;");
case '"' -> escaped.append("&quot;");
default -> escaped.append(c);
case '<':
escaped.append("&lt;");
break;
case '>':
escaped.append("&gt;");
break;
case '&':
escaped.append("&amp;");
break;
case '\'':
escaped.append("&#039;");
break;
case '"':
escaped.append("&#034;");
break;
default:
escaped.append(c);
break;
}
}
@ -86,12 +99,20 @@ public final class Utils {
* @param xml The {@link #escapeXml(String) xml} flag.
* @throws IOException If an I/O error occurs.
*/
public static void outWrite(Writer out, String value, String defaultValue, boolean xml)
throws IOException {
if (value != null) {
out.write(xml ? escapeXml(value) : value);
} else if (defaultValue != null) {
out.write(xml ? escapeXml(defaultValue) : defaultValue);
public static void outWrite(final Writer out, final String value, final String defaultValue, final boolean xml)
throws IOException {
if (xml) {
if (value != null) {
out.write(escapeXml(value));
} else if (defaultValue != null) {
out.write(escapeXml(defaultValue));
}
} else {
if (value != null) {
out.write(value);
} else if (defaultValue != null) {
out.write(defaultValue);
}
}
}
}

View file

@ -1,7 +1,7 @@
/*
* CauseTag.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,47 +32,36 @@
package net.thauvin.erik.httpstatus.taglibs;
import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.PageContext;
import net.thauvin.erik.httpstatus.Utils;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import java.io.IOException;
/**
* The <code>&lt;hs:cause&gt;</code> tag returns the cause (if any) for the current HTTP Status Error Code.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-03
* @since 1.0
*/
public class CauseTag extends XmlSupport {
/**
* Prints the cause (if any) for the current HTTP Status Error Code.
*
* @throws IOException If an error occurs while writing the output.
* {@inheritDoc}
*/
@Override
public void doTag() throws IOException {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
final PageContext pageContext = (PageContext) getJspContext();
final JspWriter out = pageContext.getOut();
Throwable cause = pageContext.getErrorData().getThrowable().getCause();
String cause;
Utils.outWrite(out, getCause(cause), defaultValue, escapeXml);
}
/**
* Returns the cause's localized message or default value.
*
* @param cause The cause.
* @return The cause or {@code null}.
*/
public String getCause(Throwable cause) {
if (cause != null && cause.getLocalizedMessage() != null) {
return cause.getLocalizedMessage();
} else {
return null;
try {
cause = pageContext.getErrorData().getThrowable().getCause().getLocalizedMessage();
} catch (NullPointerException ignore) {
cause = defaultValue;
}
Utils.outWrite(out, cause, defaultValue, escapeXml);
}
}

View file

@ -1,7 +1,7 @@
/*
* CodeTag.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,29 +32,26 @@
package net.thauvin.erik.httpstatus.taglibs;
import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.PageContext;
import jakarta.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;
/**
* The <code>&lt;hs:code&gt;</code> tag returns the HTTP Status Error Code.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-03
* @since 1.0
*/
public class CodeTag extends SimpleTagSupport {
/**
* Writes the HTTP Status Error Code to the current JspWriter.
*
* @throws IOException If an I/O error occurs.
* {@inheritDoc}
*/
@Override
public void doTag() throws IOException {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
final PageContext pageContext = (PageContext) getJspContext();
final JspWriter out = pageContext.getOut();
out.write(String.valueOf(pageContext.getErrorData().getStatusCode()));
}

View file

@ -1,64 +0,0 @@
/*
* MessageTag.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.httpstatus.taglibs;
import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.PageContext;
import net.thauvin.erik.httpstatus.Utils;
import java.io.IOException;
/**
* The <code>&lt;hs:message&gt;</code> tag returns the message (if any) for the current error.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @created 2022-03-16
* @since 1.0.5
*/
public class MessageTag extends XmlSupport {
/**
* Writes the error message associated with the current HTTP Status Error Code.
*
* @throws IOException If an I/O error occurs.
*/
@Override
public void doTag() throws IOException {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
String message = (String) pageContext.getRequest().getAttribute(
jakarta.servlet.RequestDispatcher.ERROR_MESSAGE);
Utils.outWrite(out, message, defaultValue, escapeXml);
}
}

View file

@ -1,7 +1,7 @@
/*
* ReasonTag.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,18 +32,18 @@
package net.thauvin.erik.httpstatus.taglibs;
import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.PageContext;
import net.thauvin.erik.httpstatus.Reasons;
import net.thauvin.erik.httpstatus.Utils;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import java.io.IOException;
/**
* The <code>&lt;hs:reason&gt;</code> tag returns the Reason Phrase for the current (or specified) HTTP Status Error
* Code.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-02
* @since 1.0
*/
@ -51,21 +51,21 @@ public class ReasonTag extends XmlSupport {
private int statusCode = -1;
/**
* Writes the Reason Phrase for the current (or specified) HTTP Status Error Code.
* {@inheritDoc}
*/
@Override
public void doTag() {
PageContext pageContext = (PageContext) getJspContext();
JspWriter out = pageContext.getOut();
final PageContext pageContext = (PageContext) getJspContext();
final JspWriter out = pageContext.getOut();
try {
if (statusCode > -1) {
Utils.outWrite(out, Reasons.getReasonPhrase(statusCode), defaultValue, escapeXml);
} else {
Utils.outWrite(out, Reasons.getReasonPhrase(pageContext.getErrorData().getStatusCode()), defaultValue,
escapeXml);
escapeXml);
}
} catch (IOException ignored) {
} catch (IOException ignore) {
// Ignore.
}
}
@ -75,7 +75,10 @@ public class ReasonTag extends XmlSupport {
*
* @param statusCode The status code.
*/
public void setCode(int statusCode) {
@SuppressWarnings("unused")
public void setCode(final int statusCode) {
this.statusCode = statusCode;
}
}

View file

@ -1,7 +1,7 @@
/*
* XmlSupport.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,12 +32,12 @@
package net.thauvin.erik.httpstatus.taglibs;
import jakarta.servlet.jsp.tagext.SimpleTagSupport;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* Adds support for the <code>default</code> and <code>escapeXml</code> tag attributes.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-03
* @since 1.0
*/
@ -58,7 +58,7 @@ public abstract class XmlSupport extends SimpleTagSupport {
* @param defaultValue The default value.
*/
@SuppressWarnings("unused")
public void setDefault(String defaultValue) {
public void setDefault(final String defaultValue) {
this.defaultValue = defaultValue;
}
@ -68,7 +68,7 @@ public abstract class XmlSupport extends SimpleTagSupport {
* @param escapeXml <code>true</code> or <code>false</code>
*/
@SuppressWarnings("unused")
public void setEscapeXml(boolean escapeXml) {
public void setEscapeXml(final boolean escapeXml) {
this.escapeXml = escapeXml;
}
}

View file

@ -2,7 +2,7 @@
<!--
~ httpstatus.tld
~
~ Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
~ Copyright (c) 2015-2019, Erik C. Thauvin (erik@thauvin.net)
~ All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
@ -37,7 +37,7 @@
<description>HttpStatus JSP Tag Library</description>
<display-name>HttpStatus JSP Tags</display-name>
<tlib-version>1.1.1</tlib-version>
<tlib-version>1.0.4</tlib-version>
<short-name>hs</short-name>
<uri>http://erik.thauvin.net/taglibs/httpstatus</uri>
@ -75,31 +75,6 @@
<body-content>empty</body-content>
</tag>
<tag>
<description>
Returns the message (if any) for the current error.
</description>
<name>message</name>
<tag-class>net.thauvin.erik.httpstatus.taglibs.MessageTag</tag-class>
<body-content>empty</body-content>
<attribute>
<description>
Default value if the resulting error message is null.
</description>
<name>default</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<description>
Converts &lt;, &gt; ,&amp; ,' ," to their corresponding entity codes. Value is true by default.
</description>
<name>escapeXml</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<tag>
<description>
Returns the Reason Phrase for the current (or specified) HTTP Status Error Code.

View file

@ -1,44 +1,7 @@
#
# reasons.properties
#
# Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# Neither the name of this project nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
100=Continue
101=Switching Protocols
102=Processing
103=Early Hints
110=Response is Stale
111=Revalidation Failed
112=Disconnected Operation
113=Heuristic Expiration
199=Miscellaneous Warning
200=OK
201=Created
202=Accepted
@ -48,17 +11,14 @@
206=Partial Content
207=Multi-Status
208=Already Reported
214=Transformation Applied
218=This is fine
226=IM Used
299=Miscellaneous Persistent Warning
300=Multiple Choices
301=Moved Permanently
302=Found/Moved Temporarily
303=See Other
304=Not Modified
305=Use Proxy
306=Unused
306=Switch Proxy
307=Temporary Redirect
308=Permanent Redirect
400=Bad Request
@ -74,35 +34,31 @@
410=Gone
411=Length Required
412=Precondition Failed
413=Payload Too Large
414=URI Too Long
413=Request Entity/Payload Too Large
414=Request-URI Too Long
415=Unsupported Media Type
416=Range Not Satisfiable
416=Requested Range Not Satisfiable
417=Expectation Failed
418=I'm A Teapot
419=Insufficient Space on Resource
420=Method Failure
421=Misdirected Request
422=Unprocessable Content
422=Unprocessable Entity
423=Locked
424=Failed Dependency
425=Too Early
426=Upgrade Required
428=Precondition Required
429=Too Many Requests
430=Request Header Fields Too Large
431=Request Header Fields Too Large
440=Login Timeout
444=No Response
449=Retry With
450=Blocked by Windows Parental Controls
451=Unavailable For Legal Reasons
460=Client Closed Connection Before Load Balancer Idle Timeout
463=X-Forwarded-For Header with More than 30 IP Addresses
494=Request Header Too Large
495=SSL Certificate Error
496=SSL Certificate Required
497=HTTP Request Sent to HTTPS Port
495=Cert Error
496=No Cert
497=HTTP to HTTPS
498=Token Expired/Invalid
499=Client Closed Request
500=Internal Server Error
@ -118,17 +74,6 @@
510=Not Extended
511=Network Authentication Required
520=Unknown Error
521=Web Server Is Down
522=Connection Timed Out
523=Origin Is Unreachable
524=A Timeout Occurred
525=SSL Handshake Failed
526=Invalid SSL Certificate
527=Railgun Error
529=Site is overloaded
530=Site is frozen
540=Temporarily Disabled
561=Unauthorized
522=Origin Connection Time-out
598=Network Read Timeout Error
599=Network Connect Timeout Error
783=Unexpected Token

View file

@ -1,58 +0,0 @@
/*
* CauseTagTest.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.httpstatus;
import net.thauvin.erik.httpstatus.taglibs.CauseTag;
import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.junit.jupiter.api.Test;
/**
* Implements the CauseTagTest class.
*
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @since 1.1.0
*/
class CauseTagTest {
@Test
void causeTest() {
var message = "This is the cause";
var tag = new CauseTag();
try (var softly = new AutoCloseableSoftAssertions()) {
softly.assertThat(tag.getCause(new Exception(message))).as("has cause").isEqualTo(message);
softly.assertThat(tag.getCause(new Exception())).as("no cause").isNull();
softly.assertThat(tag.getCause(null)).as("null").isNull();
softly.assertThat(tag.getCause(new Exception(""))).as("empty").isEmpty();
}
}
}

View file

@ -1,7 +1,7 @@
/*
* ReasonsMainTest.java
* TestMain.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2019, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,73 +32,47 @@
package net.thauvin.erik.httpstatus;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertTrue;
/**
* Main Class Tests.
* The <code>TestMain</code> class.
*
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @author <a href="https://erik.thauvin.net/" target="_blank">Erik C. Thauvin</a>
* @created 2019-05-06
* @since 1.0
*/
class ReasonsMainTest {
private static final ByteArrayOutputStream OUTPUT_STREAM = new ByteArrayOutputStream();
private static final PrintStream SYSTEM_OUT = System.out;
@SuppressFBWarnings({"DM_DEFAULT_ENCODING", "ITU_INAPPROPRIATE_TOSTRING_USE"})
public class ReasonsMainTest {
private final PrintStream originalOut = System.out;
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
@AfterAll
public static void restoreStreams() {
System.setOut(SYSTEM_OUT);
@AfterTest
public void restoreStreams() {
System.setOut(originalOut);
}
@BeforeAll
public static void setUpStreams() {
System.setOut(new PrintStream(OUTPUT_STREAM));
}
@BeforeEach
public void resetStreams() {
OUTPUT_STREAM.reset();
@BeforeTest
public void setUpStreams() {
System.setOut(new PrintStream(outContent));
}
@Test
void testMain() {
public void testMain() {
Reasons.main("401");
assertThat(OUTPUT_STREAM.toString()).contains(Reasons.getReasonPhrase("401")).as("401");
assertThat(OUTPUT_STREAM.toString()).doesNotContain("500").as("401 no 500");
assertTrue(outContent.toString().contains(Reasons.getReasonPhrase("401")));
}
@Test
void testMainAll() {
public void testMainAll() {
Reasons.main();
assertThat(OUTPUT_STREAM.toString()).contains(Reasons.getReasonPhrase(301)).as("301");
assertThat(OUTPUT_STREAM.toString()).contains(Reasons.getReasonPhrase(404)).as("404");
}
@Test
void testMainArgs() {
Reasons.main("500", "302");
assertThat(OUTPUT_STREAM.toString()).contains(Reasons.getReasonPhrase("500")).as("500 (302)");
assertThat(OUTPUT_STREAM.toString()).contains(Reasons.getReasonPhrase("302")).as("(500) 302");
assertThat(OUTPUT_STREAM.toString()).doesNotContain("404").as("500/302 not 404");
}
@Test
void testMainArgsClass() {
Reasons.main("2xx");
assertThat(OUTPUT_STREAM.toString()).contains(Reasons.getReasonPhrase("200")).as("2xx");
}
@Test
void testMainInvalid() {
Reasons.main("aaa");
assertThat(OUTPUT_STREAM.toString()).as("invalid argument: aaa").isEmpty();
assertTrue(outContent.toString().contains(Reasons.getReasonPhrase(401)));
}
}

View file

@ -1,7 +1,7 @@
/*
* ReasonsTest.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,27 +32,27 @@
package net.thauvin.erik.httpstatus;
import org.junit.jupiter.api.Test;
import org.testng.annotations.Test;
import java.util.ResourceBundle;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;
/**
* Reasons Tests.
* The <code>ReasonsTest</code> class.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-03
* @since 1.0
*/
class ReasonsTest {
public class ReasonsTest {
@Test
void testGetReasonPhrase() {
var bundle = ResourceBundle.getBundle(Reasons.BUNDLE_BASENAME);
for (var key : bundle.keySet()) {
assertThat(Reasons.getReasonPhrase(key)).as("getReasonPhrase(%s)", key).isEqualTo(bundle.getString(key));
assertThat(Reasons.getReasonPhrase(Integer.parseInt(key))).as("getReasonPhrase(%s)", key)
.isEqualTo(bundle.getString(key));
public void testGetReasonPhrase() {
final ResourceBundle bundle = ResourceBundle.getBundle(Reasons.BUNDLE_BASENAME);
for (final String key : bundle.keySet()) {
assertEquals(bundle.getString(key), Reasons.getReasonPhrase(key), "getReasonPhrase(" + key + ')');
assertEquals(bundle.getString(key), Reasons.getReasonPhrase(Integer.parseInt(key)),
"getReasonPhrase(int: " + key + ')');
}
}

View file

@ -1,96 +0,0 @@
/*
* StatusCodeTest.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of this project nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.thauvin.erik.httpstatus;
import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.junit.jupiter.api.Test;
import java.util.ResourceBundle;
import static org.assertj.core.api.Assertions.assertThat;
/**
* StatusCode Tests.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @since 1.1.0
*/
class StatusCodeTest {
@Test
void testStatusCode() {
var bundle = ResourceBundle.getBundle(Reasons.BUNDLE_BASENAME);
var statusCode = new StatusCode();
try (var softly = new AutoCloseableSoftAssertions()) {
for (var key : bundle.keySet()) {
int code = Integer.parseInt(key);
statusCode.setCode(code);
softly.assertThat(statusCode.getCode()).as("is not %s", code).isEqualTo(code);
softly.assertThat(statusCode.isInfo()).as("%s is info", code).isEqualTo(code >= 100 && code < 200);
softly.assertThat(statusCode.isSuccess()).as("%s is ok", code).isEqualTo(code >= 200 && code < 300);
softly.assertThat(statusCode.isRedirect()).as("%s is redirect", code)
.isEqualTo(code >= 300 && code < 400);
softly.assertThat(statusCode.isClientError()).as("%s is client error", code)
.isEqualTo(code >= 400 && code < 500);
softly.assertThat(statusCode.isServerError()).as("%s is server error", code)
.isEqualTo(code >= 500 && code < 600);
softly.assertThat(statusCode.isError()).as("%s is error", code).isEqualTo(code >= 400 && code < 600);
softly.assertThat(statusCode.isValid()).as("%s is valid", code).isTrue();
softly.assertThat(statusCode.getReason()).as("%s reason phrase is not valid", code)
.isEqualTo(Reasons.getReasonPhrase(code));
}
}
try (var softly = new AutoCloseableSoftAssertions()) {
int[] unknowns = {0, 99, 600};
for (var code : unknowns) {
statusCode.setCode(code);
softly.assertThat(statusCode.getCode()).as("is not %s", code).isEqualTo(code);
softly.assertThat(statusCode.isInfo()).as("%s is info", code).isFalse();
softly.assertThat(statusCode.isSuccess()).as("%s is ok", code).isFalse();
softly.assertThat(statusCode.isRedirect()).as("%s is redirect", code).isFalse();
softly.assertThat(statusCode.isClientError()).as("%s is client error", code).isFalse();
softly.assertThat(statusCode.isServerError()).as("%s is server error", code).isFalse();
softly.assertThat(statusCode.isError()).as("%s is error", code).isFalse();
softly.assertThat(statusCode.isValid()).as("%s is invalid", code).isFalse();
softly.assertThat(statusCode.getReason()).as("%s reason phrase is not null.", code).isNull();
}
}
statusCode = new StatusCode(900);
assertThat(statusCode.getCode()).as("is not %s", statusCode.getCode()).isEqualTo(900);
}
}

View file

@ -1,7 +1,7 @@
/*
* UtilsTest.java
*
* Copyright 2015-2025 Erik C. Thauvin (erik@thauvin.net)
* Copyright (c) 2015-2016, Erik C. Thauvin (erik@thauvin.net)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,69 +32,69 @@
package net.thauvin.erik.httpstatus;
import org.assertj.core.api.AutoCloseableSoftAssertions;
import org.junit.jupiter.api.Test;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.testng.annotations.Test;
import java.io.IOException;
import java.io.StringWriter;
import static org.assertj.core.api.Assertions.assertThat;
import static org.testng.Assert.assertEquals;
/**
* Utils Tests.
* The <code>UtilsTest</code> class.
*
* @author <a href="mailto:erik@thauvin.net">Erik C. Thauvin</a>
* @author <a href="mailto:erik@thauvin.net" target="_blank">Erik C. Thauvin</a>
* @created 2015-12-03
* @since 1.0
*/
class UtilsTest {
public class UtilsTest {
@Test
void testEscapeXml() {
assertThat(Utils.escapeXml(
"This is a test. We wan't to make sure that everything is <encoded> according the \"encoding\" "
+ "parameter & value."))
.isEqualTo("This is a test. We wan&apos;t to make sure that everything is &lt;encoded&gt; " +
"according the &quot;encoding&quot; parameter &amp; value.");
public void testEscapeXml() {
assertEquals(Utils.escapeXml(
"This is a test. We wan't to make sure that everything is <encoded> according the \"encoding\" parameter "
+ "& value."), "This is a test. We wan&#039;t to make sure that everything is &lt;encoded&gt; according "
+ "the &#034;encoding&#034; parameter &amp; value.");
}
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
@SuppressFBWarnings("CE_CLASS_ENVY")
@Test
void testOutWrite() throws IOException {
try (var sw = new StringWriter(); var softly = new AutoCloseableSoftAssertions()) {
var defaultValue = "default";
Utils.outWrite(sw, null, defaultValue, false);
softly.assertThat(sw.toString()).as("outWrite(default)").isEqualTo(defaultValue);
public void testOutWrite() throws IOException {
try (final StringWriter sw = new StringWriter()) {
Utils.outWrite(sw, null, "default", false);
assertEquals(sw.toString(), "default", "outWrite(default)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, "", defaultValue, false);
softly.assertThat(sw.toString()).as("outWrite(value empty)").isEmpty();
Utils.outWrite(sw, "", "default", false);
assertEquals(sw.toString(), "", "outWrite(value empty)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, null, null, true);
softly.assertThat(sw.toString()).as("outWrite(null)").isEmpty();
assertEquals(sw.toString(), "", "outWrite(null)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, "value", defaultValue, false);
softly.assertThat(sw.toString()).as("outWrite(value)").isEqualTo("value");
Utils.outWrite(sw, "value", "default", false);
assertEquals(sw.toString(), "value", "outWrite(value)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, "wan't", defaultValue, true);
softly.assertThat(sw.toString()).as("outWrite(wan't)").isEqualTo("wan&apos;t");
Utils.outWrite(sw, "wan't", "default", true);
assertEquals(sw.toString(), "wan&#039;t", "outWrite(wan't)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, null, "1 & 1", true);
softly.assertThat(sw.toString()).as("outWrite(1 & 1)").isEqualTo("1 &amp; 1");
assertEquals(sw.toString(), "1 &amp; 1", "outWrite(1 & 1)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, "", defaultValue, true);
softly.assertThat(sw.toString()).as("outWrite(value empty).as(xml)").isEmpty();
Utils.outWrite(sw, "", "default", true);
assertEquals(sw.toString(), "", "outWrite(value empty, xml)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, null, "", true);
softly.assertThat(sw.toString()).as("outWrite(default empty)").isEmpty();
assertEquals(sw.toString(), "", "outWrite(default empty)");
sw.getBuffer().setLength(0);
Utils.outWrite(sw, null, null, true);
softly.assertThat(sw.toString()).as("outWrite(null).as(xml)").isEmpty();
assertEquals(sw.toString(), "", "outWrite(null, xml)");
}
}
}

8
version.properties Normal file
View file

@ -0,0 +1,8 @@
#Generated by the Semver Plugin for Gradle
#Sun May 05 23:59:32 PDT 2019
version.buildmeta=
version.major=1
version.minor=0
version.patch=4
version.prerelease=
version.semver=1.0.4