Merge branch 'pr/109'

Closes gh-109
This commit is contained in:
rstoyanchev
2022-07-14 14:31:26 +01:00
241 changed files with 17516 additions and 17906 deletions

View File

@@ -6,9 +6,9 @@ buildscript {
plugins {
id 'io.spring.dependency-management' version '1.0.9.RELEASE' apply false
id 'org.asciidoctor.jvm.pdf' version '3.3.0'
id 'org.asciidoctor.jvm.gems' version '3.3.0'
id 'org.asciidoctor.jvm.convert' version '3.3.0'
id 'org.asciidoctor.jvm.pdf' version '3.3.2'
id 'org.asciidoctor.jvm.gems' version '3.3.2'
id 'org.asciidoctor.jvm.convert' version '3.3.2'
id 'de.undercouch.download' version '4.1.2'
}
@@ -23,43 +23,33 @@ ext {
allprojects {
group = "org.springframework.webflow"
apply plugin: "java"
apply plugin: "java-library"
apply plugin: "io.spring.dependency-management"
apply plugin: "org.springframework.build.optional-dependencies"
apply from: "${rootProject.projectDir}/ide.gradle"
dependencyManagement {
imports {
mavenBom "org.springframework:spring-framework-bom:5.3.3"
mavenBom "org.springframework.security:spring-security-bom:5.4.4"
mavenBom "org.springframework:spring-framework-bom:6.0.0-M4"
mavenBom "org.springframework.security:spring-security-bom:5.5.6"
mavenBom "org.junit:junit-bom:5.7.1"
}
dependencies {
dependency "javax.servlet:javax.servlet-api:4.0.1"
dependency "jakarta.servlet:jakarta.servlet-api:5.0.0"
dependency "javax.servlet:jstl:1.2"
dependency "javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02"
dependency "javax.el:javax.el-api:3.0.1-b06"
dependency "javax.validation:validation-api:2.0.1.Final"
dependencySet(group: 'org.hibernate', version: '5.4.27.Final') {
entry 'hibernate-core'
dependency "jakarta.servlet.jsp:jakarta.servlet.jsp-api:3.0.0"
dependency "jakarta.el:jakarta.el-api:4.0.0"
dependency "jakarta.validation:jakarta.validation-api:3.0.0"
dependencySet(group: 'org.hibernate', version: '5.6.6.Final') {
entry 'hibernate-core-jakarta'
entry 'hibernate-entitymanager'
}
dependency "org.hibernate:hibernate-validator:6.2.0.Final"
dependency "org.hibernate:hibernate-validator:7.0.4.Final"
dependencySet(group: 'com.sun.faces', version: '2.2.20') {
entry 'jsf-api'
entry 'jsf-impl'
}
dependencySet(group: 'org.apache.tiles', version: '3.0.8') {
entry 'tiles-api'
entry('tiles-core', withoutJclOverSlf4j)
entry('tiles-servlet', withoutJclOverSlf4j)
entry('tiles-jsp', withoutJclOverSlf4j)
entry('tiles-el', withoutJclOverSlf4j)
entry('tiles-extras') {
exclude group: "org.springframework", name: "spring-web"
}
}
dependency "org.apache.myfaces.core:myfaces-impl:2.2.14"
dependency "org.apache.myfaces.core:myfaces-impl:3.0.1"
dependency "com.sun.facelets:jsf-facelets:1.1.14"
dependency "org.hsqldb:hsqldb:2.5.0"
@@ -74,7 +64,7 @@ allprojects {
dependency("junit:junit:4.13.2")
dependency "org.easymock:easymock:4.2"
dependency "org.hamcrest:hamcrest:2.1"
dependency "org.apache.tomcat:tomcat-jasper-el:9.0.34"
dependency "org.apache.tomcat:tomcat-jasper-el:10.0.20"
dependency "org.apache.myfaces.test:myfaces-test22:1.0.8"
}
generatedPomCustomization {
@@ -89,6 +79,8 @@ allprojects {
if (version.endsWith('SNAPSHOT')) {
maven { url "https://repo.spring.io/snapshot" }
}
// For Spring Framework 6 milestones
maven { url "https://repo.spring.io/milestone" }
}
configurations.all {
resolutionStrategy {
@@ -99,30 +91,6 @@ allprojects {
}
subprojects { subproject ->
apply from: "${rootProject.projectDir}/publish-maven.gradle"
sourceCompatibility=1.8
targetCompatibility=1.8
[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:none"]
sourceSets.test.resources.srcDirs = ["src/main/java", "src/test/resources", "src/test/java"]
jar {
manifest.attributes["Implementation-Title"] = subproject.name
manifest.attributes["Implementation-Version"] = subproject.version
from("${rootProject.projectDir}/src/dist") {
include "license.txt"
include "notice.txt"
into "META-INF"
expand(copyright: new Date().format("yyyy"), version: project.version)
}
}
}
configure(javaProjects) { javaProject ->
test {
@@ -154,6 +122,33 @@ configure(javaProjects) { javaProject ->
}
}
subprojects { subproject ->
apply from: "${rootProject.projectDir}/publish-maven.gradle"
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
[compileJava, compileTestJava]*.options*.compilerArgs = ["-Xlint:none"]
sourceSets.test.resources.srcDirs = ["src/main/java", "src/test/resources", "src/test/java"]
jar {
manifest.attributes["Implementation-Title"] = subproject.name
manifest.attributes["Implementation-Version"] = subproject.version
from("${rootProject.projectDir}/src/dist") {
include "license.txt"
include "notice.txt"
into "META-INF"
expand(copyright: new Date().format("yyyy"), version: project.version)
}
}
}
configure(rootProject) {
description = "Spring Web Flow"
@@ -267,7 +262,7 @@ configure(rootProject) {
group = "Distribution"
archiveBaseName = "spring-webflow"
archiveClassifier = "docs"
description = "Builds -${archiveClassifier} archive containing api and reference " +
description = "Builds -${archiveClassifier.get()} archive containing api and reference " +
"for deployment at static.springframework.org/spring-webflow/docs."
from (api) {
@@ -292,9 +287,11 @@ configure(rootProject) {
group = "Distribution"
archiveBaseName = "spring-webflow"
archiveClassifier = "schema"
description = "Builds -${archiveClassifier} archive containing all " +
description = "Builds -${archiveClassifier.get()} archive containing all " +
"XSDs for deployment at static.springframework.org/schema."
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
subprojects.each { subproject ->
Properties schemas = new Properties()
@@ -328,10 +325,10 @@ configure(rootProject) {
group = "Distribution"
archiveBaseName = "spring-webflow"
archiveClassifier = "dist"
description = "Builds -${archiveClassifier} archive, containing all jars and docs, " +
description = "Builds -${archiveClassifier.get()} archive, containing all jars and docs, " +
"suitable for community download page."
def baseDir = "${archiveBaseName}-${project.version}"
def baseDir = "${archiveBaseName.get()}-${project.version}"
from("src/dist") {
include "notice.txt"

View File

@@ -1 +1 @@
version=2.5.2.BUILD-SNAPSHOT
version=3.0.0-SNAPSHOT

Binary file not shown.

View File

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

269
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# 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
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${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"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# 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
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
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"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
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
@@ -106,80 +140,95 @@ 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 or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
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, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# 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"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@@ -4,8 +4,8 @@ import org.gradle.plugins.ide.eclipse.model.SourceFolder
apply plugin: "eclipse"
eclipse.jdt {
sourceCompatibility = 1.8
targetCompatibility = 1.8
sourceCompatibility = 17
targetCompatibility = 17
}
// Replace classpath entries with project dependencies (GRADLE-1116)

View File

@@ -1,55 +1,61 @@
apply plugin: "maven"
apply plugin: "maven-publish"
install {
repositories.mavenInstaller {
customizePom(pom, project)
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
if (project.name != 'spring-js-resources') {
artifact sourcesJar
artifact javadocJar
}
versionMapping {
usage('java-api') {
fromResolutionOf('compileClasspath')
}
usage('java-runtime') {
fromResolutionResult()
}
}
pom {
afterEvaluate {
description = project.description
name = project.description
}
url = "https://github.com/spring-projects/spring-webflow"
organization {
name = "Spring IO"
url = "https://spring.io/projects/spring-webflow"
}
licenses {
license {
name = "The Apache Software License, Version 2.0"
url = "https://www.apache.org/licenses/LICENSE-2.0.txt"
distribution = "repo"
}
}
scm {
url = "https://github.com/spring-projects/spring-webflow"
connection = "scm:git:git://github.com/spring-projects/spring-webflow"
developerConnection = "scm:git:git://github.com/spring-projects/spring-webflow"
}
developers {
developer {
id = "rstoyanchev"
name = "Rossen Stoyanchev"
email = "rstoyanchev@pivotal.io"
}
}
issueManagement {
system = "Jira"
url = "https://jira.spring.io/browse/SWF"
}
}
}
}
}
def customizePom(pom, gradleProject) {
pom.whenConfigured { generatedPom ->
// eliminate test-scoped dependencies (no need in maven central poms)
generatedPom.dependencies.removeAll { dep ->
dep.scope == "test"
}
// sort to make pom dependencies order consistent to ease comparison of older poms
generatedPom.dependencies = generatedPom.dependencies.sort { dep ->
"$dep.scope:$dep.groupId:$dep.artifactId"
}
// add all items necessary for maven central publication
generatedPom.project {
name = gradleProject.description
description = gradleProject.description
url = "https://github.com/spring-projects/spring-webflow"
organization {
name = "Spring IO"
url = "https://spring.io/projects/spring-webflow"
}
licenses {
license {
name "The Apache Software License, Version 2.0"
url "https://www.apache.org/licenses/LICENSE-2.0.txt"
distribution "repo"
}
}
scm {
url = "https://github.com/spring-projects/spring-webflow"
connection = "scm:git:git://github.com/spring-projects/spring-webflow"
developerConnection = "scm:git:git://github.com/spring-projects/spring-webflow"
}
developers {
developer {
id = "rstoyanchev"
name = "Rossen Stoyanchev"
email = "rstoyanchev@pivotal.io"
}
}
issueManagement {
system = "Jira"
url = "https://jira.spring.io/browse/SWF"
}
}
}
// Disable generation of Gradle Module Metadata for compatibility
// with older versions of Spring Web Flow.
tasks.withType(GenerateModuleMetadata) {
enabled = false
}

View File

@@ -9,7 +9,7 @@ rootProject.name = 'webflow'
include 'spring-binding'
include 'spring-webflow'
include 'spring-faces'
//include 'spring-faces'
include 'spring-js-resources'
rootProject.children.each {project ->

View File

@@ -1,15 +1,15 @@
description = "Spring Binding"
dependencies {
compile("org.springframework:spring-context")
implementation("org.springframework:spring-context")
compileOnly("javax.el:javax.el-api")
compileOnly("jakarta.el:jakarta.el-api")
testCompile("org.junit.jupiter:junit-jupiter")
testCompile("org.hamcrest:hamcrest")
testCompile("org.easymock:easymock")
testCompile("org.apache.tomcat:tomcat-jasper-el")
testRuntime("org.apache.logging.log4j:log4j-core")
testRuntime("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntime("org.apache.logging.log4j:log4j-jul")
}
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.hamcrest:hamcrest")
testImplementation("org.easymock:easymock")
testImplementation("org.apache.tomcat:tomcat-jasper-el")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
}

View File

@@ -1,45 +1,45 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.collection;
import java.util.Map;
/**
* A simple subinterface of {@link Map} that exposes a mutex that application code can synchronize on.
* <p>
* Expected to be implemented by Maps that are backed by shared objects that require synchronization between multiple
* threads. An example would be the HTTP session map.
*
* @author Keith Donald
*/
public interface SharedMap<K, V> extends Map<K, V> {
/**
* Returns the shared mutex that may be synchronized on using a synchronized block. The returned mutex is guaranteed
* to be non-null.
*
* Example usage:
*
* <pre>
* synchronized (sharedMap.getMutex()) {
* // do synchronized work
* }
* </pre>
*
* @return the mutex
*/
Object getMutex();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.collection;
import java.util.Map;
/**
* A simple subinterface of {@link Map} that exposes a mutex that application code can synchronize on.
* <p>
* Expected to be implemented by Maps that are backed by shared objects that require synchronization between multiple
* threads. An example would be the HTTP session map.
*
* @author Keith Donald
*/
public interface SharedMap<K, V> extends Map<K, V> {
/**
* Returns the shared mutex that may be synchronized on using a synchronized block. The returned mutex is guaranteed
* to be non-null.
*
* Example usage:
*
* <pre>
* synchronized (sharedMap.getMutex()) {
* // do synchronized work
* }
* </pre>
*
* @return the mutex
*/
Object getMutex();
}

View File

@@ -1,105 +1,105 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.collection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.springframework.core.style.ToStringCreator;
/**
* A map decorator that implements <code>SharedMap</code>. By default, simply returns the map itself as the mutex.
* Subclasses may override to return a different mutex object.
*
* @author Keith Donald
*/
public class SharedMapDecorator<K, V> implements SharedMap<K, V>, Serializable {
/**
* The wrapped, target map.
*/
private Map<K, V> map;
/**
* Creates a new shared map decorator.
* @param map the map that is shared by multiple threads, to be synced
*/
public SharedMapDecorator(Map<K, V> map) {
this.map = map;
}
// implementing Map
public void clear() {
map.clear();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public Set<Entry<K, V>> entrySet() {
return map.entrySet();
}
public V get(Object key) {
return map.get(key);
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set<K> keySet() {
return map.keySet();
}
public V put(K key, V value) {
return map.put(key, value);
}
public void putAll(Map<? extends K, ? extends V> map) {
this.map.putAll(map);
}
public V remove(Object key) {
return map.remove(key);
}
public int size() {
return map.size();
}
public Collection<V> values() {
return map.values();
}
// implementing SharedMap
public Object getMutex() {
return map;
}
public String toString() {
return new ToStringCreator(this).append("map", map).append("mutex", getMutex()).toString();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.collection;
import java.io.Serializable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.springframework.core.style.ToStringCreator;
/**
* A map decorator that implements <code>SharedMap</code>. By default, simply returns the map itself as the mutex.
* Subclasses may override to return a different mutex object.
*
* @author Keith Donald
*/
public class SharedMapDecorator<K, V> implements SharedMap<K, V>, Serializable {
/**
* The wrapped, target map.
*/
private Map<K, V> map;
/**
* Creates a new shared map decorator.
* @param map the map that is shared by multiple threads, to be synced
*/
public SharedMapDecorator(Map<K, V> map) {
this.map = map;
}
// implementing Map
public void clear() {
map.clear();
}
public boolean containsKey(Object key) {
return map.containsKey(key);
}
public boolean containsValue(Object value) {
return map.containsValue(value);
}
public Set<Entry<K, V>> entrySet() {
return map.entrySet();
}
public V get(Object key) {
return map.get(key);
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set<K> keySet() {
return map.keySet();
}
public V put(K key, V value) {
return map.put(key, value);
}
public void putAll(Map<? extends K, ? extends V> map) {
this.map.putAll(map);
}
public V remove(Object key) {
return map.remove(key);
}
public int size() {
return map.size();
}
public Collection<V> values() {
return map.values();
}
// implementing SharedMap
public Object getMutex() {
return map;
}
public String toString() {
return new ToStringCreator(this).append("map", map).append("mutex", getMutex()).toString();
}
}

View File

@@ -1,289 +1,289 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* Base class for map adapters whose keys are String values. Concrete classes need only implement the abstract hook
* methods defined by this class.
*
* @author Keith Donald
*/
public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
private Set<String> keySet;
private Collection<V> values;
private Set<Entry<String, V>> entrySet;
// implementing Map
public void clear() {
for (Iterator<String> it = getAttributeNames(); it.hasNext();) {
removeAttribute(it.next());
}
}
public boolean containsKey(Object key) {
return getAttribute(key.toString()) != null;
}
public boolean containsValue(Object value) {
if (value == null) {
return false;
}
for (Iterator<String> it = getAttributeNames(); it.hasNext();) {
Object aValue = getAttribute(it.next());
if (value.equals(aValue)) {
return true;
}
}
return false;
}
public Set<Entry<String, V>> entrySet() {
return (entrySet != null) ? entrySet : (entrySet = new EntrySet());
}
public V get(Object key) {
return getAttribute(key.toString());
}
public boolean isEmpty() {
return !getAttributeNames().hasNext();
}
public Set<String> keySet() {
return (keySet != null) ? keySet : (keySet = new KeySet());
}
public V put(String key, V value) {
String stringKey = String.valueOf(key);
V previousValue = getAttribute(stringKey);
setAttribute(stringKey, value);
return previousValue;
}
public void putAll(Map<? extends String, ? extends V> map) {
for (Entry<? extends String, ? extends V> entry : map.entrySet()) {
setAttribute(entry.getKey(), entry.getValue());
}
}
public V remove(Object key) {
String stringKey = key.toString();
V retval = getAttribute(stringKey);
removeAttribute(stringKey);
return retval;
}
public int size() {
int size = 0;
for (Iterator<String> it = getAttributeNames(); it.hasNext();) {
size++;
it.next();
}
return size;
}
public Collection<V> values() {
return (values != null) ? values : (values = new Values());
}
// hook methods
/**
* Hook method that needs to be implemented by concrete subclasses. Gets a value associated with a key.
* @param key the key to lookup
* @return the associated value, or null if none
*/
protected abstract V getAttribute(String key);
/**
* Hook method that needs to be implemented by concrete subclasses. Puts a key-value pair in the map, overwriting
* any possible earlier value associated with the same key.
* @param key the key to associate the value with
* @param value the value to associate with the key
*/
protected abstract void setAttribute(String key, V value);
/**
* Hook method that needs to be implemented by concrete subclasses. Removes a key and its associated value from the
* map.
* @param key the key to remove
*/
protected abstract void removeAttribute(String key);
/**
* Hook method that needs to be implemented by concrete subclasses. Returns an enumeration listing all keys known to
* the map.
* @return the key enumeration
*/
protected abstract Iterator<String> getAttributeNames();
// internal helper classes
private abstract class AbstractSet<T> extends java.util.AbstractSet<T> {
public boolean isEmpty() {
return StringKeyedMapAdapter.this.isEmpty();
}
public int size() {
return StringKeyedMapAdapter.this.size();
}
public void clear() {
StringKeyedMapAdapter.this.clear();
}
}
private class KeySet extends AbstractSet<String> {
public Iterator<String> iterator() {
return new KeyIterator();
}
public boolean contains(Object o) {
return StringKeyedMapAdapter.this.containsKey(o);
}
public boolean remove(Object o) {
return StringKeyedMapAdapter.this.remove(o) != null;
}
}
private abstract class AbstractKeyIterator {
private final Iterator<String> it = getAttributeNames();
private String currentKey;
public void remove() {
if (currentKey == null) {
throw new NoSuchElementException("You must call next() at least once");
}
StringKeyedMapAdapter.this.remove(currentKey);
}
public boolean hasNext() {
return it.hasNext();
}
protected String nextKey() {
return currentKey = it.next();
}
}
private class KeyIterator extends AbstractKeyIterator implements Iterator<String> {
public String next() {
return nextKey();
}
}
private class Values extends AbstractSet<V> {
public Iterator<V> iterator() {
return new ValuesIterator();
}
public boolean contains(Object o) {
return StringKeyedMapAdapter.this.containsValue(o);
}
public boolean remove(Object o) {
if (o == null) {
return false;
}
for (Iterator<V> it = iterator(); it.hasNext();) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
return false;
}
}
private class ValuesIterator extends AbstractKeyIterator implements Iterator<V> {
public V next() {
return StringKeyedMapAdapter.this.get(nextKey());
}
}
private class EntrySet extends AbstractSet<Entry<String, V>> {
public Iterator<Entry<String, V>> iterator() {
return new EntryIterator();
}
public boolean contains(Object o) {
Entry<String, V> entry = getAsEntry(o);
if (entry == null || entry.getKey() == null || entry.getValue() == null) {
return false;
}
V valueFromThisMap = StringKeyedMapAdapter.this.get(entry.getKey());
return entry.getValue().equals(valueFromThisMap);
}
public boolean remove(Object o) {
Entry<String, V> entry = getAsEntry(o);
if (entry == null || entry.getKey() == null || entry.getValue() == null) {
return false;
}
V valueFromThisMap = StringKeyedMapAdapter.this.get(entry.getKey());
if (!entry.getValue().equals(valueFromThisMap)) {
return false;
}
return StringKeyedMapAdapter.this.remove(entry.getKey()) != null;
}
@SuppressWarnings("unchecked")
private Entry<String, V> getAsEntry(Object o) {
if (o instanceof Entry) {
return (Entry<String, V>) o;
}
return null;
}
}
private class EntryIterator extends AbstractKeyIterator implements Iterator<Entry<String, V>> {
public Entry<String, V> next() {
return new EntrySetEntry(nextKey());
}
}
private class EntrySetEntry implements Entry<String, V> {
private final String currentKey;
public EntrySetEntry(String currentKey) {
this.currentKey = currentKey;
}
public String getKey() {
return currentKey;
}
public V getValue() {
return StringKeyedMapAdapter.this.get(currentKey);
}
public V setValue(V value) {
return StringKeyedMapAdapter.this.put(currentKey, value);
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
/**
* Base class for map adapters whose keys are String values. Concrete classes need only implement the abstract hook
* methods defined by this class.
*
* @author Keith Donald
*/
public abstract class StringKeyedMapAdapter<V> implements Map<String, V> {
private Set<String> keySet;
private Collection<V> values;
private Set<Entry<String, V>> entrySet;
// implementing Map
public void clear() {
for (Iterator<String> it = getAttributeNames(); it.hasNext();) {
removeAttribute(it.next());
}
}
public boolean containsKey(Object key) {
return getAttribute(key.toString()) != null;
}
public boolean containsValue(Object value) {
if (value == null) {
return false;
}
for (Iterator<String> it = getAttributeNames(); it.hasNext();) {
Object aValue = getAttribute(it.next());
if (value.equals(aValue)) {
return true;
}
}
return false;
}
public Set<Entry<String, V>> entrySet() {
return (entrySet != null) ? entrySet : (entrySet = new EntrySet());
}
public V get(Object key) {
return getAttribute(key.toString());
}
public boolean isEmpty() {
return !getAttributeNames().hasNext();
}
public Set<String> keySet() {
return (keySet != null) ? keySet : (keySet = new KeySet());
}
public V put(String key, V value) {
String stringKey = String.valueOf(key);
V previousValue = getAttribute(stringKey);
setAttribute(stringKey, value);
return previousValue;
}
public void putAll(Map<? extends String, ? extends V> map) {
for (Entry<? extends String, ? extends V> entry : map.entrySet()) {
setAttribute(entry.getKey(), entry.getValue());
}
}
public V remove(Object key) {
String stringKey = key.toString();
V retval = getAttribute(stringKey);
removeAttribute(stringKey);
return retval;
}
public int size() {
int size = 0;
for (Iterator<String> it = getAttributeNames(); it.hasNext();) {
size++;
it.next();
}
return size;
}
public Collection<V> values() {
return (values != null) ? values : (values = new Values());
}
// hook methods
/**
* Hook method that needs to be implemented by concrete subclasses. Gets a value associated with a key.
* @param key the key to lookup
* @return the associated value, or null if none
*/
protected abstract V getAttribute(String key);
/**
* Hook method that needs to be implemented by concrete subclasses. Puts a key-value pair in the map, overwriting
* any possible earlier value associated with the same key.
* @param key the key to associate the value with
* @param value the value to associate with the key
*/
protected abstract void setAttribute(String key, V value);
/**
* Hook method that needs to be implemented by concrete subclasses. Removes a key and its associated value from the
* map.
* @param key the key to remove
*/
protected abstract void removeAttribute(String key);
/**
* Hook method that needs to be implemented by concrete subclasses. Returns an enumeration listing all keys known to
* the map.
* @return the key enumeration
*/
protected abstract Iterator<String> getAttributeNames();
// internal helper classes
private abstract class AbstractSet<T> extends java.util.AbstractSet<T> {
public boolean isEmpty() {
return StringKeyedMapAdapter.this.isEmpty();
}
public int size() {
return StringKeyedMapAdapter.this.size();
}
public void clear() {
StringKeyedMapAdapter.this.clear();
}
}
private class KeySet extends AbstractSet<String> {
public Iterator<String> iterator() {
return new KeyIterator();
}
public boolean contains(Object o) {
return StringKeyedMapAdapter.this.containsKey(o);
}
public boolean remove(Object o) {
return StringKeyedMapAdapter.this.remove(o) != null;
}
}
private abstract class AbstractKeyIterator {
private final Iterator<String> it = getAttributeNames();
private String currentKey;
public void remove() {
if (currentKey == null) {
throw new NoSuchElementException("You must call next() at least once");
}
StringKeyedMapAdapter.this.remove(currentKey);
}
public boolean hasNext() {
return it.hasNext();
}
protected String nextKey() {
return currentKey = it.next();
}
}
private class KeyIterator extends AbstractKeyIterator implements Iterator<String> {
public String next() {
return nextKey();
}
}
private class Values extends AbstractSet<V> {
public Iterator<V> iterator() {
return new ValuesIterator();
}
public boolean contains(Object o) {
return StringKeyedMapAdapter.this.containsValue(o);
}
public boolean remove(Object o) {
if (o == null) {
return false;
}
for (Iterator<V> it = iterator(); it.hasNext();) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
return false;
}
}
private class ValuesIterator extends AbstractKeyIterator implements Iterator<V> {
public V next() {
return StringKeyedMapAdapter.this.get(nextKey());
}
}
private class EntrySet extends AbstractSet<Entry<String, V>> {
public Iterator<Entry<String, V>> iterator() {
return new EntryIterator();
}
public boolean contains(Object o) {
Entry<String, V> entry = getAsEntry(o);
if (entry == null || entry.getKey() == null || entry.getValue() == null) {
return false;
}
V valueFromThisMap = StringKeyedMapAdapter.this.get(entry.getKey());
return entry.getValue().equals(valueFromThisMap);
}
public boolean remove(Object o) {
Entry<String, V> entry = getAsEntry(o);
if (entry == null || entry.getKey() == null || entry.getValue() == null) {
return false;
}
V valueFromThisMap = StringKeyedMapAdapter.this.get(entry.getKey());
if (!entry.getValue().equals(valueFromThisMap)) {
return false;
}
return StringKeyedMapAdapter.this.remove(entry.getKey()) != null;
}
@SuppressWarnings("unchecked")
private Entry<String, V> getAsEntry(Object o) {
if (o instanceof Entry) {
return (Entry<String, V>) o;
}
return null;
}
}
private class EntryIterator extends AbstractKeyIterator implements Iterator<Entry<String, V>> {
public Entry<String, V> next() {
return new EntrySetEntry(nextKey());
}
}
private class EntrySetEntry implements Entry<String, V> {
private final String currentKey;
public EntrySetEntry(String currentKey) {
this.currentKey = currentKey;
}
public String getKey() {
return currentKey;
}
public V getValue() {
return StringKeyedMapAdapter.this.get(currentKey);
}
public V setValue(V value) {
return StringKeyedMapAdapter.this.put(currentKey, value);
}
}
}

View File

@@ -1,58 +1,58 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.convert.service;
import org.springframework.binding.convert.converters.Converter;
/**
* Package private converter that is a "no op".
*
* @author Keith Donald
*/
class NoOpConverter implements Converter {
private Class<?> sourceClass;
private Class<?> targetClass;
/**
* Create a "no op" converter from given source to given target class.
*/
public NoOpConverter(Class<?> sourceClass, Class<?> targetClass) {
this.sourceClass = sourceClass;
this.targetClass = targetClass;
}
public Class<?> getSourceClass() {
return sourceClass;
}
public Class<?> getTargetClass() {
return targetClass;
}
public Object convertSourceToTargetClass(Object source, Class<?> targetClass) {
return source;
}
public boolean isTwoWay() {
return true;
}
public Object convertTargetToSourceClass(Object target, Class<?> sourceClass) {
return target;
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.convert.service;
import org.springframework.binding.convert.converters.Converter;
/**
* Package private converter that is a "no op".
*
* @author Keith Donald
*/
class NoOpConverter implements Converter {
private Class<?> sourceClass;
private Class<?> targetClass;
/**
* Create a "no op" converter from given source to given target class.
*/
public NoOpConverter(Class<?> sourceClass, Class<?> targetClass) {
this.sourceClass = sourceClass;
this.targetClass = targetClass;
}
public Class<?> getSourceClass() {
return sourceClass;
}
public Class<?> getTargetClass() {
return targetClass;
}
public Object convertSourceToTargetClass(Object source, Class<?> targetClass) {
return source;
}
public boolean isTwoWay() {
return true;
}
public Object convertTargetToSourceClass(Object target, Class<?> sourceClass) {
return target;
}
}

View File

@@ -1,9 +1,9 @@
package org.springframework.binding.expression.el;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import jakarta.el.ELContext;
import jakarta.el.ELException;
import jakarta.el.ExpressionFactory;
import jakarta.el.ValueExpression;
import org.springframework.binding.convert.ConversionException;
import org.springframework.binding.convert.ConversionService;

View File

@@ -15,10 +15,10 @@
*/
package org.springframework.binding.expression.el;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.FunctionMapper;
import javax.el.VariableMapper;
import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.FunctionMapper;
import jakarta.el.VariableMapper;
/**
* A generic ELContext implementation.

View File

@@ -17,14 +17,14 @@ package org.springframework.binding.expression.el;
import java.util.List;
import javax.el.ArrayELResolver;
import javax.el.BeanELResolver;
import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.ListELResolver;
import javax.el.MapELResolver;
import javax.el.ResourceBundleELResolver;
import jakarta.el.ArrayELResolver;
import jakarta.el.BeanELResolver;
import jakarta.el.CompositeELResolver;
import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.ListELResolver;
import jakarta.el.MapELResolver;
import jakarta.el.ResourceBundleELResolver;
/**
* A generic ELResolver to be used as a default when no other ELResolvers have been configured by the client

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.binding.expression.el;
import javax.el.ELContext;
import jakarta.el.ELContext;
/**
* A factory for a DefaultELContext.

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.binding.expression.el;
import javax.el.ELContext;
import javax.el.ELResolver;
import jakarta.el.ELContext;
import jakarta.el.ELResolver;
/**
* A factory for creating a EL context object that will be used to evaluate a target object of an EL expression.

View File

@@ -15,9 +15,9 @@
*/
package org.springframework.binding.expression.el;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ValueExpression;
import jakarta.el.ELContext;
import jakarta.el.ELException;
import jakarta.el.ValueExpression;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.expression.Expression;
@@ -63,7 +63,7 @@ public class ELExpression implements Expression {
}
}
return result;
} catch (javax.el.PropertyNotFoundException e) {
} catch (jakarta.el.PropertyNotFoundException e) {
throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e);
} catch (ELException e) {
throw new EvaluationException(context.getClass(), getExpressionString(),
@@ -81,7 +81,7 @@ public class ELExpression implements Expression {
+ getExpressionString() + "' did not resolve... is the base variable ''" + getBaseVariable()
+ "' spelled correctly?");
}
} catch (javax.el.PropertyNotFoundException e) {
} catch (jakarta.el.PropertyNotFoundException e) {
throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e);
} catch (ELException e) {
throw new EvaluationException(context.getClass(), getExpressionString(),
@@ -94,7 +94,7 @@ public class ELExpression implements Expression {
ELContext ctx = elContextFactory.getELContext(context);
try {
return valueExpression.getType(ctx);
} catch (javax.el.PropertyNotFoundException e) {
} catch (jakarta.el.PropertyNotFoundException e) {
throw new PropertyNotFoundException(context.getClass(), getExpressionString(), e);
} catch (ELException e) {
throw new EvaluationException(context.getClass(), getExpressionString(),

View File

@@ -18,13 +18,13 @@ package org.springframework.binding.expression.el;
import java.util.HashMap;
import java.util.Map;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.ExpressionFactory;
import javax.el.FunctionMapper;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import jakarta.el.ELContext;
import jakarta.el.ELException;
import jakarta.el.ELResolver;
import jakarta.el.ExpressionFactory;
import jakarta.el.FunctionMapper;
import jakarta.el.ValueExpression;
import jakarta.el.VariableMapper;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;

View File

@@ -18,10 +18,10 @@ package org.springframework.binding.expression.el;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import java.util.Map;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.PropertyNotWritableException;
import jakarta.el.ELContext;
import jakarta.el.ELException;
import jakarta.el.ELResolver;
import jakarta.el.PropertyNotWritableException;
import org.springframework.binding.collection.MapAdaptable;

View File

@@ -1,76 +1,76 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.expression.support;
import java.util.Collection;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
/**
* A settable expression that adds non-null values to a collection.
*
* @author Keith Donald
*/
public class CollectionAddingExpression implements Expression {
/**
* The expression that resolves a mutable collection reference.
*/
private Expression collectionExpression;
/**
* Creates a collection adding property expression.
* @param collectionExpression the collection expression
*/
public CollectionAddingExpression(Expression collectionExpression) {
this.collectionExpression = collectionExpression;
}
public Object getValue(Object context) throws EvaluationException {
return collectionExpression.getValue(context);
}
@SuppressWarnings("unchecked")
public void setValue(Object context, Object value) throws EvaluationException {
Object result = getValue(context);
if (result == null) {
throw new EvaluationException(context.getClass(), collectionExpression.getExpressionString(),
"Unable to access collection value for expression '" + collectionExpression.getExpressionString()
+ "'", new IllegalStateException(
"The collection expression evaluated to a [null] reference"));
}
Assert.isInstanceOf(Collection.class, result, "Not a collection: ");
if (value != null) {
// add the value to the collection
((Collection<Object>) result).add(value);
}
}
public Class<?> getValueType(Object context) {
return Object.class;
}
public String getExpressionString() {
return collectionExpression.getExpressionString();
}
public String toString() {
return new ToStringCreator(this).append("collectionExpression", collectionExpression).toString();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.expression.support;
import java.util.Collection;
import org.springframework.binding.expression.EvaluationException;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
/**
* A settable expression that adds non-null values to a collection.
*
* @author Keith Donald
*/
public class CollectionAddingExpression implements Expression {
/**
* The expression that resolves a mutable collection reference.
*/
private Expression collectionExpression;
/**
* Creates a collection adding property expression.
* @param collectionExpression the collection expression
*/
public CollectionAddingExpression(Expression collectionExpression) {
this.collectionExpression = collectionExpression;
}
public Object getValue(Object context) throws EvaluationException {
return collectionExpression.getValue(context);
}
@SuppressWarnings("unchecked")
public void setValue(Object context, Object value) throws EvaluationException {
Object result = getValue(context);
if (result == null) {
throw new EvaluationException(context.getClass(), collectionExpression.getExpressionString(),
"Unable to access collection value for expression '" + collectionExpression.getExpressionString()
+ "'", new IllegalStateException(
"The collection expression evaluated to a [null] reference"));
}
Assert.isInstanceOf(Collection.class, result, "Not a collection: ");
if (value != null) {
// add the value to the collection
((Collection<Object>) result).add(value);
}
}
public Class<?> getValueType(Object context) {
return Object.class;
}
public String getExpressionString() {
return collectionExpression.getExpressionString();
}
public String toString() {
return new ToStringCreator(this).append("collectionExpression", collectionExpression).toString();
}
}

View File

@@ -41,8 +41,8 @@ public class MapAccessorTests {
@Test
public void testGetInteger() {
assertEquals(new Integer(9), accessor.getInteger("integer"));
assertEquals(new Integer(9), accessor.getRequiredInteger("integer"));
assertEquals(Integer.valueOf(9), accessor.getInteger("integer"));
assertEquals(Integer.valueOf(9), accessor.getRequiredInteger("integer"));
}
@Test

View File

@@ -90,7 +90,7 @@ public class DefaultConversionServiceTests {
DefaultConversionService service = new DefaultConversionService();
ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class);
Integer three = (Integer) executor.execute("3");
assertEquals(new Integer(3), three);
assertEquals(Integer.valueOf(3), three);
ConversionExecutor executor2 = service.getConversionExecutor(Integer.class, String.class);
String threeString = (String) executor2.execute(3);
@@ -107,7 +107,7 @@ public class DefaultConversionServiceTests {
service.addConverter(converter);
ConversionExecutor executor = service.getConversionExecutor(String.class, Integer.class);
Integer three = (Integer) executor.execute("3,000");
assertEquals(new Integer(3000), three);
assertEquals(Integer.valueOf(3000), three);
ConversionExecutor executor2 = service.getConversionExecutor(Integer.class, String.class);
String string = (String) executor2.execute(3000);
assertEquals("3,000", string);
@@ -123,7 +123,7 @@ public class DefaultConversionServiceTests {
service.addConverter("usaNumber", converter);
ConversionExecutor executor = service.getConversionExecutor("usaNumber", String.class, Integer.class);
Integer three = (Integer) executor.execute("3,000");
assertEquals(new Integer(3000), three);
assertEquals(Integer.valueOf(3000), three);
ConversionExecutor executor2 = service.getConversionExecutor("usaNumber", Integer.class, String.class);
String string = (String) executor2.execute(3000);
assertEquals("3,000", string);
@@ -413,7 +413,7 @@ public class DefaultConversionServiceTests {
DefaultConversionService service = new DefaultConversionService();
ConversionExecutor executor = service.getConversionExecutor(String.class, int.class);
Integer three = (Integer) executor.execute("3");
assertEquals(new Integer(3), three);
assertEquals(Integer.valueOf(3), three);
}
@Test
@@ -421,9 +421,9 @@ public class DefaultConversionServiceTests {
DefaultConversionService service = new DefaultConversionService();
ConversionExecutor executor = service.getConversionExecutor(String[].class, Integer[].class);
Integer[] result = (Integer[]) executor.execute(new String[] { "1", "2", "3" });
assertEquals(new Integer(1), result[0]);
assertEquals(new Integer(2), result[1]);
assertEquals(new Integer(3), result[2]);
assertEquals(Integer.valueOf(1), result[0]);
assertEquals(Integer.valueOf(2), result[1]);
assertEquals(Integer.valueOf(3), result[2]);
}
@Test
@@ -490,9 +490,9 @@ public class DefaultConversionServiceTests {
// list.add("2");
// list.add("3");
// Integer[] result = (Integer[]) executor.execute(list);
// assertEquals(new Integer(1), result[0]);
// assertEquals(new Integer(2), result[1]);
// assertEquals(new Integer(3), result[2]);
// assertEquals(Integer.valueOf(1), result[0]);
// assertEquals(Integer.valueOf(2), result[1]);
// assertEquals(Integer.valueOf(3), result[2]);
} catch (ConversionExecutorNotFoundException e) {
// This is expected
@@ -549,7 +549,7 @@ public class DefaultConversionServiceTests {
ConversionExecutor executor = service.getConversionExecutor(String.class, Integer[].class);
Integer[] result = (Integer[]) executor.execute("123");
assertEquals(1, result.length);
assertEquals(new Integer(123), result[0]);
assertEquals(Integer.valueOf(123), result[0]);
}
private static class CustomConverter implements Converter {

View File

@@ -1,70 +1,70 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.binding.convert.service;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Date;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.converters.StringToDate;
public class StaticConversionExecutorImplTests {
private StaticConversionExecutor conversionExecutor;
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.binding.convert.service;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Date;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.converters.StringToDate;
public class StaticConversionExecutorImplTests {
private StaticConversionExecutor conversionExecutor;
@BeforeEach
public void setUp() {
StringToDate stringToDate = new StringToDate();
conversionExecutor = new StaticConversionExecutor(String.class, Date.class, stringToDate);
}
public void setUp() {
StringToDate stringToDate = new StringToDate();
conversionExecutor = new StaticConversionExecutor(String.class, Date.class, stringToDate);
}
@Test
public void testTypeConversion() {
assertTrue(conversionExecutor.execute("2008-10-10").getClass().equals(Date.class));
}
public void testTypeConversion() {
assertTrue(conversionExecutor.execute("2008-10-10").getClass().equals(Date.class));
}
@Test
public void testAssignmentCompatibleTypeConversion() {
java.sql.Date date = new java.sql.Date(123L);
try {
assertSame(date, conversionExecutor.execute(date));
fail("Should have failed");
} catch (ConversionExecutionException e) {
}
}
public void testAssignmentCompatibleTypeConversion() {
java.sql.Date date = new java.sql.Date(123L);
try {
assertSame(date, conversionExecutor.execute(date));
fail("Should have failed");
} catch (ConversionExecutionException e) {
}
}
@Test
public void testConvertNull() {
assertNull(conversionExecutor.execute(null));
}
public void testConvertNull() {
assertNull(conversionExecutor.execute(null));
}
@Test
public void testIllegalType() {
try {
conversionExecutor.execute(new StringBuilder());
fail();
} catch (ConversionExecutionException e) {
// expected
}
}
}
public void testIllegalType() {
try {
conversionExecutor.execute(new StringBuilder());
fail();
} catch (ConversionExecutionException e) {
// expected
}
}
}

View File

@@ -6,10 +6,10 @@ import static org.junit.jupiter.api.Assertions.fail;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.el.FunctionMapper;
import javax.el.VariableMapper;
import jakarta.el.ELContext;
import jakarta.el.ELResolver;
import jakarta.el.FunctionMapper;
import jakarta.el.VariableMapper;
import org.apache.el.ExpressionFactoryImpl;
import org.junit.jupiter.api.BeforeEach;

View File

@@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.HashMap;
import java.util.Map;
import javax.el.ELContext;
import jakarta.el.ELContext;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

View File

@@ -1,60 +1,60 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.binding.method;
import static org.junit.jupiter.api.Assertions.assertSame;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link MethodInvocationException}.
*
* @author Erwin Vervaet
*/
public class MethodInvocationExceptionTests {
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.binding.method;
import static org.junit.jupiter.api.Assertions.assertSame;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import org.junit.jupiter.api.Test;
/**
* Test case for {@link MethodInvocationException}.
*
* @author Erwin Vervaet
*/
public class MethodInvocationExceptionTests {
@Test
public void testGetTargetException() {
// runtime exception
IllegalArgumentException iae = new IllegalArgumentException("test");
MethodInvocationException ex = testException(iae);
assertSame(iae, ex.getTargetException());
// exception
IOException ioe = new IOException("test");
ex = testException(ioe);
assertSame(ioe, ex.getTargetException());
// nested
InvocationTargetException ite = new InvocationTargetException(ioe);
ex = testException(ite);
assertSame(ioe, ex.getTargetException());
// deep nesting
ite = new InvocationTargetException(new InvocationTargetException(ioe));
ex = testException(ite);
assertSame(ioe, ex.getTargetException());
}
// internal helpers
private MethodInvocationException testException(Throwable cause) {
return new MethodInvocationException(new MethodSignature("test"), null, cause);
}
}
public void testGetTargetException() {
// runtime exception
IllegalArgumentException iae = new IllegalArgumentException("test");
MethodInvocationException ex = testException(iae);
assertSame(iae, ex.getTargetException());
// exception
IOException ioe = new IOException("test");
ex = testException(ioe);
assertSame(ioe, ex.getTargetException());
// nested
InvocationTargetException ite = new InvocationTargetException(ioe);
ex = testException(ite);
assertSame(ioe, ex.getTargetException());
// deep nesting
ite = new InvocationTargetException(new InvocationTargetException(ioe));
ex = testException(ite);
assertSame(ioe, ex.getTargetException());
}
// internal helpers
private MethodInvocationException testException(Throwable cause) {
return new MethodInvocationException(new MethodSignature("test"), null, cause);
}
}

View File

@@ -1,98 +1,98 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.method;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.binding.expression.support.StaticExpression;
/**
* Unit tests for {@link org.springframework.binding.method.MethodInvoker}.
*
* @author Erwin Vervaet
* @author Jeremy Grelle
*/
public class MethodInvokerTests {
private MethodInvoker methodInvoker;
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.binding.method;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.binding.expression.support.StaticExpression;
/**
* Unit tests for {@link org.springframework.binding.method.MethodInvoker}.
*
* @author Erwin Vervaet
* @author Jeremy Grelle
*/
public class MethodInvokerTests {
private MethodInvoker methodInvoker;
@BeforeEach
public void setUp() {
this.methodInvoker = new MethodInvoker();
}
public void setUp() {
this.methodInvoker = new MethodInvoker();
}
@Test
public void testInvocationTargetException() {
try {
methodInvoker.invoke(new MethodSignature("test"), new TestObject(), null);
fail();
} catch (MethodInvocationException e) {
assertTrue(e.getTargetException() instanceof IllegalArgumentException);
assertEquals("just testing", e.getTargetException().getMessage());
}
}
public void testInvocationTargetException() {
try {
methodInvoker.invoke(new MethodSignature("test"), new TestObject(), null);
fail();
} catch (MethodInvocationException e) {
assertTrue(e.getTargetException() instanceof IllegalArgumentException);
assertEquals("just testing", e.getTargetException().getMessage());
}
}
@Test
public void testInvalidMethod() {
try {
methodInvoker.invoke(new MethodSignature("bogus"), new TestObject(), null);
fail();
} catch (MethodInvocationException e) {
assertTrue(e.getTargetException() instanceof InvalidMethodKeyException);
}
}
public void testInvalidMethod() {
try {
methodInvoker.invoke(new MethodSignature("bogus"), new TestObject(), null);
fail();
} catch (MethodInvocationException e) {
assertTrue(e.getTargetException() instanceof InvalidMethodKeyException);
}
}
@Test
public void testBeanArg() {
Parameters parameters = new Parameters();
Bean bean = new Bean();
parameters.add(new Parameter(Bean.class, new StaticExpression(bean)));
MethodSignature method = new MethodSignature("testBeanArg", parameters);
assertSame(bean, methodInvoker.invoke(method, new TestObject(), null));
}
public void testBeanArg() {
Parameters parameters = new Parameters();
Bean bean = new Bean();
parameters.add(new Parameter(Bean.class, new StaticExpression(bean)));
MethodSignature method = new MethodSignature("testBeanArg", parameters);
assertSame(bean, methodInvoker.invoke(method, new TestObject(), null));
}
@Test
public void testPrimitiveArg() {
Parameters parameters = new Parameters();
parameters.add(new Parameter(Boolean.class, new StaticExpression(true)));
MethodSignature method = new MethodSignature("testPrimitiveArg", parameters);
assertEquals(Boolean.TRUE, methodInvoker.invoke(method, new TestObject(), null));
}
static class TestObject {
public void test() {
throw new IllegalArgumentException("just testing");
}
public Object testBeanArg(Bean bean) {
return bean;
}
public boolean testPrimitiveArg(boolean primitive) {
return primitive;
}
}
static class Bean {
String value;
}
}
public void testPrimitiveArg() {
Parameters parameters = new Parameters();
parameters.add(new Parameter(Boolean.class, new StaticExpression(true)));
MethodSignature method = new MethodSignature("testPrimitiveArg", parameters);
assertEquals(Boolean.TRUE, methodInvoker.invoke(method, new TestObject(), null));
}
static class TestObject {
public void test() {
throw new IllegalArgumentException("just testing");
}
public Object testBeanArg(Bean bean) {
return bean;
}
public boolean testPrimitiveArg(boolean primitive) {
return primitive;
}
}
static class Bean {
String value;
}
}

View File

@@ -1,10 +1,10 @@
description = "Spring Faces"
dependencies {
compile(project(":spring-binding"))
compile(project(":spring-webflow"))
compile("org.springframework:spring-web")
compile("org.springframework:spring-webmvc")
implementation(project(":spring-binding"))
implementation(project(":spring-webflow"))
implementation("org.springframework:spring-web")
implementation("org.springframework:spring-webmvc")
compileOnly("javax.el:javax.el-api")
compileOnly("javax.servlet:javax.servlet-api")
@@ -17,16 +17,16 @@ dependencies {
optional("org.springframework.security:spring-security-web")
optional("org.springframework.security:spring-security-taglibs")
testCompile("org.junit.jupiter:junit-jupiter")
testCompile("org.easymock:easymock")
testCompile("org.apache.myfaces.test:myfaces-test22")
testCompile("org.apache.tomcat:tomcat-jasper-el")
testCompile("org.springframework:spring-test")
testCompile("javax.servlet:javax.servlet-api")
testCompile("com.sun.faces:jsf-api")
testCompile("com.sun.faces:jsf-impl")
testCompile("org.apache.myfaces.core:myfaces-impl")
testRuntime("org.apache.logging.log4j:log4j-core")
testRuntime("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntime("org.apache.logging.log4j:log4j-jul")
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.easymock:easymock")
testImplementation("org.apache.myfaces.test:myfaces-test22")
testImplementation("org.apache.tomcat:tomcat-jasper-el")
testImplementation("org.springframework:spring-test")
testImplementation("javax.servlet:javax.servlet-api")
testImplementation("com.sun.faces:jsf-api")
testImplementation("com.sun.faces:jsf-impl")
testImplementation("org.apache.myfaces.core:myfaces-impl")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
}

View File

@@ -289,9 +289,9 @@ public class FlowFacesContext extends FacesContextWrapper {
/**
* Adapter class to convert a {@link FacesMessage} to a Spring {@link Message}. This adapter is required to allow
* <tt>FacesMessages</tt> to be registered with Spring whilst still retaining their mutable nature. It is not
* uncommon for <tt>FacesMessages</tt> to be changed after they have been added to a <tt>FacesContext</tt>, for
* example, from a <tt>PhaseListener</tt>.
* <code>FacesMessages</code> to be registered with Spring whilst still retaining their mutable nature. It is not
* uncommon for <code>FacesMessages</code> to be changed after they have been added to a <code>FacesContext</code>, for
* example, from a <code>PhaseListener</code>.
* <p>
* NOTE: Only {@link javax.faces.application.FacesMessage} instances are directly adapted, any subclasses will be
* converted to the standard FacesMessage implementation. This is to protect against bugs such as SWF-1073.

View File

@@ -1,35 +1,35 @@
package org.springframework.faces.webflow;
import java.util.ArrayList;
import java.util.List;
public class JSFManagedBean {
String prop1;
JSFModel model;
List<String> values = new ArrayList<>();
public JSFModel getModel() {
return this.model;
}
public void setModel(JSFModel model) {
this.model = model;
}
public String getProp1() {
return this.prop1;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public void addValue(String value) {
this.values.add(value);
}
public List<String> getValues() {
return this.values;
}
}
package org.springframework.faces.webflow;
import java.util.ArrayList;
import java.util.List;
public class JSFManagedBean {
String prop1;
JSFModel model;
List<String> values = new ArrayList<>();
public JSFModel getModel() {
return this.model;
}
public void setModel(JSFModel model) {
this.model = model;
}
public String getProp1() {
return this.prop1;
}
public void setProp1(String prop1) {
this.prop1 = prop1;
}
public void addValue(String value) {
this.values.add(value);
}
public List<String> getValues() {
return this.values;
}
}

View File

@@ -1,240 +1,240 @@
package org.springframework.faces.webflow;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKitFactory;
import org.apache.myfaces.test.base.AbstractJsfTestCase;
import org.apache.myfaces.test.mock.MockApplicationFactory;
import org.apache.myfaces.test.mock.MockExternalContext;
import org.apache.myfaces.test.mock.MockHttpServletRequest;
import org.apache.myfaces.test.mock.MockHttpServletResponse;
import org.apache.myfaces.test.mock.MockHttpSession;
import org.apache.myfaces.test.mock.MockPartialViewContextFactory;
import org.apache.myfaces.test.mock.MockPrintWriter;
import org.apache.myfaces.test.mock.MockRenderKit;
import org.apache.myfaces.test.mock.MockRenderKitFactory;
import org.apache.myfaces.test.mock.MockResponseWriter;
import org.apache.myfaces.test.mock.MockServletConfig;
import org.apache.myfaces.test.mock.MockServletContext;
import org.apache.myfaces.test.mock.lifecycle.MockLifecycle;
import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory;
import org.apache.myfaces.test.mock.visit.MockVisitContextFactory;
/**
* Helper for using the mock JSF environment provided by shale-test inside unit tests that do not extend
* {@link AbstractJsfTestCase}
*
* @author Jeremy Grelle
* @author Phillip Webb
*/
public class JSFMockHelper {
private final JSFMock mock = new JSFMock();
public Application application() {
return this.mock.application();
}
public MockServletConfig config() {
return this.mock.config();
}
public String contentAsString() throws IOException {
return this.mock.contentAsString();
}
public MockExternalContext externalContext() {
return this.mock.externalContext();
}
public FacesContext facesContext() {
return this.mock.facesContext();
}
public FacesContextFactory facesContextFactory() {
return this.mock.facesContextFactory();
}
public MockLifecycle lifecycle() {
return this.mock.lifecycle();
}
public MockLifecycleFactory lifecycleFactory() {
return this.mock.lifecycleFactory();
}
public MockRenderKit renderKit() {
return this.mock.renderKit();
}
public MockHttpServletRequest request() {
return this.mock.request();
}
public MockHttpServletResponse response() {
return this.mock.response();
}
public MockServletContext servletContext() {
return this.mock.servletContext();
}
public MockHttpSession session() {
return this.mock.session();
}
public void setUp() throws Exception {
this.mock.setUp();
}
public void tearDown() throws Exception {
this.mock.tearDown();
}
private static class JSFMock extends AbstractJsfTestCase {
private ClassLoader threadContextClassLoader;
public JSFMock() {
super("JSFMock");
}
FacesContext facesContext;
FacesContextFactory facesContextFactory;
public void setUp() throws Exception {
// Ensure no pre-existing FacesContext ..
if (FacesContext.getCurrentInstance() != null) {
FacesContext.getCurrentInstance().release();
}
// Set up a new thread context class loader
this.threadContextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(
new URLClassLoader(new URL[0], this.getClass().getClassLoader()));
// Set up Servlet API Objects
this.servletContext = new MockServletContext();
this.config = new MockServletConfig(this.servletContext);
this.session = new MockHttpSession();
this.session.setServletContext(this.servletContext);
this.request = new MockHttpServletRequest(this.session);
this.request.setServletContext(this.servletContext);
this.response = new MockHttpServletResponse();
// Set up JSF API Objects
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY, MockBaseFacesContextFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY, MockLifecycleFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY,
MockPartialViewContextFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.VISIT_CONTEXT_FACTORY, MockVisitContextFactory.class.getName());
this.lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
this.lifecycle = (MockLifecycle) this.lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
this.facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
this.facesContext = this.facesContextFactory.getFacesContext(this.servletContext, this.request, this.response, this.lifecycle);
this.externalContext = (MockExternalContext) this.facesContext.getExternalContext();
this.facesContext.setResponseWriter(new MockResponseWriter(this.response.getWriter()));
UIViewRoot root = new UIViewRoot();
root.setViewId("/viewId");
root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
this.facesContext.setViewRoot(root);
ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
.getFactory(FactoryFinder.APPLICATION_FACTORY);
this.application = (org.apache.myfaces.test.mock.MockApplication) applicationFactory.getApplication();
RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
this.renderKit = new MockRenderKit();
renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, this.renderKit);
}
public void tearDown() throws Exception {
this.application = null;
this.config = null;
this.externalContext = null;
if (this.facesContext != null) {
this.facesContext.release();
}
this.facesContext = null;
this.lifecycle = null;
this.lifecycleFactory = null;
this.renderKit = null;
this.request = null;
this.response = null;
this.servletContext = null;
this.session = null;
FactoryFinder.releaseFactories();
Thread.currentThread().setContextClassLoader(this.threadContextClassLoader);
this.threadContextClassLoader = null;
}
public org.apache.myfaces.test.mock.MockApplication application() {
return this.application;
}
public MockServletConfig config() {
return this.config;
}
public String contentAsString() throws IOException {
MockPrintWriter writer = (MockPrintWriter) this.response.getWriter();
return new String(writer.content());
}
public MockExternalContext externalContext() {
return this.externalContext;
}
public FacesContext facesContext() {
return this.facesContext;
}
public FacesContextFactory facesContextFactory() {
return this.facesContextFactory;
}
public MockLifecycle lifecycle() {
return this.lifecycle;
}
public MockLifecycleFactory lifecycleFactory() {
return this.lifecycleFactory;
}
public MockRenderKit renderKit() {
return this.renderKit;
}
public MockHttpServletRequest request() {
return this.request;
}
public MockHttpServletResponse response() {
return this.response;
}
public MockServletContext servletContext() {
return this.servletContext;
}
public MockHttpSession session() {
return this.session;
}
}
}
package org.springframework.faces.webflow;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.LifecycleFactory;
import javax.faces.render.RenderKitFactory;
import org.apache.myfaces.test.base.AbstractJsfTestCase;
import org.apache.myfaces.test.mock.MockApplicationFactory;
import org.apache.myfaces.test.mock.MockExternalContext;
import org.apache.myfaces.test.mock.MockHttpServletRequest;
import org.apache.myfaces.test.mock.MockHttpServletResponse;
import org.apache.myfaces.test.mock.MockHttpSession;
import org.apache.myfaces.test.mock.MockPartialViewContextFactory;
import org.apache.myfaces.test.mock.MockPrintWriter;
import org.apache.myfaces.test.mock.MockRenderKit;
import org.apache.myfaces.test.mock.MockRenderKitFactory;
import org.apache.myfaces.test.mock.MockResponseWriter;
import org.apache.myfaces.test.mock.MockServletConfig;
import org.apache.myfaces.test.mock.MockServletContext;
import org.apache.myfaces.test.mock.lifecycle.MockLifecycle;
import org.apache.myfaces.test.mock.lifecycle.MockLifecycleFactory;
import org.apache.myfaces.test.mock.visit.MockVisitContextFactory;
/**
* Helper for using the mock JSF environment provided by shale-test inside unit tests that do not extend
* {@link AbstractJsfTestCase}
*
* @author Jeremy Grelle
* @author Phillip Webb
*/
public class JSFMockHelper {
private final JSFMock mock = new JSFMock();
public Application application() {
return this.mock.application();
}
public MockServletConfig config() {
return this.mock.config();
}
public String contentAsString() throws IOException {
return this.mock.contentAsString();
}
public MockExternalContext externalContext() {
return this.mock.externalContext();
}
public FacesContext facesContext() {
return this.mock.facesContext();
}
public FacesContextFactory facesContextFactory() {
return this.mock.facesContextFactory();
}
public MockLifecycle lifecycle() {
return this.mock.lifecycle();
}
public MockLifecycleFactory lifecycleFactory() {
return this.mock.lifecycleFactory();
}
public MockRenderKit renderKit() {
return this.mock.renderKit();
}
public MockHttpServletRequest request() {
return this.mock.request();
}
public MockHttpServletResponse response() {
return this.mock.response();
}
public MockServletContext servletContext() {
return this.mock.servletContext();
}
public MockHttpSession session() {
return this.mock.session();
}
public void setUp() throws Exception {
this.mock.setUp();
}
public void tearDown() throws Exception {
this.mock.tearDown();
}
private static class JSFMock extends AbstractJsfTestCase {
private ClassLoader threadContextClassLoader;
public JSFMock() {
super("JSFMock");
}
FacesContext facesContext;
FacesContextFactory facesContextFactory;
public void setUp() throws Exception {
// Ensure no pre-existing FacesContext ..
if (FacesContext.getCurrentInstance() != null) {
FacesContext.getCurrentInstance().release();
}
// Set up a new thread context class loader
this.threadContextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(
new URLClassLoader(new URL[0], this.getClass().getClassLoader()));
// Set up Servlet API Objects
this.servletContext = new MockServletContext();
this.config = new MockServletConfig(this.servletContext);
this.session = new MockHttpSession();
this.session.setServletContext(this.servletContext);
this.request = new MockHttpServletRequest(this.session);
this.request.setServletContext(this.servletContext);
this.response = new MockHttpServletResponse();
// Set up JSF API Objects
FactoryFinder.setFactory(FactoryFinder.APPLICATION_FACTORY, MockApplicationFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.FACES_CONTEXT_FACTORY, MockBaseFacesContextFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.LIFECYCLE_FACTORY, MockLifecycleFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.RENDER_KIT_FACTORY, MockRenderKitFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.PARTIAL_VIEW_CONTEXT_FACTORY,
MockPartialViewContextFactory.class.getName());
FactoryFinder.setFactory(FactoryFinder.VISIT_CONTEXT_FACTORY, MockVisitContextFactory.class.getName());
this.lifecycleFactory = (MockLifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
this.lifecycle = (MockLifecycle) this.lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
this.facesContextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
this.facesContext = this.facesContextFactory.getFacesContext(this.servletContext, this.request, this.response, this.lifecycle);
this.externalContext = (MockExternalContext) this.facesContext.getExternalContext();
this.facesContext.setResponseWriter(new MockResponseWriter(this.response.getWriter()));
UIViewRoot root = new UIViewRoot();
root.setViewId("/viewId");
root.setRenderKitId(RenderKitFactory.HTML_BASIC_RENDER_KIT);
this.facesContext.setViewRoot(root);
ApplicationFactory applicationFactory = (ApplicationFactory) FactoryFinder
.getFactory(FactoryFinder.APPLICATION_FACTORY);
this.application = (org.apache.myfaces.test.mock.MockApplication) applicationFactory.getApplication();
RenderKitFactory renderKitFactory = (RenderKitFactory) FactoryFinder
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
this.renderKit = new MockRenderKit();
renderKitFactory.addRenderKit(RenderKitFactory.HTML_BASIC_RENDER_KIT, this.renderKit);
}
public void tearDown() throws Exception {
this.application = null;
this.config = null;
this.externalContext = null;
if (this.facesContext != null) {
this.facesContext.release();
}
this.facesContext = null;
this.lifecycle = null;
this.lifecycleFactory = null;
this.renderKit = null;
this.request = null;
this.response = null;
this.servletContext = null;
this.session = null;
FactoryFinder.releaseFactories();
Thread.currentThread().setContextClassLoader(this.threadContextClassLoader);
this.threadContextClassLoader = null;
}
public org.apache.myfaces.test.mock.MockApplication application() {
return this.application;
}
public MockServletConfig config() {
return this.config;
}
public String contentAsString() throws IOException {
MockPrintWriter writer = (MockPrintWriter) this.response.getWriter();
return new String(writer.content());
}
public MockExternalContext externalContext() {
return this.externalContext;
}
public FacesContext facesContext() {
return this.facesContext;
}
public FacesContextFactory facesContextFactory() {
return this.facesContextFactory;
}
public MockLifecycle lifecycle() {
return this.lifecycle;
}
public MockLifecycleFactory lifecycleFactory() {
return this.lifecycleFactory;
}
public MockRenderKit renderKit() {
return this.renderKit;
}
public MockHttpServletRequest request() {
return this.request;
}
public MockHttpServletResponse response() {
return this.response;
}
public MockServletContext servletContext() {
return this.servletContext;
}
public MockHttpSession session() {
return this.session;
}
}
}

View File

@@ -1,13 +1,13 @@
package org.springframework.faces.webflow;
public class JSFModel {
String value;
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}
package org.springframework.faces.webflow;
public class JSFModel {
String value;
public String getValue() {
return this.value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@@ -1,6 +1,6 @@
package org.springframework.faces.webflow;
public interface MockService {
void doSomething(String arg);
}
package org.springframework.faces.webflow;
public interface MockService {
void doSomething(String arg);
}

View File

@@ -1,134 +1,134 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* FORM ELEMENTS */
form {
margin:0;
padding:0;
}
form div,
form p {
margin: 0 0 1em 0;
padding: 0;
font-size: 1em;
}
label {
font-weight: bold;
}
fieldset {
padding: 5px 10px;
margin: 0 0 1.5em 0;
border: 1px solid #eee;
}
fieldset legend {
margin: 0 0 0 0px;
padding: 0;
font-size: 1.1em;
font-weight: bold;
color: #666;
background-color: white;
}
* html fieldset legend {
margin: 0 0 10px -10px;
}
fieldset ul {
margin: 0 0 1.5em 0;
padding: 0;
list-style: none;
}
fieldset ul li {
margin: 0 0 0.5em 0;
padding: 0;
list-style: none;
}
input, select, textarea {
margin: 0;
padding: 2px;
font-size: 1em;
font-family: arial, helvetica, verdana, sans-serif;
}
input, select {
vertical-align: middle;
}
textarea {
width: 200px;
height: 8em;
}
input.check {
width: auto;
height: auto;
margin: 0;
border: none;
}
input.radio {
width: auto;
height: auto;
margin: 0;
border: none;
}
input.file {
width: 250px;
height: auto;
}
input.readonly {
background-color: transparent;
border: none;
}
input.button {
width: 10em;
background-color: #ddd;
border: 1px solid black;
}
input.image {
width: auto;
height: auto;
border: none;
}
form div.submit {
margin: 1em 0;
}
form div.submit input {
width: 15em;
height: 2em;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* FORM ELEMENTS */
form {
margin:0;
padding:0;
}
form div,
form p {
margin: 0 0 1em 0;
padding: 0;
font-size: 1em;
}
label {
font-weight: bold;
}
fieldset {
padding: 5px 10px;
margin: 0 0 1.5em 0;
border: 1px solid #eee;
}
fieldset legend {
margin: 0 0 0 0px;
padding: 0;
font-size: 1.1em;
font-weight: bold;
color: #666;
background-color: white;
}
* html fieldset legend {
margin: 0 0 10px -10px;
}
fieldset ul {
margin: 0 0 1.5em 0;
padding: 0;
list-style: none;
}
fieldset ul li {
margin: 0 0 0.5em 0;
padding: 0;
list-style: none;
}
input, select, textarea {
margin: 0;
padding: 2px;
font-size: 1em;
font-family: arial, helvetica, verdana, sans-serif;
}
input, select {
vertical-align: middle;
}
textarea {
width: 200px;
height: 8em;
}
input.check {
width: auto;
height: auto;
margin: 0;
border: none;
}
input.radio {
width: auto;
height: auto;
margin: 0;
border: none;
}
input.file {
width: 250px;
height: auto;
}
input.readonly {
background-color: transparent;
border: none;
}
input.button {
width: 10em;
background-color: #ddd;
border: 1px solid black;
}
input.image {
width: auto;
height: auto;
border: none;
}
form div.submit {
margin: 1em 0;
}
form div.submit input {
width: 15em;
height: 2em;
}
/* END FORM ELEMENTS */

View File

@@ -1,52 +1,52 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
width: 100%;
}
div#local {
display: none;
}
div#sub {
display: none;
}
div#nav {
display: none;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
width: 100%;
}
div#local {
display: none;
}
div#sub {
display: none;
}
div#nav {
display: none;
}
/* END CONTENT */

View File

@@ -1,56 +1,56 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-vertical.css");
/* NAV BAR ON THE LEFT AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 780px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: right;
width: 560px;
display: inline;
}
div#local {
display: none;
}
div#sub {
display: none;
}
div#nav {
float: left;
width: 200px;
display: inline;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-vertical.css");
/* NAV BAR ON THE LEFT AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 780px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: right;
width: 560px;
display: inline;
}
div#local {
display: none;
}
div#sub {
display: none;
}
div#nav {
float: left;
width: 200px;
display: inline;
}
/* END CONTENT */

View File

@@ -1,64 +1,64 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-vertical.css");
/* NAV BAR ON THE LEFT AND TWO COLUMNS OF CONTENT */
div#content {
position: relative;
width: 780px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: right;
width: 340px;
display: inline;
margin-right: 220px;
margin-left: -220px;
}
div#local {
display: none;
}
div#sub {
float: right;
width: 200px;
display: inline;
margin-right: -340px;
margin-left: 200px;
}
div#nav {
float: left;
width: 200px;
display: inline;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-vertical.css");
/* NAV BAR ON THE LEFT AND TWO COLUMNS OF CONTENT */
div#content {
position: relative;
width: 780px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: right;
width: 340px;
display: inline;
margin-right: 220px;
margin-left: -220px;
}
div#local {
display: none;
}
div#sub {
float: right;
width: 200px;
display: inline;
margin-right: -340px;
margin-left: 200px;
}
div#nav {
float: left;
width: 200px;
display: inline;
}
/* END CONTENT */

View File

@@ -1,57 +1,57 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
width: 100%;
}
div#local {
width: 100%;
}
div#sub {
width: 100%;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 100%;
text-align: left;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
width: 100%;
}
div#local {
width: 100%;
}
div#sub {
width: 100%;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 100%;
text-align: left;
}
/* END CONTENT */

View File

@@ -1,68 +1,68 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP, LOCAL NAV ON THE LEFT AND TWO COLUMNS OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: left;
width: 300px;
display: inline;
margin-right: -200px;
margin-left: 200px;
}
div#sub {
float: right;
width: 180px;
display: inline;
}
div#local {
float: left;
width: 180px;
display: inline;
margin-left: -300px;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 701px;
text-align: left;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP, LOCAL NAV ON THE LEFT AND TWO COLUMNS OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: left;
width: 300px;
display: inline;
margin-right: -200px;
margin-left: 200px;
}
div#sub {
float: right;
width: 180px;
display: inline;
}
div#local {
float: left;
width: 180px;
display: inline;
margin-left: -300px;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 701px;
text-align: left;
}
/* END CONTENT */

View File

@@ -1,61 +1,61 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP, LOCAL NAVIGATION ON THE LEFT AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: right;
width: 500px;
display: inline;
}
div#local {
float: left;
width: 200px;
display: inline;
}
div#sub {
display: none;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 100%;
text-align: left;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP, LOCAL NAVIGATION ON THE LEFT AND ONE COLUMN OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: right;
width: 500px;
display: inline;
}
div#local {
float: left;
width: 200px;
display: inline;
}
div#sub {
display: none;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 100%;
text-align: left;
}
/* END CONTENT */

View File

@@ -1,61 +1,61 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP AND TWO COLUMNS OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: left;
width: 480px;
display: inline;
}
div#sub {
float: right;
width: 200px;
display: inline;
}
div#local {
display: none;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 100%;
text-align: left;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
@import url("nav-horizontal.css");
/* NAV BAR AT THE TOP AND TWO COLUMNS OF CONTENT */
div#content {
position: relative;
width: 701px;
margin: 0 auto 20px auto;
padding: 0;
text-align: left;
}
div#main {
float: left;
width: 480px;
display: inline;
}
div#sub {
float: right;
width: 200px;
display: inline;
}
div#local {
display: none;
}
div#nav {
position: absolute;
top: -15px;
left: 0;
width: 100%;
text-align: left;
}
/* END CONTENT */

View File

@@ -1,152 +1,152 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* SITE SPECIFIC LAYOUT */
body {
margin: 0;
padding: 0;
text-align: center;
background: white;
}
div#page {
width: 780px;
margin: 0 auto;
padding: 0;
text-align: center;
background: white;
}
/* HEADER */
div#header {
margin: 0 0 5em 0;
padding: 40px 20px;
color: white;
background: black;
text-align: left;
}
div#branding {
float: left;
width: 40%;
margin: 0;
padding: 10px 0 10px 20px;
text-align: left;
}
div#search {
float: right;
width: 49%;
margin: 0;
padding: 16px 20px 0 0;
text-align: right;
}
/* END HEADER */
/* CONTENT */
div#content {
}
/* MAIN */
div#main {
}
/* END MAIN */
/* SUB */
div#sub {
}
/* END SUB */
/* END CONTENT */
/* FOOTER */
div#footer {
color: white;
background-color: black;
}
div#footer p {
margin: 0;
padding: 15px;
font-size: 0.8em;
}
/* END FOOTER */
/* END LAYOUT */
/* UL.SUBNAV */
ul.subnav {
margin: 0;
padding: 0;
font-size: 0.8em;
list-style: none;
}
ul.subnav li {
margin: 0 0 1em 0;
padding: 0;
list-style: none;
}
ul.subnav li a,
ul.subnav li a:link,
ul.subnav li a:visited,
ul.subnav li a:active {
text-decoration: none;
font-weight: bold;
color: black;
}
ul.subnav li a:hover {
text-decoration: underline;
}
ul.subnav li strong {
padding: 0 0 0 12px;
background: url("../i/subnav-highlight.gif") left top no-repeat transparent;
}
ul.subnav li strong a,
ul.subnav li strong a:link,
ul.subnav li strong a:visited,
ul.subnav li strong a:active {
color: white;
background-color: black;
}
/* END UL.SUBNAV */
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* SITE SPECIFIC LAYOUT */
body {
margin: 0;
padding: 0;
text-align: center;
background: white;
}
div#page {
width: 780px;
margin: 0 auto;
padding: 0;
text-align: center;
background: white;
}
/* HEADER */
div#header {
margin: 0 0 5em 0;
padding: 40px 20px;
color: white;
background: black;
text-align: left;
}
div#branding {
float: left;
width: 40%;
margin: 0;
padding: 10px 0 10px 20px;
text-align: left;
}
div#search {
float: right;
width: 49%;
margin: 0;
padding: 16px 20px 0 0;
text-align: right;
}
/* END HEADER */
/* CONTENT */
div#content {
}
/* MAIN */
div#main {
}
/* END MAIN */
/* SUB */
div#sub {
}
/* END SUB */
/* END CONTENT */
/* FOOTER */
div#footer {
color: white;
background-color: black;
}
div#footer p {
margin: 0;
padding: 15px;
font-size: 0.8em;
}
/* END FOOTER */
/* END LAYOUT */
/* UL.SUBNAV */
ul.subnav {
margin: 0;
padding: 0;
font-size: 0.8em;
list-style: none;
}
ul.subnav li {
margin: 0 0 1em 0;
padding: 0;
list-style: none;
}
ul.subnav li a,
ul.subnav li a:link,
ul.subnav li a:visited,
ul.subnav li a:active {
text-decoration: none;
font-weight: bold;
color: black;
}
ul.subnav li a:hover {
text-decoration: underline;
}
ul.subnav li strong {
padding: 0 0 0 12px;
background: url("../i/subnav-highlight.gif") left top no-repeat transparent;
}
ul.subnav li strong a,
ul.subnav li strong a:link,
ul.subnav li strong a:visited,
ul.subnav li strong a:active {
color: white;
background-color: black;
}
/* END UL.SUBNAV */

View File

@@ -1,105 +1,105 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* NAV */
div#nav {
font-size: 0.8em;
}
* html div#nav {
/* hide ie/mac \*/
height: 1%;
/* end hide */
}
div#nav div.wrapper {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
div#nav ul {
width: 100%;
margin: 0;
padding: 0;
line-height: 1em;
list-style: none;
}
div#nav li {
float: left;
display: inline;
margin: 0;
padding: 0;
list-style: none;
line-height: 1em;
border-right: 1px solid #aaa;
}
div#nav li.last {
border-right: none;
}
div#nav a,
div#nav a:link,
div#nav a:active,
div#nav a:visited {
display: inline-block;
/* hide from ie/mac \*/
display: block;
/* end hide */
margin: 0;
padding: 5px 38px 5px 38px;
font-weight: bold;
text-decoration: none;
color: black;
background: #ddd;
}
div#nav a:hover {
text-decoration: underline;
}
div#nav strong {
display: inline-block;
/* hide from ie/mac \*/
display: block;
/* end hide */
color: white;
background: black;
}
div#nav strong a,
div#nav strong a:link,
div#nav strong a:active,
div#nav strong a:visited,
div#nav strong a:hover {
color: white;
background-color: black;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* NAV */
div#nav {
font-size: 0.8em;
}
* html div#nav {
/* hide ie/mac \*/
height: 1%;
/* end hide */
}
div#nav div.wrapper {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
div#nav ul {
width: 100%;
margin: 0;
padding: 0;
line-height: 1em;
list-style: none;
}
div#nav li {
float: left;
display: inline;
margin: 0;
padding: 0;
list-style: none;
line-height: 1em;
border-right: 1px solid #aaa;
}
div#nav li.last {
border-right: none;
}
div#nav a,
div#nav a:link,
div#nav a:active,
div#nav a:visited {
display: inline-block;
/* hide from ie/mac \*/
display: block;
/* end hide */
margin: 0;
padding: 5px 38px 5px 38px;
font-weight: bold;
text-decoration: none;
color: black;
background: #ddd;
}
div#nav a:hover {
text-decoration: underline;
}
div#nav strong {
display: inline-block;
/* hide from ie/mac \*/
display: block;
/* end hide */
color: white;
background: black;
}
div#nav strong a,
div#nav strong a:link,
div#nav strong a:active,
div#nav strong a:visited,
div#nav strong a:hover {
color: white;
background-color: black;
}
/* END NAV */

View File

@@ -1,104 +1,104 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* NAV */
div#nav {
font-size: 0.8em;
}
* html div#nav {
/* hide ie/mac \*/
height: 1%;
/* end hide */
}
div#nav div.wrapper {
width: 100%;
background: #ddd;
}
div#nav ul {
width: 100%;
margin: 0;
padding: 0;
line-height: 1em;
list-style: none;
}
div#nav li {
display: block;
margin: 0;
padding: 0;
list-style: none;
line-height: 1em;
}
* html div#nav li {
/* hide ie/mac \*/
height: 1%;
/* end hide */
}
div#nav li.last {
}
div#nav a,
div#nav a:link,
div#nav a:active,
div#nav a:visited {
display: block;
font-weight: bold;
text-decoration: none;
margin: 0;
padding: 5px 10px 5px 10px;
color: black;
background: white;
}
div#nav a:hover {
text-decoration: underline;
color: white;
background: black;
}
div#nav strong {
display: block;
color: white;
background: black;
}
div#nav strong a,
div#nav strong a:link,
div#nav strong a:active,
div#nav strong a:visited,
div#nav strong a:hover {
color: white;
background-color: black;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* NAV */
div#nav {
font-size: 0.8em;
}
* html div#nav {
/* hide ie/mac \*/
height: 1%;
/* end hide */
}
div#nav div.wrapper {
width: 100%;
background: #ddd;
}
div#nav ul {
width: 100%;
margin: 0;
padding: 0;
line-height: 1em;
list-style: none;
}
div#nav li {
display: block;
margin: 0;
padding: 0;
list-style: none;
line-height: 1em;
}
* html div#nav li {
/* hide ie/mac \*/
height: 1%;
/* end hide */
}
div#nav li.last {
}
div#nav a,
div#nav a:link,
div#nav a:active,
div#nav a:visited {
display: block;
font-weight: bold;
text-decoration: none;
margin: 0;
padding: 5px 10px 5px 10px;
color: black;
background: white;
}
div#nav a:hover {
text-decoration: underline;
color: white;
background: black;
}
div#nav strong {
display: block;
color: white;
background: black;
}
div#nav strong a,
div#nav strong a:link,
div#nav strong a:active,
div#nav strong a:visited,
div#nav strong a:hover {
color: white;
background-color: black;
}
/* END NAV */

View File

@@ -1,64 +1,64 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* clearing */
.stretch,
.clear {
clear: both;
height: 1px;
margin: 0;
padding: 0;
font-size: 15px;
line-height: 1px;
}
.clearfix:after {
clear: both;
height: 0;
display: block;
visibility: hidden;
content: ".";
}
.clearfix {display:inline-block;}
/* Hide from IE Mac \*/
.clearfix {display:block;}
/* End hide from IE Mac */
/* end clearing */
/* accessibility */
span.accesskey {
text-decoration: none;
}
.accessibility {
position: absolute;
top: -999em;
left: -999em;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* clearing */
.stretch,
.clear {
clear: both;
height: 1px;
margin: 0;
padding: 0;
font-size: 15px;
line-height: 1px;
}
.clearfix:after {
clear: both;
height: 0;
display: block;
visibility: hidden;
content: ".";
}
.clearfix {display:inline-block;}
/* Hide from IE Mac \*/
.clearfix {display:block;}
/* End hide from IE Mac */
/* end clearing */
/* accessibility */
span.accesskey {
text-decoration: none;
}
.accessibility {
position: absolute;
top: -999em;
left: -999em;
}
/* end accessibility */

View File

@@ -1,228 +1,228 @@
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* TYPOGRAPHY */
body {
text-align: left;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 76%;
line-height: 1em;
color: #333;
}
div {
font-size: 1em;
}
img {
border: 0;
}
/* LINKS */
a,
a:link,
a:active {
text-decoration: underline;
color: blue;
background-color: white;
}
a:visited {
color: purple;
background-color: transparent;
}
a:hover {
text-decoration: none;
color: white;
background-color: black;
}
/* END LINKS */
/* HEADINGS */
h1 {
margin: 0 0 0.5em 0;
padding: 0;
font-size: 2em;
line-height: 1.5em;
color: black;
}
h2 {
margin: 0 0 0.5em 0;
padding: 0;
font-size: 1.5em;
line-height: 1.5em;
color: black;
}
h3 {
margin: 0 0 0.5em 0;
padding:0;
font-size: 1.3em;
line-height: 1.3em;
color: black;
}
h4 {
margin: 0 0 0.25em 0;
padding: 0;
font-size: 1.2em;
line-height: 1.3em;
color: black;
}
h5 {
margin: 0 0 0.25em 0;
padding: 0;
font-size: 1.1em;
line-height: 1.3em;
color: black;
}
h6 {
margin: 0 0 0.25em 0;
padding: 0;
font-size: 1em;
line-height: 1.3em;
color: black;
}
/* END HEADINGS */
/* TEXT */
p {
margin: 0 0 1.5em 0;
padding: 0;
font-size: 1em;
line-height:1.4em;
}
blockquote {
margin-left: 10px;
border-left: 10px solid #ddd;
}
pre {
font-family: monospace;
font-size: 1.0em;
}
strong, b {
font-weight: bold;
}
em, i {
font-style:italic;
}
code {
font-family: "Courier New", Courier, monospace;
font-size: 1em;
white-space: pre;
}
/* END TEXT */
/* LISTS */
ul {
margin: 0 0 1.5em 0;
padding: 0;
line-height:1.4em;
}
ul li {
margin: 0 0 0.25em 30px;
padding: 0;
}
ol {
margin: 0 0 1.5em 0;
padding: 0;
font-size: 1.0em;
line-height: 1.4em;
}
ol li {
margin: 0 0 0.25em 30px;
padding: 0;
font-size: 1.0em;
}
dl {
margin: 0 0 1.5em 0;
padding: 0;
line-height: 1.4em;
}
dl dt {
margin: 0.25em 0 0.25em 0;
padding: 0;
font-weight: bold;
}
dl dd {
margin: 0 0 0 30px;
padding: 0;
}
/* END LISTS */
/* TABLE */
table {
margin: 0 0 1.5em 0;
padding: 0;
font-size: 1em;
}
table caption {
margin: 0;
padding: 0 0 1.5em 0;
font-weight: bold;
}
th {
font-weight: bold;
text-align: left;
}
td {
font-size: 1em;
}
/* END TABLE */
hr {
display: none;
}
div.hr {
height: 1px;
margin: 1.5em 10px;
border-bottom: 1px dotted black;
}
/*
A CSS Framework by Mike Stenhouse of Content with Style
-------------------------------------------------------
Copyright (c) 2005, Mike Stenhouse of Content with Style
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 CSS Framework 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 OWNER 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.
*/
/* TYPOGRAPHY */
body {
text-align: left;
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: 76%;
line-height: 1em;
color: #333;
}
div {
font-size: 1em;
}
img {
border: 0;
}
/* LINKS */
a,
a:link,
a:active {
text-decoration: underline;
color: blue;
background-color: white;
}
a:visited {
color: purple;
background-color: transparent;
}
a:hover {
text-decoration: none;
color: white;
background-color: black;
}
/* END LINKS */
/* HEADINGS */
h1 {
margin: 0 0 0.5em 0;
padding: 0;
font-size: 2em;
line-height: 1.5em;
color: black;
}
h2 {
margin: 0 0 0.5em 0;
padding: 0;
font-size: 1.5em;
line-height: 1.5em;
color: black;
}
h3 {
margin: 0 0 0.5em 0;
padding:0;
font-size: 1.3em;
line-height: 1.3em;
color: black;
}
h4 {
margin: 0 0 0.25em 0;
padding: 0;
font-size: 1.2em;
line-height: 1.3em;
color: black;
}
h5 {
margin: 0 0 0.25em 0;
padding: 0;
font-size: 1.1em;
line-height: 1.3em;
color: black;
}
h6 {
margin: 0 0 0.25em 0;
padding: 0;
font-size: 1em;
line-height: 1.3em;
color: black;
}
/* END HEADINGS */
/* TEXT */
p {
margin: 0 0 1.5em 0;
padding: 0;
font-size: 1em;
line-height:1.4em;
}
blockquote {
margin-left: 10px;
border-left: 10px solid #ddd;
}
pre {
font-family: monospace;
font-size: 1.0em;
}
strong, b {
font-weight: bold;
}
em, i {
font-style:italic;
}
code {
font-family: "Courier New", Courier, monospace;
font-size: 1em;
white-space: pre;
}
/* END TEXT */
/* LISTS */
ul {
margin: 0 0 1.5em 0;
padding: 0;
line-height:1.4em;
}
ul li {
margin: 0 0 0.25em 30px;
padding: 0;
}
ol {
margin: 0 0 1.5em 0;
padding: 0;
font-size: 1.0em;
line-height: 1.4em;
}
ol li {
margin: 0 0 0.25em 30px;
padding: 0;
font-size: 1.0em;
}
dl {
margin: 0 0 1.5em 0;
padding: 0;
line-height: 1.4em;
}
dl dt {
margin: 0.25em 0 0.25em 0;
padding: 0;
font-weight: bold;
}
dl dd {
margin: 0 0 0 30px;
padding: 0;
}
/* END LISTS */
/* TABLE */
table {
margin: 0 0 1.5em 0;
padding: 0;
font-size: 1em;
}
table caption {
margin: 0;
padding: 0 0 1.5em 0;
font-weight: bold;
}
th {
font-weight: bold;
text-align: left;
}
td {
font-size: 1em;
}
/* END TABLE */
hr {
display: none;
}
div.hr {
height: 1px;
margin: 1.5em 10px;
border-bottom: 1px dotted black;
}
/* END TYPOGRAPHY */

View File

@@ -1,40 +1,48 @@
description = "Spring Web Flow"
dependencies {
compile(project(":spring-binding"))
compile("org.springframework:spring-web")
compile("org.springframework:spring-webmvc")
api(project(":spring-binding"))
implementation("org.springframework:spring-web")
implementation("org.springframework:spring-webmvc")
compileOnly("javax.el:javax.el-api")
compileOnly("javax.servlet:javax.servlet-api")
compileOnly("jakarta.el:jakarta.el-api")
compileOnly("jakarta.servlet:jakarta.servlet-api")
compileOnly("junit:junit")
optional("org.hibernate:hibernate-core")
optional("org.hibernate:hibernate-core-jakarta")
optional("org.springframework.security:spring-security-core")
optional("org.springframework:spring-orm")
optional("org.springframework:spring-tx")
optional("org.apache.tiles:tiles-api")
optional("org.apache.tiles:tiles-core")
optional("org.apache.tiles:tiles-servlet")
optional("org.apache.tiles:tiles-jsp")
optional("org.apache.tiles:tiles-el")
optional("org.apache.tiles:tiles-extras")
testCompile("junit:junit")
testCompile("org.junit.jupiter:junit-jupiter")
testCompile("org.easymock:easymock")
testCompile("org.apache.tomcat:tomcat-jasper-el")
testCompile("org.springframework:spring-aop")
testCompile("org.springframework:spring-jdbc")
testCompile("org.springframework:spring-test")
testCompile("org.hibernate:hibernate-entitymanager")
testCompile("org.hibernate:hibernate-validator")
testCompile("org.hsqldb:hsqldb")
testCompile("javax.servlet.jsp:javax.servlet.jsp-api")
testCompile("javax.servlet:jstl")
testCompile("javax.servlet:javax.servlet-api")
testCompile("javax.validation:validation-api")
testRuntime("org.apache.logging.log4j:log4j-core")
testRuntime("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntime("org.apache.logging.log4j:log4j-jul")
}
testImplementation("junit:junit")
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation("org.easymock:easymock")
testImplementation("org.apache.tomcat:tomcat-jasper-el")
testImplementation("org.springframework:spring-aop")
testImplementation("org.springframework:spring-jdbc")
testImplementation("org.springframework:spring-test")
testImplementation("org.hibernate:hibernate-entitymanager")
testImplementation("org.hibernate:hibernate-validator")
testImplementation("org.hsqldb:hsqldb")
testImplementation("jakarta.servlet.jsp:jakarta.servlet.jsp-api")
testImplementation("javax.servlet:jstl")
testImplementation("jakarta.servlet:jakarta.servlet-api")
testImplementation("jakarta.validation:jakarta.validation-api")
testRuntimeOnly("org.apache.logging.log4j:log4j-core")
testRuntimeOnly("org.apache.logging.log4j:log4j-slf4j-impl")
testRuntimeOnly("org.apache.logging.log4j:log4j-jul")
//
// To use Hibernate 5 in the context of the Jakarta EE 9 namespace,
// we need to use hibernate-core-jakarta instead of hibernate-core.
// Unfortunately the hibernate-entitymanager module directly
// references hibernate-core and we don't want both versions
// in the classpath. To avoid this, explicitly exclude the
// plain hibernate-core module in all configurations.
//
// This wrinkle will probably go away again in Hibernate 6.
//
configurations.all {
exclude group: 'org.hibernate', module: 'hibernate-core'
}
}

View File

@@ -1,113 +1,113 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.webflow.execution.Action;
import org.springframework.webflow.execution.ActionExecutor;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
/**
* An action that evaluates an expression and optionally exposes its result.
* <p>
* Delegates to a {@link ResultEventFactory} to determine how to map the evaluation result to an action outcome
* {@link Event}.
*
* @see Expression
* @see ResultEventFactory
*
* @author Keith Donald
* @author Jeremy Grelle
*/
public class EvaluateAction extends AbstractAction {
/**
* The expression to evaluate when this action is invoked. Required.
*/
private Expression expression;
/**
* The expression to evaluate to set the result of the action. Optional.
*/
private Expression resultExpression;
/**
* The selector for the factory that will create the action result event callers can respond to.
*/
private ResultEventFactory resultEventFactory;
/**
* Create a new evaluate action.
* @param expression the expression to evaluate (required)
* @param resultExpression the expression to evaluate the result (optional)
*/
public EvaluateAction(Expression expression, Expression resultExpression) {
init(expression, resultExpression, null);
}
/**
* Create a new evaluate action.
* @param expression the expression to evaluate (required)
* @param resultExpression the strategy for how the expression result will be exposed to the flow (optional)
* @param resultEventFactory the factory that will map the evaluation result to a Web Flow event (optional)
*/
public EvaluateAction(Expression expression, Expression resultExpression, ResultEventFactory resultEventFactory) {
init(expression, resultExpression, resultEventFactory);
}
protected Event doExecute(RequestContext context) throws Exception {
Object result = expression.getValue(context);
if (result instanceof Action) {
return ActionExecutor.execute((Action) result, context);
} else {
if (resultExpression != null) {
resultExpression.setValue(context, result);
}
return resultEventFactory.createResultEvent(this, result, context);
}
}
public String toString() {
return new ToStringCreator(this).append("expression", expression).append("resultExpression", resultExpression)
.toString();
}
// internal helpers
private void init(Expression expression, Expression resultExpression, ResultEventFactory resultEventFactory) {
Assert.notNull(expression, "The expression this action should evaluate is required");
this.expression = expression;
this.resultExpression = resultExpression;
this.resultEventFactory = resultEventFactory != null ? resultEventFactory : new DefaultResultEventFactory();
}
/**
* Default implementation that uses the ResultEventFactorySelector helper.
* @author Keith Donald
*/
private class DefaultResultEventFactory implements ResultEventFactory {
private ResultEventFactorySelector selector = new ResultEventFactorySelector();
public Event createResultEvent(Object source, Object resultObject, RequestContext context) {
return selector.forResult(resultObject).createResultEvent(source, resultObject, context);
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.webflow.execution.Action;
import org.springframework.webflow.execution.ActionExecutor;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
/**
* An action that evaluates an expression and optionally exposes its result.
* <p>
* Delegates to a {@link ResultEventFactory} to determine how to map the evaluation result to an action outcome
* {@link Event}.
*
* @see Expression
* @see ResultEventFactory
*
* @author Keith Donald
* @author Jeremy Grelle
*/
public class EvaluateAction extends AbstractAction {
/**
* The expression to evaluate when this action is invoked. Required.
*/
private Expression expression;
/**
* The expression to evaluate to set the result of the action. Optional.
*/
private Expression resultExpression;
/**
* The selector for the factory that will create the action result event callers can respond to.
*/
private ResultEventFactory resultEventFactory;
/**
* Create a new evaluate action.
* @param expression the expression to evaluate (required)
* @param resultExpression the expression to evaluate the result (optional)
*/
public EvaluateAction(Expression expression, Expression resultExpression) {
init(expression, resultExpression, null);
}
/**
* Create a new evaluate action.
* @param expression the expression to evaluate (required)
* @param resultExpression the strategy for how the expression result will be exposed to the flow (optional)
* @param resultEventFactory the factory that will map the evaluation result to a Web Flow event (optional)
*/
public EvaluateAction(Expression expression, Expression resultExpression, ResultEventFactory resultEventFactory) {
init(expression, resultExpression, resultEventFactory);
}
protected Event doExecute(RequestContext context) throws Exception {
Object result = expression.getValue(context);
if (result instanceof Action) {
return ActionExecutor.execute((Action) result, context);
} else {
if (resultExpression != null) {
resultExpression.setValue(context, result);
}
return resultEventFactory.createResultEvent(this, result, context);
}
}
public String toString() {
return new ToStringCreator(this).append("expression", expression).append("resultExpression", resultExpression)
.toString();
}
// internal helpers
private void init(Expression expression, Expression resultExpression, ResultEventFactory resultEventFactory) {
Assert.notNull(expression, "The expression this action should evaluate is required");
this.expression = expression;
this.resultExpression = resultExpression;
this.resultEventFactory = resultEventFactory != null ? resultEventFactory : new DefaultResultEventFactory();
}
/**
* Default implementation that uses the ResultEventFactorySelector helper.
* @author Keith Donald
*/
private class DefaultResultEventFactory implements ResultEventFactory {
private ResultEventFactorySelector selector = new ResultEventFactorySelector();
public Event createResultEvent(Object source, Object resultObject, RequestContext context) {
return selector.forResult(resultObject).createResultEvent(source, resultObject, context);
}
}
}

View File

@@ -1,257 +1,257 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.CollectionUtils;
import org.springframework.webflow.execution.Event;
/**
* A convenience support class assisting in the creation of {@link Event} objects.
* <p>
* This class can be used as a simple utility class when you need to create common event objects. Alternatively you
* could extend it as a base support class when creating custom event factories.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class EventFactorySupport {
/**
* The default 'success' result event identifier ("success").
*/
private static final String SUCCESS_EVENT_ID = "success";
/**
* The default 'error' result event identifier ("error").
*/
private static final String ERROR_EVENT_ID = "error";
/**
* The default 'yes' result event identifier ("yes").
*/
private static final String YES_EVENT_ID = "yes";
/**
* The default 'no' result event identifier ("no").
*/
private static final String NO_EVENT_ID = "no";
/**
* The default 'null' result event identifier ("null").
*/
private static final String NULL_EVENT_ID = "null";
/**
* The default 'exception' event attribute name ("exception").
*/
private static final String EXCEPTION_ATTRIBUTE_NAME = "exception";
/**
* The default 'result' event attribute name ("result").
*/
private static final String RESULT_ATTRIBUTE_NAME = "result";
/**
* The success event identifier.
*/
private String successEventId = SUCCESS_EVENT_ID;
/**
* The error event identifier.
*/
private String errorEventId = ERROR_EVENT_ID;
/**
* The yes event identifier.
*/
private String yesEventId = YES_EVENT_ID;
/**
* The no event identifier.
*/
private String noEventId = NO_EVENT_ID;
/**
* The null event identifier.
*/
private String nullEventId = NULL_EVENT_ID;
/**
* The exception event attribute name.
*/
private String exceptionAttributeName = EXCEPTION_ATTRIBUTE_NAME;
/**
* The result event attribute name.
*/
private String resultAttributeName = RESULT_ATTRIBUTE_NAME;
public String getSuccessEventId() {
return successEventId;
}
public void setSuccessEventId(String successEventId) {
this.successEventId = successEventId;
}
public String getErrorEventId() {
return errorEventId;
}
public void setErrorEventId(String errorEventId) {
this.errorEventId = errorEventId;
}
public String getYesEventId() {
return yesEventId;
}
public void setYesEventId(String yesEventId) {
this.yesEventId = yesEventId;
}
public String getNoEventId() {
return noEventId;
}
public void setNoEventId(String noEventId) {
this.noEventId = noEventId;
}
public String getNullEventId() {
return nullEventId;
}
public void setNullEventId(String nullEventId) {
this.nullEventId = nullEventId;
}
public String getExceptionAttributeName() {
return exceptionAttributeName;
}
public void setExceptionAttributeName(String exceptionAttributeName) {
this.exceptionAttributeName = exceptionAttributeName;
}
public String getResultAttributeName() {
return resultAttributeName;
}
public void setResultAttributeName(String resultAttributeName) {
this.resultAttributeName = resultAttributeName;
}
/**
* Returns a "success" event.
* @param source the source of the event
*/
public Event success(Object source) {
return event(source, getSuccessEventId());
}
/**
* Returns a "success" event with the provided result object as an attribute. The result object is identified by the
* attribute name {@link #getResultAttributeName()}.
* @param source the source of the event
* @param result the action success result
*/
public Event success(Object source, Object result) {
return event(source, getSuccessEventId(), getResultAttributeName(), result);
}
/**
* Returns an "error" event.
* @param source the source of the event
*/
public Event error(Object source) {
return event(source, getErrorEventId());
}
/**
* Returns an "error" event caused by the provided exception.
* @param source the source of the event
* @param e the exception that caused the error event, to be put as an event attribute under the name
* {@link #getExceptionAttributeName()}
*/
public Event error(Object source, Exception e) {
return event(source, getErrorEventId(), getExceptionAttributeName(), e);
}
/**
* Returns a "yes" event.
* @param source the source of the event
*/
public Event yes(Object source) {
return event(source, getYesEventId());
}
/**
* Returns a "no" result event.
* @param source the source of the event
*/
public Event no(Object source) {
return event(source, getNoEventId());
}
/**
* Returns an event to communicate an occurrence of a boolean expression.
* @param source the source of the event
* @param booleanResult the boolean
* @return yes or no
*/
public Event event(Object source, boolean booleanResult) {
if (booleanResult) {
return yes(source);
} else {
return no(source);
}
}
/**
* Returns a event with the specified identifier.
* @param source the source of the event
* @param eventId the result event identifier
* @return the event
*/
public Event event(Object source, String eventId) {
return new Event(source, eventId, null);
}
/**
* Returns a event with the specified identifier and the specified set of attributes.
* @param source the source of the event
* @param eventId the result event identifier
* @param attributes the event payload attributes
* @return the event
*/
public Event event(Object source, String eventId, AttributeMap<Object> attributes) {
return new Event(source, eventId, attributes);
}
/**
* Returns a result event with the specified identifier and a single attribute.
* @param source the source of the event
* @param eventId the result id
* @param attributeName the attribute name
* @param attributeValue the attribute value
* @return the event
*/
public Event event(Object source, String eventId, String attributeName, Object attributeValue) {
return new Event(source, eventId, CollectionUtils.singleEntryMap(attributeName, attributeValue));
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.CollectionUtils;
import org.springframework.webflow.execution.Event;
/**
* A convenience support class assisting in the creation of {@link Event} objects.
* <p>
* This class can be used as a simple utility class when you need to create common event objects. Alternatively you
* could extend it as a base support class when creating custom event factories.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class EventFactorySupport {
/**
* The default 'success' result event identifier ("success").
*/
private static final String SUCCESS_EVENT_ID = "success";
/**
* The default 'error' result event identifier ("error").
*/
private static final String ERROR_EVENT_ID = "error";
/**
* The default 'yes' result event identifier ("yes").
*/
private static final String YES_EVENT_ID = "yes";
/**
* The default 'no' result event identifier ("no").
*/
private static final String NO_EVENT_ID = "no";
/**
* The default 'null' result event identifier ("null").
*/
private static final String NULL_EVENT_ID = "null";
/**
* The default 'exception' event attribute name ("exception").
*/
private static final String EXCEPTION_ATTRIBUTE_NAME = "exception";
/**
* The default 'result' event attribute name ("result").
*/
private static final String RESULT_ATTRIBUTE_NAME = "result";
/**
* The success event identifier.
*/
private String successEventId = SUCCESS_EVENT_ID;
/**
* The error event identifier.
*/
private String errorEventId = ERROR_EVENT_ID;
/**
* The yes event identifier.
*/
private String yesEventId = YES_EVENT_ID;
/**
* The no event identifier.
*/
private String noEventId = NO_EVENT_ID;
/**
* The null event identifier.
*/
private String nullEventId = NULL_EVENT_ID;
/**
* The exception event attribute name.
*/
private String exceptionAttributeName = EXCEPTION_ATTRIBUTE_NAME;
/**
* The result event attribute name.
*/
private String resultAttributeName = RESULT_ATTRIBUTE_NAME;
public String getSuccessEventId() {
return successEventId;
}
public void setSuccessEventId(String successEventId) {
this.successEventId = successEventId;
}
public String getErrorEventId() {
return errorEventId;
}
public void setErrorEventId(String errorEventId) {
this.errorEventId = errorEventId;
}
public String getYesEventId() {
return yesEventId;
}
public void setYesEventId(String yesEventId) {
this.yesEventId = yesEventId;
}
public String getNoEventId() {
return noEventId;
}
public void setNoEventId(String noEventId) {
this.noEventId = noEventId;
}
public String getNullEventId() {
return nullEventId;
}
public void setNullEventId(String nullEventId) {
this.nullEventId = nullEventId;
}
public String getExceptionAttributeName() {
return exceptionAttributeName;
}
public void setExceptionAttributeName(String exceptionAttributeName) {
this.exceptionAttributeName = exceptionAttributeName;
}
public String getResultAttributeName() {
return resultAttributeName;
}
public void setResultAttributeName(String resultAttributeName) {
this.resultAttributeName = resultAttributeName;
}
/**
* Returns a "success" event.
* @param source the source of the event
*/
public Event success(Object source) {
return event(source, getSuccessEventId());
}
/**
* Returns a "success" event with the provided result object as an attribute. The result object is identified by the
* attribute name {@link #getResultAttributeName()}.
* @param source the source of the event
* @param result the action success result
*/
public Event success(Object source, Object result) {
return event(source, getSuccessEventId(), getResultAttributeName(), result);
}
/**
* Returns an "error" event.
* @param source the source of the event
*/
public Event error(Object source) {
return event(source, getErrorEventId());
}
/**
* Returns an "error" event caused by the provided exception.
* @param source the source of the event
* @param e the exception that caused the error event, to be put as an event attribute under the name
* {@link #getExceptionAttributeName()}
*/
public Event error(Object source, Exception e) {
return event(source, getErrorEventId(), getExceptionAttributeName(), e);
}
/**
* Returns a "yes" event.
* @param source the source of the event
*/
public Event yes(Object source) {
return event(source, getYesEventId());
}
/**
* Returns a "no" result event.
* @param source the source of the event
*/
public Event no(Object source) {
return event(source, getNoEventId());
}
/**
* Returns an event to communicate an occurrence of a boolean expression.
* @param source the source of the event
* @param booleanResult the boolean
* @return yes or no
*/
public Event event(Object source, boolean booleanResult) {
if (booleanResult) {
return yes(source);
} else {
return no(source);
}
}
/**
* Returns a event with the specified identifier.
* @param source the source of the event
* @param eventId the result event identifier
* @return the event
*/
public Event event(Object source, String eventId) {
return new Event(source, eventId, null);
}
/**
* Returns a event with the specified identifier and the specified set of attributes.
* @param source the source of the event
* @param eventId the result event identifier
* @param attributes the event payload attributes
* @return the event
*/
public Event event(Object source, String eventId, AttributeMap<Object> attributes) {
return new Event(source, eventId, attributes);
}
/**
* Returns a result event with the specified identifier and a single attribute.
* @param source the source of the event
* @param eventId the result id
* @param attributeName the attribute name
* @param attributeValue the attribute value
* @return the event
*/
public Event event(Object source, String eventId, String attributeName, Object attributeValue) {
return new Event(source, eventId, CollectionUtils.singleEntryMap(attributeName, attributeValue));
}
}

View File

@@ -165,7 +165,7 @@ import org.springframework.webflow.execution.ScopeType;
* &lt;/evaluate&gt;
* </pre>
*
* Would result in the <tt>public void validateSearchCriteria(SearchCriteria, Errors)</tt> method of the registered
* Would result in the <code>public void validateSearchCriteria(SearchCriteria, Errors)</code> method of the registered
* validator being called if the form object class would be <code>SearchCriteria</code>.</li>
* <li>If you want to do full validation using the
* {@link org.springframework.validation.Validator#validate(java.lang.Object, org.springframework.validation.Errors)
@@ -910,7 +910,7 @@ public class FormAction extends MultiAction implements InitializingBean {
* display on a user interface such as a HTML page.
* <p>
* This default implementation will call the {@link #registerPropertyEditors(PropertyEditorRegistry) simpler form}
* of the method not taking a <tt>RequestContext</tt> parameter.
* of the method not taking a <code>RequestContext</code> parameter.
* @param context the action execution context, for accessing and setting data in "flow scope" or "request scope"
* @param registry the property editor registry to register editors in
* @see #registerPropertyEditors(PropertyEditorRegistry)
@@ -927,7 +927,7 @@ public class FormAction extends MultiAction implements InitializingBean {
* Property editors give you full control over how objects are transformed to and from a formatted String form for
* display on a user interface such as a HTML page.
* <p>
* This default implementation will simply call <tt>registerCustomEditors</tt> on the
* This default implementation will simply call <code>registerCustomEditors</code> on the
* {@link #getPropertyEditorRegistrar() propertyEditorRegistrar} object that has been set for the action, if any.
* @param registry the property editor registry to register editors in
*/

View File

@@ -1,62 +1,62 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.View;
/**
* An action that sets a special attribute that views use to render partial views called "fragments", instead of the
* entire view.
*
* @author Keith Donald
*/
public class RenderAction extends AbstractAction {
/**
* The expression for setting the scoped attribute value.
*/
private Expression[] fragmentExpressions;
/**
* Creates a new render action.
* @param fragmentExpressions the set of expressions to resolve the view fragments to render
*/
public RenderAction(Expression... fragmentExpressions) {
if (fragmentExpressions == null || fragmentExpressions.length == 0) {
throw new IllegalArgumentException(
"You must provide at least one fragment expression to this render action");
}
this.fragmentExpressions = fragmentExpressions;
}
protected Event doExecute(RequestContext context) throws Exception {
String[] fragments = new String[fragmentExpressions.length];
for (int i = 0; i < fragmentExpressions.length; i++) {
Expression exp = fragmentExpressions[i];
fragments[i] = (String) exp.getValue(context);
}
context.getFlashScope().put(View.RENDER_FRAGMENTS_ATTRIBUTE, fragments);
return success();
}
public String toString() {
return new ToStringCreator(this).append("fragments", fragmentExpressions).toString();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.View;
/**
* An action that sets a special attribute that views use to render partial views called "fragments", instead of the
* entire view.
*
* @author Keith Donald
*/
public class RenderAction extends AbstractAction {
/**
* The expression for setting the scoped attribute value.
*/
private Expression[] fragmentExpressions;
/**
* Creates a new render action.
* @param fragmentExpressions the set of expressions to resolve the view fragments to render
*/
public RenderAction(Expression... fragmentExpressions) {
if (fragmentExpressions == null || fragmentExpressions.length == 0) {
throw new IllegalArgumentException(
"You must provide at least one fragment expression to this render action");
}
this.fragmentExpressions = fragmentExpressions;
}
protected Event doExecute(RequestContext context) throws Exception {
String[] fragments = new String[fragmentExpressions.length];
for (int i = 0; i < fragmentExpressions.length; i++) {
Expression exp = fragmentExpressions[i];
fragments[i] = (String) exp.getValue(context);
}
context.getFlashScope().put(View.RENDER_FRAGMENTS_ATTRIBUTE, fragments);
return success();
}
public String toString() {
return new ToStringCreator(this).append("fragments", fragmentExpressions).toString();
}
}

View File

@@ -1,77 +1,77 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import java.lang.reflect.Method;
/**
* Helper that selects the {@link ResultEventFactory} to use for a particular result object.
*
* @see EvaluateAction
*
* @author Keith Donald
*/
public class ResultEventFactorySelector {
/**
* The event factory instance for mapping a return value to a success event.
*/
private SuccessEventFactory successEventFactory = new SuccessEventFactory();
/**
* The event factory instance for mapping a result object to an event, using the type of the result object as the
* mapping criteria.
*/
private ResultObjectBasedEventFactory resultObjectBasedEventFactory = new ResultObjectBasedEventFactory();
/**
* Select the appropriate result event factory for attempts to invoke the given method.
* @param method the method
* @return the result event factory
*/
public ResultEventFactory forMethod(Method method) {
return forType(method.getReturnType());
}
/**
* Select the appropriate result event factory for the given result.
* @param result the result
* @return the result event factory
*/
public ResultEventFactory forResult(Object result) {
if (result == null) {
return successEventFactory;
} else {
return forType(result.getClass());
}
}
/**
* Select the appropriate result event factory for given result type. This implementation returns
* {@link ResultObjectBasedEventFactory} if the type is
* {@link ResultObjectBasedEventFactory#isMappedValueType(Class) mapped} by that result event factory, otherwise
* {@link SuccessEventFactory} is returned.
* @param resultType the result type
* @return the result event factory
*/
protected ResultEventFactory forType(Class<?> resultType) {
if (resultObjectBasedEventFactory.isMappedValueType(resultType)) {
return resultObjectBasedEventFactory;
} else {
return successEventFactory;
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.action;
import java.lang.reflect.Method;
/**
* Helper that selects the {@link ResultEventFactory} to use for a particular result object.
*
* @see EvaluateAction
*
* @author Keith Donald
*/
public class ResultEventFactorySelector {
/**
* The event factory instance for mapping a return value to a success event.
*/
private SuccessEventFactory successEventFactory = new SuccessEventFactory();
/**
* The event factory instance for mapping a result object to an event, using the type of the result object as the
* mapping criteria.
*/
private ResultObjectBasedEventFactory resultObjectBasedEventFactory = new ResultObjectBasedEventFactory();
/**
* Select the appropriate result event factory for attempts to invoke the given method.
* @param method the method
* @return the result event factory
*/
public ResultEventFactory forMethod(Method method) {
return forType(method.getReturnType());
}
/**
* Select the appropriate result event factory for the given result.
* @param result the result
* @return the result event factory
*/
public ResultEventFactory forResult(Object result) {
if (result == null) {
return successEventFactory;
} else {
return forType(result.getClass());
}
}
/**
* Select the appropriate result event factory for given result type. This implementation returns
* {@link ResultObjectBasedEventFactory} if the type is
* {@link ResultObjectBasedEventFactory#isMappedValueType(Class) mapped} by that result event factory, otherwise
* {@link SuccessEventFactory} is returned.
* @param resultType the result type
* @return the result event factory
*/
protected ResultEventFactory forType(Class<?> resultType) {
if (resultObjectBasedEventFactory.isMappedValueType(resultType)) {
return resultObjectBasedEventFactory;
} else {
return successEventFactory;
}
}
}

View File

@@ -1,64 +1,64 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.ScopeType;
/**
* An action that sets an attribute in a {@link ScopeType scope} when executed. Always returns the "success" event.
*
* @author Keith Donald
*/
public class SetAction extends AbstractAction {
/**
* The expression for setting the scoped attribute value.
*/
private Expression nameExpression;
/**
* The expression for resolving the scoped attribute value.
*/
private Expression valueExpression;
/**
* Creates a new set attribute action.
* @param nameExpression the name of the property to set (required)
* @param valueExpression the expression to obtain the new property value (required) expected
*/
public SetAction(Expression nameExpression, Expression valueExpression) {
Assert.notNull(nameExpression, "The name expression is required");
Assert.notNull(valueExpression, "The value expression is required");
this.nameExpression = nameExpression;
this.valueExpression = valueExpression;
}
protected Event doExecute(RequestContext context) throws Exception {
Object value = valueExpression.getValue(context);
nameExpression.setValue(context, value);
return success();
}
public String toString() {
return new ToStringCreator(this).append("name", nameExpression).append("value", valueExpression).toString();
}
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.action;
import org.springframework.binding.expression.Expression;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
import org.springframework.webflow.execution.Event;
import org.springframework.webflow.execution.RequestContext;
import org.springframework.webflow.execution.ScopeType;
/**
* An action that sets an attribute in a {@link ScopeType scope} when executed. Always returns the "success" event.
*
* @author Keith Donald
*/
public class SetAction extends AbstractAction {
/**
* The expression for setting the scoped attribute value.
*/
private Expression nameExpression;
/**
* The expression for resolving the scoped attribute value.
*/
private Expression valueExpression;
/**
* Creates a new set attribute action.
* @param nameExpression the name of the property to set (required)
* @param valueExpression the expression to obtain the new property value (required) expected
*/
public SetAction(Expression nameExpression, Expression valueExpression) {
Assert.notNull(nameExpression, "The name expression is required");
Assert.notNull(valueExpression, "The value expression is required");
this.nameExpression = nameExpression;
this.valueExpression = valueExpression;
}
protected Event doExecute(RequestContext context) throws Exception {
Object value = valueExpression.getValue(context);
nameExpression.setValue(context, value);
return success();
}
public String toString() {
return new ToStringCreator(this).append("name", nameExpression).append("value", valueExpression).toString();
}
}

View File

@@ -1,246 +1,246 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.config;
import java.util.Set;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.webflow.conversation.ConversationManager;
import org.springframework.webflow.conversation.impl.SessionBindingConversationManager;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
import org.springframework.webflow.execution.FlowExecutionFactory;
import org.springframework.webflow.execution.factory.FlowExecutionListenerLoader;
import org.springframework.webflow.execution.repository.FlowExecutionRepository;
import org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository;
import org.springframework.webflow.execution.repository.snapshot.FlowExecutionSnapshotFactory;
import org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshotFactory;
import org.springframework.webflow.execution.repository.snapshot.SimpleFlowExecutionSnapshotFactory;
import org.springframework.webflow.executor.FlowExecutor;
import org.springframework.webflow.executor.FlowExecutorImpl;
/**
* This factory encapsulates the construction and assembly of a {@link FlowExecutor}, including the provision of its
* {@link FlowExecutionRepository} strategy. As a <code>FactoryBean</code>, this class has been designed for use as a
* Spring managed bean.
* <p>
* The definition locator property is required, all other properties are optional.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, BeanClassLoaderAware, InitializingBean {
private static final String ALWAYS_REDIRECT_ON_PAUSE = "alwaysRedirectOnPause";
private static final String REDIRECT_IN_SAME_STATE = "redirectInSameState";
private FlowDefinitionLocator flowDefinitionLocator;
private Integer maxFlowExecutions;
private Integer maxFlowExecutionSnapshots;
private Set<FlowElementAttribute> flowExecutionAttributes;
private FlowExecutionListenerLoader flowExecutionListenerLoader;
private ConversationManager conversationManager;
private ConversionService conversionService;
private FlowExecutor flowExecutor;
private ClassLoader classLoader;
/**
* Sets the flow definition locator that will locate flow definitions needed for execution. Typically also a
* {@link FlowDefinitionRegistry}. Required.
* @param flowDefinitionLocator the flow definition locator (registry)
*/
public void setFlowDefinitionLocator(FlowDefinitionLocator flowDefinitionLocator) {
this.flowDefinitionLocator = flowDefinitionLocator;
}
/**
* Set the maximum number of allowed flow executions allowed per user.
*/
public void setMaxFlowExecutions(int maxFlowExecutions) {
this.maxFlowExecutions = maxFlowExecutions;
}
/**
* Set the maximum number of history snapshots allowed per flow execution.
*/
public void setMaxFlowExecutionSnapshots(int maxFlowExecutionSnapshots) {
this.maxFlowExecutionSnapshots = maxFlowExecutionSnapshots;
}
/**
* Sets the system attributes that apply to flow executions launched by the executor created by this factory.
* Execution attributes may affect flow execution behavior.
* @param flowExecutionAttributes the flow execution system attributes
*/
public void setFlowExecutionAttributes(Set<FlowElementAttribute> flowExecutionAttributes) {
this.flowExecutionAttributes = flowExecutionAttributes;
}
/**
* Sets the strategy for loading the listeners that will observe executions of a flow definition. Allows full
* control over what listeners should apply to executions of a flow definition launched by the executor created by
* this factory.
*/
public void setFlowExecutionListenerLoader(FlowExecutionListenerLoader flowExecutionListenerLoader) {
this.flowExecutionListenerLoader = flowExecutionListenerLoader;
}
/**
* Sets the service type that manages conversations and effectively controls how state is stored physically when a
* flow execution is paused.
*/
public void setConversationManager(ConversationManager conversationManager) {
this.conversationManager = conversationManager;
}
// implement BeanClassLoaderAware
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
// implementing InitializingBean
public void afterPropertiesSet() throws Exception {
Assert.notNull(flowDefinitionLocator, "The flow definition locator property is required");
if (conversionService == null) {
conversionService = new DefaultConversionService();
}
MutableAttributeMap<Object> executionAttributes = createFlowExecutionAttributes();
FlowExecutionImplFactory executionFactory = createFlowExecutionFactory(executionAttributes);
DefaultFlowExecutionRepository executionRepository = createFlowExecutionRepository(executionFactory);
executionFactory.setExecutionKeyFactory(executionRepository);
flowExecutor = new FlowExecutorImpl(flowDefinitionLocator, executionFactory, executionRepository);
}
// implementing FactoryBean
public Class<?> getObjectType() {
return FlowExecutor.class;
}
public boolean isSingleton() {
return true;
}
public FlowExecutor getObject() throws Exception {
return flowExecutor;
}
private MutableAttributeMap<Object> createFlowExecutionAttributes() {
LocalAttributeMap<Object> executionAttributes = new LocalAttributeMap<>();
if (flowExecutionAttributes != null) {
for (FlowElementAttribute attribute : flowExecutionAttributes) {
executionAttributes.put(attribute.getName(), getConvertedValue(attribute));
}
}
putDefaultFlowExecutionAttributes(executionAttributes);
return executionAttributes;
}
private void putDefaultFlowExecutionAttributes(LocalAttributeMap<Object> executionAttributes) {
if (!executionAttributes.contains(ALWAYS_REDIRECT_ON_PAUSE)) {
executionAttributes.put(ALWAYS_REDIRECT_ON_PAUSE, true);
}
if (!executionAttributes.contains(REDIRECT_IN_SAME_STATE)) {
executionAttributes.put(REDIRECT_IN_SAME_STATE, true);
}
}
private DefaultFlowExecutionRepository createFlowExecutionRepository(FlowExecutionFactory executionFactory) {
ConversationManager conversationManager = createConversationManager();
FlowExecutionSnapshotFactory snapshotFactory = createFlowExecutionSnapshotFactory(executionFactory);
DefaultFlowExecutionRepository rep = new DefaultFlowExecutionRepository(conversationManager, snapshotFactory);
if (maxFlowExecutionSnapshots != null) {
rep.setMaxSnapshots(maxFlowExecutionSnapshots);
}
return rep;
}
private ConversationManager createConversationManager() {
if (conversationManager == null) {
conversationManager = new SessionBindingConversationManager();
if (maxFlowExecutions != null) {
((SessionBindingConversationManager) conversationManager).setMaxConversations(maxFlowExecutions);
}
}
return this.conversationManager;
}
private FlowExecutionSnapshotFactory createFlowExecutionSnapshotFactory(FlowExecutionFactory executionFactory) {
if (maxFlowExecutionSnapshots != null && maxFlowExecutionSnapshots == 0) {
maxFlowExecutionSnapshots = 1;
return new SimpleFlowExecutionSnapshotFactory(executionFactory, flowDefinitionLocator);
} else {
return new SerializedFlowExecutionSnapshotFactory(executionFactory, flowDefinitionLocator);
}
}
private FlowExecutionImplFactory createFlowExecutionFactory(AttributeMap<Object> executionAttributes) {
FlowExecutionImplFactory executionFactory = new FlowExecutionImplFactory();
executionFactory.setExecutionAttributes(executionAttributes);
if (flowExecutionListenerLoader != null) {
executionFactory.setExecutionListenerLoader(flowExecutionListenerLoader);
}
return executionFactory;
}
// utility methods
private Object getConvertedValue(FlowElementAttribute attribute) {
if (attribute.needsTypeConversion()) {
Class<?> targetType = fromStringToClass(attribute.getType());
ConversionExecutor converter = conversionService.getConversionExecutor(String.class, targetType);
return converter.execute(attribute.getValue());
} else {
return attribute.getValue();
}
}
private Class<?> fromStringToClass(String name) {
Class<?> clazz = conversionService.getClassForAlias(name);
if (clazz != null) {
return clazz;
} else {
try {
return ClassUtils.forName(name, classLoader);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Unable to load class '" + name + "'");
}
}
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.config;
import java.util.Set;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.webflow.conversation.ConversationManager;
import org.springframework.webflow.conversation.impl.SessionBindingConversationManager;
import org.springframework.webflow.core.collection.AttributeMap;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.definition.registry.FlowDefinitionLocator;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.impl.FlowExecutionImplFactory;
import org.springframework.webflow.execution.FlowExecutionFactory;
import org.springframework.webflow.execution.factory.FlowExecutionListenerLoader;
import org.springframework.webflow.execution.repository.FlowExecutionRepository;
import org.springframework.webflow.execution.repository.impl.DefaultFlowExecutionRepository;
import org.springframework.webflow.execution.repository.snapshot.FlowExecutionSnapshotFactory;
import org.springframework.webflow.execution.repository.snapshot.SerializedFlowExecutionSnapshotFactory;
import org.springframework.webflow.execution.repository.snapshot.SimpleFlowExecutionSnapshotFactory;
import org.springframework.webflow.executor.FlowExecutor;
import org.springframework.webflow.executor.FlowExecutorImpl;
/**
* This factory encapsulates the construction and assembly of a {@link FlowExecutor}, including the provision of its
* {@link FlowExecutionRepository} strategy. As a <code>FactoryBean</code>, this class has been designed for use as a
* Spring managed bean.
* <p>
* The definition locator property is required, all other properties are optional.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
class FlowExecutorFactoryBean implements FactoryBean<FlowExecutor>, BeanClassLoaderAware, InitializingBean {
private static final String ALWAYS_REDIRECT_ON_PAUSE = "alwaysRedirectOnPause";
private static final String REDIRECT_IN_SAME_STATE = "redirectInSameState";
private FlowDefinitionLocator flowDefinitionLocator;
private Integer maxFlowExecutions;
private Integer maxFlowExecutionSnapshots;
private Set<FlowElementAttribute> flowExecutionAttributes;
private FlowExecutionListenerLoader flowExecutionListenerLoader;
private ConversationManager conversationManager;
private ConversionService conversionService;
private FlowExecutor flowExecutor;
private ClassLoader classLoader;
/**
* Sets the flow definition locator that will locate flow definitions needed for execution. Typically also a
* {@link FlowDefinitionRegistry}. Required.
* @param flowDefinitionLocator the flow definition locator (registry)
*/
public void setFlowDefinitionLocator(FlowDefinitionLocator flowDefinitionLocator) {
this.flowDefinitionLocator = flowDefinitionLocator;
}
/**
* Set the maximum number of allowed flow executions allowed per user.
*/
public void setMaxFlowExecutions(int maxFlowExecutions) {
this.maxFlowExecutions = maxFlowExecutions;
}
/**
* Set the maximum number of history snapshots allowed per flow execution.
*/
public void setMaxFlowExecutionSnapshots(int maxFlowExecutionSnapshots) {
this.maxFlowExecutionSnapshots = maxFlowExecutionSnapshots;
}
/**
* Sets the system attributes that apply to flow executions launched by the executor created by this factory.
* Execution attributes may affect flow execution behavior.
* @param flowExecutionAttributes the flow execution system attributes
*/
public void setFlowExecutionAttributes(Set<FlowElementAttribute> flowExecutionAttributes) {
this.flowExecutionAttributes = flowExecutionAttributes;
}
/**
* Sets the strategy for loading the listeners that will observe executions of a flow definition. Allows full
* control over what listeners should apply to executions of a flow definition launched by the executor created by
* this factory.
*/
public void setFlowExecutionListenerLoader(FlowExecutionListenerLoader flowExecutionListenerLoader) {
this.flowExecutionListenerLoader = flowExecutionListenerLoader;
}
/**
* Sets the service type that manages conversations and effectively controls how state is stored physically when a
* flow execution is paused.
*/
public void setConversationManager(ConversationManager conversationManager) {
this.conversationManager = conversationManager;
}
// implement BeanClassLoaderAware
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
// implementing InitializingBean
public void afterPropertiesSet() throws Exception {
Assert.notNull(flowDefinitionLocator, "The flow definition locator property is required");
if (conversionService == null) {
conversionService = new DefaultConversionService();
}
MutableAttributeMap<Object> executionAttributes = createFlowExecutionAttributes();
FlowExecutionImplFactory executionFactory = createFlowExecutionFactory(executionAttributes);
DefaultFlowExecutionRepository executionRepository = createFlowExecutionRepository(executionFactory);
executionFactory.setExecutionKeyFactory(executionRepository);
flowExecutor = new FlowExecutorImpl(flowDefinitionLocator, executionFactory, executionRepository);
}
// implementing FactoryBean
public Class<?> getObjectType() {
return FlowExecutor.class;
}
public boolean isSingleton() {
return true;
}
public FlowExecutor getObject() throws Exception {
return flowExecutor;
}
private MutableAttributeMap<Object> createFlowExecutionAttributes() {
LocalAttributeMap<Object> executionAttributes = new LocalAttributeMap<>();
if (flowExecutionAttributes != null) {
for (FlowElementAttribute attribute : flowExecutionAttributes) {
executionAttributes.put(attribute.getName(), getConvertedValue(attribute));
}
}
putDefaultFlowExecutionAttributes(executionAttributes);
return executionAttributes;
}
private void putDefaultFlowExecutionAttributes(LocalAttributeMap<Object> executionAttributes) {
if (!executionAttributes.contains(ALWAYS_REDIRECT_ON_PAUSE)) {
executionAttributes.put(ALWAYS_REDIRECT_ON_PAUSE, true);
}
if (!executionAttributes.contains(REDIRECT_IN_SAME_STATE)) {
executionAttributes.put(REDIRECT_IN_SAME_STATE, true);
}
}
private DefaultFlowExecutionRepository createFlowExecutionRepository(FlowExecutionFactory executionFactory) {
ConversationManager conversationManager = createConversationManager();
FlowExecutionSnapshotFactory snapshotFactory = createFlowExecutionSnapshotFactory(executionFactory);
DefaultFlowExecutionRepository rep = new DefaultFlowExecutionRepository(conversationManager, snapshotFactory);
if (maxFlowExecutionSnapshots != null) {
rep.setMaxSnapshots(maxFlowExecutionSnapshots);
}
return rep;
}
private ConversationManager createConversationManager() {
if (conversationManager == null) {
conversationManager = new SessionBindingConversationManager();
if (maxFlowExecutions != null) {
((SessionBindingConversationManager) conversationManager).setMaxConversations(maxFlowExecutions);
}
}
return this.conversationManager;
}
private FlowExecutionSnapshotFactory createFlowExecutionSnapshotFactory(FlowExecutionFactory executionFactory) {
if (maxFlowExecutionSnapshots != null && maxFlowExecutionSnapshots == 0) {
maxFlowExecutionSnapshots = 1;
return new SimpleFlowExecutionSnapshotFactory(executionFactory, flowDefinitionLocator);
} else {
return new SerializedFlowExecutionSnapshotFactory(executionFactory, flowDefinitionLocator);
}
}
private FlowExecutionImplFactory createFlowExecutionFactory(AttributeMap<Object> executionAttributes) {
FlowExecutionImplFactory executionFactory = new FlowExecutionImplFactory();
executionFactory.setExecutionAttributes(executionAttributes);
if (flowExecutionListenerLoader != null) {
executionFactory.setExecutionListenerLoader(flowExecutionListenerLoader);
}
return executionFactory;
}
// utility methods
private Object getConvertedValue(FlowElementAttribute attribute) {
if (attribute.needsTypeConversion()) {
Class<?> targetType = fromStringToClass(attribute.getType());
ConversionExecutor converter = conversionService.getConversionExecutor(String.class, targetType);
return converter.execute(attribute.getValue());
} else {
return attribute.getValue();
}
}
private Class<?> fromStringToClass(String name) {
Class<?> clazz = conversionService.getClassForAlias(name);
if (clazz != null) {
return clazz;
} else {
try {
return ClassUtils.forName(name, classLoader);
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Unable to load class '" + name + "'");
}
}
}
}

View File

@@ -1,34 +1,34 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.config;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* <code>NamespaceHandler</code> for the <code>webflow-config</code> namespace.
*
* @author Keith Donald
* @author Ben Hale
* @author Jeremy Grelle
*/
public class WebFlowConfigNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("flow-executor", new FlowExecutorBeanDefinitionParser());
registerBeanDefinitionParser("flow-execution-listeners", new FlowExecutionListenerLoaderBeanDefinitionParser());
registerBeanDefinitionParser("flow-registry", new FlowRegistryBeanDefinitionParser());
registerBeanDefinitionParser("flow-builder-services", new FlowBuilderServicesBeanDefinitionParser());
}
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.config;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
/**
* <code>NamespaceHandler</code> for the <code>webflow-config</code> namespace.
*
* @author Keith Donald
* @author Ben Hale
* @author Jeremy Grelle
*/
public class WebFlowConfigNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("flow-executor", new FlowExecutorBeanDefinitionParser());
registerBeanDefinitionParser("flow-execution-listeners", new FlowExecutionListenerLoaderBeanDefinitionParser());
registerBeanDefinitionParser("flow-registry", new FlowRegistryBeanDefinitionParser());
registerBeanDefinitionParser("flow-builder-services", new FlowBuilderServicesBeanDefinitionParser());
}
}

View File

@@ -1,216 +1,216 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.context;
import java.io.Writer;
import java.security.Principal;
import java.util.Locale;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.core.collection.SharedAttributeMap;
/**
* A facade that provides normalized access to an external system that has called into the Spring Web Flow system.
* <p>
* This context object provides a normalized interface for internal web flow artifacts to use to reason on and
* manipulate the state of an external actor calling into SWF to execute flows. It represents the context about a
* single, <i>external</i> client request to manipulate a flow execution.
* <p>
* The design of this interface was inspired by JSF's own ExternalContext abstraction and shares the same name for
* consistency. If a particular external client type does not support all methods defined by this interface, they can
* just be implemented as returning an empty map or <code>null</code>.
*
* @author Keith Donald
* @author Erwin Vervaet
* @author Jeremy Grelle
* @author Scott Andrews
*/
public interface ExternalContext {
/**
* Returns the logical path to the application hosting this external context.
* @return the context path
*/
String getContextPath();
/**
* Provides access to the parameters associated with the user request that led to SWF being called. This map is
* expected to be immutable and cannot be changed.
* @return the immutable request parameter map
*/
ParameterMap getRequestParameterMap();
/**
* Provides access to the external request attribute map, providing a storage for data local to the current user
* request and accessible to both internal and external SWF artifacts.
* @return the mutable request attribute map
*/
MutableAttributeMap<Object> getRequestMap();
/**
* Provides access to the external session map, providing a storage for data local to the current user session and
* accessible to both internal and external SWF artifacts.
* @return the mutable session attribute map
*/
SharedAttributeMap<Object> getSessionMap();
/**
* Provides access to the <i>global</i> external session map, providing a storage for data globally accross the user
* session and accessible to both internal and external SWF artifacts.
* <p>
* Note: most external context implementations do not distinguish between the concept of a "local" user session
* scope and a "global" session scope. Otherwise this method returns the same map as calling {@link #getSessionMap()}.
* @return the mutable global session attribute map
*/
SharedAttributeMap<Object> getGlobalSessionMap();
/**
* Provides access to the external application map, providing a storage for data local to the current user
* application and accessible to both internal and external SWF artifacts.
* @return the mutable application attribute map
*/
SharedAttributeMap<Object> getApplicationMap();
/**
* Returns true if the current request is an asynchronous Ajax request.
* @return true if the current request is an Ajax request
*/
boolean isAjaxRequest();
/**
* Get a flow execution URL for the execution with the provided key. Typically used by response writers that write
* out references to the flow execution to support postback on a subsequent request. The URL returned is encoded.
* @param flowId the flow definition id
* @param flowExecutionKey the flow execution key
* @return the flow execution URL
*/
String getFlowExecutionUrl(String flowId, String flowExecutionKey);
/**
* Provides access to the user's principal security object.
* @return the user principal
*/
Principal getCurrentUser();
/**
* Returns the client locale.
* @return the locale
*/
Locale getLocale();
/**
* Provides access to the context object for the current environment.
* @return the environment specific context object
*/
Object getNativeContext();
/**
* Provides access to the request object for the current environment.
* @return the environment specific request object.
*/
Object getNativeRequest();
/**
* Provides access to the response object for the current environment.
* @return the environment specific response object.
*/
Object getNativeResponse();
/**
* Get a writer for writing out a response.
* @return the writer
* @throws IllegalStateException if the response has completed or is not allowed
*/
Writer getResponseWriter() throws IllegalStateException;
/**
* Is a <i>render</i> response allowed to be written for this request? Always return false after a response has been
* completed. May return false before that to indicate a response is not allowed to be completed.
* @return true if yes, false otherwise
*/
boolean isResponseAllowed();
/**
* Request that a flow execution redirect be performed by the calling environment. Typically called from within a
* flow execution to request a refresh operation, usually to support "refresh after event processing" behavior.
* Calling this method also sets responseComplete status to true.
* @see #isResponseComplete()
* @throws IllegalStateException if the response has completed
*/
void requestFlowExecutionRedirect() throws IllegalStateException;
/**
* Request that a flow definition redirect be performed by the calling environment. Typically called from within a
* flow execution end state to request starting a new, independent execution of a flow in a chain-like manner.
* Calling this method also sets responseComplete status to true.
* @see #isResponseComplete()
* @param flowId the id of the flow definition to redirect to
* @param input input to pass the flow; this input is generally encoded the url to launch the flow
* @throws IllegalStateException if the response has completed
*/
void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap<?> input) throws IllegalStateException;
/**
* Request a redirect to an arbitrary resource location. May not be supported in some environments. Calling this
* method also sets responseComplete status to true.
* @see #isResponseComplete()
* @param location the location of the resource to redirect to
* @throws IllegalStateException if the response has completed
*/
void requestExternalRedirect(String location) throws IllegalStateException;
/**
* Request that the current redirect requested be sent to the client in a manner that causes the client to issue the
* redirect from a popup dialog. Only call this method after a redirect has been requested.
* @see #requestFlowExecutionRedirect()
* @see #requestFlowDefinitionRedirect(String, MutableAttributeMap)
* @see #requestExternalRedirect(String)
* @throws IllegalStateException if a redirect has not been requested
*/
void requestRedirectInPopup() throws IllegalStateException;
/**
* Called by flow artifacts such as View states and end states to indicate they handled the response, typically by
* writing out content to the response stream. Setting this flag allows this external context to know the response
* was handled, and that it not need to take additional response handling action itself.
*/
void recordResponseComplete();
/**
* Has the response been completed? Response complete status can be achieved by:
* <ul>
* <li>Writing out the response and calling {@link #recordResponseComplete()}, or
* <li>Calling one of the redirect request methods
* </ul>
* @see #getResponseWriter()
* @see #recordResponseComplete()
* @see #requestFlowExecutionRedirect()
* @see #requestFlowDefinitionRedirect(String, MutableAttributeMap)
* @see #requestExternalRedirect(String)
* @return true if yes, false otherwise
*/
boolean isResponseComplete();
/**
* Returns true if the response has been completed with flow execution redirect request.
* @return true if a redirect response has been completed
* @see #isResponseComplete()
* @see #requestFlowExecutionRedirect()
*/
boolean isResponseCompleteFlowExecutionRedirect();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.context;
import java.io.Writer;
import java.security.Principal;
import java.util.Locale;
import org.springframework.webflow.core.collection.MutableAttributeMap;
import org.springframework.webflow.core.collection.ParameterMap;
import org.springframework.webflow.core.collection.SharedAttributeMap;
/**
* A facade that provides normalized access to an external system that has called into the Spring Web Flow system.
* <p>
* This context object provides a normalized interface for internal web flow artifacts to use to reason on and
* manipulate the state of an external actor calling into SWF to execute flows. It represents the context about a
* single, <i>external</i> client request to manipulate a flow execution.
* <p>
* The design of this interface was inspired by JSF's own ExternalContext abstraction and shares the same name for
* consistency. If a particular external client type does not support all methods defined by this interface, they can
* just be implemented as returning an empty map or <code>null</code>.
*
* @author Keith Donald
* @author Erwin Vervaet
* @author Jeremy Grelle
* @author Scott Andrews
*/
public interface ExternalContext {
/**
* Returns the logical path to the application hosting this external context.
* @return the context path
*/
String getContextPath();
/**
* Provides access to the parameters associated with the user request that led to SWF being called. This map is
* expected to be immutable and cannot be changed.
* @return the immutable request parameter map
*/
ParameterMap getRequestParameterMap();
/**
* Provides access to the external request attribute map, providing a storage for data local to the current user
* request and accessible to both internal and external SWF artifacts.
* @return the mutable request attribute map
*/
MutableAttributeMap<Object> getRequestMap();
/**
* Provides access to the external session map, providing a storage for data local to the current user session and
* accessible to both internal and external SWF artifacts.
* @return the mutable session attribute map
*/
SharedAttributeMap<Object> getSessionMap();
/**
* Provides access to the <i>global</i> external session map, providing a storage for data globally accross the user
* session and accessible to both internal and external SWF artifacts.
* <p>
* Note: most external context implementations do not distinguish between the concept of a "local" user session
* scope and a "global" session scope. Otherwise this method returns the same map as calling {@link #getSessionMap()}.
* @return the mutable global session attribute map
*/
SharedAttributeMap<Object> getGlobalSessionMap();
/**
* Provides access to the external application map, providing a storage for data local to the current user
* application and accessible to both internal and external SWF artifacts.
* @return the mutable application attribute map
*/
SharedAttributeMap<Object> getApplicationMap();
/**
* Returns true if the current request is an asynchronous Ajax request.
* @return true if the current request is an Ajax request
*/
boolean isAjaxRequest();
/**
* Get a flow execution URL for the execution with the provided key. Typically used by response writers that write
* out references to the flow execution to support postback on a subsequent request. The URL returned is encoded.
* @param flowId the flow definition id
* @param flowExecutionKey the flow execution key
* @return the flow execution URL
*/
String getFlowExecutionUrl(String flowId, String flowExecutionKey);
/**
* Provides access to the user's principal security object.
* @return the user principal
*/
Principal getCurrentUser();
/**
* Returns the client locale.
* @return the locale
*/
Locale getLocale();
/**
* Provides access to the context object for the current environment.
* @return the environment specific context object
*/
Object getNativeContext();
/**
* Provides access to the request object for the current environment.
* @return the environment specific request object.
*/
Object getNativeRequest();
/**
* Provides access to the response object for the current environment.
* @return the environment specific response object.
*/
Object getNativeResponse();
/**
* Get a writer for writing out a response.
* @return the writer
* @throws IllegalStateException if the response has completed or is not allowed
*/
Writer getResponseWriter() throws IllegalStateException;
/**
* Is a <i>render</i> response allowed to be written for this request? Always return false after a response has been
* completed. May return false before that to indicate a response is not allowed to be completed.
* @return true if yes, false otherwise
*/
boolean isResponseAllowed();
/**
* Request that a flow execution redirect be performed by the calling environment. Typically called from within a
* flow execution to request a refresh operation, usually to support "refresh after event processing" behavior.
* Calling this method also sets responseComplete status to true.
* @see #isResponseComplete()
* @throws IllegalStateException if the response has completed
*/
void requestFlowExecutionRedirect() throws IllegalStateException;
/**
* Request that a flow definition redirect be performed by the calling environment. Typically called from within a
* flow execution end state to request starting a new, independent execution of a flow in a chain-like manner.
* Calling this method also sets responseComplete status to true.
* @see #isResponseComplete()
* @param flowId the id of the flow definition to redirect to
* @param input input to pass the flow; this input is generally encoded the url to launch the flow
* @throws IllegalStateException if the response has completed
*/
void requestFlowDefinitionRedirect(String flowId, MutableAttributeMap<?> input) throws IllegalStateException;
/**
* Request a redirect to an arbitrary resource location. May not be supported in some environments. Calling this
* method also sets responseComplete status to true.
* @see #isResponseComplete()
* @param location the location of the resource to redirect to
* @throws IllegalStateException if the response has completed
*/
void requestExternalRedirect(String location) throws IllegalStateException;
/**
* Request that the current redirect requested be sent to the client in a manner that causes the client to issue the
* redirect from a popup dialog. Only call this method after a redirect has been requested.
* @see #requestFlowExecutionRedirect()
* @see #requestFlowDefinitionRedirect(String, MutableAttributeMap)
* @see #requestExternalRedirect(String)
* @throws IllegalStateException if a redirect has not been requested
*/
void requestRedirectInPopup() throws IllegalStateException;
/**
* Called by flow artifacts such as View states and end states to indicate they handled the response, typically by
* writing out content to the response stream. Setting this flag allows this external context to know the response
* was handled, and that it not need to take additional response handling action itself.
*/
void recordResponseComplete();
/**
* Has the response been completed? Response complete status can be achieved by:
* <ul>
* <li>Writing out the response and calling {@link #recordResponseComplete()}, or
* <li>Calling one of the redirect request methods
* </ul>
* @see #getResponseWriter()
* @see #recordResponseComplete()
* @see #requestFlowExecutionRedirect()
* @see #requestFlowDefinitionRedirect(String, MutableAttributeMap)
* @see #requestExternalRedirect(String)
* @return true if yes, false otherwise
*/
boolean isResponseComplete();
/**
* Returns true if the response has been completed with flow execution redirect request.
* @return true if a redirect response has been completed
* @see #isResponseComplete()
* @see #requestFlowExecutionRedirect()
*/
boolean isResponseCompleteFlowExecutionRedirect();
}

View File

@@ -1,56 +1,56 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.context;
import org.springframework.core.NamedThreadLocal;
/**
* Simple holder class that associates an {@link ExternalContext} instance with the current thread. The ExternalContext
* will not be inherited by any child threads spawned by the current thread.
* <p>
* Used as a central holder for the current ExternalContext in Spring Web Flow, wherever necessary. Often used by
* artifacts needing access to the current application session.
*
* @see ExternalContext
*
* @author Keith Donald
*/
public final class ExternalContextHolder {
private static final ThreadLocal<ExternalContext> externalContextHolder = new NamedThreadLocal<>(
"Flow ExternalContext");
/**
* Associate the given ExternalContext with the current thread.
* @param externalContext the current ExternalContext, or <code>null</code> to reset the thread-bound context
*/
public static void setExternalContext(ExternalContext externalContext) {
externalContextHolder.set(externalContext);
}
/**
* Return the ExternalContext associated with the current thread, if any.
* @return the current ExternalContext
*/
public static ExternalContext getExternalContext() {
return externalContextHolder.get();
}
// not instantiable
private ExternalContextHolder() {
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.context;
import org.springframework.core.NamedThreadLocal;
/**
* Simple holder class that associates an {@link ExternalContext} instance with the current thread. The ExternalContext
* will not be inherited by any child threads spawned by the current thread.
* <p>
* Used as a central holder for the current ExternalContext in Spring Web Flow, wherever necessary. Often used by
* artifacts needing access to the current application session.
*
* @see ExternalContext
*
* @author Keith Donald
*/
public final class ExternalContextHolder {
private static final ThreadLocal<ExternalContext> externalContextHolder = new NamedThreadLocal<>(
"Flow ExternalContext");
/**
* Associate the given ExternalContext with the current thread.
* @param externalContext the current ExternalContext, or <code>null</code> to reset the thread-bound context
*/
public static void setExternalContext(ExternalContext externalContext) {
externalContextHolder.set(externalContext);
}
/**
* Return the ExternalContext associated with the current thread, if any.
* @return the current ExternalContext
*/
public static ExternalContext getExternalContext() {
return externalContextHolder.get();
}
// not instantiable
private ExternalContextHolder() {
}
}

View File

@@ -2,8 +2,8 @@ package org.springframework.webflow.context.servlet;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.context.support.WebApplicationObjectSupport;

View File

@@ -17,8 +17,8 @@ package org.springframework.webflow.context.servlet;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* Strategy interface that encapsulates knowledge about a client-side ajax system and how to communicate with that

View File

@@ -15,8 +15,8 @@
*/
package org.springframework.webflow.context.servlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.HttpHeaders;
import org.springframework.util.StringUtils;

View File

@@ -20,7 +20,7 @@ import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.util.WebUtils;

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.webflow.context.servlet;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UrlPathHelper;

View File

@@ -15,7 +15,7 @@
*/
package org.springframework.webflow.context.servlet;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.webflow.core.collection.AttributeMap;

View File

@@ -17,7 +17,7 @@ package org.springframework.webflow.context.servlet;
import java.util.Iterator;
import javax.servlet.ServletContext;
import jakarta.servlet.ServletContext;
import org.springframework.binding.collection.SharedMap;
import org.springframework.binding.collection.StringKeyedMapAdapter;

View File

@@ -17,7 +17,7 @@ package org.springframework.webflow.context.servlet;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.binding.collection.StringKeyedMapAdapter;
import org.springframework.webflow.core.collection.CollectionUtils;

View File

@@ -18,7 +18,7 @@ package org.springframework.webflow.context.servlet;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.binding.collection.StringKeyedMapAdapter;
import org.springframework.util.Assert;

View File

@@ -17,8 +17,8 @@ package org.springframework.webflow.context.servlet;
import java.util.Iterator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.binding.collection.SharedMap;
import org.springframework.binding.collection.StringKeyedMapAdapter;

View File

@@ -20,9 +20,9 @@ import java.io.Writer;
import java.security.Principal;
import java.util.Locale;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.webflow.context.ExternalContext;
import org.springframework.webflow.core.collection.LocalAttributeMap;

View File

@@ -20,7 +20,7 @@ import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.webflow.core.collection.AttributeMap;

View File

@@ -1,77 +1,77 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.context.web;
import java.util.Map;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import org.springframework.webflow.core.collection.AttributeMapBindingEvent;
import org.springframework.webflow.core.collection.AttributeMapBindingListener;
import org.springframework.webflow.core.collection.LocalAttributeMap;
/**
* Helper class that adapts a generic {@link AttributeMapBindingListener} to a HTTP specific
* {@link HttpSessionBindingListener}. Calls will be forwarded to the wrapped listener.
*
* @author Keith Donald
*/
public class HttpSessionMapBindingListener implements HttpSessionBindingListener {
private AttributeMapBindingListener listener;
private Map<String, Object> sessionMap;
/**
* Create a new wrapper for given listener.
* @param listener the listener to wrap
* @param sessionMap the session map containing the listener
*/
public HttpSessionMapBindingListener(AttributeMapBindingListener listener, Map<String, Object> sessionMap) {
this.listener = listener;
this.sessionMap = sessionMap;
}
/**
* Returns the wrapped listener.
*/
public AttributeMapBindingListener getListener() {
return listener;
}
/**
* Returns the session map containing the listener.
*/
public Map<String, Object> getSessionMap() {
return sessionMap;
}
public void valueBound(HttpSessionBindingEvent event) {
listener.valueBound(getContextBindingEvent(event));
}
public void valueUnbound(HttpSessionBindingEvent event) {
listener.valueUnbound(getContextBindingEvent(event));
}
/**
* Create a attribute map binding event for given HTTP session binding event.
*/
private AttributeMapBindingEvent getContextBindingEvent(HttpSessionBindingEvent event) {
return new AttributeMapBindingEvent(new LocalAttributeMap<>(sessionMap), event.getName(), listener);
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.context.web;
import java.util.Map;
import jakarta.servlet.http.HttpSessionBindingEvent;
import jakarta.servlet.http.HttpSessionBindingListener;
import org.springframework.webflow.core.collection.AttributeMapBindingEvent;
import org.springframework.webflow.core.collection.AttributeMapBindingListener;
import org.springframework.webflow.core.collection.LocalAttributeMap;
/**
* Helper class that adapts a generic {@link AttributeMapBindingListener} to a HTTP specific
* {@link HttpSessionBindingListener}. Calls will be forwarded to the wrapped listener.
*
* @author Keith Donald
*/
public class HttpSessionMapBindingListener implements HttpSessionBindingListener {
private AttributeMapBindingListener listener;
private Map<String, Object> sessionMap;
/**
* Create a new wrapper for given listener.
* @param listener the listener to wrap
* @param sessionMap the session map containing the listener
*/
public HttpSessionMapBindingListener(AttributeMapBindingListener listener, Map<String, Object> sessionMap) {
this.listener = listener;
this.sessionMap = sessionMap;
}
/**
* Returns the wrapped listener.
*/
public AttributeMapBindingListener getListener() {
return listener;
}
/**
* Returns the session map containing the listener.
*/
public Map<String, Object> getSessionMap() {
return sessionMap;
}
public void valueBound(HttpSessionBindingEvent event) {
listener.valueBound(getContextBindingEvent(event));
}
public void valueUnbound(HttpSessionBindingEvent event) {
listener.valueUnbound(getContextBindingEvent(event));
}
/**
* Create a attribute map binding event for given HTTP session binding event.
*/
private AttributeMapBindingEvent getContextBindingEvent(HttpSessionBindingEvent event) {
return new AttributeMapBindingEvent(new LocalAttributeMap<>(sessionMap), event.getName(), listener);
}
}

View File

@@ -1,97 +1,97 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation;
/**
* A service interface for working with state associated with a single logical user interaction called a "conversation"
* in the scope of a single request. Conversation objects are not thread safe and should not be shared among multiple
* threads.
* <p>
* A conversation provides a "task" context that is begun and eventually ends. Between the beginning and the end
* attributes can be placed in and read from a conversation's context.
* <p>
* A conversation needs to be {@link #lock() locked} to obtain exclusive access to it before it can be manipulated. Once
* manipulation is finished, you need to {@link #unlock() unlock} the conversation. So code interacting with a
* conversation always looks like this:
*
* <pre>
* Conversation conv = ...;
* conv.lock();
* try {
* // work with the Conversation object, calling methods like
* // getAttribute(), putAttribute() and end()
* }
* finally {
* conv.unlock();
* }
* </pre>
*
* <p>
* Note that the attributes associated with a conversation are not "conversation scope" as defined for a flow execution.
* They can be any attributes, possibly technical in nature, associated with the conversation.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface Conversation {
/**
* Returns the unique id assigned to this conversation. This id remains the same throughout the life of the
* conversation. This method can be safely called without owning the lock of this conversation.
* @return the conversation id
*/
ConversationId getId();
/**
* Lock this conversation. May block until the lock is available, if someone else has acquired the lock.
* @throws ConversationLockException if the lock could not be acquired
*/
void lock() throws ConversationLockException;
/**
* Returns the conversation attribute with the specified name. You need to acquire the lock on this conversation
* before calling this method.
* @param name the attribute name
* @return the attribute value
*/
Object getAttribute(Object name);
/**
* Puts a conversation attribute into this context. You need to acquire the lock on this conversation before calling
* this method.
* @param name the attribute name
* @param value the attribute value
*/
void putAttribute(Object name, Object value);
/**
* Removes a conversation attribute. You need to acquire the lock on this conversation before calling this method.
* @param name the attribute name
*/
void removeAttribute(Object name);
/**
* Ends this conversation. This method should only be called once to terminate the conversation and cleanup any
* allocated resources. You need to aquire the lock on this conversation before calling this method.
*/
void end();
/**
* Unlock this conversation, making it available to others for manipulation.
*/
void unlock();
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation;
/**
* A service interface for working with state associated with a single logical user interaction called a "conversation"
* in the scope of a single request. Conversation objects are not thread safe and should not be shared among multiple
* threads.
* <p>
* A conversation provides a "task" context that is begun and eventually ends. Between the beginning and the end
* attributes can be placed in and read from a conversation's context.
* <p>
* A conversation needs to be {@link #lock() locked} to obtain exclusive access to it before it can be manipulated. Once
* manipulation is finished, you need to {@link #unlock() unlock} the conversation. So code interacting with a
* conversation always looks like this:
*
* <pre>
* Conversation conv = ...;
* conv.lock();
* try {
* // work with the Conversation object, calling methods like
* // getAttribute(), putAttribute() and end()
* }
* finally {
* conv.unlock();
* }
* </pre>
*
* <p>
* Note that the attributes associated with a conversation are not "conversation scope" as defined for a flow execution.
* They can be any attributes, possibly technical in nature, associated with the conversation.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface Conversation {
/**
* Returns the unique id assigned to this conversation. This id remains the same throughout the life of the
* conversation. This method can be safely called without owning the lock of this conversation.
* @return the conversation id
*/
ConversationId getId();
/**
* Lock this conversation. May block until the lock is available, if someone else has acquired the lock.
* @throws ConversationLockException if the lock could not be acquired
*/
void lock() throws ConversationLockException;
/**
* Returns the conversation attribute with the specified name. You need to acquire the lock on this conversation
* before calling this method.
* @param name the attribute name
* @return the attribute value
*/
Object getAttribute(Object name);
/**
* Puts a conversation attribute into this context. You need to acquire the lock on this conversation before calling
* this method.
* @param name the attribute name
* @param value the attribute value
*/
void putAttribute(Object name, Object value);
/**
* Removes a conversation attribute. You need to acquire the lock on this conversation before calling this method.
* @param name the attribute name
*/
void removeAttribute(Object name);
/**
* Ends this conversation. This method should only be called once to terminate the conversation and cleanup any
* allocated resources. You need to aquire the lock on this conversation before calling this method.
*/
void end();
/**
* Unlock this conversation, making it available to others for manipulation.
*/
void unlock();
}

View File

@@ -1,41 +1,41 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation;
/**
* The root of the conversation service exception hierarchy.
*
* @author Keith Donald
*/
public abstract class ConversationException extends RuntimeException {
/**
* Creates a conversation service exception.
* @param message a descriptive message
*/
public ConversationException(String message) {
super(message);
}
/**
* Creates a conversation service exception.
* @param message a descriptive message
* @param cause the root cause of the problem
*/
public ConversationException(String message, Throwable cause) {
super(message, cause);
}
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation;
/**
* The root of the conversation service exception hierarchy.
*
* @author Keith Donald
*/
public abstract class ConversationException extends RuntimeException {
/**
* Creates a conversation service exception.
* @param message a descriptive message
*/
public ConversationException(String message) {
super(message);
}
/**
* Creates a conversation service exception.
* @param message a descriptive message
* @param cause the root cause of the problem
*/
public ConversationException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,47 +1,47 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation;
/**
* Thrown when no logical conversation exists with the specified <code>conversationId</code>. This might occur if the
* conversation ended, expired, or was otherwise invalidated, but a client view still references it.
*
* @author Keith Donald
*/
public class NoSuchConversationException extends ConversationException {
/**
* The unique conversation identifier that was invalid.
*/
private ConversationId conversationId;
/**
* Create a new conversation lookup exception.
* @param conversationId the conversation id
*/
public NoSuchConversationException(ConversationId conversationId) {
super("No conversation could be found with id '" + conversationId
+ "' -- perhaps this conversation has ended? ");
this.conversationId = conversationId;
}
/**
* Returns the conversation id that was not found.
*/
public ConversationId getConversationId() {
return conversationId;
}
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation;
/**
* Thrown when no logical conversation exists with the specified <code>conversationId</code>. This might occur if the
* conversation ended, expired, or was otherwise invalidated, but a client view still references it.
*
* @author Keith Donald
*/
public class NoSuchConversationException extends ConversationException {
/**
* The unique conversation identifier that was invalid.
*/
private ConversationId conversationId;
/**
* Create a new conversation lookup exception.
* @param conversationId the conversation id
*/
public NoSuchConversationException(ConversationId conversationId) {
super("No conversation could be found with id '" + conversationId
+ "' -- perhaps this conversation has ended? ");
this.conversationId = conversationId;
}
/**
* Returns the conversation id that was not found.
*/
public ConversationId getConversationId() {
return conversationId;
}
}

View File

@@ -1,135 +1,135 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.conversation.Conversation;
import org.springframework.webflow.conversation.ConversationId;
import org.springframework.webflow.core.collection.SharedAttributeMap;
/**
* Internal {@link Conversation} implementation used by the conversation container.
* <p>
* This is an internal helper class of the {@link SessionBindingConversationManager}.
*
* @author Erwin Vervaet
*/
public class ContainedConversation implements Conversation, Serializable {
private static final Log logger = LogFactory.getLog(SessionBindingConversationManager.class);
private ConversationContainer container;
private ConversationId id;
private ConversationLock lock;
private Map<Object, Object> attributes;
/**
* Create a new contained conversation.
* @param container the container containing the conversation
* @param id the unique id assigned to the conversation
* @param lock the conversation lock
*/
public ContainedConversation(ConversationContainer container, ConversationId id, ConversationLock lock) {
this.container = container;
this.id = id;
this.lock = lock;
this.attributes = new HashMap<>();
}
protected void setContainer(ConversationContainer container) {
this.container = container;
}
public ConversationId getId() {
return this.id;
}
protected void setId(ConversationId id) {
this.id = id;
}
public void lock() {
if (logger.isDebugEnabled()) {
logger.debug("Locking conversation " + this.id);
}
this.lock.lock();
}
public Object getAttribute(Object name) {
return this.attributes.get(name);
}
public void putAttribute(Object name, Object value) {
if (logger.isDebugEnabled()) {
logger.debug("Putting conversation attribute '" + name + "' with value " + value);
}
this.attributes.put(name, value);
}
public void removeAttribute(Object name) {
if (logger.isDebugEnabled()) {
logger.debug("Removing conversation attribute '" + name + "'");
}
this.attributes.remove(name);
}
public void end() {
if (logger.isDebugEnabled()) {
logger.debug("Ending conversation " + this.id);
}
this.container.removeConversation(getId());
}
public void unlock() {
if (logger.isDebugEnabled()) {
logger.debug("Unlocking conversation " + this.id);
}
this.lock.unlock();
// re-bind the conversation container in the session
// this is required to make session replication work correctly in
// a clustered environment
// we do this after releasing the lock since we're no longer
// manipulating the contents of the conversation
SharedAttributeMap<Object> sessionMap = ExternalContextHolder.getExternalContext().getSessionMap();
synchronized (sessionMap.getMutex()) {
sessionMap.put(this.container.getSessionKey(), this.container);
}
}
public String toString() {
return getId().toString();
}
// id based equality
public boolean equals(Object obj) {
return obj instanceof ContainedConversation && this.id.equals(((ContainedConversation) obj).id);
}
public int hashCode() {
return this.id.hashCode();
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.conversation.Conversation;
import org.springframework.webflow.conversation.ConversationId;
import org.springframework.webflow.core.collection.SharedAttributeMap;
/**
* Internal {@link Conversation} implementation used by the conversation container.
* <p>
* This is an internal helper class of the {@link SessionBindingConversationManager}.
*
* @author Erwin Vervaet
*/
public class ContainedConversation implements Conversation, Serializable {
private static final Log logger = LogFactory.getLog(SessionBindingConversationManager.class);
private ConversationContainer container;
private ConversationId id;
private ConversationLock lock;
private Map<Object, Object> attributes;
/**
* Create a new contained conversation.
* @param container the container containing the conversation
* @param id the unique id assigned to the conversation
* @param lock the conversation lock
*/
public ContainedConversation(ConversationContainer container, ConversationId id, ConversationLock lock) {
this.container = container;
this.id = id;
this.lock = lock;
this.attributes = new HashMap<>();
}
protected void setContainer(ConversationContainer container) {
this.container = container;
}
public ConversationId getId() {
return this.id;
}
protected void setId(ConversationId id) {
this.id = id;
}
public void lock() {
if (logger.isDebugEnabled()) {
logger.debug("Locking conversation " + this.id);
}
this.lock.lock();
}
public Object getAttribute(Object name) {
return this.attributes.get(name);
}
public void putAttribute(Object name, Object value) {
if (logger.isDebugEnabled()) {
logger.debug("Putting conversation attribute '" + name + "' with value " + value);
}
this.attributes.put(name, value);
}
public void removeAttribute(Object name) {
if (logger.isDebugEnabled()) {
logger.debug("Removing conversation attribute '" + name + "'");
}
this.attributes.remove(name);
}
public void end() {
if (logger.isDebugEnabled()) {
logger.debug("Ending conversation " + this.id);
}
this.container.removeConversation(getId());
}
public void unlock() {
if (logger.isDebugEnabled()) {
logger.debug("Unlocking conversation " + this.id);
}
this.lock.unlock();
// re-bind the conversation container in the session
// this is required to make session replication work correctly in
// a clustered environment
// we do this after releasing the lock since we're no longer
// manipulating the contents of the conversation
SharedAttributeMap<Object> sessionMap = ExternalContextHolder.getExternalContext().getSessionMap();
synchronized (sessionMap.getMutex()) {
sessionMap.put(this.container.getSessionKey(), this.container);
}
}
public String toString() {
return getId().toString();
}
// id based equality
public boolean equals(Object obj) {
return obj instanceof ContainedConversation && this.id.equals(((ContainedConversation) obj).id);
}
public int hashCode() {
return this.id.hashCode();
}
}

View File

@@ -1,39 +1,39 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.io.Serializable;
import org.springframework.webflow.conversation.ConversationLockException;
/**
* A normalized interface for conversation locks, used to obtain exclusive access to a conversation.
*
* @author Keith Donald
*/
public interface ConversationLock extends Serializable {
/**
* Acquire the conversation lock.
* @throws ConversationLockException if an exception is thrown attempting to acquire this lock
*/
void lock() throws ConversationLockException;
/**
* Release the conversation lock.
*/
void unlock();
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.io.Serializable;
import org.springframework.webflow.conversation.ConversationLockException;
/**
* A normalized interface for conversation locks, used to obtain exclusive access to a conversation.
*
* @author Keith Donald
*/
public interface ConversationLock extends Serializable {
/**
* Acquire the conversation lock.
* @throws ConversationLockException if an exception is thrown attempting to acquire this lock
*/
void lock() throws ConversationLockException;
/**
* Release the conversation lock.
*/
void unlock();
}

View File

@@ -1,54 +1,54 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.springframework.webflow.conversation.ConversationLockException;
/**
* A conversation lock that relies on a {@link ReentrantLock} within Java 5's <code>util.concurrent.locks</code>
* package.
*
* @author Keith Donald
*/
public class JdkConcurrentConversationLock implements ConversationLock {
private Lock lock = new ReentrantLock();
private int timeoutSeconds;
public JdkConcurrentConversationLock(int timeoutSeconds) {
this.timeoutSeconds = timeoutSeconds;
}
public void lock() throws ConversationLockException {
try {
boolean acquired = this.lock.tryLock(this.timeoutSeconds, TimeUnit.SECONDS);
if (!acquired) {
throw new LockTimeoutException(this.timeoutSeconds);
}
} catch (InterruptedException e) {
throw new LockInterruptedException(e);
}
}
public void unlock() {
this.lock.unlock();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.springframework.webflow.conversation.ConversationLockException;
/**
* A conversation lock that relies on a {@link ReentrantLock} within Java 5's <code>util.concurrent.locks</code>
* package.
*
* @author Keith Donald
*/
public class JdkConcurrentConversationLock implements ConversationLock {
private Lock lock = new ReentrantLock();
private int timeoutSeconds;
public JdkConcurrentConversationLock(int timeoutSeconds) {
this.timeoutSeconds = timeoutSeconds;
}
public void lock() throws ConversationLockException {
try {
boolean acquired = this.lock.tryLock(this.timeoutSeconds, TimeUnit.SECONDS);
if (!acquired) {
throw new LockTimeoutException(this.timeoutSeconds);
}
} catch (InterruptedException e) {
throw new LockInterruptedException(e);
}
}
public void unlock() {
this.lock.unlock();
}
}

View File

@@ -1,51 +1,51 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.io.ObjectStreamException;
/**
* A singleton lock that doesn't do anything. For use when conversations don't require or choose not to implement
* locking.
*
* @author Keith Donald
*/
public class NoOpConversationLock implements ConversationLock {
/**
* The singleton instance.
*/
public static final NoOpConversationLock INSTANCE = new NoOpConversationLock();
/**
* Private constructor to avoid instantiation.
*/
private NoOpConversationLock() {
}
public void lock() {
// no-op
}
public void unlock() {
// no-op
}
// resolve the singleton instance
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import java.io.ObjectStreamException;
/**
* A singleton lock that doesn't do anything. For use when conversations don't require or choose not to implement
* locking.
*
* @author Keith Donald
*/
public class NoOpConversationLock implements ConversationLock {
/**
* The singleton instance.
*/
public static final NoOpConversationLock INSTANCE = new NoOpConversationLock();
/**
* Private constructor to avoid instantiation.
*/
private NoOpConversationLock() {
}
public void lock() {
// no-op
}
public void unlock() {
// no-op
}
// resolve the singleton instance
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}
}

View File

@@ -1,149 +1,149 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.conversation.Conversation;
import org.springframework.webflow.conversation.ConversationException;
import org.springframework.webflow.conversation.ConversationId;
import org.springframework.webflow.conversation.ConversationManager;
import org.springframework.webflow.conversation.ConversationParameters;
import org.springframework.webflow.core.collection.SharedAttributeMap;
/**
* Simple implementation of a conversation manager that stores conversations in the session attribute map.
* <p>
* Using the {@link #setMaxConversations(int) maxConversations} property, you can limit the number of concurrently
* active conversations allowed in a single session. If the maximum is exceeded, the conversation manager will
* automatically end the oldest conversation. The default is 5, which should be fine for most situations. Set it to -1
* for no limit. Setting maxConversations to 1 allows easy resource cleanup in situations where there should only be one
* active conversation per session.
*
* @author Erwin Vervaet
*/
public class SessionBindingConversationManager implements ConversationManager {
/**
* The name of the session attribute that will hold the conversation container used by this conversation manager.
*
* To support multiple independent conversation containers in the same web application, for example, for use with
* multiple flow executors each configured with their own session-binding conversation manager, set this field's
* value to something unique.
* @see #setSessionKey(String)
*/
private String sessionKey = "webflowConversationContainer";
/**
* The maximum number of active conversations allowed in a session. The default is 5. This is high enough for most
* practical situations and low enough to avoid excessive resource usage or easy denial of service attacks.
*/
private int maxConversations = 5;
/**
* The lock timeout in seconds.
*/
private int lockTimeoutSeconds = 30;
/**
* Returns the key this conversation manager uses to store conversation data in the session.
* @return the session key
*/
public String getSessionKey() {
return sessionKey;
}
/**
* Sets the key this conversation manager uses to store conversation data in the session. If multiple session
* binding conversation managers are used in the same web application to back independent flow executors, this value
* should be unique among them.
* @param sessionKey the session key
*/
public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}
/**
* Returns the maximum number of allowed concurrent conversations. The default is 5.
*/
public int getMaxConversations() {
return maxConversations;
}
/**
* Set the maximum number of allowed concurrent conversations. Set to -1 for no limit. The default is 5.
*/
public void setMaxConversations(int maxConversations) {
this.maxConversations = maxConversations;
}
/**
* Returns the time period that can elapse before a timeout occurs on an attempt to acquire a conversation lock. The
* default is 30 seconds.
*/
public int getLockTimeoutSeconds() {
return lockTimeoutSeconds;
}
/**
* Sets the time period that can elapse before a timeout occurs on an attempt to acquire a conversation lock. The
* default is 30 seconds.
* @param lockTimeoutSeconds the timeout period in seconds
*/
public void setLockTimeoutSeconds(int lockTimeoutSeconds) {
this.lockTimeoutSeconds = lockTimeoutSeconds;
}
// implementing conversation manager
public Conversation beginConversation(ConversationParameters conversationParameters) throws ConversationException {
ConversationLock lock = new JdkConcurrentConversationLock(lockTimeoutSeconds);
return getConversationContainer().createConversation(conversationParameters, lock);
}
public Conversation getConversation(ConversationId id) throws ConversationException {
return getConversationContainer().getConversation(id);
}
public ConversationId parseConversationId(String encodedId) throws ConversationException {
try {
return new SimpleConversationId(Integer.valueOf(encodedId));
} catch (NumberFormatException e) {
throw new BadlyFormattedConversationIdException(encodedId, e);
}
}
// hooks for subclassing
protected ConversationContainer createConversationContainer() {
return new ConversationContainer(maxConversations, sessionKey);
}
/**
* Obtain the conversation container from the session. Create a new empty container and add it to the session if no
* existing container can be found.
*/
protected final ConversationContainer getConversationContainer() {
SharedAttributeMap<Object> sessionMap = ExternalContextHolder.getExternalContext().getSessionMap();
synchronized (sessionMap.getMutex()) {
ConversationContainer container = (ConversationContainer) sessionMap.get(sessionKey);
if (container == null) {
container = createConversationContainer();
sessionMap.put(sessionKey, container);
}
return container;
}
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.conversation.impl;
import org.springframework.webflow.context.ExternalContextHolder;
import org.springframework.webflow.conversation.Conversation;
import org.springframework.webflow.conversation.ConversationException;
import org.springframework.webflow.conversation.ConversationId;
import org.springframework.webflow.conversation.ConversationManager;
import org.springframework.webflow.conversation.ConversationParameters;
import org.springframework.webflow.core.collection.SharedAttributeMap;
/**
* Simple implementation of a conversation manager that stores conversations in the session attribute map.
* <p>
* Using the {@link #setMaxConversations(int) maxConversations} property, you can limit the number of concurrently
* active conversations allowed in a single session. If the maximum is exceeded, the conversation manager will
* automatically end the oldest conversation. The default is 5, which should be fine for most situations. Set it to -1
* for no limit. Setting maxConversations to 1 allows easy resource cleanup in situations where there should only be one
* active conversation per session.
*
* @author Erwin Vervaet
*/
public class SessionBindingConversationManager implements ConversationManager {
/**
* The name of the session attribute that will hold the conversation container used by this conversation manager.
*
* To support multiple independent conversation containers in the same web application, for example, for use with
* multiple flow executors each configured with their own session-binding conversation manager, set this field's
* value to something unique.
* @see #setSessionKey(String)
*/
private String sessionKey = "webflowConversationContainer";
/**
* The maximum number of active conversations allowed in a session. The default is 5. This is high enough for most
* practical situations and low enough to avoid excessive resource usage or easy denial of service attacks.
*/
private int maxConversations = 5;
/**
* The lock timeout in seconds.
*/
private int lockTimeoutSeconds = 30;
/**
* Returns the key this conversation manager uses to store conversation data in the session.
* @return the session key
*/
public String getSessionKey() {
return sessionKey;
}
/**
* Sets the key this conversation manager uses to store conversation data in the session. If multiple session
* binding conversation managers are used in the same web application to back independent flow executors, this value
* should be unique among them.
* @param sessionKey the session key
*/
public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}
/**
* Returns the maximum number of allowed concurrent conversations. The default is 5.
*/
public int getMaxConversations() {
return maxConversations;
}
/**
* Set the maximum number of allowed concurrent conversations. Set to -1 for no limit. The default is 5.
*/
public void setMaxConversations(int maxConversations) {
this.maxConversations = maxConversations;
}
/**
* Returns the time period that can elapse before a timeout occurs on an attempt to acquire a conversation lock. The
* default is 30 seconds.
*/
public int getLockTimeoutSeconds() {
return lockTimeoutSeconds;
}
/**
* Sets the time period that can elapse before a timeout occurs on an attempt to acquire a conversation lock. The
* default is 30 seconds.
* @param lockTimeoutSeconds the timeout period in seconds
*/
public void setLockTimeoutSeconds(int lockTimeoutSeconds) {
this.lockTimeoutSeconds = lockTimeoutSeconds;
}
// implementing conversation manager
public Conversation beginConversation(ConversationParameters conversationParameters) throws ConversationException {
ConversationLock lock = new JdkConcurrentConversationLock(lockTimeoutSeconds);
return getConversationContainer().createConversation(conversationParameters, lock);
}
public Conversation getConversation(ConversationId id) throws ConversationException {
return getConversationContainer().getConversation(id);
}
public ConversationId parseConversationId(String encodedId) throws ConversationException {
try {
return new SimpleConversationId(Integer.valueOf(encodedId));
} catch (NumberFormatException e) {
throw new BadlyFormattedConversationIdException(encodedId, e);
}
}
// hooks for subclassing
protected ConversationContainer createConversationContainer() {
return new ConversationContainer(maxConversations, sessionKey);
}
/**
* Obtain the conversation container from the session. Create a new empty container and add it to the session if no
* existing container can be found.
*/
protected final ConversationContainer getConversationContainer() {
SharedAttributeMap<Object> sessionMap = ExternalContextHolder.getExternalContext().getSessionMap();
synchronized (sessionMap.getMutex()) {
ConversationContainer container = (ConversationContainer) sessionMap.get(sessionKey);
if (container == null) {
container = createConversationContainer();
sessionMap.put(sessionKey, container);
}
return container;
}
}
}

View File

@@ -1,47 +1,47 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core;
import org.springframework.webflow.core.collection.MutableAttributeMap;
/**
* An interface to be implemented by objects that are annotated with attributes they wish to expose to clients.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface Annotated {
/**
* Returns a short summary of this object, suitable for display as an icon caption or tool tip.
* @return the caption
*/
String getCaption();
/**
* Returns a longer, more detailed description of this object.
* @return the description
*/
String getDescription();
/**
* Returns a attribute map containing the attributes annotating this object. These attributes provide descriptive
* characteristics or properties that may affect object behavior.
* @return the attribute map
*/
MutableAttributeMap<Object> getAttributes();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core;
import org.springframework.webflow.core.collection.MutableAttributeMap;
/**
* An interface to be implemented by objects that are annotated with attributes they wish to expose to clients.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface Annotated {
/**
* Returns a short summary of this object, suitable for display as an icon caption or tool tip.
* @return the caption
*/
String getCaption();
/**
* Returns a longer, more detailed description of this object.
* @return the description
*/
String getDescription();
/**
* Returns a attribute map containing the attributes annotating this object. These attributes provide descriptive
* characteristics or properties that may affect object behavior.
* @return the attribute map
*/
MutableAttributeMap<Object> getAttributes();
}

View File

@@ -1,79 +1,79 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
/**
* A base class for all objects in the web flow system that support annotation using arbitrary properties. Mainly used
* to ensure consistent configuration of properties for all annotated objects.
*
* @author Erwin Vervaet
* @author Keith Donald
*/
public abstract class AnnotatedObject implements Annotated {
/**
* The caption property name ("caption"). A caption is also known as a "short description" and may be used in a GUI
* tooltip.
*/
public static final String CAPTION_PROPERTY = "caption";
/**
* The long description property name ("description"). A description provides additional, free-form detail about
* this object and might be shown in a GUI text area.
*/
public static final String DESCRIPTION_PROPERTY = "description";
/**
* Additional properties further describing this object. The properties set in this map may be arbitrary.
*/
private LocalAttributeMap<Object> attributes = new LocalAttributeMap<>();
// implementing Annotated
public String getCaption() {
return attributes.getString(CAPTION_PROPERTY);
}
public String getDescription() {
return attributes.getString(DESCRIPTION_PROPERTY);
}
public MutableAttributeMap<Object> getAttributes() {
return attributes;
}
// mutators
/**
* Sets the short description (suitable for display in a tooltip).
* @param caption the caption
*/
public void setCaption(String caption) {
attributes.put(CAPTION_PROPERTY, caption);
}
/**
* Sets the long description.
* @param description the long description
*/
public void setDescription(String description) {
attributes.put(DESCRIPTION_PROPERTY, description);
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core;
import org.springframework.webflow.core.collection.LocalAttributeMap;
import org.springframework.webflow.core.collection.MutableAttributeMap;
/**
* A base class for all objects in the web flow system that support annotation using arbitrary properties. Mainly used
* to ensure consistent configuration of properties for all annotated objects.
*
* @author Erwin Vervaet
* @author Keith Donald
*/
public abstract class AnnotatedObject implements Annotated {
/**
* The caption property name ("caption"). A caption is also known as a "short description" and may be used in a GUI
* tooltip.
*/
public static final String CAPTION_PROPERTY = "caption";
/**
* The long description property name ("description"). A description provides additional, free-form detail about
* this object and might be shown in a GUI text area.
*/
public static final String DESCRIPTION_PROPERTY = "description";
/**
* Additional properties further describing this object. The properties set in this map may be arbitrary.
*/
private LocalAttributeMap<Object> attributes = new LocalAttributeMap<>();
// implementing Annotated
public String getCaption() {
return attributes.getString(CAPTION_PROPERTY);
}
public String getDescription() {
return attributes.getString(DESCRIPTION_PROPERTY);
}
public MutableAttributeMap<Object> getAttributes() {
return attributes;
}
// mutators
/**
* Sets the short description (suitable for display in a tooltip).
* @param caption the caption
*/
public void setCaption(String caption) {
attributes.put(CAPTION_PROPERTY, caption);
}
/**
* Sets the long description.
* @param description the long description
*/
public void setDescription(String description) {
attributes.put(DESCRIPTION_PROPERTY, description);
}
}

View File

@@ -1,44 +1,44 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.core;
/**
* Root class for exceptions thrown by the Spring Web Flow system. All other exceptions within the system should be
* assignable to this class.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public abstract class FlowException extends RuntimeException {
/**
* Creates a new flow exception.
* @param msg the message
* @param cause the cause
*/
public FlowException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Creates a new flow exception.
* @param msg the message
*/
public FlowException(String msg) {
super(msg);
}
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.core;
/**
* Root class for exceptions thrown by the Spring Web Flow system. All other exceptions within the system should be
* assignable to this class.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public abstract class FlowException extends RuntimeException {
/**
* Creates a new flow exception.
* @param msg the message
* @param cause the cause
*/
public FlowException(String msg, Throwable cause) {
super(msg, cause);
}
/**
* Creates a new flow exception.
* @param msg the message
*/
public FlowException(String msg) {
super(msg);
}
}

View File

@@ -1,315 +1,315 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.util.Collection;
import org.springframework.binding.collection.MapAdaptable;
/**
* An immutable interface for accessing attributes in a backing map with string keys.
* <p>
* Implementations can optionally support {@link AttributeMapBindingListener listeners} that will be notified when
* they're bound in or unbound from the map.
*
* @author Keith Donald
*/
public interface AttributeMap<V> extends MapAdaptable<String, V> {
/**
* Get an attribute value out of this map, returning <code>null</code> if not found.
* @param attributeName the attribute name
* @return the attribute value
*/
V get(String attributeName);
/**
* Returns the size of this map.
* @return the number of entries in the map
*/
int size();
/**
* Is this attribute map empty with a size of 0?
* @return true if empty, false if not
*/
boolean isEmpty();
/**
* Does the attribute with the provided name exist in this map?
* @param attributeName the attribute name
* @return true if so, false otherwise
*/
boolean contains(String attributeName);
/**
* Does the attribute with the provided name exist in this map and is its value of the specified required type?
* @param attributeName the attribute name
* @param requiredType the required class of the attribute value
* @return true if so, false otherwise
* @throws IllegalArgumentException when the value is not of the required type
*/
boolean contains(String attributeName, Class<? extends V> requiredType) throws IllegalArgumentException;
/**
* Get an attribute value, returning the default value if no value is found.
* @param attributeName the name of the attribute
* @param defaultValue the default value
* @return the attribute value, falling back to the default if no such attribute exists
*/
V get(String attributeName, V defaultValue);
/**
* Get an attribute value, asserting the value is of the required type.
* @param attributeName the name of the attribute
* @param requiredType the required type of the attribute value
* @return the attribute value, or null if not found
* @throws IllegalArgumentException when the value is not of the required type
*/
<T extends V> T get(String attributeName, Class<T> requiredType) throws IllegalArgumentException;
/**
* Get an attribute value, asserting the value is of the required type and returning the default value if not found.
* @param attributeName the name of the attribute
* @param requiredType the value required type
* @param defaultValue the default value
* @return the attribute value, or the default if not found
* @throws IllegalArgumentException when the value (if found) is not of the required type
*/
<T extends V> T get(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalStateException;
/**
* Get the value of a required attribute, throwing an exception of no attribute is found.
* @param attributeName the name of the attribute
* @return the attribute value
* @throws IllegalArgumentException when the attribute is not found
*/
V getRequired(String attributeName) throws IllegalArgumentException;
/**
* Get the value of a required attribute and make sure it is of the required type.
* @param attributeName name of the attribute to get
* @param requiredType the required type of the attribute value
* @return the attribute value
* @throws IllegalArgumentException when the attribute is not found or not of the required type
*/
<T extends V> T getRequired(String attributeName, Class<T> requiredType) throws IllegalArgumentException;
/**
* Returns a string attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the string attribute value
* @throws IllegalArgumentException if the attribute is present but not a string
*/
String getString(String attributeName) throws IllegalArgumentException;
/**
* Returns a string attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the string attribute value
* @throws IllegalArgumentException if the attribute is present but not a string
*/
String getString(String attributeName, String defaultValue) throws IllegalArgumentException;
/**
* Returns a string attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the string attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not a string
*/
String getRequiredString(String attributeName) throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map.
* @param attributeName the attribute name
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is present but not a collection
*/
Collection<V> getCollection(String attributeName) throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map and make sure it is of the required type.
* @param attributeName the attribute name
* @param requiredType the required type of the attribute value
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is present but not a collection of the required type
*/
<T extends Collection<V>> T getCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map, throwing an exception if the attribute is not present or not a
* collection.
* @param attributeName the attribute name
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is not present or is present but not a collection
*/
Collection<V> getRequiredCollection(String attributeName) throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map, throwing an exception if the attribute is not present or not a
* collection of the required type.
* @param attributeName the attribute name
* @param requiredType the required collection type
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is not present or is present but not a collection of the
* required type
*/
<T extends Collection<V>> T getRequiredCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException;
/**
* Returns an array attribute value in the map and makes sure it is of the required type.
* @param attributeName the attribute name
* @param requiredType the required type of the attribute value
* @return the array attribute value
* @throws IllegalArgumentException if the attribute is present but not an array of the required type
*/
<T extends V> T[] getArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException;
/**
* Returns an array attribute value in the map, throwing an exception if the attribute is not present or not an
* array of the required type.
* @param attributeName the attribute name
* @param requiredType the required array type
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is not present or is present but not a array of the required
* type
*/
<T extends V> T[] getRequiredArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException;
/**
* Returns a number attribute value in the map that is of the specified type, returning <code>null</code> if no
* value was found.
* @param attributeName the attribute name
* @param requiredType the required number type
* @return the number attribute value
* @throws IllegalArgumentException if the attribute is present but not a number of the required type
*/
<T extends Number> T getNumber(String attributeName, Class<T> requiredType) throws IllegalArgumentException;
/**
* Returns a number attribute value in the map of the specified type, returning the default value if no value was
* found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the number attribute value
* @throws IllegalArgumentException if the attribute is present but not a number of the required type
*/
<T extends Number> T getNumber(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalArgumentException;
/**
* Returns a number attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the number attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not a number of the required type
*/
<T extends Number> T getRequiredNumber(String attributeName, Class<T> requiredType)
throws IllegalArgumentException;
/**
* Returns an integer attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the integer attribute value
* @throws IllegalArgumentException if the attribute is present but not an integer
*/
Integer getInteger(String attributeName) throws IllegalArgumentException;
/**
* Returns an integer attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the integer attribute value
* @throws IllegalArgumentException if the attribute is present but not an integer
*/
Integer getInteger(String attributeName, Integer defaultValue) throws IllegalArgumentException;
/**
* Returns an integer attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the integer attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not an integer
*/
Integer getRequiredInteger(String attributeName) throws IllegalArgumentException;
/**
* Returns a long attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is present but not a long
*/
Long getLong(String attributeName) throws IllegalArgumentException;
/**
* Returns a long attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is present but not a long
*/
Long getLong(String attributeName, Long defaultValue) throws IllegalArgumentException;
/**
* Returns a long attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not a long
*/
Long getRequiredLong(String attributeName) throws IllegalArgumentException;
/**
* Returns a boolean attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is present but not a boolean
*/
Boolean getBoolean(String attributeName) throws IllegalArgumentException;
/**
* Returns a boolean attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the boolean attribute value
* @throws IllegalArgumentException if the attribute is present but not a boolean
*/
Boolean getBoolean(String attributeName, Boolean defaultValue) throws IllegalArgumentException;
/**
* Returns a boolean attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the boolean attribute value
* @throws IllegalArgumentException if the attribute is not present or present but is not a boolean
*/
Boolean getRequiredBoolean(String attributeName) throws IllegalArgumentException;
/**
* Returns a new attribute map containing the union of this map with the provided map.
* @param attributes the map to combine with this map
* @return a new, combined map
*/
AttributeMap<V> union(AttributeMap<? extends V> attributes);
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.util.Collection;
import org.springframework.binding.collection.MapAdaptable;
/**
* An immutable interface for accessing attributes in a backing map with string keys.
* <p>
* Implementations can optionally support {@link AttributeMapBindingListener listeners} that will be notified when
* they're bound in or unbound from the map.
*
* @author Keith Donald
*/
public interface AttributeMap<V> extends MapAdaptable<String, V> {
/**
* Get an attribute value out of this map, returning <code>null</code> if not found.
* @param attributeName the attribute name
* @return the attribute value
*/
V get(String attributeName);
/**
* Returns the size of this map.
* @return the number of entries in the map
*/
int size();
/**
* Is this attribute map empty with a size of 0?
* @return true if empty, false if not
*/
boolean isEmpty();
/**
* Does the attribute with the provided name exist in this map?
* @param attributeName the attribute name
* @return true if so, false otherwise
*/
boolean contains(String attributeName);
/**
* Does the attribute with the provided name exist in this map and is its value of the specified required type?
* @param attributeName the attribute name
* @param requiredType the required class of the attribute value
* @return true if so, false otherwise
* @throws IllegalArgumentException when the value is not of the required type
*/
boolean contains(String attributeName, Class<? extends V> requiredType) throws IllegalArgumentException;
/**
* Get an attribute value, returning the default value if no value is found.
* @param attributeName the name of the attribute
* @param defaultValue the default value
* @return the attribute value, falling back to the default if no such attribute exists
*/
V get(String attributeName, V defaultValue);
/**
* Get an attribute value, asserting the value is of the required type.
* @param attributeName the name of the attribute
* @param requiredType the required type of the attribute value
* @return the attribute value, or null if not found
* @throws IllegalArgumentException when the value is not of the required type
*/
<T extends V> T get(String attributeName, Class<T> requiredType) throws IllegalArgumentException;
/**
* Get an attribute value, asserting the value is of the required type and returning the default value if not found.
* @param attributeName the name of the attribute
* @param requiredType the value required type
* @param defaultValue the default value
* @return the attribute value, or the default if not found
* @throws IllegalArgumentException when the value (if found) is not of the required type
*/
<T extends V> T get(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalStateException;
/**
* Get the value of a required attribute, throwing an exception of no attribute is found.
* @param attributeName the name of the attribute
* @return the attribute value
* @throws IllegalArgumentException when the attribute is not found
*/
V getRequired(String attributeName) throws IllegalArgumentException;
/**
* Get the value of a required attribute and make sure it is of the required type.
* @param attributeName name of the attribute to get
* @param requiredType the required type of the attribute value
* @return the attribute value
* @throws IllegalArgumentException when the attribute is not found or not of the required type
*/
<T extends V> T getRequired(String attributeName, Class<T> requiredType) throws IllegalArgumentException;
/**
* Returns a string attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the string attribute value
* @throws IllegalArgumentException if the attribute is present but not a string
*/
String getString(String attributeName) throws IllegalArgumentException;
/**
* Returns a string attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the string attribute value
* @throws IllegalArgumentException if the attribute is present but not a string
*/
String getString(String attributeName, String defaultValue) throws IllegalArgumentException;
/**
* Returns a string attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the string attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not a string
*/
String getRequiredString(String attributeName) throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map.
* @param attributeName the attribute name
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is present but not a collection
*/
Collection<V> getCollection(String attributeName) throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map and make sure it is of the required type.
* @param attributeName the attribute name
* @param requiredType the required type of the attribute value
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is present but not a collection of the required type
*/
<T extends Collection<V>> T getCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map, throwing an exception if the attribute is not present or not a
* collection.
* @param attributeName the attribute name
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is not present or is present but not a collection
*/
Collection<V> getRequiredCollection(String attributeName) throws IllegalArgumentException;
/**
* Returns a collection attribute value in the map, throwing an exception if the attribute is not present or not a
* collection of the required type.
* @param attributeName the attribute name
* @param requiredType the required collection type
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is not present or is present but not a collection of the
* required type
*/
<T extends Collection<V>> T getRequiredCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException;
/**
* Returns an array attribute value in the map and makes sure it is of the required type.
* @param attributeName the attribute name
* @param requiredType the required type of the attribute value
* @return the array attribute value
* @throws IllegalArgumentException if the attribute is present but not an array of the required type
*/
<T extends V> T[] getArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException;
/**
* Returns an array attribute value in the map, throwing an exception if the attribute is not present or not an
* array of the required type.
* @param attributeName the attribute name
* @param requiredType the required array type
* @return the collection attribute value
* @throws IllegalArgumentException if the attribute is not present or is present but not a array of the required
* type
*/
<T extends V> T[] getRequiredArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException;
/**
* Returns a number attribute value in the map that is of the specified type, returning <code>null</code> if no
* value was found.
* @param attributeName the attribute name
* @param requiredType the required number type
* @return the number attribute value
* @throws IllegalArgumentException if the attribute is present but not a number of the required type
*/
<T extends Number> T getNumber(String attributeName, Class<T> requiredType) throws IllegalArgumentException;
/**
* Returns a number attribute value in the map of the specified type, returning the default value if no value was
* found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the number attribute value
* @throws IllegalArgumentException if the attribute is present but not a number of the required type
*/
<T extends Number> T getNumber(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalArgumentException;
/**
* Returns a number attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the number attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not a number of the required type
*/
<T extends Number> T getRequiredNumber(String attributeName, Class<T> requiredType)
throws IllegalArgumentException;
/**
* Returns an integer attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the integer attribute value
* @throws IllegalArgumentException if the attribute is present but not an integer
*/
Integer getInteger(String attributeName) throws IllegalArgumentException;
/**
* Returns an integer attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the integer attribute value
* @throws IllegalArgumentException if the attribute is present but not an integer
*/
Integer getInteger(String attributeName, Integer defaultValue) throws IllegalArgumentException;
/**
* Returns an integer attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the integer attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not an integer
*/
Integer getRequiredInteger(String attributeName) throws IllegalArgumentException;
/**
* Returns a long attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is present but not a long
*/
Long getLong(String attributeName) throws IllegalArgumentException;
/**
* Returns a long attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is present but not a long
*/
Long getLong(String attributeName, Long defaultValue) throws IllegalArgumentException;
/**
* Returns a long attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is not present or present but not a long
*/
Long getRequiredLong(String attributeName) throws IllegalArgumentException;
/**
* Returns a boolean attribute value in the map, returning <code>null</code> if no value was found.
* @param attributeName the attribute name
* @return the long attribute value
* @throws IllegalArgumentException if the attribute is present but not a boolean
*/
Boolean getBoolean(String attributeName) throws IllegalArgumentException;
/**
* Returns a boolean attribute value in the map, returning the default value if no value was found.
* @param attributeName the attribute name
* @param defaultValue the default
* @return the boolean attribute value
* @throws IllegalArgumentException if the attribute is present but not a boolean
*/
Boolean getBoolean(String attributeName, Boolean defaultValue) throws IllegalArgumentException;
/**
* Returns a boolean attribute value in the map, throwing an exception if the attribute is not present and of the
* correct type.
* @param attributeName the attribute name
* @return the boolean attribute value
* @throws IllegalArgumentException if the attribute is not present or present but is not a boolean
*/
Boolean getRequiredBoolean(String attributeName) throws IllegalArgumentException;
/**
* Returns a new attribute map containing the union of this map with the provided map.
* @param attributes the map to combine with this map
* @return a new, combined map
*/
AttributeMap<V> union(AttributeMap<? extends V> attributes);
}

View File

@@ -1,59 +1,59 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.util.EventObject;
/**
* Holder for information about the binding or unbinding event in an {@link AttributeMap}.
*
* @see AttributeMapBindingListener
*
* @author Ben Hale
*/
public class AttributeMapBindingEvent extends EventObject {
private String attributeName;
private Object attributeValue;
/**
* Creates an event for map binding that contains information about the event.
* @param source the source map that this attribute was bound in
* @param attributeName the name that this attribute was bound with
* @param attributeValue the attribute
*/
public AttributeMapBindingEvent(AttributeMap<?> source, String attributeName, Object attributeValue) {
super(source);
this.source = source;
this.attributeName = attributeName;
this.attributeValue = attributeValue;
}
/**
* Returns the name the attribute was bound with.
*/
public String getAttributeName() {
return attributeName;
}
/**
* Returns the value of the attribute.
*/
public Object getAttributeValue() {
return attributeValue;
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.util.EventObject;
/**
* Holder for information about the binding or unbinding event in an {@link AttributeMap}.
*
* @see AttributeMapBindingListener
*
* @author Ben Hale
*/
public class AttributeMapBindingEvent extends EventObject {
private String attributeName;
private Object attributeValue;
/**
* Creates an event for map binding that contains information about the event.
* @param source the source map that this attribute was bound in
* @param attributeName the name that this attribute was bound with
* @param attributeValue the attribute
*/
public AttributeMapBindingEvent(AttributeMap<?> source, String attributeName, Object attributeValue) {
super(source);
this.source = source;
this.attributeName = attributeName;
this.attributeValue = attributeValue;
}
/**
* Returns the name the attribute was bound with.
*/
public String getAttributeName() {
return attributeName;
}
/**
* Returns the value of the attribute.
*/
public Object getAttributeValue() {
return attributeValue;
}
}

View File

@@ -1,40 +1,40 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
/**
* Causes an object to be notified when it is bound or unbound from an {@link AttributeMap}.
* <p>
* Note that this is an optional feature and not all {@link AttributeMap} implementations support it.
*
* @see AttributeMap
*
* @author Ben Hale
*/
public interface AttributeMapBindingListener {
/**
* Called when the implementing instance is bound into an <code>AttributeMap</code>.
* @param event information about the binding event
*/
void valueBound(AttributeMapBindingEvent event);
/**
* Called when the implementing instance is unbound from an <code>AttributeMap</code>.
* @param event information about the unbinding event
*/
void valueUnbound(AttributeMapBindingEvent event);
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
/**
* Causes an object to be notified when it is bound or unbound from an {@link AttributeMap}.
* <p>
* Note that this is an optional feature and not all {@link AttributeMap} implementations support it.
*
* @see AttributeMap
*
* @author Ben Hale
*/
public interface AttributeMapBindingListener {
/**
* Called when the implementing instance is bound into an <code>AttributeMap</code>.
* @param event information about the binding event
*/
void valueBound(AttributeMapBindingEvent event);
/**
* Called when the implementing instance is unbound from an <code>AttributeMap</code>.
* @param event information about the unbinding event
*/
void valueUnbound(AttributeMapBindingEvent event);
}

View File

@@ -1,140 +1,140 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.io.Serializable;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
/**
* A utility class for working with attribute and parameter collections used by Spring Web FLow.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class CollectionUtils {
/**
* The shared, singleton empty iterator instance.
*/
@SuppressWarnings("rawtypes")
public static final Iterator EMPTY_ITERATOR = new EmptyIterator();
/**
* The shared, singleton empty attribute map instance.
*/
public static final AttributeMap<Object> EMPTY_ATTRIBUTE_MAP = new LocalAttributeMap<>(Collections.emptyMap());
/**
* Private constructor to avoid instantiation.
*/
private CollectionUtils() {
}
@SuppressWarnings("unchecked")
public static <E> Iterator<E> emptyIterator() {
return EMPTY_ITERATOR;
}
/**
* Factory method that adapts an enumeration to an iterator.
* @param enumeration the enumeration
* @return the iterator
*/
public static <E> Iterator<E> toIterator(Enumeration<E> enumeration) {
return new EnumerationIterator<>(enumeration);
}
/**
* Factory method that returns a unmodifiable attribute map with a single entry.
* @param attributeName the attribute name
* @param attributeValue the attribute value
* @return the unmodifiable map with a single element
*/
public static <V> AttributeMap<V> singleEntryMap(String attributeName, V attributeValue) {
return new LocalAttributeMap<>(attributeName, attributeValue);
}
/**
* Add all given objects to given target list. No duplicates will be added. The contains() method of the given
* target list will be used to determine whether or not an object is already in the list.
* @param target the collection to which to objects will be added
* @param objects the objects to add
* @return whether or not the target collection changed
*/
@SuppressWarnings("unchecked")
public static <T> boolean addAllNoDuplicates(List<T> target, T... objects) {
if (objects == null || objects.length == 0) {
return false;
} else {
boolean changed = false;
for (T object : objects) {
if (!target.contains(object)) {
target.add(object);
changed = true;
}
}
return changed;
}
}
/**
* Iterator iterating over no elements (hasNext() always returns false).
*/
private static class EmptyIterator<E> implements Iterator<E>, Serializable {
private EmptyIterator() {
}
public boolean hasNext() {
return false;
}
public E next() {
throw new UnsupportedOperationException("There are no elements");
}
public void remove() {
throw new UnsupportedOperationException("There are no elements");
}
}
/**
* Iterator wrapping an Enumeration.
*/
private static class EnumerationIterator<E> implements Iterator<E> {
private Enumeration<E> enumeration;
public EnumerationIterator(Enumeration<E> enumeration) {
this.enumeration = enumeration;
}
public boolean hasNext() {
return enumeration.hasMoreElements();
}
public E next() {
return enumeration.nextElement();
}
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException("Not supported");
}
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.io.Serializable;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
/**
* A utility class for working with attribute and parameter collections used by Spring Web FLow.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class CollectionUtils {
/**
* The shared, singleton empty iterator instance.
*/
@SuppressWarnings("rawtypes")
public static final Iterator EMPTY_ITERATOR = new EmptyIterator();
/**
* The shared, singleton empty attribute map instance.
*/
public static final AttributeMap<Object> EMPTY_ATTRIBUTE_MAP = new LocalAttributeMap<>(Collections.emptyMap());
/**
* Private constructor to avoid instantiation.
*/
private CollectionUtils() {
}
@SuppressWarnings("unchecked")
public static <E> Iterator<E> emptyIterator() {
return EMPTY_ITERATOR;
}
/**
* Factory method that adapts an enumeration to an iterator.
* @param enumeration the enumeration
* @return the iterator
*/
public static <E> Iterator<E> toIterator(Enumeration<E> enumeration) {
return new EnumerationIterator<>(enumeration);
}
/**
* Factory method that returns a unmodifiable attribute map with a single entry.
* @param attributeName the attribute name
* @param attributeValue the attribute value
* @return the unmodifiable map with a single element
*/
public static <V> AttributeMap<V> singleEntryMap(String attributeName, V attributeValue) {
return new LocalAttributeMap<>(attributeName, attributeValue);
}
/**
* Add all given objects to given target list. No duplicates will be added. The contains() method of the given
* target list will be used to determine whether or not an object is already in the list.
* @param target the collection to which to objects will be added
* @param objects the objects to add
* @return whether or not the target collection changed
*/
@SuppressWarnings("unchecked")
public static <T> boolean addAllNoDuplicates(List<T> target, T... objects) {
if (objects == null || objects.length == 0) {
return false;
} else {
boolean changed = false;
for (T object : objects) {
if (!target.contains(object)) {
target.add(object);
changed = true;
}
}
return changed;
}
}
/**
* Iterator iterating over no elements (hasNext() always returns false).
*/
private static class EmptyIterator<E> implements Iterator<E>, Serializable {
private EmptyIterator() {
}
public boolean hasNext() {
return false;
}
public E next() {
throw new UnsupportedOperationException("There are no elements");
}
public void remove() {
throw new UnsupportedOperationException("There are no elements");
}
}
/**
* Iterator wrapping an Enumeration.
*/
private static class EnumerationIterator<E> implements Iterator<E> {
private Enumeration<E> enumeration;
public EnumerationIterator(Enumeration<E> enumeration) {
this.enumeration = enumeration;
}
public boolean hasNext() {
return enumeration.hasMoreElements();
}
public E next() {
return enumeration.nextElement();
}
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException("Not supported");
}
}
}

View File

@@ -1,344 +1,344 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.springframework.binding.collection.MapAccessor;
import org.springframework.core.style.StylerUtils;
import org.springframework.util.Assert;
/**
* A generic, mutable attribute map with string keys.
*
* @author Keith Donald
*/
public class LocalAttributeMap<V> implements MutableAttributeMap<V>, Serializable {
/**
* The backing map storing the attributes.
*/
private Map<String, V> attributes;
/**
* A helper for accessing attributes. Marked transient and restored on deserialization.
*/
private transient MapAccessor<String, V> attributeAccessor;
/**
* Creates a new attribute map, initially empty.
*/
public LocalAttributeMap() {
initAttributes(createTargetMap());
}
/**
* Creates a new attribute map, initially empty.
* @param size the initial size
* @param loadFactor the load factor
*/
public LocalAttributeMap(int size, int loadFactor) {
initAttributes(createTargetMap(size, loadFactor));
}
/**
* Creates a new attribute map with a single entry.
*/
public LocalAttributeMap(String attributeName, V attributeValue) {
initAttributes(createTargetMap(1, 1));
put(attributeName, attributeValue);
}
/**
* Creates a new attribute map wrapping the specified map.
*/
public LocalAttributeMap(Map<String, V> map) {
Assert.notNull(map, "The target map is required");
initAttributes(map);
}
// implementing attribute map
public Map<String, V> asMap() {
return attributeAccessor.asMap();
}
public int size() {
return attributes.size();
}
public V get(String attributeName) {
return attributes.get(attributeName);
}
public boolean isEmpty() {
return attributes.isEmpty();
}
public boolean contains(String attributeName) {
return attributes.containsKey(attributeName);
}
public boolean contains(String attributeName, Class<? extends V> requiredType) throws IllegalArgumentException {
return attributeAccessor.containsKey(attributeName, requiredType);
}
public V get(String attributeName, V defaultValue) {
return attributeAccessor.get(attributeName, defaultValue);
}
public <T extends V> T get(String attributeName, Class<T> requiredType) throws IllegalArgumentException {
return attributeAccessor.get(attributeName, requiredType);
}
public <T extends V> T get(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalStateException {
return attributeAccessor.get(attributeName, requiredType, defaultValue);
}
public V getRequired(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequired(attributeName);
}
public <T extends V> T getRequired(String attributeName, Class<T> requiredType) throws IllegalArgumentException {
return attributeAccessor.getRequired(attributeName, requiredType);
}
public String getString(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getString(attributeName);
}
public String getString(String attributeName, String defaultValue) throws IllegalArgumentException {
return attributeAccessor.getString(attributeName, defaultValue);
}
public String getRequiredString(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredString(attributeName);
}
public Collection<V> getCollection(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getCollection(attributeName);
}
public <T extends Collection<V>> T getCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getCollection(attributeName, requiredType);
}
public Collection<V> getRequiredCollection(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredCollection(attributeName);
}
public <T extends Collection<V>> T getRequiredCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getRequiredCollection(attributeName, requiredType);
}
public <T extends V> T[] getArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getArray(attributeName, requiredType);
}
public <T extends V> T[] getRequiredArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getRequiredArray(attributeName, requiredType);
}
public <T extends Number> T getNumber(String attributeName, Class<T> requiredType) throws IllegalArgumentException {
return attributeAccessor.getNumber(attributeName, requiredType);
}
public <T extends Number> T getNumber(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalArgumentException {
return attributeAccessor.getNumber(attributeName, requiredType, defaultValue);
}
public <T extends Number> T getRequiredNumber(String attributeName, Class<T> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getRequiredNumber(attributeName, requiredType);
}
public Integer getInteger(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getInteger(attributeName);
}
public Integer getInteger(String attributeName, Integer defaultValue) throws IllegalArgumentException {
return attributeAccessor.getInteger(attributeName, defaultValue);
}
public Integer getRequiredInteger(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredInteger(attributeName);
}
public Long getLong(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getLong(attributeName);
}
public Long getLong(String attributeName, Long defaultValue) throws IllegalArgumentException {
return attributeAccessor.getLong(attributeName, defaultValue);
}
public Long getRequiredLong(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredLong(attributeName);
}
public Boolean getBoolean(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getBoolean(attributeName);
}
public Boolean getBoolean(String attributeName, Boolean defaultValue) throws IllegalArgumentException {
return attributeAccessor.getBoolean(attributeName, defaultValue);
}
public Boolean getRequiredBoolean(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredBoolean(attributeName);
}
public AttributeMap<V> union(AttributeMap<? extends V> attributes) {
if (attributes == null) {
return new LocalAttributeMap<>(getMapInternal());
} else {
Map<String, V> map = createTargetMap();
map.putAll(getMapInternal());
map.putAll(attributes.asMap());
return new LocalAttributeMap<>(map);
}
}
// implementing MutableAttributeMap
public V put(String attributeName, V attributeValue) {
return getMapInternal().put(attributeName, attributeValue);
}
public MutableAttributeMap<V> putAll(AttributeMap<? extends V> attributes) {
if (attributes == null) {
return this;
}
getMapInternal().putAll(attributes.asMap());
return this;
}
public MutableAttributeMap<V> removeAll(MutableAttributeMap<? extends V> attributes) {
if (attributes == null) {
return this;
}
Map<String, V> internal = getMapInternal();
for (String attribute : attributes.asMap().keySet()) {
internal.remove(attribute);
}
return this;
}
public Object remove(String attributeName) {
return getMapInternal().remove(attributeName);
}
public Object extract(String attributeName) {
Map<String, V> map = getMapInternal();
if (map.containsKey(attributeName)) {
Object value = map.get(attributeName);
map.remove(attributeName);
return value;
} else {
return null;
}
}
public MutableAttributeMap<V> clear() throws UnsupportedOperationException {
getMapInternal().clear();
return this;
}
public MutableAttributeMap<V> replaceWith(AttributeMap<? extends V> attributes)
throws UnsupportedOperationException {
clear();
putAll(attributes);
return this;
}
// helpers for subclasses
/**
* Initializes this attribute map.
* @param attributes the attributes
*/
protected void initAttributes(Map<String, V> attributes) {
this.attributes = attributes;
attributeAccessor = new MapAccessor<>(this.attributes);
}
/**
* Returns the wrapped, modifiable map implementation.
*/
protected Map<String, V> getMapInternal() {
return attributes;
}
// helpers
/**
* Factory method that returns the target map storing the data in this attribute map.
* @return the target map
*/
protected Map<String, V> createTargetMap() {
return new HashMap<>();
}
/**
* Factory method that returns the target map storing the data in this attribute map.
* @param size the initial size of the map
* @param loadFactor the load factor
* @return the target map
*/
protected Map<String, V> createTargetMap(int size, int loadFactor) {
return new HashMap<>(size, loadFactor);
}
@SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (!(o instanceof LocalAttributeMap)) {
return false;
}
LocalAttributeMap<V> other = (LocalAttributeMap<V>) o;
return getMapInternal().equals(other.getMapInternal());
}
public int hashCode() {
return getMapInternal().hashCode();
}
// custom serialization
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
attributeAccessor = new MapAccessor<>(attributes);
}
public String toString() {
return StylerUtils.style(attributes);
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.springframework.binding.collection.MapAccessor;
import org.springframework.core.style.StylerUtils;
import org.springframework.util.Assert;
/**
* A generic, mutable attribute map with string keys.
*
* @author Keith Donald
*/
public class LocalAttributeMap<V> implements MutableAttributeMap<V>, Serializable {
/**
* The backing map storing the attributes.
*/
private Map<String, V> attributes;
/**
* A helper for accessing attributes. Marked transient and restored on deserialization.
*/
private transient MapAccessor<String, V> attributeAccessor;
/**
* Creates a new attribute map, initially empty.
*/
public LocalAttributeMap() {
initAttributes(createTargetMap());
}
/**
* Creates a new attribute map, initially empty.
* @param size the initial size
* @param loadFactor the load factor
*/
public LocalAttributeMap(int size, int loadFactor) {
initAttributes(createTargetMap(size, loadFactor));
}
/**
* Creates a new attribute map with a single entry.
*/
public LocalAttributeMap(String attributeName, V attributeValue) {
initAttributes(createTargetMap(1, 1));
put(attributeName, attributeValue);
}
/**
* Creates a new attribute map wrapping the specified map.
*/
public LocalAttributeMap(Map<String, V> map) {
Assert.notNull(map, "The target map is required");
initAttributes(map);
}
// implementing attribute map
public Map<String, V> asMap() {
return attributeAccessor.asMap();
}
public int size() {
return attributes.size();
}
public V get(String attributeName) {
return attributes.get(attributeName);
}
public boolean isEmpty() {
return attributes.isEmpty();
}
public boolean contains(String attributeName) {
return attributes.containsKey(attributeName);
}
public boolean contains(String attributeName, Class<? extends V> requiredType) throws IllegalArgumentException {
return attributeAccessor.containsKey(attributeName, requiredType);
}
public V get(String attributeName, V defaultValue) {
return attributeAccessor.get(attributeName, defaultValue);
}
public <T extends V> T get(String attributeName, Class<T> requiredType) throws IllegalArgumentException {
return attributeAccessor.get(attributeName, requiredType);
}
public <T extends V> T get(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalStateException {
return attributeAccessor.get(attributeName, requiredType, defaultValue);
}
public V getRequired(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequired(attributeName);
}
public <T extends V> T getRequired(String attributeName, Class<T> requiredType) throws IllegalArgumentException {
return attributeAccessor.getRequired(attributeName, requiredType);
}
public String getString(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getString(attributeName);
}
public String getString(String attributeName, String defaultValue) throws IllegalArgumentException {
return attributeAccessor.getString(attributeName, defaultValue);
}
public String getRequiredString(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredString(attributeName);
}
public Collection<V> getCollection(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getCollection(attributeName);
}
public <T extends Collection<V>> T getCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getCollection(attributeName, requiredType);
}
public Collection<V> getRequiredCollection(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredCollection(attributeName);
}
public <T extends Collection<V>> T getRequiredCollection(String attributeName, Class<T> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getRequiredCollection(attributeName, requiredType);
}
public <T extends V> T[] getArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getArray(attributeName, requiredType);
}
public <T extends V> T[] getRequiredArray(String attributeName, Class<? extends T[]> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getRequiredArray(attributeName, requiredType);
}
public <T extends Number> T getNumber(String attributeName, Class<T> requiredType) throws IllegalArgumentException {
return attributeAccessor.getNumber(attributeName, requiredType);
}
public <T extends Number> T getNumber(String attributeName, Class<T> requiredType, T defaultValue)
throws IllegalArgumentException {
return attributeAccessor.getNumber(attributeName, requiredType, defaultValue);
}
public <T extends Number> T getRequiredNumber(String attributeName, Class<T> requiredType)
throws IllegalArgumentException {
return attributeAccessor.getRequiredNumber(attributeName, requiredType);
}
public Integer getInteger(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getInteger(attributeName);
}
public Integer getInteger(String attributeName, Integer defaultValue) throws IllegalArgumentException {
return attributeAccessor.getInteger(attributeName, defaultValue);
}
public Integer getRequiredInteger(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredInteger(attributeName);
}
public Long getLong(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getLong(attributeName);
}
public Long getLong(String attributeName, Long defaultValue) throws IllegalArgumentException {
return attributeAccessor.getLong(attributeName, defaultValue);
}
public Long getRequiredLong(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredLong(attributeName);
}
public Boolean getBoolean(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getBoolean(attributeName);
}
public Boolean getBoolean(String attributeName, Boolean defaultValue) throws IllegalArgumentException {
return attributeAccessor.getBoolean(attributeName, defaultValue);
}
public Boolean getRequiredBoolean(String attributeName) throws IllegalArgumentException {
return attributeAccessor.getRequiredBoolean(attributeName);
}
public AttributeMap<V> union(AttributeMap<? extends V> attributes) {
if (attributes == null) {
return new LocalAttributeMap<>(getMapInternal());
} else {
Map<String, V> map = createTargetMap();
map.putAll(getMapInternal());
map.putAll(attributes.asMap());
return new LocalAttributeMap<>(map);
}
}
// implementing MutableAttributeMap
public V put(String attributeName, V attributeValue) {
return getMapInternal().put(attributeName, attributeValue);
}
public MutableAttributeMap<V> putAll(AttributeMap<? extends V> attributes) {
if (attributes == null) {
return this;
}
getMapInternal().putAll(attributes.asMap());
return this;
}
public MutableAttributeMap<V> removeAll(MutableAttributeMap<? extends V> attributes) {
if (attributes == null) {
return this;
}
Map<String, V> internal = getMapInternal();
for (String attribute : attributes.asMap().keySet()) {
internal.remove(attribute);
}
return this;
}
public Object remove(String attributeName) {
return getMapInternal().remove(attributeName);
}
public Object extract(String attributeName) {
Map<String, V> map = getMapInternal();
if (map.containsKey(attributeName)) {
Object value = map.get(attributeName);
map.remove(attributeName);
return value;
} else {
return null;
}
}
public MutableAttributeMap<V> clear() throws UnsupportedOperationException {
getMapInternal().clear();
return this;
}
public MutableAttributeMap<V> replaceWith(AttributeMap<? extends V> attributes)
throws UnsupportedOperationException {
clear();
putAll(attributes);
return this;
}
// helpers for subclasses
/**
* Initializes this attribute map.
* @param attributes the attributes
*/
protected void initAttributes(Map<String, V> attributes) {
this.attributes = attributes;
attributeAccessor = new MapAccessor<>(this.attributes);
}
/**
* Returns the wrapped, modifiable map implementation.
*/
protected Map<String, V> getMapInternal() {
return attributes;
}
// helpers
/**
* Factory method that returns the target map storing the data in this attribute map.
* @return the target map
*/
protected Map<String, V> createTargetMap() {
return new HashMap<>();
}
/**
* Factory method that returns the target map storing the data in this attribute map.
* @param size the initial size of the map
* @param loadFactor the load factor
* @return the target map
*/
protected Map<String, V> createTargetMap(int size, int loadFactor) {
return new HashMap<>(size, loadFactor);
}
@SuppressWarnings("unchecked")
public boolean equals(Object o) {
if (!(o instanceof LocalAttributeMap)) {
return false;
}
LocalAttributeMap<V> other = (LocalAttributeMap<V>) o;
return getMapInternal().equals(other.getMapInternal());
}
public int hashCode() {
return getMapInternal().hashCode();
}
// custom serialization
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
attributeAccessor = new MapAccessor<>(attributes);
}
public String toString() {
return StylerUtils.style(attributes);
}
}

View File

@@ -1,323 +1,323 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.binding.collection.MapAccessor;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.core.style.StylerUtils;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
/**
* An immutable parameter map storing String-keyed, String-valued parameters in a backing {@link Map} implementation.
* This base provides convenient operations for accessing parameters in a typed-manner.
*
* @author Keith Donald
*/
public class LocalParameterMap implements ParameterMap, Serializable {
private static final DefaultConversionService DEFAULT_CONVERSION_SERVICE = new DefaultConversionService();
/**
* The backing map storing the parameters.
*/
private Map<String, Object> parameters;
/**
* A helper for accessing parameters. Marked transient and restored on deserialization.
*/
private transient MapAccessor<String, Object> parameterAccessor;
/**
* A helper for converting string parameter values. Marked transient and restored on deserialization.
*/
private transient ConversionService conversionService;
/**
* Creates a new parameter map from the provided map.
* <p>
* It is expected that the contents of the backing map adhere to the parameter map contract; that is, map entries
* have string keys, string values, and remain unmodifiable.
* @param parameters the contents of this parameter map
*/
public LocalParameterMap(Map<String, Object> parameters) {
this(parameters, DEFAULT_CONVERSION_SERVICE);
}
/**
* Creates a new parameter map from the provided map.
* <p>
* It is expected that the contents of the backing map adhere to the parameter map contract; that is, map entries
* have string keys, string values, and remain unmodifiable.
* @param parameters the contents of this parameter map
* @param conversionService a helper for performing type conversion of map entry values
*/
public LocalParameterMap(Map<String, Object> parameters, ConversionService conversionService) {
initParameters(parameters);
this.conversionService = conversionService;
}
public boolean equals(Object o) {
if (!(o instanceof LocalParameterMap)) {
return false;
}
LocalParameterMap other = (LocalParameterMap) o;
return parameters.equals(other.parameters);
}
public int hashCode() {
return parameters.hashCode();
}
public Map<String, Object> asMap() {
return Collections.unmodifiableMap(parameterAccessor.asMap());
}
public boolean isEmpty() {
return parameters.isEmpty();
}
public int size() {
return parameters.size();
}
public boolean contains(String parameterName) {
return parameters.containsKey(parameterName);
}
public String get(String parameterName) {
return get(parameterName, (String) null);
}
public String get(String parameterName, String defaultValue) {
if (!parameters.containsKey(parameterName)) {
return defaultValue;
}
Object value = parameters.get(parameterName);
if (value.getClass().isArray()) {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String[].class);
String[] array = (String[]) value;
if (array.length == 0) {
return null;
} else {
Object first = ((String[]) value)[0];
parameterAccessor.assertKeyValueInstanceOf(parameterName, first, String.class);
return (String) first;
}
} else {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String.class);
return (String) value;
}
}
public String[] getArray(String parameterName) {
if (!parameters.containsKey(parameterName)) {
return null;
}
Object value = parameters.get(parameterName);
if (value.getClass().isArray()) {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String[].class);
return (String[]) value;
} else {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String.class);
return new String[] { (String) value };
}
}
public <T> T[] getArray(String parameterName, Class<T> targetElementType) throws ConversionExecutionException {
String[] parameters = getArray(parameterName);
return parameters != null ? convert(parameters, targetElementType) : null;
}
public <T> T get(String parameterName, Class<T> targetType) throws ConversionExecutionException {
return get(parameterName, targetType, null);
}
public <T> T get(String parameterName, Class<T> targetType, T defaultValue) throws ConversionExecutionException {
if (defaultValue != null) {
assertAssignableTo(targetType, defaultValue.getClass());
}
String parameter = get(parameterName);
return parameter != null ? convert(parameter, targetType) : defaultValue;
}
public String getRequired(String parameterName) throws IllegalArgumentException {
parameterAccessor.assertContainsKey(parameterName);
return get(parameterName);
}
public String[] getRequiredArray(String parameterName) throws IllegalArgumentException {
parameterAccessor.assertContainsKey(parameterName);
return getArray(parameterName);
}
public <T> T[] getRequiredArray(String parameterName, Class<T> targetElementType) throws IllegalArgumentException,
ConversionExecutionException {
String[] parameters = getRequiredArray(parameterName);
return convert(parameters, targetElementType);
}
public <T> T getRequired(String parameterName, Class<T> targetType) throws IllegalArgumentException,
ConversionExecutionException {
return convert(getRequired(parameterName), targetType);
}
public <T extends Number> T getNumber(String parameterName, Class<T> targetType)
throws ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return get(parameterName, targetType);
}
public <T extends Number> T getNumber(String parameterName, Class<T> targetType, T defaultValue)
throws ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return get(parameterName, targetType, defaultValue);
}
public <T extends Number> T getRequiredNumber(String parameterName, Class<T> targetType)
throws IllegalArgumentException, ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return getRequired(parameterName, targetType);
}
public Integer getInteger(String parameterName) throws ConversionExecutionException {
return get(parameterName, Integer.class);
}
public Integer getInteger(String parameterName, Integer defaultValue) throws ConversionExecutionException {
return get(parameterName, Integer.class, defaultValue);
}
public Integer getRequiredInteger(String parameterName) throws IllegalArgumentException,
ConversionExecutionException {
return getRequired(parameterName, Integer.class);
}
public Long getLong(String parameterName) throws ConversionExecutionException {
return get(parameterName, Long.class);
}
public Long getLong(String parameterName, Long defaultValue) throws ConversionExecutionException {
return get(parameterName, Long.class, defaultValue);
}
public Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionExecutionException {
return getRequired(parameterName, Long.class);
}
public Boolean getBoolean(String parameterName) throws ConversionExecutionException {
return get(parameterName, Boolean.class);
}
public Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionExecutionException {
return get(parameterName, Boolean.class, defaultValue);
}
public Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException,
ConversionExecutionException {
return getRequired(parameterName, Boolean.class);
}
public MultipartFile getMultipartFile(String parameterName) {
return parameterAccessor.get(parameterName, MultipartFile.class);
}
public MultipartFile getRequiredMultipartFile(String parameterName) throws IllegalArgumentException {
return parameterAccessor.getRequired(parameterName, MultipartFile.class);
}
public AttributeMap<Object> asAttributeMap() {
return new LocalAttributeMap<>(getMapInternal());
}
/**
* Initializes this parameter map.
* @param parameters the parameters
*/
protected void initParameters(Map<String, Object> parameters) {
this.parameters = parameters;
parameterAccessor = new MapAccessor<>(this.parameters);
}
/**
* Returns the wrapped, modifiable map implementation.
*/
protected Map<String, Object> getMapInternal() {
return parameters;
}
// internal helpers
/**
* Convert given String parameter to specified target type.
*/
@SuppressWarnings("unchecked")
private <T> T convert(String parameter, Class<T> targetType) throws ConversionExecutionException {
return (T) conversionService.getConversionExecutor(String.class, targetType).execute(parameter);
}
/**
* Convert given array of String parameters to specified target type and return the resulting array.
*/
@SuppressWarnings("unchecked")
private <T> T[] convert(String[] parameters, Class<? extends T> targetElementType)
throws ConversionExecutionException {
List<T> list = new ArrayList<>(parameters.length);
ConversionExecutor converter = conversionService.getConversionExecutor(String.class, targetElementType);
for (String parameter : parameters) {
list.add((T) converter.execute(parameter));
}
return list.toArray((T[]) Array.newInstance(targetElementType, parameters.length));
}
/**
* Make sure clazz is assignable from requiredType.
*/
private void assertAssignableTo(Class<?> clazz, Class<?> requiredType) {
Assert.isTrue(clazz.isAssignableFrom(requiredType), "The provided required type must be assignable to ["
+ clazz + "]");
}
// custom serialization
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
parameterAccessor = new MapAccessor<>(parameters);
conversionService = DEFAULT_CONVERSION_SERVICE;
}
public String toString() {
return StylerUtils.style(parameters);
}
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.binding.collection.MapAccessor;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.service.DefaultConversionService;
import org.springframework.core.style.StylerUtils;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
/**
* An immutable parameter map storing String-keyed, String-valued parameters in a backing {@link Map} implementation.
* This base provides convenient operations for accessing parameters in a typed-manner.
*
* @author Keith Donald
*/
public class LocalParameterMap implements ParameterMap, Serializable {
private static final DefaultConversionService DEFAULT_CONVERSION_SERVICE = new DefaultConversionService();
/**
* The backing map storing the parameters.
*/
private Map<String, Object> parameters;
/**
* A helper for accessing parameters. Marked transient and restored on deserialization.
*/
private transient MapAccessor<String, Object> parameterAccessor;
/**
* A helper for converting string parameter values. Marked transient and restored on deserialization.
*/
private transient ConversionService conversionService;
/**
* Creates a new parameter map from the provided map.
* <p>
* It is expected that the contents of the backing map adhere to the parameter map contract; that is, map entries
* have string keys, string values, and remain unmodifiable.
* @param parameters the contents of this parameter map
*/
public LocalParameterMap(Map<String, Object> parameters) {
this(parameters, DEFAULT_CONVERSION_SERVICE);
}
/**
* Creates a new parameter map from the provided map.
* <p>
* It is expected that the contents of the backing map adhere to the parameter map contract; that is, map entries
* have string keys, string values, and remain unmodifiable.
* @param parameters the contents of this parameter map
* @param conversionService a helper for performing type conversion of map entry values
*/
public LocalParameterMap(Map<String, Object> parameters, ConversionService conversionService) {
initParameters(parameters);
this.conversionService = conversionService;
}
public boolean equals(Object o) {
if (!(o instanceof LocalParameterMap)) {
return false;
}
LocalParameterMap other = (LocalParameterMap) o;
return parameters.equals(other.parameters);
}
public int hashCode() {
return parameters.hashCode();
}
public Map<String, Object> asMap() {
return Collections.unmodifiableMap(parameterAccessor.asMap());
}
public boolean isEmpty() {
return parameters.isEmpty();
}
public int size() {
return parameters.size();
}
public boolean contains(String parameterName) {
return parameters.containsKey(parameterName);
}
public String get(String parameterName) {
return get(parameterName, (String) null);
}
public String get(String parameterName, String defaultValue) {
if (!parameters.containsKey(parameterName)) {
return defaultValue;
}
Object value = parameters.get(parameterName);
if (value.getClass().isArray()) {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String[].class);
String[] array = (String[]) value;
if (array.length == 0) {
return null;
} else {
Object first = ((String[]) value)[0];
parameterAccessor.assertKeyValueInstanceOf(parameterName, first, String.class);
return (String) first;
}
} else {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String.class);
return (String) value;
}
}
public String[] getArray(String parameterName) {
if (!parameters.containsKey(parameterName)) {
return null;
}
Object value = parameters.get(parameterName);
if (value.getClass().isArray()) {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String[].class);
return (String[]) value;
} else {
parameterAccessor.assertKeyValueInstanceOf(parameterName, value, String.class);
return new String[] { (String) value };
}
}
public <T> T[] getArray(String parameterName, Class<T> targetElementType) throws ConversionExecutionException {
String[] parameters = getArray(parameterName);
return parameters != null ? convert(parameters, targetElementType) : null;
}
public <T> T get(String parameterName, Class<T> targetType) throws ConversionExecutionException {
return get(parameterName, targetType, null);
}
public <T> T get(String parameterName, Class<T> targetType, T defaultValue) throws ConversionExecutionException {
if (defaultValue != null) {
assertAssignableTo(targetType, defaultValue.getClass());
}
String parameter = get(parameterName);
return parameter != null ? convert(parameter, targetType) : defaultValue;
}
public String getRequired(String parameterName) throws IllegalArgumentException {
parameterAccessor.assertContainsKey(parameterName);
return get(parameterName);
}
public String[] getRequiredArray(String parameterName) throws IllegalArgumentException {
parameterAccessor.assertContainsKey(parameterName);
return getArray(parameterName);
}
public <T> T[] getRequiredArray(String parameterName, Class<T> targetElementType) throws IllegalArgumentException,
ConversionExecutionException {
String[] parameters = getRequiredArray(parameterName);
return convert(parameters, targetElementType);
}
public <T> T getRequired(String parameterName, Class<T> targetType) throws IllegalArgumentException,
ConversionExecutionException {
return convert(getRequired(parameterName), targetType);
}
public <T extends Number> T getNumber(String parameterName, Class<T> targetType)
throws ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return get(parameterName, targetType);
}
public <T extends Number> T getNumber(String parameterName, Class<T> targetType, T defaultValue)
throws ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return get(parameterName, targetType, defaultValue);
}
public <T extends Number> T getRequiredNumber(String parameterName, Class<T> targetType)
throws IllegalArgumentException, ConversionExecutionException {
assertAssignableTo(Number.class, targetType);
return getRequired(parameterName, targetType);
}
public Integer getInteger(String parameterName) throws ConversionExecutionException {
return get(parameterName, Integer.class);
}
public Integer getInteger(String parameterName, Integer defaultValue) throws ConversionExecutionException {
return get(parameterName, Integer.class, defaultValue);
}
public Integer getRequiredInteger(String parameterName) throws IllegalArgumentException,
ConversionExecutionException {
return getRequired(parameterName, Integer.class);
}
public Long getLong(String parameterName) throws ConversionExecutionException {
return get(parameterName, Long.class);
}
public Long getLong(String parameterName, Long defaultValue) throws ConversionExecutionException {
return get(parameterName, Long.class, defaultValue);
}
public Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionExecutionException {
return getRequired(parameterName, Long.class);
}
public Boolean getBoolean(String parameterName) throws ConversionExecutionException {
return get(parameterName, Boolean.class);
}
public Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionExecutionException {
return get(parameterName, Boolean.class, defaultValue);
}
public Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException,
ConversionExecutionException {
return getRequired(parameterName, Boolean.class);
}
public MultipartFile getMultipartFile(String parameterName) {
return parameterAccessor.get(parameterName, MultipartFile.class);
}
public MultipartFile getRequiredMultipartFile(String parameterName) throws IllegalArgumentException {
return parameterAccessor.getRequired(parameterName, MultipartFile.class);
}
public AttributeMap<Object> asAttributeMap() {
return new LocalAttributeMap<>(getMapInternal());
}
/**
* Initializes this parameter map.
* @param parameters the parameters
*/
protected void initParameters(Map<String, Object> parameters) {
this.parameters = parameters;
parameterAccessor = new MapAccessor<>(this.parameters);
}
/**
* Returns the wrapped, modifiable map implementation.
*/
protected Map<String, Object> getMapInternal() {
return parameters;
}
// internal helpers
/**
* Convert given String parameter to specified target type.
*/
@SuppressWarnings("unchecked")
private <T> T convert(String parameter, Class<T> targetType) throws ConversionExecutionException {
return (T) conversionService.getConversionExecutor(String.class, targetType).execute(parameter);
}
/**
* Convert given array of String parameters to specified target type and return the resulting array.
*/
@SuppressWarnings("unchecked")
private <T> T[] convert(String[] parameters, Class<? extends T> targetElementType)
throws ConversionExecutionException {
List<T> list = new ArrayList<>(parameters.length);
ConversionExecutor converter = conversionService.getConversionExecutor(String.class, targetElementType);
for (String parameter : parameters) {
list.add((T) converter.execute(parameter));
}
return list.toArray((T[]) Array.newInstance(targetElementType, parameters.length));
}
/**
* Make sure clazz is assignable from requiredType.
*/
private void assertAssignableTo(Class<?> clazz, Class<?> requiredType) {
Assert.isTrue(clazz.isAssignableFrom(requiredType), "The provided required type must be assignable to ["
+ clazz + "]");
}
// custom serialization
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
parameterAccessor = new MapAccessor<>(parameters);
conversionService = DEFAULT_CONVERSION_SERVICE;
}
public String toString() {
return StylerUtils.style(parameters);
}
}

View File

@@ -1,48 +1,48 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import org.springframework.binding.collection.SharedMap;
/**
* An attribute map that exposes a mutex that application code can synchronize on. This class wraps another shared map
* in an attribute map.
* <p>
* The mutex can be used to serialize concurrent access to the shared map's contents by multiple threads.
*
* @author Keith Donald
*/
public class LocalSharedAttributeMap<V> extends LocalAttributeMap<V> implements SharedAttributeMap<V> {
/**
* Creates a new shared attribute map.
* @param sharedMap the shared map
*/
public LocalSharedAttributeMap(SharedMap<String, V> sharedMap) {
super(sharedMap);
}
public Object getMutex() {
return getSharedMap().getMutex();
}
/**
* Returns the wrapped shared map.
*/
protected SharedMap<String, V> getSharedMap() {
return (SharedMap<String, V>) getMapInternal();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import org.springframework.binding.collection.SharedMap;
/**
* An attribute map that exposes a mutex that application code can synchronize on. This class wraps another shared map
* in an attribute map.
* <p>
* The mutex can be used to serialize concurrent access to the shared map's contents by multiple threads.
*
* @author Keith Donald
*/
public class LocalSharedAttributeMap<V> extends LocalAttributeMap<V> implements SharedAttributeMap<V> {
/**
* Creates a new shared attribute map.
* @param sharedMap the shared map
*/
public LocalSharedAttributeMap(SharedMap<String, V> sharedMap) {
super(sharedMap);
}
public Object getMutex() {
return getSharedMap().getMutex();
}
/**
* Returns the wrapped shared map.
*/
protected SharedMap<String, V> getSharedMap() {
return (SharedMap<String, V>) getMapInternal();
}
}

View File

@@ -1,84 +1,84 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
/**
* An interface for accessing and modifying attributes in a backing map with string keys.
* <p>
* Implementations can optionally support {@link AttributeMapBindingListener listeners} that will be notified when
* they're bound in or unbound from the map.
*
* @author Keith Donald
*/
public interface MutableAttributeMap<V> extends AttributeMap<V> {
/**
* Put the attribute into this map.
* <p>
* If the attribute value is an {@link AttributeMapBindingListener} this map will publish
* {@link AttributeMapBindingEvent binding events} such as on "bind" and "unbind" if supported.
* <p>
* <b>Note</b>: not all <code>MutableAttributeMap</code> implementations support this.
* @param attributeName the attribute name
* @param attributeValue the attribute value
* @return the previous value of the attribute, or <code>null</code> of there was no previous value
*/
V put(String attributeName, V attributeValue);
/**
* Put all the attributes into this map.
* @param attributes the attributes to put into this map
* @return this, to support call chaining
*/
MutableAttributeMap<V> putAll(AttributeMap<? extends V> attributes);
/**
* Remove all attributes in the map provided from this map.
* @param attributes the attributes to remove from this map
* @return this, to support call chaining
*/
MutableAttributeMap<V> removeAll(MutableAttributeMap<? extends V> attributes);
/**
* Remove an attribute from this map.
* @param attributeName the name of the attribute to remove
* @return previous value associated with specified attribute name, or <tt>null</tt> if there was no mapping for the
* name
*/
Object remove(String attributeName);
/**
* Extract an attribute from this map, getting it and removing it in a single operation.
* @param attributeName the attribute name
* @return the value of the attribute, or <code>null</code> of there was no value
*/
Object extract(String attributeName);
/**
* Remove all attributes in this map.
* @return this, to support call chaining
*/
MutableAttributeMap<V> clear();
/**
* Replace the contents of this attribute map with the contents of the provided collection.
* @param attributes the attribute collection
* @return this, to support call chaining
*/
MutableAttributeMap<V> replaceWith(AttributeMap<? extends V> attributes)
throws UnsupportedOperationException;
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
/**
* An interface for accessing and modifying attributes in a backing map with string keys.
* <p>
* Implementations can optionally support {@link AttributeMapBindingListener listeners} that will be notified when
* they're bound in or unbound from the map.
*
* @author Keith Donald
*/
public interface MutableAttributeMap<V> extends AttributeMap<V> {
/**
* Put the attribute into this map.
* <p>
* If the attribute value is an {@link AttributeMapBindingListener} this map will publish
* {@link AttributeMapBindingEvent binding events} such as on "bind" and "unbind" if supported.
* <p>
* <b>Note</b>: not all <code>MutableAttributeMap</code> implementations support this.
* @param attributeName the attribute name
* @param attributeValue the attribute value
* @return the previous value of the attribute, or <code>null</code> of there was no previous value
*/
V put(String attributeName, V attributeValue);
/**
* Put all the attributes into this map.
* @param attributes the attributes to put into this map
* @return this, to support call chaining
*/
MutableAttributeMap<V> putAll(AttributeMap<? extends V> attributes);
/**
* Remove all attributes in the map provided from this map.
* @param attributes the attributes to remove from this map
* @return this, to support call chaining
*/
MutableAttributeMap<V> removeAll(MutableAttributeMap<? extends V> attributes);
/**
* Remove an attribute from this map.
* @param attributeName the name of the attribute to remove
* @return previous value associated with specified attribute name, or <code>null</code> if there was no mapping for the
* name
*/
Object remove(String attributeName);
/**
* Extract an attribute from this map, getting it and removing it in a single operation.
* @param attributeName the attribute name
* @return the value of the attribute, or <code>null</code> of there was no value
*/
Object extract(String attributeName);
/**
* Remove all attributes in this map.
* @return this, to support call chaining
*/
MutableAttributeMap<V> clear();
/**
* Replace the contents of this attribute map with the contents of the provided collection.
* @param attributes the attribute collection
* @return this, to support call chaining
*/
MutableAttributeMap<V> replaceWith(AttributeMap<? extends V> attributes)
throws UnsupportedOperationException;
}

View File

@@ -1,279 +1,279 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import org.springframework.binding.collection.MapAdaptable;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.web.multipart.MultipartFile;
/**
* An interface for accessing parameters in a backing map. Parameters are immutable and have string keys and string
* values.
* <p>
* The accessor methods offered by this class taking a target type argument only need to support conversions to well
* know types like String, Number subclasses, Boolean and so on.
*
* @author Keith Donald
*/
public interface ParameterMap extends MapAdaptable<String, Object> {
/**
* Is this parameter map empty, with a size of 0?
* @return true if empty, false if not
*/
boolean isEmpty();
/**
* Returns the number of parameters in this map.
* @return the parameter count
*/
int size();
/**
* Does the parameter with the provided name exist in this map?
* @param parameterName the parameter name
* @return true if so, false otherwise
*/
boolean contains(String parameterName);
/**
* Get a parameter value, returning <code>null</code> if no value is found.
* @param parameterName the parameter name
* @return the parameter value
*/
String get(String parameterName);
/**
* Get a parameter value, returning the defaultValue if no value is found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the parameter value
*/
String get(String parameterName, String defaultValue);
/**
* Get a multi-valued parameter value, returning <code>null</code> if no value is found. If the parameter is single
* valued an array with a single element is returned.
* @param parameterName the parameter name
* @return the parameter value array
*/
String[] getArray(String parameterName);
/**
* Get a multi-valued parameter value, converting each value to the target type or returning <code>null</code> if no
* value is found.
* @param parameterName the parameter name
* @param targetElementType the target type of the array's elements
* @return the converterd parameter value array
* @throws ConversionExecutionException when the value could not be converted
*/
<T> T[] getArray(String parameterName, Class<T> targetElementType) throws ConversionExecutionException;
/**
* Get a parameter value, converting it from <code>String</code> to the target type.
* @param parameterName the name of the parameter
* @param targetType the target type of the parameter value
* @return the converted parameter value, or null if not found
* @throws ConversionExecutionException when the value could not be converted
*/
<T> T get(String parameterName, Class<T> targetType) throws ConversionExecutionException;
/**
* Get a parameter value, converting it from <code>String</code> to the target type or returning the defaultValue if
* not found.
* @param parameterName name of the parameter to get
* @param targetType the target type of the parameter value
* @param defaultValue the default value
* @return the converted parameter value, or the default if not found
* @throws ConversionExecutionException when a value could not be converted
*/
<T> T get(String parameterName, Class<T> targetType, T defaultValue) throws ConversionExecutionException;
/**
* Get the value of a required parameter.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
*/
String getRequired(String parameterName) throws IllegalArgumentException;
/**
* Get a required multi-valued parameter value.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
*/
String[] getRequiredArray(String parameterName) throws IllegalArgumentException;
/**
* Get a required multi-valued parameter value, converting each value to the target type.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
* @throws ConversionExecutionException when a value could not be converted
*/
<T> T[] getRequiredArray(String parameterName, Class<T> targetElementType) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Get the value of a required parameter and convert it to the target type.
* @param parameterName the name of the parameter
* @param targetType the target type of the parameter value
* @return the converted parameter value
* @throws IllegalArgumentException when the parameter is not found
* @throws ConversionExecutionException when the value could not be converted
*/
<T> T getRequired(String parameterName, Class<T> targetType) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Returns a number parameter value in the map that is of the specified type, returning <code>null</code> if no
* value was found.
* @param parameterName the parameter name
* @param targetType the target number type
* @return the number parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
<T extends Number> T getNumber(String parameterName, Class<T> targetType)
throws ConversionExecutionException;
/**
* Returns a number parameter value in the map of the specified type, returning the defaultValue if no value was
* found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the number parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
<T extends Number> T getNumber(String parameterName, Class<T> targetType, T defaultValue)
throws ConversionExecutionException;
/**
* Returns a number parameter value in the map, throwing an exception if the parameter is not present or could not
* be converted.
* @param parameterName the parameter name
* @return the number parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
<T extends Number> T getRequiredNumber(String parameterName, Class<T> targetType)
throws IllegalArgumentException, ConversionExecutionException;
/**
* Returns an integer parameter value in the map, returning <code>null</code> if no value was found.
* @param parameterName the parameter name
* @return the integer parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Integer getInteger(String parameterName) throws ConversionExecutionException;
/**
* Returns an integer parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the integer parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Integer getInteger(String parameterName, Integer defaultValue) throws ConversionExecutionException;
/**
* Returns an integer parameter value in the map, throwing an exception if the parameter is not present or could not
* be converted.
* @param parameterName the parameter name
* @return the integer parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
Integer getRequiredInteger(String parameterName) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Returns a long parameter value in the map, returning <code>null</code> if no value was found.
* @param parameterName the parameter name
* @return the long parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Long getLong(String parameterName) throws ConversionExecutionException;
/**
* Returns a long parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the long parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Long getLong(String parameterName, Long defaultValue) throws ConversionExecutionException;
/**
* Returns a long parameter value in the map, throwing an exception if the parameter is not present or could not be
* converted.
* @param parameterName the parameter name
* @return the long parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, returning <code>null</code> if no value was found.
* @param parameterName the parameter name
* @return the long parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Boolean getBoolean(String parameterName) throws ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the boolean parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, throwing an exception if the parameter is not present or could not
* be converted.
* @param parameterName the parameter name
* @return the boolean parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Get a multi-part file parameter value, returning <code>null</code> if no value is found.
* @param parameterName the parameter name
* @return the multipart file
*/
MultipartFile getMultipartFile(String parameterName);
/**
* Get the value of a required multipart file parameter.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
*/
MultipartFile getRequiredMultipartFile(String parameterName);
/**
* Adapts this parameter map to an {@link AttributeMap}.
* @return the underlying map as a unmodifiable attribute map
*/
AttributeMap<Object> asAttributeMap();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
import org.springframework.binding.collection.MapAdaptable;
import org.springframework.binding.convert.ConversionExecutionException;
import org.springframework.web.multipart.MultipartFile;
/**
* An interface for accessing parameters in a backing map. Parameters are immutable and have string keys and string
* values.
* <p>
* The accessor methods offered by this class taking a target type argument only need to support conversions to well
* know types like String, Number subclasses, Boolean and so on.
*
* @author Keith Donald
*/
public interface ParameterMap extends MapAdaptable<String, Object> {
/**
* Is this parameter map empty, with a size of 0?
* @return true if empty, false if not
*/
boolean isEmpty();
/**
* Returns the number of parameters in this map.
* @return the parameter count
*/
int size();
/**
* Does the parameter with the provided name exist in this map?
* @param parameterName the parameter name
* @return true if so, false otherwise
*/
boolean contains(String parameterName);
/**
* Get a parameter value, returning <code>null</code> if no value is found.
* @param parameterName the parameter name
* @return the parameter value
*/
String get(String parameterName);
/**
* Get a parameter value, returning the defaultValue if no value is found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the parameter value
*/
String get(String parameterName, String defaultValue);
/**
* Get a multi-valued parameter value, returning <code>null</code> if no value is found. If the parameter is single
* valued an array with a single element is returned.
* @param parameterName the parameter name
* @return the parameter value array
*/
String[] getArray(String parameterName);
/**
* Get a multi-valued parameter value, converting each value to the target type or returning <code>null</code> if no
* value is found.
* @param parameterName the parameter name
* @param targetElementType the target type of the array's elements
* @return the converterd parameter value array
* @throws ConversionExecutionException when the value could not be converted
*/
<T> T[] getArray(String parameterName, Class<T> targetElementType) throws ConversionExecutionException;
/**
* Get a parameter value, converting it from <code>String</code> to the target type.
* @param parameterName the name of the parameter
* @param targetType the target type of the parameter value
* @return the converted parameter value, or null if not found
* @throws ConversionExecutionException when the value could not be converted
*/
<T> T get(String parameterName, Class<T> targetType) throws ConversionExecutionException;
/**
* Get a parameter value, converting it from <code>String</code> to the target type or returning the defaultValue if
* not found.
* @param parameterName name of the parameter to get
* @param targetType the target type of the parameter value
* @param defaultValue the default value
* @return the converted parameter value, or the default if not found
* @throws ConversionExecutionException when a value could not be converted
*/
<T> T get(String parameterName, Class<T> targetType, T defaultValue) throws ConversionExecutionException;
/**
* Get the value of a required parameter.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
*/
String getRequired(String parameterName) throws IllegalArgumentException;
/**
* Get a required multi-valued parameter value.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
*/
String[] getRequiredArray(String parameterName) throws IllegalArgumentException;
/**
* Get a required multi-valued parameter value, converting each value to the target type.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
* @throws ConversionExecutionException when a value could not be converted
*/
<T> T[] getRequiredArray(String parameterName, Class<T> targetElementType) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Get the value of a required parameter and convert it to the target type.
* @param parameterName the name of the parameter
* @param targetType the target type of the parameter value
* @return the converted parameter value
* @throws IllegalArgumentException when the parameter is not found
* @throws ConversionExecutionException when the value could not be converted
*/
<T> T getRequired(String parameterName, Class<T> targetType) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Returns a number parameter value in the map that is of the specified type, returning <code>null</code> if no
* value was found.
* @param parameterName the parameter name
* @param targetType the target number type
* @return the number parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
<T extends Number> T getNumber(String parameterName, Class<T> targetType)
throws ConversionExecutionException;
/**
* Returns a number parameter value in the map of the specified type, returning the defaultValue if no value was
* found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the number parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
<T extends Number> T getNumber(String parameterName, Class<T> targetType, T defaultValue)
throws ConversionExecutionException;
/**
* Returns a number parameter value in the map, throwing an exception if the parameter is not present or could not
* be converted.
* @param parameterName the parameter name
* @return the number parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
<T extends Number> T getRequiredNumber(String parameterName, Class<T> targetType)
throws IllegalArgumentException, ConversionExecutionException;
/**
* Returns an integer parameter value in the map, returning <code>null</code> if no value was found.
* @param parameterName the parameter name
* @return the integer parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Integer getInteger(String parameterName) throws ConversionExecutionException;
/**
* Returns an integer parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the integer parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Integer getInteger(String parameterName, Integer defaultValue) throws ConversionExecutionException;
/**
* Returns an integer parameter value in the map, throwing an exception if the parameter is not present or could not
* be converted.
* @param parameterName the parameter name
* @return the integer parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
Integer getRequiredInteger(String parameterName) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Returns a long parameter value in the map, returning <code>null</code> if no value was found.
* @param parameterName the parameter name
* @return the long parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Long getLong(String parameterName) throws ConversionExecutionException;
/**
* Returns a long parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the long parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Long getLong(String parameterName, Long defaultValue) throws ConversionExecutionException;
/**
* Returns a long parameter value in the map, throwing an exception if the parameter is not present or could not be
* converted.
* @param parameterName the parameter name
* @return the long parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
Long getRequiredLong(String parameterName) throws IllegalArgumentException, ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, returning <code>null</code> if no value was found.
* @param parameterName the parameter name
* @return the long parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Boolean getBoolean(String parameterName) throws ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, returning the defaultValue if no value was found.
* @param parameterName the parameter name
* @param defaultValue the default
* @return the boolean parameter value
* @throws ConversionExecutionException when the value could not be converted
*/
Boolean getBoolean(String parameterName, Boolean defaultValue) throws ConversionExecutionException;
/**
* Returns a boolean parameter value in the map, throwing an exception if the parameter is not present or could not
* be converted.
* @param parameterName the parameter name
* @return the boolean parameter value
* @throws IllegalArgumentException if the parameter is not present
* @throws ConversionExecutionException when the value could not be converted
*/
Boolean getRequiredBoolean(String parameterName) throws IllegalArgumentException,
ConversionExecutionException;
/**
* Get a multi-part file parameter value, returning <code>null</code> if no value is found.
* @param parameterName the parameter name
* @return the multipart file
*/
MultipartFile getMultipartFile(String parameterName);
/**
* Get the value of a required multipart file parameter.
* @param parameterName the name of the parameter
* @return the parameter value
* @throws IllegalArgumentException when the parameter is not found
*/
MultipartFile getRequiredMultipartFile(String parameterName);
/**
* Adapts this parameter map to an {@link AttributeMap}.
* @return the underlying map as a unmodifiable attribute map
*/
AttributeMap<Object> asAttributeMap();
}

View File

@@ -1,29 +1,29 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
/**
* An interface to be implemented by mutable attribute maps accessed by multiple threads that need to be synchronized.
*
* @author Keith Donald
*/
public interface SharedAttributeMap<V> extends MutableAttributeMap<V> {
/**
* Returns the shared map's mutex, which may be synchronized on to block access to the map by other threads.
*/
Object getMutex();
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.core.collection;
/**
* An interface to be implemented by mutable attribute maps accessed by multiple threads that need to be synchronized.
*
* @author Keith Donald
*/
public interface SharedAttributeMap<V> extends MutableAttributeMap<V> {
/**
* Returns the shared map's mutex, which may be synchronized on to block access to the map by other threads.
*/
Object getMutex();
}

View File

@@ -1,95 +1,95 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
import org.springframework.context.ApplicationContext;
import org.springframework.webflow.core.Annotated;
/**
* The definition of a flow, a program that when executed carries out a task on behalf of a single client.
* <p>
* A flow definition is a reusable, self-contained controller module that defines a blue print for an executable user
* task. Flows typically orchestrate controlled navigations or dialogs within web applications to guide users through
* fulfillment of a business process/goal that takes place over a series of steps, modeled as states.
* <p>
* Structurally a flow definition is composed of a set of states. A {@link StateDefinition state} is a point in a flow
* where a behavior is executed; for example, showing a view, executing an action, spawning a subflow, or terminating
* the flow. Different types of states execute different behaviors in a polymorphic fashion. Most states are
* {@link TransitionableStateDefinition transitionable states}, meaning they can respond to events by taking the flow
* from one state to another.
* <p>
* Each flow has exactly one {@link #getStartState() start state} which defines the starting point of the program.
* <p>
* This interface exposes the flow's identifier, states, and other definitional attributes. It is suitable for
* introspection by tools as well as user-code at flow execution time.
* <p>
* Flow definitions may be annotated with attributes.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface FlowDefinition extends Annotated {
/**
* Returns the unique id of this flow.
* @return the flow id
*/
String getId();
/**
* Return this flow's starting point.
* @return the start state
*/
StateDefinition getStartState();
/**
* Returns the state definition with the specified id.
* @param id the state id
* @return the state definition
* @throws IllegalArgumentException if a state with this id does not exist
*/
StateDefinition getState(String id) throws IllegalArgumentException;
/**
* Returns the outcomes that are possible for this flow to reach.
* @return the possible outcomes
*/
String[] getPossibleOutcomes();
/**
* Returns the class loader used by this flow definition to load classes.
* @return the class loader
*/
ClassLoader getClassLoader();
/**
* Returns a reference to application context hosting application objects and services used by this flow definition.
* @return the application context
*/
ApplicationContext getApplicationContext();
/**
* Returns true if this flow definition is currently in development (running in development mode).
* @return the development flag
*/
boolean inDevelopment();
/**
* Destroy this flow definition, releasing any resources. After the flow is destroyed it cannot be started again.
*/
void destroy();
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
import org.springframework.context.ApplicationContext;
import org.springframework.webflow.core.Annotated;
/**
* The definition of a flow, a program that when executed carries out a task on behalf of a single client.
* <p>
* A flow definition is a reusable, self-contained controller module that defines a blue print for an executable user
* task. Flows typically orchestrate controlled navigations or dialogs within web applications to guide users through
* fulfillment of a business process/goal that takes place over a series of steps, modeled as states.
* <p>
* Structurally a flow definition is composed of a set of states. A {@link StateDefinition state} is a point in a flow
* where a behavior is executed; for example, showing a view, executing an action, spawning a subflow, or terminating
* the flow. Different types of states execute different behaviors in a polymorphic fashion. Most states are
* {@link TransitionableStateDefinition transitionable states}, meaning they can respond to events by taking the flow
* from one state to another.
* <p>
* Each flow has exactly one {@link #getStartState() start state} which defines the starting point of the program.
* <p>
* This interface exposes the flow's identifier, states, and other definitional attributes. It is suitable for
* introspection by tools as well as user-code at flow execution time.
* <p>
* Flow definitions may be annotated with attributes.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface FlowDefinition extends Annotated {
/**
* Returns the unique id of this flow.
* @return the flow id
*/
String getId();
/**
* Return this flow's starting point.
* @return the start state
*/
StateDefinition getStartState();
/**
* Returns the state definition with the specified id.
* @param id the state id
* @return the state definition
* @throws IllegalArgumentException if a state with this id does not exist
*/
StateDefinition getState(String id) throws IllegalArgumentException;
/**
* Returns the outcomes that are possible for this flow to reach.
* @return the possible outcomes
*/
String[] getPossibleOutcomes();
/**
* Returns the class loader used by this flow definition to load classes.
* @return the class loader
*/
ClassLoader getClassLoader();
/**
* Returns a reference to application context hosting application objects and services used by this flow definition.
* @return the application context
*/
ApplicationContext getApplicationContext();
/**
* Returns true if this flow definition is currently in development (running in development mode).
* @return the development flag
*/
boolean inDevelopment();
/**
* Destroy this flow definition, releasing any resources. After the flow is destroyed it cannot be started again.
*/
void destroy();
}

View File

@@ -1,48 +1,48 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
import org.springframework.webflow.core.Annotated;
/**
* A step within a {@link FlowDefinition flow definition} where behavior is executed.
* <p>
* States have identifiers that are local to their containing flow definitions. They may also be annotated with
* attributes.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface StateDefinition extends Annotated {
/**
* Returns the flow definition this state belongs to.
* @return the owning flow definition
*/
FlowDefinition getOwner();
/**
* Returns this state's identifier, locally unique to is containing flow definition.
* @return the state identifier
*/
String getId();
/**
* Returns true if this state is a view state.
* @return true if a view state, false otherwise
*/
boolean isViewState();
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
import org.springframework.webflow.core.Annotated;
/**
* A step within a {@link FlowDefinition flow definition} where behavior is executed.
* <p>
* States have identifiers that are local to their containing flow definitions. They may also be annotated with
* attributes.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface StateDefinition extends Annotated {
/**
* Returns the flow definition this state belongs to.
* @return the owning flow definition
*/
FlowDefinition getOwner();
/**
* Returns this state's identifier, locally unique to is containing flow definition.
* @return the state identifier
*/
String getId();
/**
* Returns true if this state is a view state.
* @return true if a view state, false otherwise
*/
boolean isViewState();
}

View File

@@ -1,41 +1,41 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
import org.springframework.webflow.core.Annotated;
/**
* A transition takes a flow from one state to another.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface TransitionDefinition extends Annotated {
/**
* The identifier of this transition. This id value should be unique among all other transitions in a set.
* @return the transition identifier
*/
String getId();
/**
* Returns an identification of the target state of this transition. This could be an actual static state id or
* something more dynamic, like a string representation of an expression evaluating the target state id at flow
* execution time.
* @return the target state identifier
*/
String getTargetStateId();
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
import org.springframework.webflow.core.Annotated;
/**
* A transition takes a flow from one state to another.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface TransitionDefinition extends Annotated {
/**
* The identifier of this transition. This id value should be unique among all other transitions in a set.
* @return the transition identifier
*/
String getId();
/**
* Returns an identification of the target state of this transition. This could be an actual static state id or
* something more dynamic, like a string representation of an expression evaluating the target state id at flow
* execution time.
* @return the target state identifier
*/
String getTargetStateId();
}

View File

@@ -1,38 +1,38 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
/**
* A state that can transition to another state.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface TransitionableStateDefinition extends StateDefinition {
/**
* Returns the available transitions out of this state.
* @return the available state transitions
*/
TransitionDefinition[] getTransitions();
/**
* Returns the transition that matches the event with the provided id.
* @param eventId the event id
* @return the transition that matches, or null if no match is found.
*/
TransitionDefinition getTransition(String eventId);
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition;
/**
* A state that can transition to another state.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface TransitionableStateDefinition extends StateDefinition {
/**
* Returns the available transitions out of this state.
* @return the available state transitions
*/
TransitionDefinition[] getTransitions();
/**
* Returns the transition that matches the event with the provided id.
* @param eventId the event id
* @return the transition that matches, or null if no match is found.
*/
TransitionDefinition getTransition(String eventId);
}

View File

@@ -1,50 +1,50 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition.registry;
import org.springframework.webflow.core.FlowException;
/**
* Thrown when a flow definition was found during a lookup operation but could not be constructed.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class FlowDefinitionConstructionException extends FlowException {
/**
* The id of the flow that could not be constructed.
*/
private String flowDefinitionId;
/**
* Creates an exception indicating a flow definition could not be constructed.
* @param flowDefinitionId the flow definition identifier
* @param cause the underlying cause of the exception
*/
public FlowDefinitionConstructionException(String flowDefinitionId, Throwable cause) {
super("An exception occurred constructing the flow '" + flowDefinitionId + "'", cause);
this.flowDefinitionId = flowDefinitionId;
}
/**
* Returns the id of the flow definition that could not be constructed.
* @return the flow id
*/
public String getFlowDefinitionId() {
return flowDefinitionId;
}
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition.registry;
import org.springframework.webflow.core.FlowException;
/**
* Thrown when a flow definition was found during a lookup operation but could not be constructed.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public class FlowDefinitionConstructionException extends FlowException {
/**
* The id of the flow that could not be constructed.
*/
private String flowDefinitionId;
/**
* Creates an exception indicating a flow definition could not be constructed.
* @param flowDefinitionId the flow definition identifier
* @param cause the underlying cause of the exception
*/
public FlowDefinitionConstructionException(String flowDefinitionId, Throwable cause) {
super("An exception occurred constructing the flow '" + flowDefinitionId + "'", cause);
this.flowDefinitionId = flowDefinitionId;
}
/**
* Returns the id of the flow definition that could not be constructed.
* @return the flow id
*/
public String getFlowDefinitionId() {
return flowDefinitionId;
}
}

View File

@@ -1,66 +1,66 @@
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition.registry;
import org.springframework.webflow.definition.FlowDefinition;
/**
* A holder holding a reference to a Flow definition. Provides a layer of indirection, enabling things like
* "hot-reloadable" flow definitions.
*
* @see FlowDefinitionRegistry#registerFlowDefinition(FlowDefinitionHolder)
*
* @author Keith Donald
*/
public interface FlowDefinitionHolder {
/**
* Returns the <code>id</code> of the flow definition held by this holder. This is a <i>lightweight</i> method
* callers may call to obtain the id of the flow without triggering full flow definition assembly (which may be an
* expensive operation).
*/
String getFlowDefinitionId();
/**
* Returns a descriptive string that identifies the source of this FlowDefinition. This is also a lightweight method
* callers may call to obtain the logical resource where the flow definition resides without triggering flow
* definition assembly. Used for informational purposes.
* @return the flow definition resource string
*/
String getFlowDefinitionResourceString();
/**
* Returns the flow definition held by this holder. Calling this method the first time may trigger flow assembly
* (which may be expensive).
* @throws FlowDefinitionConstructionException if there is a problem constructing the target flow definition
*/
FlowDefinition getFlowDefinition() throws FlowDefinitionConstructionException;
/**
* Refresh the flow definition held by this holder. Calling this method typically triggers flow re-assembly, which
* may include a refresh from an externalized resource such as a file.
* @throws FlowDefinitionConstructionException if there is a problem constructing the target flow definition
*/
void refresh() throws FlowDefinitionConstructionException;
/**
* Indicates that the system is being shutdown and any resources flow resources should be released. After this
* method is called, calls to {@link #getFlowDefinition()} are undefined. Should only be called once. May be a no-op
* if the held flow was never constructed to begin with.
*/
void destroy();
/*
* Copyright 2004-2008 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
*
* https://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.
*/
package org.springframework.webflow.definition.registry;
import org.springframework.webflow.definition.FlowDefinition;
/**
* A holder holding a reference to a Flow definition. Provides a layer of indirection, enabling things like
* "hot-reloadable" flow definitions.
*
* @see FlowDefinitionRegistry#registerFlowDefinition(FlowDefinitionHolder)
*
* @author Keith Donald
*/
public interface FlowDefinitionHolder {
/**
* Returns the <code>id</code> of the flow definition held by this holder. This is a <i>lightweight</i> method
* callers may call to obtain the id of the flow without triggering full flow definition assembly (which may be an
* expensive operation).
*/
String getFlowDefinitionId();
/**
* Returns a descriptive string that identifies the source of this FlowDefinition. This is also a lightweight method
* callers may call to obtain the logical resource where the flow definition resides without triggering flow
* definition assembly. Used for informational purposes.
* @return the flow definition resource string
*/
String getFlowDefinitionResourceString();
/**
* Returns the flow definition held by this holder. Calling this method the first time may trigger flow assembly
* (which may be expensive).
* @throws FlowDefinitionConstructionException if there is a problem constructing the target flow definition
*/
FlowDefinition getFlowDefinition() throws FlowDefinitionConstructionException;
/**
* Refresh the flow definition held by this holder. Calling this method typically triggers flow re-assembly, which
* may include a refresh from an externalized resource such as a file.
* @throws FlowDefinitionConstructionException if there is a problem constructing the target flow definition
*/
void refresh() throws FlowDefinitionConstructionException;
/**
* Indicates that the system is being shutdown and any resources flow resources should be released. After this
* method is called, calls to {@link #getFlowDefinition()} are undefined. Should only be called once. May be a no-op
* if the held flow was never constructed to begin with.
*/
void destroy();
}

View File

@@ -1,38 +1,38 @@
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.definition.registry;
import org.springframework.webflow.definition.FlowDefinition;
/**
* A runtime service locator interface for retrieving flow definitions by <code>id</code>. Flow locators are needed by
* flow executors at runtime to retrieve fully-configured flow definitions to support launching new flow executions.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface FlowDefinitionLocator {
/**
* Lookup the flow definition with the specified id.
* @param id the flow definition identifier
* @return the flow definition
* @throws NoSuchFlowDefinitionException when the flow definition with the specified id does not exist
* @throws FlowDefinitionConstructionException if there is a problem constructing the identified flow definition
*/
FlowDefinition getFlowDefinition(String id) throws NoSuchFlowDefinitionException,
FlowDefinitionConstructionException;
}
/*
* Copyright 2004-2012 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
*
* https://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.
*/
package org.springframework.webflow.definition.registry;
import org.springframework.webflow.definition.FlowDefinition;
/**
* A runtime service locator interface for retrieving flow definitions by <code>id</code>. Flow locators are needed by
* flow executors at runtime to retrieve fully-configured flow definitions to support launching new flow executions.
*
* @author Keith Donald
* @author Erwin Vervaet
*/
public interface FlowDefinitionLocator {
/**
* Lookup the flow definition with the specified id.
* @param id the flow definition identifier
* @return the flow definition
* @throws NoSuchFlowDefinitionException when the flow definition with the specified id does not exist
* @throws FlowDefinitionConstructionException if there is a problem constructing the identified flow definition
*/
FlowDefinition getFlowDefinition(String id) throws NoSuchFlowDefinitionException,
FlowDefinitionConstructionException;
}

Some files were not shown because too many files have changed in this diff Show More