Moved Spring Web Flow to a top level project

This commit is contained in:
Ben Hale
2006-12-21 16:02:27 +00:00
commit e7ecbbc7e5
1083 changed files with 80775 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
build.properties
target

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>build-spring-webflow</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

View File

@@ -0,0 +1,78 @@
<?xml version="1.0"?>
<!--
=======================================================================
Build file containing targets for continuously integrating build
Targets are put in a separate build file to prevent users from
having to put in an SSH library in ANT_HOME/lib
This build requires an SSH client to be put in ANT_HOME/lib. Refer
to Ant's SCP documentation for more information.
@author Alef Arendsen
@author Arjen Poutsma
=======================================================================
-->
<project name="build-spring-webflow-continuous" default="snapshot" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="${basedir}/build.xml"/>
<!-- targets for uploading binaries, creating snapshots, et cetera -->
<!--
properties needed (some are set in CruiseControl configuration)
- release.zip release zip (set by build.xml)
- release.version release version (set by build.xml)
- target.release.dir release directory (set by build.xml)
- upload.tmp.dir temporary directory to use when uploading
- upload.username username to use when SCP'ing to server
- upload.password password to use when SCP'ing to server
- upload.url url to use when SCP'ing to server
- upload.log.dir directory to upload logs to
- upload.binaries.dir directory to upload binaries to
-->
<target name="snapshot" depends="init, guard.upload.tmp.dir">
<delete quiet="true" dir="${upload.tmp.dir}"/>
<mkdir dir="${upload.tmp.dir}"/>
<tstamp>
<format property="tstamp" pattern="yyyyMMdd-HHmm"/>
</tstamp>
<move file="${target.release.dir}/${release.zip}"
tofile="${upload.tmp.dir}/spring-webflow-${release.version}-${tstamp}.zip"/>
</target>
<target name="upload" depends="upload-binaries"/>
<!-- SCP needs an SSH library on the classpath (see Ant documentation for more info) -->
<target name="upload-binaries" depends="init, guard.upload.tmp.dir, guard.upload.binaries.dir, guard.upload.url, guard.upload.password, guard.upload.username">
<scp todir="${upload.username}@${upload.url}:${upload.binaries.dir}" password="${upload.password}">
<fileset dir="${upload.tmp.dir}">
<include name="spring-*.zip"/>
</fileset>
</scp>
<delete quiet="true" dir="${upload.tmp.dir}"/>
</target>
<target name="guard.upload.tmp.dir" unless="upload.tmp.dir">
<fail message="This target requires the upload.tmp.dir property to be set"/>
</target>
<target name="guard.upload.log.dir" unless="upload.log.dir">
<fail message="This target requires the upload.log.dir property to be set"/>
</target>
<target name="guard.upload.binaries.dir" unless="upload.binaries.dir">
<fail message="This target requires the upload.binaries.dir property to be set"/>
</target>
<target name="guard.upload.username" unless="upload.username">
<fail message="This target requires the upload.username property to be set"/>
</target>
<target name="guard.upload.url" unless="upload.url">
<fail message="This target requires the upload.url.property to be set"/>
</target>
<target name="guard.upload.password" unless="upload.password">
<fail message="This target requires the upload.password property to be set"/>
</target>
</project>

View File

@@ -0,0 +1,232 @@
<?xml version="1.0"?>
<!--
=======================================================================
A master build file for creating a release of Spring Web Flow
=======================================================================
-->
<project name="build-spring-webflow" default="release" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<!-- Load local and user build preferences -->
<property file="build.properties" />
<property file="project.properties" />
<property file="${user.home}/build.properties" />
<!-- Try to load ivy here from local lib dir, in case the user has not already dropped
it into ant's lib dir (note that the latter copy will always take precedence).
We will not fail as long as local lib dir exists (it may be empty) and
ivy is in at least one of ant's lib dir or the local lib dir. -->
<path id="ivy.lib.path">
<fileset dir="${common.build.dir}/lib" includes="*.jar" />
</path>
<taskdef resource="fr/jayasoft/ivy/ant/antlib.xml" uri="antlib:fr.jayasoft.ivy.ant" classpathref="ivy.lib.path" />
<!-- simplistic pattern for zipping up sources -->
<selector id="project.source.zip.includes">
<or>
<filename name="common-build/**" />
<and>
<or>
<filename name="spring-webflow/build-spring-webflow/**" />
<filename name="spring-webflow/spring-binding/**" />
<filename name="spring-webflow/spring-webflow/**" />
<filename name="spring-webflow/spring-webflow-samples/**" />
</or>
<and>
<!-- exclude core project derived artifacts -->
<filename name="*/*/docs/**" negate="true"/>
<filename name="*/*/target/**" negate="true" />
<filename name="*/*/build.properties" negate="true" />
<filename name="*/*/lib/**" negate="true" />
</and>
<and>
<!-- exclude sample project derived artifacts -->
<filename name="*/*/*/docs/**" negate="true"/>
<filename name="*/*/*/target/**" negate="true" />
<filename name="*/*/*/build.properties" negate="true" />
<filename name="*/*/*/lib/**" negate="true" />
</and>
</and>
</or>
</selector>
<!--
targets: displays all targets suitable for developer use
-->
<target name="targets">
<echo>
Master build for Spring Web Flow and Spring Web Flow samples.
Please execute
ant -p
to see a list of all relevant targets.
</echo>
</target>
<!--
init: initializes some common settings
-->
<target name="init" unless="init.done" depends="init.pre, init.post" />
<target name="init.pre">
<!-- ivy will determine the right order to build web flow main and samples -->
<property name="ivy.conf.dir" value="${common.build.dir}" />
<ivy:configure file="${ivy.conf.dir}/ivyconf.xml" />
<ivy:buildlist reference="modules">
<fileset dir="..">
<include name="spring-binding/build.xml" />
<include name="spring-webflow/build.xml" />
<include name="spring-webflow-samples/*/build.xml" />
</fileset>
</ivy:buildlist>
<tstamp>
<format property="build.timestamp" pattern="yyyyMMddHHmmss" />
</tstamp>
<tstamp>
<format property="TSTAMPCOL" pattern="hh:mm" />
</tstamp>
<!-- default the release version (used in release archive zips) to the current timestamp -->
<property name="release.version" value="${build.timestamp}" />
<!-- root of build hierarchy -->
<property name="target.dir" value="${basedir}/target" />
<!-- directory for release zips -->
<property name="target.release.dir" value="${target.dir}/release" />
<!-- directory for release zips -->
<property name="zip.toplevel.dir" value="spring-webflow-${release.version}" />
<property name="release.zip" value="spring-webflow-${release.version}.zip" />
<echo message='user.dir = "${user.dir}"' />
<echo message='ant.file = "${ant.file}"' />
<echo message='ant.java.version = "${ant.java.version}"' />
<echo message='release.version = "${release.version}"' />
</target>
<target name="init.post">
<property name="projects" value="modules" />
<property name="projects.names" refid="modules" />
<property name="init.done" value="true" />
</target>
<target name="clean" depends="init" description="Cleans all build output files from all projects">
<delete dir="${target.dir}" />
<echo>projects=${projects}</echo>
<echo>projects.names=${projects.names}</echo>
<subant target="clean" inheritall="false">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="clean-all" depends="init" description="Cleans all build output files from all projects, and also retrieved libs">
<delete dir="${target.dir}" />
<echo>projects=${projects}</echo>
<subant target="clean-all" inheritall="false">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="retrieve" depends="init" description="Does a retrieve in all projects">
<delete dir="${target.dir}" />
<echo>projects=${projects}</echo>
<echo>projects.names=${projects.names}</echo>
<subant target="retrieve" inheritall="false">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="publish" depends="init" description="Calls publish targets on each project">
<echo>projects=${projects}</echo>
<subant target="publish" inheritall="false">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="dist" depends="init" description="Calls dist targets on each project">
<echo>projects=${projects}</echo>
<subant target="dist" inheritall="false">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="build-release-repo" depends="init"
description="Builds repo of all dependencies for all projects">
<echo>projects=${projects}</echo>
<subant target="retrieve-to-repo" inheritall="false">
<property name="retrieve.to.repo.dir" value="${target.dir}/repo" />
<property name="retrieve.to.repo.pattern"
value="${release.repo.ivy.retrieve.pattern}" />
<property name="retrieve.to.repo.pattern.ivy"
value="${release.repo.ivy.retrieve.ivy.pattern}" />
<buildpath refid="${projects}" />
</subant>
</target>
<target name="tests" depends="init" description="Calls test targets on each project">
<echo>projects=${projects}</echo>
<subant target="tests" inheritall="false">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="javadoc" depends="init" description="Calls javadoc targets on each project">
<echo>projects=${projects}</echo>
<subant target="javadoc" inheritall="false" failonerror="no">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="doc" depends="init" description="Calls doc targets on applicable projects">
<echo>projects=${projects}</echo>
<subant target="doc-all" inheritall="false" failonerror="false">
<buildpathelement location="../spring-webflow" />
</subant>
</target>
<target name="tomcat-copy-war" depends="init" description="Copies all war to tomcat webapp dir">
<echo>projects=${projects}</echo>
<subant target="tomcat-copy-war" inheritall="false" failonerror="no">
<buildpath refid="${projects}" />
</subant>
</target>
<target name="release" depends="dist, build-release-repo, javadoc, doc, gen.release.zip"
description="Generate the spring-webflow release archive" />
<target name="gen.release.zip" depends="init">
<mkdir dir="${target.release.dir}" />
<delete file="${target.release.dir}/${release.zip}" />
<zip zipfile="${target.release.dir}/${release.zip}">
<!-- important readme, license, and other text files -->
<zipfileset file="../spring-webflow/*.txt" prefix="${zip.toplevel.dir}" />
<!-- binary files -->
<zipfileset dir="../spring-binding/target/dist/jars" prefix="${zip.toplevel.dir}" />
<zipfileset dir="../spring-binding/target/dist/ivys" prefix="${zip.toplevel.dir}/ivys" />
<zipfileset dir="../spring-binding/target/javadocs" prefix="${zip.toplevel.dir}/docs/api-binding" />
<zipfileset dir="../spring-webflow/target/dist/jars" prefix="${zip.toplevel.dir}" />
<zipfileset dir="../spring-webflow/target/dist/ivys" prefix="${zip.toplevel.dir}/ivys" />
<zipfileset dir="../spring-webflow/target/javadocs" prefix="${zip.toplevel.dir}/docs/api" />
<zipfileset dir="../spring-webflow/docs/reference/target" prefix="${zip.toplevel.dir}/docs/reference">
<exclude name="**/html_single/**" />
<exclude name="**/pdf/images/**" />
</zipfileset>
<zipfileset dir="../spring-webflow/docs" includes="upgrade-guide.pdf" prefix="${zip.toplevel.dir}/docs" />
<zipfileset dir="${target.dir}/repo" prefix="${zip.toplevel.dir}/projects/repository" />
<!-- project sources -->
<zipfileset dir="../.." prefix="${zip.toplevel.dir}/projects">
<selector refid="project.source.zip.includes" />
</zipfileset>
</zip>
</target>
</project>

View File

@@ -0,0 +1,7 @@
# Configurable property values that may be locally overriden by a build.properties file
# The version number of the release that will be built
release.version=1.0.1
# The location of the common build system
common.build.dir=${basedir}/../common-build

View File

@@ -0,0 +1,27 @@
This is where the master build that creates releases of Spring Web Flow resides.
USERS
- To build all Spring Web Flow related projects:
1. From this directory, run:
ant dist
Build Pre-requisites:
- javac 1.5 or > must be in your system path
- ant 1.6 or > must be in your system path
- ivy 1.3 or > (Note: a version of Ivy is included and will be used automatically if you do not already have
Ivy installed in your ANT_HOME/lib directory.
If you have Ivy already installed in %ANT_HOME%/lib make sure it is 1.3 or >. 1.2 won't work.)
DEVELOPERS
- To build a new Spring Web Flow product release:
1. Update project.properties to reflect the new release version, if necessary.
2. From this directory, run:
ant release
The release archive will be created and placed in:
target/release
Questions? See http://forum.springframework.org.

11
common-build/.cvsignore Normal file
View File

@@ -0,0 +1,11 @@
build.properties
*.jpx.local*
*.log
*.iws
*.tws
target
dist
gen-src
bak
mimedata
ivy-cache

11
common-build/.project Normal file
View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>common-build</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>

View File

@@ -0,0 +1,82 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Colin Sampaleanu
Author: Keith Donald
Ant XML fragment that contains useful targets for working with clover. These
include targets to instrument (cloverize) project code, execute tests with clover,
and produce test coverage reports.
This ant XML fragment is meant to be imported into a project build file, along with
common-targets.xml. This is an optional module, and due to the way the ant import works,
there is no way to automatically hook this up into the build. The importing project
must override appropropriate 'hook' targets from common-targets.xml, and then have
the override targets depend on both the targets from common-targets and those from here.
Note, for clover to work:
- Make sure clover.jar and cenquatasks.jar is in your ant lib directory.
- Make sure clover.jar is expressed as a test dependency for your project.
-->
<project name="clover-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml" />
<target name="clover.tasks" depends="retrieve">
<taskdef resource="com/cenqua/ant/antlib.xml" classpath="${test.classpath}" />
<taskdef resource="clovertasks" classpath="${test.classpath}" />
</target>
<target name="-check.clover" depends="clover.tasks">
<available property="clover.installed" classname="com.cenqua.clover.CloverInstr" />
</target>
<target name="guard.noclover" depends="-check.clover" unless="clover.installed">
<fail message="The target you are attempting to run requires Clover, which doesn't appear" />
</target>
<target name="clover.init" depends="guard.noclover">
<property name="target.clover.dir" value="${target.dir}/clover" />
<mkdir dir="${target.clover.dir}" />
<clover-setup initstring="${target.clover.dir}/coverage.db" tmpdir="${target.clover.dir}" preserve="true">
<fileset dir="${src.java.main.dir}">
<include name="**/*.java" />
</fileset>
</clover-setup>
</target>
<target name="clover.instrument" depends="clover.init, compile" />
<target name="clover-report" depends="clover.instrument, tests-local" description="Produce a test coverage report">
<clover-report>
<current outfile="${target.clover.dir}/html">
<format type="html" />
</current>
</clover-report>
</target>
<target name="clover-summary" depends="clover.instrument, tests-local" description="Produce a test coverage summary">
<clover-report>
<current summary="yes" outfile="${target.clover.dir}/coverage.pdf">
<format type="pdf" />
</current>
</clover-report>
</target>
</project>

View File

@@ -0,0 +1,928 @@
<?xml version="1.0"?>
<!--
Copyright 2003-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Colin Sampaleanu
- - -
-->
<project name="common-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<!-- try to load ivy here from local lib dir, in case the user has not already dropped
it into ant's lib dir (note that the latter copy will always take precedence).
We will not fail as long as local lib dir exists (it may be empty) and
ivy is in at least one of ant's lib dir or the local lib dir. -->
<path id="ivy.lib.path">
<fileset dir="${common.build.dir}/lib" includes="*.jar"/>
</path>
<taskdef resource="fr/jayasoft/ivy/ant/antlib.xml"
uri="antlib:fr.jayasoft.ivy.ant" classpathref="ivy.lib.path"/>
<!-- targets: displays all targets suitable for developer use -->
<target name="targets" depends="init">
<echo>
ANT build for ${project.name} ${project.version}.
Please execute:
ant -projecthelp
or
ant -p
to see a list of publically executable targets.
</echo>
</target>
<!--
init: initializes some common settings
-->
<target name="init" unless="init.done" depends="force.env.load,
init.cl.external.props,
init.env.external.props,
init.pre,
init.post,
init.post2">
</target>
<target name="init.pre">
<!-- we default project.version to be ${project.base.version}-${build.timestamp}
where project.base.version defaults to 1.0-dev.
An importing project or master build should override project.base.version.
For a release build which doesn't need the build timestamp, should override
project.version itself to just be equal to ${project.base.version} -->
<tstamp>
<format property="build.timestamp" pattern="yyyyMMddHHmmss" />
</tstamp>
<tstamp>
<format property="TSTAMPCOL" pattern="hh:mm" />
</tstamp>
<property name="ivy.conf.dir" value="${common.build.dir}" />
<property name="org.name" value="springframework.org" />
<property name="org.package.prefix" value="org.springframework" />
<property name="project.name" value="${ant.project.name}" />
<property name="project.webapp.name" value="${ant.project.name}" />
<property name="project.title" value="${project.name}" />
<property name="project.base.version" value="1.0-dev" />
<property name="project.version" value="${project.base.version}-${build.timestamp}" />
<property name="project.copyright" value="Copyright &#169; 2002-2006. All Rights Reserved."/>
<property environment="myenv" />
<!-- Compiler options -->
<property name="optimize" value="false" />
<property name="debug" value="true" />
<property name="deprecation" value="false" />
<property name="javac.source" value="1.3" />
<property name="javac.target" value="1.3" />
<!-- vm to use for unit tests, will not override if already set -->
<!-- set to a dummy default val which will be ignored if already set -->
<property name="unitvm" value="-DzzzDummyVal" />
<echo message='org.name = "${org.name}"' />
<echo message='org.package.prefix = "${org.package.prefix}"' />
<echo message='project.name = "${project.name}"' />
<echo message='project.webapp.name = "${project.webapp.name}"' />
<echo message='project.title = "${project.title}"' />
<echo message='project.base.version = "${project.base.version}"' />
<echo message='project.version = "${project.version}"' />
<echo message='ant.file = "${ant.file}"' />
<echo message='basedir = "${basedir}"' />
<echo message='user.dir = "${user.dir}"' />
<echo message='ant.java.version = "${ant.java.version}"' />
<echo message='debug = "${debug}"' />
<echo message='optimize = "${optimize}"' />
<echo message='javac.source = "${javac.source}"' />
<echo message='javac.target = "${javac.target}"' />
<echo message='target.appserver = "${target.appserver}"' />
<echo message='unit test vm: vm arg="${unitvm}"' />
</target>
<target name="init.post" depends="eclipse.configure">
<!-- set target appserver, default to UNDEFINED. A project should override this
if it actually needs to use appserver specific properties -->
<property name="target.appserver" value="UNDEFINED" />
<!-- by default we filter certain file types on copying -->
<patternset id="std.files.to.filter">
<include name="**/*.xml" />
<include name="**/*.properties" />
<include name="**/*.conf" />
<include name="**/*.sql" />
<include name="**/*.txt" />
<include name="**/*.email" />
<include name="**/*.html" />
<include name="**/*.htm" />
</patternset>
<patternset id="std.files.not.to.filter">
<exclude name="**/*.xml" />
<exclude name="**/*.properties" />
<exclude name="**/*.conf" />
<exclude name="**/*.sql" />
<exclude name="**/*.txt" />
<exclude name="**/*.email" />
<exclude name="**/*.html" />
<exclude name="**/*.htm" />
</patternset>
<patternset id="web.public.content.files">
<patternset refid="image.files" />
<patternset refid="html.files" />
<include name="index.jsp" />
<include name="**/*.js" />
<exclude name="WEB-INF/**" />
</patternset>
<patternset id="image.files">
<include name="**/*.png" />
<include name="**/*.gif" />
<include name="**/*.jpg" />
</patternset>
<patternset id="html.files">
<include name="**/*.html" />
<include name="**/*.htm" />
<include name="**/*.css" />
</patternset>
<patternset id="web.protected.content.files">
<patternset refid="scriptlet.files" />
<patternset refid="web.config.files" />
</patternset>
<patternset id="scriptlet.files">
<include name="**/*.jsp" />
<include name="**/*.vm" />
</patternset>
<patternset id="web.config.files">
<include name="WEB-INF/classes/**/*.xml" />
<include name="WEB-INF/classes/**/*.properties" />
<include name="WEB-INF/classes/**/*.txt" />
<include name="WEB-INF/classes/**/*.conf" />
</patternset>
<property name="target.lib.dir" value="${target.artifacts.dir}/lib" />
<property name="project.war" value="${target.artifacts.war.dir}/${project.webapp.name}.war" />
<!-- convert appserver specific properties to final property names -->
<echoproperties destfile="properties.tmp">
<propertyset id="appserver.specific.properties">
<propertyref prefix="${target.appserver}" />
<mapper type="glob" from="${target.appserver}.*" to="*" />
</propertyset>
</echoproperties>
<loadproperties srcFile="properties.tmp" />
<delete file="properties.tmp" />
</target>
<target name="init.post2">
<path id="compile.classpath">
<fileset dir="${lib.dir}/global">
<include name="**/*.jar" />
</fileset>
<fileset dir="${lib.dir}/buildtime">
<include name="**/*.jar" />
</fileset>
</path>
<path id="test.classpath">
<path refid="compile.classpath" />
<fileset dir="${lib.dir}/test">
<include name="**/*.jar" />
</fileset>
</path>
<property name="init.done" value="true" />
</target>
<!-- used to assist loading of properties from environment -->
<target name="force.env.load">
<property environment="myenv" />
</target>
<!-- targets which allow loading a command line or env specified external properties file -->
<target name="init.cl.external.props" if="build.prop.file">
<property environment="myenv" />
<echo message='loading external prop file: ${build.prop.file}' />
<property file="${build.prop.file}" />
</target>
<target name="init.env.external.props" if="myenv.STUB.BUILD.PROP.FILE">
<property environment="myenv" />
<property file="${myenv.STUB.BUILD.PROP.FILE}" />
<echo message='loading external prop file: ${myenv.STUB.BUILD.PROP.FILE}' />
</target>
<!-- check.for.optional.packages: -->
<!-- Check to see what optional dependencies are available -->
<target name="check.for.optional.packages">
<available property="jdk1.2+" classname="java.lang.ThreadLocal" />
<available property="jdk1.3+" classname="java.lang.StrictMath" />
<available property="xalan.present" classname="org.apache.xalan.xslt.XSLTProcessorFactory" />
<available property="junit.present" classname="junit.framework.TestCase" />
<!-- compiler value may be 'modern', 'classic', or 'jikes' -->
<!-- will do nothing if it has already been set for eclipse -->
<property name="build.compiler" value="modern" />
</target>
<!-- needed so this build can be run properly from Eclipse -->
<target name="eclipse.configure" if="eclipse.running">
<property name="build.compiler" value="org.eclipse.jdt.core.JDTCompilerAdapter" />
<echo message="Configuring compiler for Eclipse..." />
</target>
<!-- clean: Cleans up generated stuff -->
<target name="clean" depends="init" description="Scrub build, distribution, and test results directories">
<delete dir="${target.dir}" />
<!-- also clean up dist.dir, in case it is not under target.dir -->
<delete dir="${dist.dir}" />
</target>
<!-- clean-all: Also cleans lib dir stuff pulled down by ivy -->
<target name="clean-all" depends="clean" description="Calls clean, but also cleans lib dir dependencies pulled down by Ivy">
<delete dir="${lib.dir}" />
</target>
<!-- build.prepare: Prepares the build directory -->
<target name="build.prepare" unless="build.prepare.done" depends="init, check.for.optional.packages">
<tstamp />
<!-- set up dirs that we need -->
<antcall target="build.prepare.make.config.dirs" />
<mkdir dir="${target.dir}" />
<mkdir dir="${target.gen.java.dir}" />
<mkdir dir="${target.gen.java.test.dir}" />
<mkdir dir="${target.testresults.dir}" />
<mkdir dir="${target.classes.dir}" />
<mkdir dir="${target.testclasses.dir}" />
<!-- now we want to create/update file used for filter properties. Other parts of the
build can also write properties to this file. Note that we also do some work to put
out test results dir in UNIX format since it will go in the log4j.properties file -->
<copy file="${src.etc.dir}/filter.properties" overwrite="true" tofile="${target.filter.file}" failonerror="false" />
<path id="target.testresults.dir.path" location="${target.testresults.dir}" />
<pathconvert targetos="unix" property="target.testresults.dir.unix" refid="target.testresults.dir.path" />
<propertyfile file="${target.filter.file}">
<entry key="PROJECT_NAME" value="${project.name}" />
<entry key="TEST_RESULTS_DIR" value="${target.testresults.dir.unix}" />
<entry key="DATABASE_DRIVER" value="${database.driver}" />
<entry key="DATABASE_URL" value="${database.url}" />
<entry key="DATABASE_SCHEMA" value="${database.schema}" />
<entry key="DATABASE_USERNAME" value="${database.username}" />
<entry key="DATABASE_PASSWORD" value="${database.password}" />
<entry key="DATA_DIR" value="${data.dir}" />
</propertyfile>
<property name="build.prepare.done" value="true" />
</target>
<target name="build.prepare.make.config.dirs">
<mkdir dir="${lib.dir}/global" />
<mkdir dir="${lib.dir}/buildtime" />
<mkdir dir="${lib.dir}/test" />
</target>
<target name="ivy.configure" depends="init">
<echo>reading ivy config</echo>
<ivy:configure file="${ivy.conf.dir}/ivyconf.xml" />
</target>
<presetdef name="resolve.conf">
<ivy:resolve file="${basedir}/ivy.xml" conf="${conf}" />
</presetdef>
<presetdef name="resolve.all">
<ivy:resolve file="${basedir}/ivy.xml" conf="*" />
</presetdef>
<!-- presetdef to retrieve one or more confs, defaulting to "default" -->
<presetdef name="retrieve.conf">
<ivy:retrieve pattern="${ivy.retrieve.pattern}" conf="default" />
</presetdef>
<presetdef name="retrieve.all">
<ivy:retrieve pattern="${${ivy.retrieve.pattern}}" conf="*" />
</presetdef>
<target name="retrieve.all" depends="resolve.all">
<retrieve.all />
</target>
<target name="resolve.conf" depends="ivy.configure">
<resolve.conf />
</target>
<target name="resolve.all" depends="ivy.configure">
<resolve.all />
</target>
<!-- resolve: resolve dependencies -->
<target name="resolve" depends="build.prepare, ivy.configure, resolve.pre, resolve.main, resolve.post" />
<target name="resolve.pre" />
<target name="resolve.main">
<property name="main.build.configs" value="global,buildtime,test" />
<resolve.conf conf="${main.build.configs}" />
</target>
<target name="resolve.post" />
<!-- retrieve: retrieve dependencies -->
<target name="retrieve" depends="resolve, retrieve.pre, retrieve.main, retrieve.post"
description="Retrieve all declared dependencies into the lib dir" />
<target name="retrieve.pre" />
<target name="retrieve.main">
<!-- when we retrieve with revision numbers in jar names, we really have to kill the
retrieve dir so we don't get multiple snapshot versions -->
<antcall target="clear.lib.dir.before.retrieve" />
<retrieve.conf conf="${main.build.configs}" />
</target>
<target name="retrieve.post" />
<target name="clear.lib.dir.before.retrieve" if="clear.libs.before.retrieve">
<delete dir="${lib.dir}" />
<antcall target="build.prepare.make.config.dirs" />
</target>
<!-- retrieve target to pull down deps and ivys to some location, used for building repos -->
<target name="retrieve-to-repo" depends="resolve">
<property name="retrieve.to.repo.conf" value="*" />
<property name="retrieve.to.repo.dir" value="${target.dir}/repo" />
<property name="retrieve.to.repo.pattern"
value="[organisation]/[module]/[type]s/[artifact]-[revision].[ext]" />
<property name="retrieve.to.repo.pattern.ivy"
value="[organisation]/[module]/ivy-[revision].xml" />
<retrieve.conf conf="${retrieve.to.repo.conf}"
pattern="${retrieve.to.repo.dir}/${retrieve.to.repo.pattern}"
ivypattern="${retrieve.to.repo.dir}/${retrieve.to.repo.pattern.ivy}"/>
</target>
<!-- statics: copies statics files before compiles -->
<target name="statics" depends="retrieve, ivy.configure, statics.pre, statics.main, statics.test, statics.web, statics.post" description="Copy static files before compile, replacing tokens as needed">
</target>
<!-- hook target -->
<target name="statics.pre" />
<!-- copy main statics -->
<target name="statics.main">
<mkdir dir="${target.artifacts.dir}" />
<!-- copy everything from the source dir, except java and javadoc files. Do not filter. Files that need filtering should go in resources. -->
<copy todir="${target.classes.dir}">
<fileset dir="${src.java.main.dir}">
<exclude name="**/*.java" />
<exclude name="**/package.html"/>
<exclude name="**/overview.html"/>
</fileset>
</copy>
<!-- copy resource files if neccessary, filtering for non-binary types -->
<available file="${src.resources.dir}" property="resources.exists" />
<antcall target="copy.resources" />
</target>
<target name="copy.resources" if="resources.exists">
<copy todir="${target.classes.dir}" filtering="on">
<fileset dir="${src.resources.dir}">
<patternset refid="std.files.to.filter" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
<copy todir="${target.classes.dir}">
<fileset dir="${src.resources.dir}">
<patternset refid="std.files.not.to.filter" />
</fileset>
</copy>
</target>
<!-- copy test statics -->
<target name="statics.test">
<!-- copy everything from the source dir, except java files. Do not filter. Files
that need filtering should source from ${src.test.resources.dir} -->
<copy todir="${target.testclasses.dir}">
<fileset dir="${src.java.test.dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
<!-- copy test resource files if neccessary, filtering for non-binary types -->
<available file="${src.test.resources.dir}" property="test.resources.exists" />
<antcall target="copy.test.resources" />
<!-- write out a test.properties file with common properties -->
<propertyfile file="${target.testclasses.dir}/test.properties" comment="Common unit/integration test properties">
<entry key="lastupdate" type="date" value="now" />
</propertyfile>
</target>
<target name="copy.test.resources" if="test.resources.exists">
<copy todir="${target.testclasses.dir}" filtering="on">
<fileset dir="${src.test.resources.dir}">
<patternset refid="std.files.to.filter" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
<copy todir="${target.testclasses.dir}">
<fileset dir="${src.test.resources.dir}">
<patternset refid="std.files.not.to.filter" />
</fileset>
</copy>
</target>
<target name="resources" depends="build.prepare" description="Force update of filterable resources (property config files, etc) needed at runtime and test time">
<copy todir="${target.classes.dir}" filtering="on" overwrite="true">
<fileset dir="${src.resources.dir}">
<patternset refid="std.files.to.filter" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
<copy todir="${target.classes.dir}" overwrite="true">
<fileset dir="${src.resources.dir}">
<patternset refid="std.files.not.to.filter" />
</fileset>
</copy>
<antcall target="test-resources"/>
</target>
<target name="test-resources" depends="build.prepare" description="Force update of filterable resources (logging config files, etc) needed at test time">
<copy todir="${target.testclasses.dir}" filtering="on" overwrite="true">
<fileset dir="${src.test.resources.dir}">
<patternset refid="std.files.to.filter" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
<copy todir="${target.testclasses.dir}" overwrite="true">
<fileset dir="${src.test.resources.dir}">
<patternset refid="std.files.not.to.filter" />
</fileset>
</copy>
</target>
<!-- hook target -->
<target name="statics.post" />
<!-- gen: hook targets for code generation -->
<target name="gen" depends="statics, gen.pre, gen.main, gen.post" description="Generate code artifacts" />
<target name="gen.pre" />
<target name="gen.main" />
<target name="gen.post" />
<!-- compile: Compiles the source code -->
<target name="compile" depends="gen, compile.pre, compile.main, compile.source, compile.tests, compile.post" description="Compile all source code" />
<!-- hook target -->
<target name="compile.pre" />
<!-- main compile target -->
<target name="compile.main">
<!-- copy any non-java files from the generated java source dir -->
<echo>copying generated resources</echo>
<copy todir="${target.classes.dir}">
<fileset dir="${target.gen.java.dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
<!-- copy any non-java files from the generated test java source dir -->
<echo>copying generated test resources</echo>
<copy todir="${target.testclasses.dir}" >
<fileset dir="${target.gen.java.test.dir}">
<exclude name="**/*.java" />
</fileset>
</copy>
<!-- we also redo this when we actually produce a distribution -->
<filter token="VERSION" value="${project.version}" />
<filter token="DATE" value="${DSTAMP}" />
<filter token="TIME" value="${TSTAMPCOL}" />
<copy todir="${target.classes.dir}" overwrite="false" filtering="on">
<fileset dir="${src.java.main.dir}">
<include name="**/version.txt" />
<include name="**/defaultManifest.mf" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
</target>
<target name="compile.source">
<echo>compiling main sources</echo>
<javac destdir="${target.classes.dir}" debug="${debug}" deprecation="${deprecation}" optimize="${optimize}" source="${javac.source}" target="${javac.target}">
<src path="${src.java.main.dir}" />
<src path="${target.gen.java.dir}" />
<classpath refid="compile.classpath" />
</javac>
</target>
<target name="compile.tests">
<echo>compiling test sources</echo>
<javac destdir="${target.testclasses.dir}" debug="${debug}" deprecation="${deprecation}" optimize="${optimize}" source="${javac.source}" target="${javac.target}">
<src path="${src.java.test.dir}" />
<src path="${target.gen.java.test.dir}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<path refid="test.classpath" />
</classpath>
</javac>
</target>
<!-- hook target -->
<target name="compile.post" />
<!-- jar: Creates main jar containing utility and other classes -->
<target name="jar" depends="compile, jar.pre, jar.main, jar.post" description="Create project jar containing code artifacts and other resources" />
<!-- hook target -->
<target name="jar.pre" depends="compile">
<mkdir dir="${target.lib.dir}" />
</target>
<!-- main jar target -->
<target name="jar.main">
<jar jarfile="${target.lib.dir}/${project.name}.jar">
<manifest>
<attribute name="Implementation-Vendor" value="${org.name}" />
<attribute name="Implementation-Title" value="${project.title}" />
<attribute name="Implementation-Version" value="${project.version}" />
</manifest>
<fileset dir="${target.classes.dir}">
<!-- todo, make this more selective, we don't neccessarily want to include everything here -->
</fileset>
</jar>
</target>
<target name="jar.post" />
<target name="source-zip" depends="jar">
<zip zipfile="${target.lib.dir}/${project.name}-src.zip">
<fileset dir="${src.java.main.dir}" />
<fileset dir="${target.gen.java.dir}" />
</zip>
</target>
<!-- web: Creates primary webapp in exploded format -->
<target name="web" depends="source-zip, web.pre, web.main, web.post" if="build.web" description="Create this webapp in exploded format" />
<!-- copy web statics -->
<target name="statics.web" if="build.web">
<propertyfile file="${target.filter.file}">
<entry key="PROJECT_WEBAPP_NAME" value="${project.webapp.name}" />
</propertyfile>
<!-- copy statics files for exploded webapps. This is useful for quick updating of a deployed webapp when
only statics files like images, jsps, html (no java code) change. -->
<mkdir dir="${target.war.expanded.dir}" />
<copy todir="${target.war.expanded.dir}" filtering="on">
<fileset dir="${src.web.dir}">
<patternset refid="std.files.to.filter" />
</fileset>
<filterset>
<filtersfile file="${target.filter.file}" />
</filterset>
</copy>
<!-- Disable filtering on image and pdf files -->
<copy todir="${target.war.expanded.dir}">
<fileset dir="${src.web.dir}">
<patternset refid="std.files.not.to.filter" />
</fileset>
</copy>
</target>
<!-- hook target -->
<target name="web.pre" if="build.web" />
<!-- note that we don't copy buildtime or test dependencies to WEB-INF/lib -->
<target name="web.main" if="build.web">
<antcall target="web.copy.classes" />
<antcall target="web.copy.libs" />
</target>
<!-- broken out so derived build can override which classes and libs get copied -->
<target name="web.copy.classes">
<!-- by default copy all classes -->
<copy todir="${target.war.expanded.dir}/WEB-INF/classes">
<fileset dir="${target.classes.dir}">
<include name="**/*" />
</fileset>
</copy>
</target>
<target name="web.copy.libs">
<!-- by default copy all classes -->
<copy todir="${target.war.expanded.dir}/WEB-INF/lib" flatten="true">
<fileset dir="${lib.dir}/global">
<include name="**/*.jar" />
</fileset>
</copy>
</target>
<!-- hook target -->
<target name="web.post" if="build.web" />
<!-- war: Creates primary web-app in war format -->
<target name="war" depends="web, war.pre, war.main, war.post" if="build.web" description="Create the webapp in .war format" />
<!-- hook target -->
<target name="war.pre" if="build.web" />
<!-- main war target -->
<target name="war.main" if="build.web">
<mkdir dir="${target.artifacts.war.dir}" />
<jar jarfile="${project.war}">
<fileset dir="${target.war.expanded.dir}">
<exclude name="**/*.dependency" />
</fileset>
</jar>
</target>
<!-- hook target -->
<target name="war.post" if="build.web" />
<!-- TODO: all the EJB stuff still needs to get updated for Ivy -->
<!-- exp-ear: Creates an enterprise application (EAR) in exploded format -->
<target name="ear-stage" depends="war, ear.stage.pre, ear.stage.main, ear.stage.post" if="build.j2eeapp" description="Create this enterprise application (.ear) in exploded format" />
<!-- hook target -->
<target name="ear.stage.pre" if="build.j2eeapp">
<mkdir dir="${target.ear.dir}" />
</target>
<!-- main exp-ear target -->
<target name="ear.stage.main" if="build.j2eeapp">
<!-- copy ear application.xml, replacing tokens as needed -->
<copy file="${src.dir}/application/META-INF/application.xml" tofile="${target.ear.dir}/META-INF/application.xml" filtering="on" />
<!-- copy web-apps -->
<mkdir dir="${target.artifacts.dir}/war" />
<copy todir="${target.ear.dir}">
<fileset dir="${target.artifacts.dir}/war">
<include name="${project.name}.war" />
</fileset>
</copy>
<!-- note: any EJB 2.1 ejbs are handled by ejb21-targets.xml -->
<!-- copy special log4j properties jar -->
<copy todir="${target.ear.dir}">
<fileset dir="${target.lib.dir}">
<include name="log4j-properties.jar" />
</fileset>
</copy>
<!-- copy support libs -->
<pathtofileset2 name="deps.ear.modules.fileset" pathrefid="deps.ear.modules" ignoreNonExistent="false" />
<copy todir="${target.ear.dir}" flatten="yes">
<fileset dir="${target.lib.dir}">
<include name="${project.name}.jar" />
</fileset>
<fileset refid="deps.ear.modules.fileset" />
</copy>
</target>
<!-- hook target -->
<target name="ear.stage.post" if="build.j2eeapp" />
<target name="ear" depends="ear-stage, ear.pre, ear.main, ear.post" if="build.j2eeapp" description="Create the enterprise application archive (.ear)" />
<!-- hook target -->
<target name="ear.pre" if="build.j2eeapp" />
<!-- main ear target -->
<target name="ear.main" if="build.j2eeapp">
<mkdir dir="${target.artifacts.ear.dir}" />
<ear earfile="${target.artifacts.ear.dir}/${project.name}.ear" appxml="${target.ear.dir}/META-INF/application.xml">
<fileset dir="${target.ear.dir}">
<exclude name="**/application.xml" />
</fileset>
</ear>
</target>
<!-- hook target -->
<target name="ear.post" if="build.j2eeapp" />
<!-- publish: Construct and publish the project distributables -->
<target name="publish" depends="ear, publish.setup, publish.do.publish"
description="Publish this project in the ivy repository"/>
<target name="publish.setup">
<!-- we do physical publish by default, unless do.publish property set to "false" -->
<condition property="publish.needed">
<or>
<not><isset property="do.publish"/></not>
<istrue value="${do.publish}"/>
</or>
</condition>
<!-- we clean out the deliver dir, since we don't want multiple integration versions
to end up in there -->
<delete dir="${ivy.distrib.dir}/jars" />
<delete dir="${ivy.distrib.dir}/ivys" />
<tstamp>
<format property="pubdate" pattern="yyyyMMddHHmmss" />
<!-- default value -->
</tstamp>
<mkdir dir="${ivy.distrib.dir}/jars" />
<copy file="${target.lib.dir}/${project.name}.jar" tofile="${ivy.distrib.dir}/jars/${project.name}-${project.version}.jar" />
<copy file="${target.lib.dir}/${project.name}-src.zip" tofile="${ivy.distrib.dir}/jars/${project.name}-src-${project.version}.zip" failonerror="no"/>
</target>
<target name="publish.do.publish" if="publish.needed">
<ivy:publish resolver="integration-repo" artifactspattern="${ivy.distrib.dir}/jars/[artifact]-[revision].[ext]" pubrevision="${project.version}" pubdate="${pubdate}" srcivypattern="${ivy.srcivypattern}" />
<echo message="project ${project.name} released with version ${project.version}" />
</target>
<!-- dist: Construct the project distributables, but really an alias for publish -->
<target name="dist" depends="publish, dist.pre, dist.main, dist.post" description="Create all project distributables">
</target>
<!-- hook target -->
<target name="dist.pre" />
<target name="dist.main" />
<target name="dist.post" />
<!-- javadocs: Creates the API documentation -->
<target name="javadoc" depends="build.prepare" description="Create the project API documentation">
<mkdir dir="${target.javadocs.dir}" />
<javadoc destdir="${target.javadocs.dir}" author="true" version="true" windowtitle="${project.title} ${project.version} API" doctitle="${project.title} ${project.version}" bottom="${project.copyright}"
overview="${src.java.main.dir}/overview.html">
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
<path refid="compile.classpath"/>
</classpath>
<sourcepath>
<pathelement location="${src.java.main.dir}" />
</sourcepath>
<packageset dir="${src.java.main.dir}">
<include name="**/*" />
</packageset>
</javadoc>
</target>
<!-- run: allows arbitrary java code to be run -->
<target name="run" depends="init,guard.runclass" description="Run a java application">
<java classname="${run.class}" fork="true">
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
<path refid="test.classpath" />
</classpath>
</java>
</target>
<target name="guard.runclass" unless="run.class">
<fail message="The target you are attempting to run requires the ${run.class} property to be set, which doesn't appear to be" />
</target>
<!-- runp: allows arbitrary java code to be run, prompting for arguments -->
<target name="run-with-arguments" depends="init,guard.runclass" description="Run a java application with arguments">
<input message="Please enter arguments:" addproperty="run.arguments" />
<java classname="${run.class}" fork="true">
<arg line="${run.arguments}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
<path refid="test.classpath" />
</classpath>
</java>
</target>
<!-- classicvm: call before any other targets if you want to run unit tests with classic vm -->
<target name="classicvm">
<property name="unitvm" value="-classic" />
</target>
<!-- jvm arguments we want tacked on to all unit tests -->
<!-- set fake default value, will not override existing setting -->
<property name="test.arguments" value="-Dzzz456zzz" />
<target name="tests.prepare" depends="compile" unless="tests.prepare.done">
<mkdir dir="${target.testresults.dir}" />
<delete>
<fileset dir="${target.testresults.dir}" includes="**/*.txt,**/*.log" />
</delete>
<property name="tests.prepare.done" value="true" />
</target>
<!-- automatically runs all the junit tests. -->
<target name="tests" depends="tests-local" description="Runs all tests, first local then server (if any)">
<!-- add code here to run server unit tests if there are any -->
<!-- this usually involves starting up the server, and in parallel running tests against it -->
</target>
<!-- automatically runs all the junit tests, with compile dependencies. -->
<target name="tests-dist" depends="dist, tests" description="Run all tests after creating a project distribution" />
<!-- Runs the local unit tests. -->
<target name="tests-local" depends="tests.prepare" description="Run all local tests">
<!-- for the time being we just halt on failure, since these are
local tests and there is no server to shut down, etc. But if
we want to optionally run all tests and report on the whole
batch, then we need to set a failure property as in the server
tests. -->
<junit forkmode="perBatch" printsummary="yes" haltonfailure="no" haltonerror="no"
dir="${basedir}">
<jvmarg value="${unitvm}" />
<jvmarg value="-Djava.security.auth.login.config=${target.testclasses.dir}/auth.conf" />
<jvmarg value="${test.arguments}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
<pathelement location="${target.genclasses.dir}" />
<path refid="test.classpath" />
</classpath>
<formatter type="plain" />
<formatter type="xml" />
<batchtest fork="yes" todir="${target.testresults.dir}">
<fileset dir="${target.testclasses.dir}" includes="${test.includes}" excludes="${test.excludes}" />
</batchtest>
</junit>
</target>
<!-- runs one local unit test -->
<target name="test" depends="guard.testclass,tests.prepare" description="Runs one local test using the value of the test.class property">
<junit forkmode="perBatch" printsummary="yes" haltonfailure="no" haltonerror="no">
<jvmarg value="${unitvm}" />
<jvmarg value="-Djava.security.auth.login.config=${target.testclasses.dir}/auth.conf" />
<jvmarg value="${test.arguments}" />
<classpath>
<pathelement location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
<pathelement location="${target.genclasses.dir}" />
<path refid="test.classpath" />
</classpath>
<formatter type="plain" />
<formatter type="xml" />
<!-- the test case -->
<test name="${test.class}" todir="${target.testresults.dir}" />
</junit>
</target>
<target name="guard.testclass" unless="test.class">
<fail message="The target you are attempting to run requires the ${test.class} property to be set, which doesn't appear to be" />
</target>
<!--
test-example - a sample unit test
shows how to make a target to run just one specific unit test instead
of having to specify the class
It can get a lot more elaborate than this, with various properties being
set up, etc. Property files can be written out, etc.
<target name="test.example" depends="init">
<antcall target="test">
<param name="test.class" value="com.mycompany.myproject.MyTest"/>
</antcall>
</target>
-->
</project>

140
common-build/db-targets.xml Normal file
View File

@@ -0,0 +1,140 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Colin Sampaleanu
Author: Keith Donald
Ant XML fragment that contains useful targets for working with databases. These
include targets to load the project db schema and test data, as well as export a
dbunit dtd to facilitate validating xml test data documents.
This fragment is meant to be imported into a project build file, along with
common-targets.xml, in order to provide build handling for basic db-properties and
operations. This is an optional module, and due to the way the ant import works,
there is no way to automatically hook this up into the build. The importing project
must override appropropriate 'hook' targets from common-targets.xml, and then have
the override targets depend on both the targets from common-targets and those from here.
-->
<project name="db-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml" />
<!-- db.task.init: not to be called directly, but needed by other targets -->
<target name="db.task.init" depends="dbunit.presetdef.schema,
dbunit.presetdef.noschema,
retrieve">
<property name="src.db.dir" value="${src.etc.dir}/db"/>
<property name="target.db.dir" value="${target.dir}/db"/>
<presetdef name="my.sql">
<sql driver="${database.driver}" url="${database.url}" userid="${database.username}" password="${database.password}" classpathref="test.classpath" />
</presetdef>
<presetdef name="my.sqladmin">
<sql driver="${database.driver}" url="${database.url}" userid="${database.admin.username}" password="${database.admin.password}" classpathref="test.classpath" />
</presetdef>
</target>
<target name="dbunit.presetdef.schema" if="database.schema">
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask" classpathref="test.classpath" />
<presetdef name="my.dbunit">
<dbunit driver="${database.driver}" url="${database.url}" schema="${database.schema}"
userid="${database.username}" password="${database.password}">
<classpath>
<path refid="test.classpath" />
<pathelement location="${src.test.resources.dir}" />
</classpath>
</dbunit>
</presetdef>
</target>
<target name="dbunit.presetdef.noschema" unless="database.schema">
<taskdef name="dbunit" classname="org.dbunit.ant.DbUnitTask" classpathref="test.classpath" />
<presetdef name="my.dbunit">
<dbunit driver="${database.driver}" url="${database.url}"
userid="${database.username}" password="${database.password}">
<classpath>
<path refid="test.classpath" />
<pathelement location="${src.test.resources.dir}" />
</classpath>
</dbunit>
</presetdef>
</target>
<target name="db-schema-create" depends="db.task.init" description="Load the project schema (tables) into the database">
<property name="sql.src" value="${src.db.dir}/schema.sql" />
<antcall target="db-sql">
<param name="onerror" value="continue" />
<param name="autocommit" value="true" />
</antcall>
</target>
<target name="db-user-create" depends="db.task.init" description="Create the project schema tablespaces and user">
<property name="sql.src" value="${target.testclasses.dir}/create-user.sql" />
<antcall target="db-sql-admin">
<param name="onerror" value="continue" />
<param name="autocommit" value="true" />
</antcall>
</target>
<target name="db-schema-dtd" depends="db.task.init" description="Export db unit dtd for testdata file">
<mkdir dir="${target.db.dir}" />
<my.dbunit>
<export dest="${target.db.dir}/schema.dtd" format="dtd" />
</my.dbunit>
</target>
<target name="db-data-load" depends="db.task.init" description="Load all data contained in a file to the database">
<property name="db.data.file" value="${src.db.dir}/data.xml" />
<my.dbunit>
<operation type="CLEAN_INSERT" src="${db.data.file}" />
</my.dbunit>
</target>
<target name="db-sql" depends="guard.sqlsrc, db.task.init" description="Execute sql statements stored in the file defined by the ${sql.src} property">
<property name="onerror" value="stop" />
<property name="autocommit" value="false" />
<echo>User sql.src = '${sql.src}'</echo>
<my.sql src="${sql.src}" onerror="${onerror}" autocommit="${autocommit}">
<classpath>
<path refid="test.classpath" />
<pathelement location="${src.test.resources.dir}" />
</classpath>
</my.sql>
</target>
<target name="db-sql-admin" depends="guard.sqlsrc, guard.admin, db.task.init" description="Execute sql statements stored in the file defined by the ${sql.src} property">
<property name="onerror" value="stop" />
<property name="autocommit" value="false" />
<echo>Admin sql.src = '${sql.src}'</echo>
<my.sqladmin src="${sql.src}" onerror="${onerror}" autocommit="${autocommit}">
<classpath>
<path refid="test.classpath" />
<pathelement location="${src.test.resources.dir}" />
</classpath>
</my.sqladmin>
</target>
<target name="guard.sqlsrc" unless="sql.src">
<fail message="The target you are attempting to run requires the ${sql.src} property to be set, but it doesn't appear to be" />
</target>
<target name="guard.admin" unless="database.admin.username">
<fail message="The target you are attempting to run requires the ${database.admin.username} property to be set, but it doesn't appear to be. Since this is a local admin property, define it in a local (secured) build.properties file" />
</target>
</project>

View File

@@ -0,0 +1,157 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Alef Arendsen
Targets for generating reference documentation.
-->
<project name="doc-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml" />
<target name="doc-targets">
<echo>
Targets for generating reference documentation.
Please execute
ant -p
to see a list of all relevant targets.
</echo>
</target>
<target name="doc-clean" description="Delete temporary directories for reference docs">
<delete quiet="true" dir="${docs.ref.target.dir}" />
</target>
<target name="doc-prepare">
<fail message="Supporting libraries needed to generate documentation not found in: ${docs.ref.lib.dir}, please see docs/reference/readme.txt for instructions.">
<condition>
<not>
<available file="${docs.ref.lib.dir}" />
</not>
</condition>
</fail>
<copy todir="${docs.ref.target.dir}/images">
<fileset dir="${docs.ref.dir}/images">
<include name="*.gif" />
<include name="*.png" />
<include name="*.svg" />
<include name="*.jpg" />
</fileset>
<fileset dir="${docs.ref.dir}/images">
<include name="**/*.gif" />
<include name="**/*.png" />
<include name="**/*.svg" />
<include name="**/*.jpg" />
</fileset>
</copy>
</target>
<target name="doc-pdf" depends="doc-prepare" description="Generate PDF reference documentation">
<mkdir dir="${docs.ref.target.dir}/pdf/images" />
<copy todir="${docs.ref.target.dir}/pdf/images">
<fileset dir="${docs.ref.src.dir}/images">
<include name="*.gif" />
<include name="*.png" />
<include name="*.svg" />
<include name="*.jpg" />
</fileset>
</copy>
<java classname="com.icl.saxon.StyleSheet" fork="true" dir="${docs.ref.dir}">
<classpath>
<fileset dir="${docs.ref.lib.dir}">
<include name="**/*.jar" />
</fileset>
</classpath>
<arg value="-o" />
<arg value="${docs.ref.target.dir}/pdf/docbook_fop.tmp" />
<arg value="${docs.ref.src.dir}/index.xml" />
<arg value="${docs.ref.dir}/styles/fopdf.xsl" />
</java>
<java classname="org.apache.fop.apps.Fop" fork="true" maxmemory="256m" dir="${docs.ref.dir}">
<classpath>
<fileset dir="${docs.ref.lib.dir}">
<include name="**/*.jar" />
</fileset>
</classpath>
<arg value="-d"/>
<arg value="${docs.ref.target.dir}/pdf/docbook_fop.tmp" />
<arg value="${docs.ref.target.dir}/pdf/${ant.project.name}-reference.pdf" />
</java>
<delete file="${docs.ref.target.dir}/pdf/docbook_fop.tmp" />
</target>
<target name="doc-html" depends="doc-prepare" description="Generate multi-page HTML reference documentation">
<mkdir dir="${docs.ref.target.dir}/html/images" />
<mkdir dir="${docs.ref.target.dir}/html_single/styles" />
<copy todir="${docs.ref.target.dir}/html/images">
<fileset dir="${docs.ref.src.dir}/images">
<include name="*.gif" />
<include name="*.png" />
<include name="*.svg" />
<include name="*.jpg" />
</fileset>
</copy>
<copy todir="${docs.ref.target.dir}/html/styles" file="${docs.ref.dir}/styles/html.css"/>
<java classname="com.icl.saxon.StyleSheet" fork="true" dir="${docs.ref.target.dir}/html">
<classpath>
<fileset dir="${docs.ref.lib.dir}">
<include name="**/*.jar" />
</fileset>
</classpath>
<arg value="${docs.ref.src.dir}/index.xml" />
<arg value="${docs.ref.dir}/styles/html_chunk.xsl" />
</java>
<delete file="${docs.ref.target.dir}/html/docbook_fop.tmp" />
</target>
<target name="doc-htmlsingle" depends="doc-prepare" description="Generate single-page HTML reference documentation">
<mkdir dir="${docs.ref.target.dir}/html_single/images" />
<mkdir dir="${docs.ref.target.dir}/html_single/styles" />
<copy todir="${docs.ref.target.dir}/html_single/images">
<fileset dir="${docs.ref.src.dir}/images">
<include name="*.gif" />
<include name="*.png" />
<include name="*.svg" />
<include name="*.jpg" />
</fileset>
</copy>
<copy todir="${docs.ref.target.dir}/html_single/styles" file="${docs.ref.dir}/styles/html.css"/>
<java classname="com.icl.saxon.StyleSheet" fork="true" dir="${docs.ref.target.dir}/html_single">
<classpath>
<fileset dir="${docs.ref.lib.dir}">
<include name="**/*.jar" />
</fileset>
</classpath>
<arg value="-o" />
<arg value="${docs.ref.target.dir}/html_single/index.html" />
<arg value="${docs.ref.src.dir}/index.xml" />
<arg value="${docs.ref.dir}/styles/html.xsl" />
</java>
<delete file="${docs.ref.target.dir}/htmlsingle/docbook_fop.tmp" />
</target>
<target name="doc-all" depends="doc-html,doc-htmlsingle,doc-pdf" description="Generate reference documentation in all formats" />
</project>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Colin Sampaleanu
This ant XML fragment is meant to be imported into a project build file, along with
common-targets.xml, in order to provide build handling for EJB 2.1 format EJBs. This
is an optional module, and due to the way the ant import works, there is no way to
automatically hook this up into the build. The importing project must override
appropropriate 'hook' targets from common-targets.xml, and then have the override
targets depend on both the targets from common-targets and those from here.
TODO: this is currently not finished. It is in the process of being re-organized due
to use of Ivy.
-->
<project name="ejb21" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml" />
<!--
init: this target must be hooked up to after common-targets.init
-->
<target name="init">
<!-- where ejbs go -->
<property name="target.ejb.dir" value="${target.artifacts.dir}/ejb" />
<!-- where any exploded ejbs go -->
<property name="target.ear.expanded.dir" value="${target.artifacts.dir}/ejb-expanded/primary" />
<!-- where deployment descriptors go -->
<property name="target.ear.expanded.descriptor.dir" value="${target.ear.expanded.dir}/META-INF" />
</target>
<!--
copy-target-ejbs: copies ejbs from target.ejb.dir where something like XDoclet
has produced them, into target.expear.dir
This target must be hooked up to run before or after common-targets.ear.stage.main
-->
<target name="copy.target.ejbs" if="build.j2eeapp">
<!-- copy ejb modules -->
<mkdir dir="${target.ejb.dir}" />
<copy todir="${target.ear.expanded.dir}">
<fileset dir="${target.ejb.dir}">
<include name="*.jar" />
</fileset>
</copy>
</target>
</project>

View File

@@ -0,0 +1,127 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Colin Sampaleanu
Author: Keith Donald
Ant XML fragment that contains useful targets for working with hibernate. These
include targets to generate hibernate mappings from xdoclet attributes, as well as
export a database schema from the mappings.
This ant XML fragment is meant to be imported into a project build file, along with
common-targets.xml. This is an optional module, and due to the way the ant import works,
there is no way to automatically hook this up into the build. The importing project
must override appropropriate 'hook' targets from common-targets.xml, and then have
the override targets depend on both the targets from common-targets and those from here.
-->
<project name="hibernate-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml" />
<!-- hooks: these are not optional! -->
<!-- you must hook build.prepare -->
<target name="build.prepare" depends="common-targets.build.prepare">
<!-- Make sure hibernatedoclet is necessary -->
<uptodate property="hibernatedoclet.unnecessary">
<srcfiles dir="${src.java.main.dir}" includes="**/*.java" />
<srcfiles dir="${target.gen.java.dir}" includes="**/*.java" />
<mapper type="glob" from="*.java" to="${target.classes.dir}/*.class" />
</uptodate>
<propertyfile file="${target.filter.file}">
<entry key="HIBERNATE_DIALECT" value="${hibernate.dialect}" />
<entry key="HIBERNATE_SHOW_SQL" value="${hibernate.show.sql}" />
</propertyfile>
<path id="xdoclet.classpath">
<path refid="test.classpath" />
</path>
<path id="hibernate.classpath">
<path refid="test.classpath" />
<path location="${target.classes.dir}" />
<pathelement location="${target.testclasses.dir}" />
</path>
</target>
<!-- you must hook statics! -->
<target name="statics" depends="common-targets.statics">
<antcall target="hibernatedoclet" />
</target>
<!-- end of hooks -->
<!-- hibernatedoclet: generates Hibernate mapping files based on XDoclet marked-up Plain Old Java Object (POJO) -->
<target name="hibernatedoclet" depends="hibernate.task.init" if="use.hibernatedoclet" unless="hibernatedoclet.unnecessary" description="Generate Persistence and form classes">
<taskdef name="hibernatedoclet" classname="xdoclet.modules.hibernate.HibernateDocletTask" classpathref="xdoclet.classpath" />
<!-- generate hibernate files -->
<hibernatedoclet destdir="${target.gen.java.dir}" mergedir="${src.etc.dir}/merge" excludedtags="@version,@author" addedtags="@xdoclet-generated at ${TODAY}" force="${xdoclet.force}">
<fileset dir="${src.java.main.dir}" />
<hibernate validatexml="true" version="3.0" />
</hibernatedoclet>
</target>
<target name="hibernate.task.init" depends="retrieve">
<taskdef name="schemaexport" classname="org.hibernate.tool.hbm2ddl.SchemaExportTask">
<classpath>
<path refid="xdoclet.classpath" />
<path refid="hibernate.classpath" />
</classpath>
</taskdef>
</target>
<!-- db-init: generates the database schema and creates tables based on the mapping files -->
<target name="hibernate-schema-create" depends="hibernate.task.init, statics" description="Creates database tables from hibernate mapping files">
<mkdir dir="${target.dir}/db" />
<antcall target="generate.hibernate.properties" />
<schemaexport quiet="no" text="no" drop="no" delimiter=";" properties="${target.dir}/db/database.properties" output="${target.dir}/db/hib-schema.sql">
<fileset dir="${target.classes.dir}" includes="**/*.hbm.xml" />
</schemaexport>
</target>
<!-- db-init: drops the database tables -->
<target name="hibernate-schema-drop" depends="hibernate.task.init, statics" description="Drop database tables created by Hibernate's schema export">
<mkdir dir="${target.dir}/db" />
<antcall target="generate.hibernate.properties" />
<schemaexport quiet="no" text="no" drop="yes" delimiter=";" properties="${target.dir}/db/database.properties" output="${target.dir}/db/hib-drop-tables.sql">
<fileset dir="${target.classes.dir}" includes="**/*.hbm.xml" />
</schemaexport>
</target>
<!-- this task is called by tasks that need it in build.xml -->
<target name="generate.hibernate.properties">
<echo>generating database.properties from build.properties</echo>
<propertyfile comment="Hibernate Configuration for targets from db-targets.xml" file="${target.dir}/db/database.properties">
<entry key="hibernate.connection.driver_class" value="${database.driver}" />
<entry key="hibernate.connection.url" value="${database.url}" />
<entry key="hibernate.connection.username" value="${database.username}" />
<entry key="hibernate.connection.password" value="${database.password}" />
<entry key="hibernate.dialect" value="${hibernate.dialect}" />
<entry key="hibernate.connection.show_sql" value="${hibernate.show.sql}" />
</propertyfile>
<property file="database.properties" />
</target>
</project>

View File

@@ -0,0 +1,2 @@
repository.dir=${ivy.conf.dir}/../repository
integration.repo.dir=${ivy.conf.dir}/../integration-repo

89
common-build/ivyconf.xml Normal file
View File

@@ -0,0 +1,89 @@
<ivyconf>
<properties file="${ivy.conf.dir}/ivyconf.properties"/>
<conf defaultResolver="maven2"/>
<resolvers>
<chain name="spring-projects" returnFirst="true">
<!-- try developer's local integration repository first -->
<filesystem name="integration-repo">
<ivy pattern="${integration.repo.dir}/artifacts/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${integration.repo.dir}/artifacts/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</filesystem>
<!-- try shared local filesystem repository second -->
<filesystem name="filesystem-repo">
<ivy pattern="${repository.dir}/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="${repository.dir}/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</filesystem>
<!-- pull from the main release repository third -->
<url name="spring-repo" m2compatible="true">
<ivy pattern="https://svn.sourceforge.net/svnroot/springframework/repos/repo/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="https://svn.sourceforge.net/svnroot/springframework/repos/repo/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<!-- if still not resolved, try snapshots -->
<url name="spring-repo-snapshots" m2compatible="true">
<ivy pattern="https://svn.sourceforge.net/svnroot/springframework/repos/repo-snapshots/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="https://svn.sourceforge.net/svnroot/springframework/repos/repo-snapshots/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
</chain>
<chain name="maven2" returnFirst="true">
<!-- try shared local filesystem repository first -->
<filesystem name="filesystem-repo">
<ivy pattern="${repository.dir}/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="${repository.dir}/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</filesystem>
<!-- if still not resolved, try external repo -->
<url name="spring-repo-ext" m2compatible="true">
<ivy pattern="https://svn.sourceforge.net/svnroot/springframework/repos/repo-ext/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="https://svn.sourceforge.net/svnroot/springframework/repos/repo-ext/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]" />
</url>
<!-- try popular maven2 ibiblio mirror second -->
<ibiblio name="dotsrc-maven2-repo" checkconsistency="false" m2compatible="true" root="http://mirrors.dotsrc.org/maven2/"/>
<!-- try ibiblio itself third -->
<ibiblio name="ibiblio-maven2-repo" checkconsistency="false" m2compatible="true" root="http://www.ibiblio.org/maven2/"/>
</chain>
</resolvers>
<modules>
<!-- Pointing modules at local resolvers speeds resolution performance -->
<module organisation="org.springframework" name="spring-aop" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-beans" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-binding" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-context" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-core" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-dao" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-hibernate2" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-hibernate3" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-ibatis" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-jca" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-jdbc" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-jdo" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-jms" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-jmx" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-jpa" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-mock" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-obj" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-orm" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-oxm" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-portlet" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-remoting" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-struts" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-support" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-toplink" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-web" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-webflow" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-webmvc" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-ws-core" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-ws-security" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-xml" resolver="spring-projects"/>
<module organisation="org.springframework" name="spring-ldap" resolver="spring-projects"/>
<module organisation="org.springframework" name="various" resolver="spring-projects"/>
</modules>
</ivyconf>

Binary file not shown.

View File

@@ -0,0 +1,135 @@
# values in here are overriden by build.properties and project.properties in
# individual projects, and build.properties in this dir, in that order
# default wildcard for finding JUnit tests
# the convention is that our JUnit test classes have XXXTests-style names
test.includes=**/*Test.class,**/*Tests.class
# wildcards to exclude among JUnit tests
test.excludes=**/Abstract*
# we define standard directory locations here
# these should not normally never have to be overriden
# we define them here instead of in the XML so that Ant nested property
# replacement can work for properties overrides by other properties files
# root of any bin files needed during build
bin.dir=${basedir}/bin
# libs needed for build process. ivy pulls down jars into various dirs under here
lib.dir=${basedir}/lib
# any static libs that need to be checked in instead of being pulled down by ivy
# should be placed somehwere under here. The standard build doesn't touch this though
static.lib.dir=${basedir}/static-lib
# root of sources hierarchy
src.dir=${basedir}/src
# main sources
src.java.main.dir=${src.dir}/main/java
# test sources
src.java.test.dir=${src.dir}/test/java
# root of web-apps sources
src.web.dir=${basedir}/src/main/webapp
# root of source doc files
src.doc.dir=${basedir}/src/doc
# root of etc hierarchy, typically used for templated sources and config files
src.etc.dir=${basedir}/src/etc
# resources get copied into target classes dir with filtering
src.resources.dir=${src.dir}/main/resources
src.dtd.dir=${src.etc.dir}/dtd
src.tld.dir=${src.etc.dir}/tld
# test resources get copied into target test classes dir with filtering
src.test.resources.dir=${src.etc.dir}/test-resources
# root of build hierarchy
target.dir=${basedir}/target
# any generated java sources go here
target.gen.java.dir=${target.dir}/gen-java-src
target.gen.java.test.dir=${target.dir}/gen-java-test-src
# where built source class files and resources go
target.classes.dir=${target.dir}/classes
# where built test class files and resources go
target.testclasses.dir=${target.dir}/test-classes
# where test results end up
target.testresults.dir=${target.dir}/test-reports
# where JavaDoc generate files go
target.javadocs.dir=${target.dir}/javadocs
# where J2SE/J2EE modules (.jar, .war, .ear) go
target.artifacts.dir=${target.dir}/artifacts
# where target lib archives (.JARs) go
target.lib.dir=${target.artifacts.dir}/lib
# where WAR archive goes
target.artifacts.war.dir=${target.artifacts.dir}/war
# where EAR archive goes
target.artifacts.ear.dir=${target.artifacts.dir}/ear
# where any exploded web-app goes
target.war.expanded.dir=${target.artifacts.dir}/war-expanded
# where any exploded EAR goes
target.ear.expanded.dir=${target.artifacts.dir}/ear-expanded
# file used to provide token filter values during text file copies
target.filter.file=${target.dir}/filter.properties
# where all project documentation resides
docs.dir=${basedir}/docs
# where all project reference documentation resides
docs.ref.dir=${docs.dir}/reference
# where all project reference documentation sources reside
docs.ref.src.dir=${docs.dir}/reference/src
# where all DocBook libraries reside
docs.ref.lib.dir=${docs.dir}/reference/lib
# where the project reference documentation is built
docs.ref.target.dir=${docs.dir}/reference/target
# where the dist target is saved
dist.dir=${target.dir}/dist
# sample: set proper packages here, for javadocs
packages=stub.*
# override default ivy retrieve pattern to include configuration name in path, and no
# revision number The main advantage of no revision number in the name is that when pulling
# down subsequent snapshots of the same jar, a newer one will just overwrite a previous
# version. This means we are not forced to clean the lib dir between retrieves.
ivy.retrieve.pattern=${lib.dir}/[conf]/[artifact].[ext]
# To add the revision, comment out the previous, and add next 2 to build.properties
# clear.libs.before.retrieve=anything
# ivy.retrieve.pattern=${lib.dir}/[conf]/[artifact]-[revision].[ext]
# now define patterns for special retrieve used to build repo for release
release.repo.ivy.retrieve.pattern=[organisation]/[module]/[revision]/[artifact]-[revision].[ext]
release.repo.ivy.retrieve.ivy.pattern=[organisation]/[module]/ivy-[revision].xml
# override default ivy distrib dir to go under targets
ivy.distrib.dir=${target.dir}/dist
# override where ivy.xml files are placed, so they are hierarchical and are safe
# to merge from multiple projects
ivy.srcivypattern=${ivy.distrib.dir}/ivys/[organisation]/[module]/ivy-[revision].xml
# Location where temporary data goes. Only used for Oracle-specific create-user script
# needs to be customized for the user if location is not appropriate, or always for unix
data.dir=c:\\temp

37
common-build/readme.txt Normal file
View File

@@ -0,0 +1,37 @@
Contained in this directory is the Spring Jumpstart common build system used
to build all Spring projects.
This generic build system is ant 1.6 based and also requires Ivy 1.3 or > for dependency management.
Projects are expected to import master build files contained within
this directory as needed for the build targets they require.
Build targets are organized into logical files:
- common-targets.xml : core targets applicable to all projects
- clover-targets.xml : for working with clover
- tomcat-targets.xml : for deploying webapps to the tomcat servlet container
etc...
As an example, here is Spring Web Flow's project build.xml:
<project name="spring-webflow" default="dist">
<property file="build.properties"/>
<property file="project.properties"/>
<property file="${common.build.dir}/build.properties"/>
<property file="${common.build.dir}/project.properties"/>
<property file="${user.home}/build.properties"/>
<property name="project.title" value="Spring Web Flow"/>
<property name="project.package" value="org.springframework.webflow"/>
<import file="${common.build.dir}/common-targets.xml"/>
<import file="${common.build.dir}/clover-targets.xml"/>
</project>
This build.xml imports the "common-targets.xml" fragment containing
core targets for compilation, distribution unit creation, and junit
testing. It also imports "clover-targets.xml" to facilitate the
generation of test coverage reports with clover.

View File

@@ -0,0 +1,49 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Keith Donald
-->
<project name="spring-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml"/>
<target name="spring-beandoc" depends="init" description="Generate Spring bean documentation">
<property name="spring.beandoc.input.files" value="${src.web.dir}/WEB-INF/applicationContext.xml"/>
<property name="spring.beandoc.output.dir" value="${target.artifacts.dir}/beandoc/"/>
<property name="spring.beandoc.properties" value="${common.build.dir}/beandoc.properties"/>
<mkdir dir="${spring.beandoc.output.dir}"/>
<path id="beandoc.classpath">
<path refid="test.classpath"/>
</path>
<taskdef name="beandoc" classname="org.springframework.beandoc.client.AntTask">
<classpath refid="beandoc.classpath"/>
</taskdef>
<beandoc
inputFiles="${spring.beandoc.input.files}"
outputDir="${spring.beandoc.output.dir}"
beandocProps="${spring.beandoc.properties}"
/>
</target>
</project>

View File

@@ -0,0 +1,5 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE dataset SYSTEM "schema.dtd">
<dataset>
<!-- table data rows go here -->
</dataset>

View File

@@ -0,0 +1,5 @@
<div id="copyright">
<p>&copy; Copyright 2006, <a href="http://www.springframework.org">www.springframework.org</a>, under the terms of the Apache 2.0 software license.</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,22 @@
<%@ page contentType="text/html" %>
<%@ page session="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>@TITLE@</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="style.css" type="text/css">
</head>
<body>
<div id="logo">
<img src="images/spring-logo.jpg" alt="Logo" border="0">
</div>
<div id="navigation">
</div>

View File

@@ -0,0 +1,7 @@
<%@ include file="includeTop.jsp" %>
<div id="content">
</div>
<%@ include file="includeBottom.jsp" %>

View File

@@ -0,0 +1,19 @@
log4j.rootCategory=WARN, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${@PROJECT_NAME@.root}/@PROJECT_NAME@.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
#Pattern to output : date priority [category] - <message>line_separator
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n
# Enable debug interceptor
#log4j.category.org.springframework.aop.interceptor=DEBUG

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry output="target/classes" kind="src" path="src/java"/>
<classpathentry output="target/test-classes" kind="src" path="src/test"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/global/commons-logging.jar"/>
<classpathentry kind="lib" path="lib/global/log4j.jar"/>
<classpathentry kind="lib" path="lib/global/spring.jar"/>
<classpathentry kind="lib" path="lib/test/easymock.jar"/>
<classpathentry kind="lib" path="lib/test/junit.jar"/>
<classpathentry kind="lib" path="lib/test/spring-mock.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,8 @@
target
lib
bak
build.properties
*.log
*.jpx.local*
*.iws
*.tws

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>@PROJECT_NAME@</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<project name="@PROJECT_NAME@" default="dist">
<!-- you may override default properties for the build by using entries
in a build.properties file, or by just adding 'property' elements
here, before the following properties files are loaded -->
<property file="build.properties"/>
<property file="project.properties"/>
<property file="${common.build.dir}/build.properties"/>
<property file="${common.build.dir}/project.properties"/>
<property file="${user.home}/build.properties"/>
<import file="${common.build.dir}/common-targets.xml"/>
<!-- import clover support -->
<import file="${common.build.dir}/clover-targets.xml"/>
</project>

View File

@@ -0,0 +1,35 @@
<ivy-module version="1.1">
<info organisation="@ORGANISATION@" module="@PROJECT_NAME@"/>
<configurations>
<!-- default configuration that 'by default' pulls in the global configuration -->
<conf name="default" extends="global"/>
<!-- core dependencies needed at compile-time, test-time, and runtime -->
<conf name="global" visibility="private"/>
<!-- additional dependencies needed only at build-time -->
<conf name="buildtime" visibility="private"/>
<!-- additional dependencies needed only at test-time -->
<conf name="test" visibility="private"/>
</configurations>
<dependencies defaultconf="global->default">
<!-- global (compile, test, runtime) dependencies -->
<dependency org="apache" name="commons-logging" rev="1.1"/>
<dependency org="apache" name="log4j" rev="1.2.13"/>
<dependency org="org.springframework" name="spring-beans" rev="2.0-rc3"/>
<dependency org="org.springframework" name="spring-core" rev="2.0-rc3"/>
<dependency org="org.springframework" name="spring-context" rev="2.0-rc3"/>
<!-- build time only dependencies -->
<!-- test time only dependencies -->
<dependency org="easymock" name="easymock" rev="1.1" conf="test->default"/>
<dependency org="cenqua" name="clover" rev="1.3.11" conf="test->default"/>
<dependency org="junit" name="junit" rev="3.8.1" conf="test->default"/>
<dependency org="springframework" name="spring-mock" rev="2.0-rc3" conf="test->default"/>
</dependencies>
</ivy-module>

View File

@@ -0,0 +1,5 @@
# to override these or other properties with local user settings,
# create a unversioned build.properties file
# The location of the common build system
common.build.dir=${basedir}/../common-build

View File

@@ -0,0 +1,33 @@
# $Header$
# Contains filterable project settings. Setting placeholders in filterable project text
# files will be replaced with these values when the 'statics' build target is run.
#
# You may add static settings directly to this source file in the format:
# setting=value e.g MY_SETTING=myvalue
# This is appropriate usage if you know the setting value will never change.
#
# At build time this source file is copied to the ${target.dir} where additional
# dynamic settings may be appended using the <propertyfile> task. Use this approach
# when a setting value depends on the build or the local user's environment.
#
# An example of this approach is shown below:
#
# build.xml
# <target name="build.prepare" depends="common-targets.build.prepare">
# <!-- Append additional local settings that are applicable to this project -->
# <propertyfile file="${target.filter.file}">
# <!-- key=the name of the setting
# value=the property in your build.properties file that has the local setting value -->
# <entry key="MY_LOCAL_SETTING" value="${my.local.setting}" />
# </propertyfile>
# </target>
#
# This allows for dynamic replacement values that are sourced from local properties files to facilitate
# local user settings.
#
# To refer to filterable settings within project source files like config files, JSPs, or
# other text files use the standard ant placeholder format:
# @SETTING_NAME@ e.g, @MY_SETTING@ and @MY_LOCAL_SETTING@
#
# Your settings:

View File

@@ -0,0 +1,16 @@
log4j.rootCategory=WARN, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${@PROJECT_NAME@.root}/@PROJECT_NAME@.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
#Pattern to output : date priority [category] - <message>line_separator
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n

View File

@@ -0,0 +1,5 @@
test-resources
---------
Test-time related configuration files (*.properties, *.xml) and other resources reside in this directory. These files are copied into the test classpath, they are not included in the project distribution unit.
You may remove this file once you understand the project structure and the purpose of this directory: this file also serves as a "empty directory" placeholder so CVS won't prune the directory.

View File

@@ -0,0 +1,5 @@
java
------
Project source code resides in this directory. Files here are compiled into classes placed in ${project.dir}/target/classes and added to the compile classpath.
You may remove this file once you understand the project structure and the purpose of this directory: this file also serves as a "empty directory" placeholder so CVS won't prune the directory.

View File

@@ -0,0 +1,5 @@
resources
---------
Tweakable application configuration files (*.properties) and other resources reside in this directory.
You may remove this file once you understand the project structure and the purpose of this directory: this file also serves as a "empty directory" placeholder so CVS won't prune the directory.

View File

@@ -0,0 +1,5 @@
test
------
Project unit and integration tests reside within this directory. Files here are compiled into classes placed in ${project.dir}/target/test-classes and added to the test classpath.
You may remove this file once you understand the project structure and the purpose of this directory: this file also serves as a "empty directory" placeholder so CVS won't prune the directory.

View File

@@ -0,0 +1,19 @@
log4j.rootCategory=WARN, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=${@PROJECT_NAME@.root}/@PROJECT_NAME@.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
#Pattern to output : date priority [category] - <message>line_separator
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n
# Enable debug interceptor
#log4j.category.org.springframework.aop.interceptor=DEBUG

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<!--
- Location of the Spring bean definition files, for initialization of
- root spring application context
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
<!-- Service layer config files go here, space delimited -->
</param-value>
</context-param>
<!--
- Load the spring root application context from the paths define by
- the contextConfigLocation param.
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>@PROJECT_NAME@</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>@PROJECT_NAME@</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>

View File

@@ -0,0 +1,10 @@
<html>
<head>
<title>Shell</title>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,2 @@
Contained in this directory are useful templates for projects, configuration files,
and Java artifacts for products such as Spring, Spring Web Flow, and log4j.

View File

@@ -0,0 +1,24 @@
package webflow.templates;
import java.util.Map;
import org.springframework.webflow.definition.registry.FlowDefinitionResource;
import org.springframework.webflow.test.execution.AbstractXmlFlowExecutionTests;
import org.springframework.webflow.test.execution.MockFlowServiceLocator;
public class FlowExecutionTestTemplate extends AbstractXmlFlowExecutionTests {
public void testStartFlow() {
}
@Override
protected FlowDefinitionResource getFlowDefinitionResource() {
return createFlowDefinitionResource("/path/to/myflow.xml");
}
@Override
protected void registerMockServices(MockFlowServiceLocator serviceRegistry) {
}
}

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
<start-state idref="displayForm"/>
<view-state id="displayForm" view="form">
<render-actions>
<action bean="formAction" method="setupForm"/>
</render-actions>
<transition on="submit" to="finish">
<action bean="formAction" method="bindAndValidate"/>
</transition>
</view-state>
<end-state id="finish"/>
<import resource="my-flow-beans.xml"/>
</flow>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
<start-state idref="displayView" />
<view-state id="displayView" view="view">
<transition on="submit" to="finish"/>
</view-state>
<end-state id="finish"/>
</flow>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-1.0.xsd">
<start-state idref="yourStartStateId" />
<!-- Define your states here -->
</flow>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!--
Exposes web flows for execution at a single request URL.
The id of a flow to launch should be passed in by clients using
the "_flowId" request parameter:
e.g. /flowController.htm?_flowId=myflow
-->
<bean name="/flowController.htm" class="org.springframework.webflow.executor.mvc.FlowController">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<!-- Launches new flow executions and resumes existing executions: Spring 1.2 config version -->
<bean id="flowExecutor" class="org.springframework.webflow.config.FlowExecutorFactoryBean">
<property name="definitionLocator" ref="flowRegistry"/>
</bean>
<!-- Creates the registry of flow definitions for this application: Spring 1.2 config version -->
<bean id="flowRegistry" class="org.springframework.webflow.engine.builder.xml.XmlFlowRegistryFactoryBean">
<property name="flowLocations" value="/WEB-INF/flows/**/*-flow.xml"/>
</bean>
<!-- Resolves flow view names to .jsp templates -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:flow="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/webflow-config
http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">
<!--
Exposes web flows for execution at a single request URL.
The id of a flow to launch should be passed in by clients using
the "_flowId" request parameter:
e.g. /flowController.htm?_flowId=myflow
-->
<bean name="/flowController.htm" class="org.springframework.webflow.executor.mvc.FlowController">
<property name="flowExecutor" ref="flowExecutor" />
</bean>
<!-- Launches new flow executions and resumes existing executions. -->
<flow:executor id="flowExecutor" registry-ref="flowRegistry"/>
<!-- Creates the registry of flow definitions for this application -->
<flow:registry id="flowRegistry">
<flow:location path="/WEB-INF/flows/**/*-flow.xml" />
</flow:registry>
<!-- Resolves flow view names to .jsp templates -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>

View File

@@ -0,0 +1,18 @@
<%@ include file="includeTop.jsp" %>
<div id="content">
<form action="flowController.htm" method="post"/>
<table>
<tr>
<td colspan="2" class="buttonBar">
<!-- Tell webflow what flow execution we're participating in -->
<input type="hidden" name="_flowExecutionKey" value="${flowExecutionKey}"/>
<!-- Tell webflow what event occurred -->
<input type="submit" name="_eventId_submit" value="Submit">
</td>
</tr>
</table>
</form>
</div>
<%@ include file="includeBottom.jsp" %>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- Deploy your beans here -->
</beans>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<!-- Deploy your beans here -->
</beans>

View File

@@ -0,0 +1,4 @@
<Context path="/@PROJECT_NAME@" docBase="@DOC_BASE@"
debug="0" privileged="true">
</Context>

View File

@@ -0,0 +1,139 @@
<?xml version="1.0"?>
<!--
Copyright 2002-2005 the original author or authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
- - -
Author: Keith Donald
Author: Colin Sampaleanu
Ant XML fragment that contains useful targets for working with tomcat. These
include targets to spawn a tomcat process deplyoing the project, as well as update
the deployed application and static web content.
This ant XML fragment is meant to be imported into a project build file, along with
common-targets.xml. This is an optional module, and due to the way the ant import works,
there is no way to automatically hook this up into the build. The importing project
must override appropropriate 'hook' targets from common-targets.xml, and then have
the override targets depend on both the targets from common-targets and those from here.
-->
<!--
For these tasks to work, the specified user (tomcat.username property below,
which defaults to 'manager' but may be specified in build.properties) must be
a user defined in the TomCat server, and that user must have the role
'manager'. For the default in-memory realm in TomCat, this is done by modifying
conf/tomcat-users.xml in the TomCat install. See
http://jakarta.apache.org/tomcat/tomcat-5.5-doc/manager-howto.html
for more information.
-->
<project name="tomcat-targets" xmlns:ivy="antlib:fr.jayasoft.ivy.ant">
<import file="common-targets.xml" />
<target name="tomcat.init" depends="init,guard.tomcatdir">
<property name="tomcat.deploy.dir" value="${tomcat.dir}/webapps" />
<property name="tomcat.manager.url" value="http://localhost:8080/manager" />
<property name="tomcat.username" value="manager" />
<property name="tomcat.password" value="manager" />
<taskdef resource="org/apache/catalina/ant/catalina.tasks" onerror="ignore">
<classpath>
<filelist dir="${tomcat.dir}/server/lib">
<file name="catalina.jar" />
<file name="catalina-ant.jar" />
</filelist>
</classpath>
</taskdef>
</target>
<target name="guard.tomcatdir" unless="tomcat.dir">
<fail message="The target you are attempting to run requires the ${tomcat.dir} property to be set, which doesn't appear to be" />
</target>
<target name="tomcat-deploy" depends="tomcat.init, war" description="Install this web application to tomcat">
<deploy url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${project.webapp.name}" war="${project.war}" />
</target>
<target name="tomcat-undeploy" depends="tomcat.init" description="Remove this application from tomcat">
<undeploy url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${project.webapp.name}" failonerror="false" />
</target>
<target name="tomcat-redeploy" depends="tomcat-undeploy, tomcat-deploy" description="Redeploy the web application" />
<target name="tomcat-reload" depends="tomcat.init" description="Reload this application in tomcat">
<reload url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${project.name}" />
</target>
<target name="tomcat-copy-war" depends="tomcat.init, war" description="Copy this application .war to tomcat">
<copy file="${project.war}" todir="${tomcat.deploy.dir}" />
</target>
<target name="tomcat-clean-war" depends="tomcat.init" description="Clean this application expanded war directory from tomcat">
<delete failonerror="false" dir="${tomcat.deploy.dir}/${project.webapp.name}" />
</target>
<target name="tomcat-refresh-war" depends="tomcat-clean-war, tomcat-copy-war" description="Clean and copy this application .war to tomcat">
</target>
<target name="tomcat-launch" depends="tomcat.init,tomcat-refresh-war" description="Launch the tomcat server process and have it deploy this web application">
<exec dir="${tomcat.dir}/bin" executable="startup.bat" spawn="true" vmlauncher="false">
<env key="JAVA_OPTS" value="${tomcat.javaopts}" />
</exec>
</target>
<target name="tomcat-start" depends="tomcat.init" description="Start this web application in tomcat">
<start url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${project.webapp.name}" />
</target>
<target name="tomcat-stop" depends="tomcat.init" description="Stop this web application in tomcat">
<stop url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" path="/${project.webapp.name}" />
</target>
<target name="tomcat-list" depends="tomcat.init" description="List installed tomcat applications">
<list url="${tomcat.manager.url}" username="${tomcat.username}" password="${tomcat.password}" />
</target>
<target name="tomcat-content" depends="statics, tomcat.init" description="Copy web content to tomcat without redeploy">
<copy todir="${tomcat.deploy.dir}/${project.webapp.name}">
<fileset dir="${target.war.expanded.dir}">
<patternset refid="web.public.content.files" />
</fileset>
<fileset dir="${target.war.expanded.dir}">
<patternset refid="web.protected.content.files" />
</fileset>
</copy>
</target>
<target name="tomcat-context" depends="init.post,tomcat-context-error">
<delete quiet="true" file="${tomcat.dir}/conf/Catalina/localhost/${ant.project.name}.xml" />
<!-- create tomcat context file -->
<copy file="${common.build.dir}/templates/tomcat/context.xml" tofile="${tomcat.dir}/conf/Catalina/${ant.project.name}.xml" />
<replace file="${tomcat.dir}/conf/Catalina/${ant.project.name}.xml" token="@PROJECT_NAME@" value="${ant.project.name}" />
<replace file="${tomcat.dir}/conf/Catalina/${ant.project.name}.xml" token="@DOC_BASE@" value="${target.war.expanded.dir}" />
<copy file="${tomcat.dir}/conf/Catalina/${ant.project.name}.xml" todir="${tomcat.dir}/conf/Catalina/localhost" />
<delete quiet="true" file="${tomcat.dir}/conf/Catalina/${ant.project.name}.xml" />
</target>
<target name="tomcat-context-error" unless="tomcat.dir">
<fail>Set tomcat.dir in your USER_HOME/build.properties file (create if it doesn't exist)</fail>
</target>
</project>

13
common-build/version.txt Normal file
View File

@@ -0,0 +1,13 @@
version 20060409-1
Changelog:
2006-08-25: Keith: updated project and file templates inside "templates"
2006-04-09: Colin: upgrade Ivy to 1.3.1
2006-03-26: Colin: upgrade Ivy to snapshot 20060322, for transitive dep fix.
2006-03-08: Colin: upgrade Ivy to 1.3RC3
2006-02-17: Colin: Add retrieve-to-repo to common-targets.xml, user for release procoess
2006-02-13: Arjen: Standard docbook images are now also copied in doc-targets.xml
2006-02-08: Colin: add dir="${basedir} to junit task so it runs ok from other dirs
2006-01-04: Colin: add description element to "retrieve" since it's not an internal target
2005-11-27: Update Spring version in templates
2005-11-20: Arjen: add gen java source dir functionality for test sources too

36
readme.txt Normal file
View File

@@ -0,0 +1,36 @@
Contained in this directory are the Spring Web Flow (SWF) related project sources.
DIRECTORIES
1. build-spring-webflow - Contains the build scripts needed to build all SWF projects.
To build all, simply execute the 'dist' ant target.
2. spring-binding - the data binding and mapping project, a Spring Web Flow driven internal library.
3. spring-webflow - The core Spring Web Flow project.
4. spring-webflow-samples - The Spring Web Flow sample applications, illustrating the framework in action.
ARCHITECTURE DOCUMENTS
Also contained in this directory are two SonarJ files
1. webflow-architecture.xml
2. webflow-workspace.xml
When opened from SonarJ these provide an architectural breakdown of the Spring Web Flow projects.
It is recommended that you view this breakdown to familiarize yourself with the Spring Web Flow system
architecture, including its layers, subsystems, dependencies, and various architectural metrics such
as total lines of code and average component dependency.
To use SonarJ:
1. Download it from http://www.hello2morrow.com/en/sonarj/sonarj.php
2. Install it
3. Launch it
4. Point to license key
5. Open workspace (webflow-workspace.xml)
6. Open architecture template (webflow-architecture.xml)
7. Right click on Web Flow Workspace root and click "Run all operations"
8. Click the various tabs to see different views
- Architecture view is recommended
- Layers sub-tab shows layer diagram
- Subsytstem sub-tab shows breakdown by subsystem

15
spring-binding/.classpath Normal file
View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="lib/test/easymock.jar"/>
<classpathentry kind="lib" path="lib/test/junit.jar"/>
<classpathentry kind="lib" path="lib/global/commons-logging.jar"/>
<classpathentry kind="lib" path="lib/test/log4j.jar"/>
<classpathentry kind="lib" path="lib/global/spring-core.jar" sourcepath="C:/development/spring/spring/src"/>
<classpathentry kind="lib" path="lib/global/spring-beans.jar" sourcepath="/spring/src"/>
<classpathentry kind="lib" path="lib/global/ognl.jar"/>
<classpathentry kind="lib" path="lib/global/spring-context.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@@ -0,0 +1,8 @@
target
lib
bak
build.properties
*.log
*.jpx.local*
*.iws
*.tws

19
spring-binding/.project Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spring-binding</name>
<comment></comment>
<projects>
<project>common-build</project>
<project>repository</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,74 @@
#Fri Oct 06 15:22:02 CEST 2006
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.3
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.3
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.deprecation=warning
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
org.eclipse.jdt.core.compiler.problem.nullReference=ignore
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.3

View File

@@ -0,0 +1,3 @@
#Wed Oct 04 14:36:37 EDT 2006
eclipse.preferences.version=1
internal.default.compliance=user

View File

@@ -0,0 +1,6 @@
#Fri May 05 18:13:37 EDT 2006
DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator;
USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.jst.jsp.core.internal.validation.JSPELValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.jst.jsp.core.internal.validation.JSPJavaValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.jst.jsp.core.internal.validation.JSPDirectiveValidator;
USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.jst.jsp.core.internal.validation.JSPELValidator;org.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator;org.eclipse.jst.jsp.core.internal.validation.JSPJavaValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.jst.jsp.core.internal.validation.JSPDirectiveValidator;
USER_PREFERENCE=overrideGlobalPreferencesfalse
eclipse.preferences.version=1

17
spring-binding/build.xml Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<project name="spring-binding" default="dist">
<property file="build.properties"/>
<property file="project.properties"/>
<property file="${common.build.dir}/build.properties"/>
<property file="${common.build.dir}/project.properties"/>
<property file="${user.home}/build.properties"/>
<property name="project.title" value="Spring Data Binding"/>
<property name="project.package" value="org.springframework.binding"/>
<property name="project.copyright" value="Copyright &#169; 2004-2006. All Rights Reserved."/>
<import file="${common.build.dir}/common-targets.xml"/>
</project>

26
spring-binding/ivy.xml Normal file
View File

@@ -0,0 +1,26 @@
<ivy-module version="1.3">
<info organisation="org.springframework" module="spring-binding" />
<configurations>
<conf name="default" extends="global" />
<conf name="global" visibility="private" />
<conf name="buildtime" visibility="private" />
<conf name="test" visibility="private" />
</configurations>
<dependencies defaultconf="global->default">
<!-- global dependencies -->
<dependency org="commons-logging" name="commons-logging" rev="1.0.4"/>
<dependency org="ognl" name="ognl" rev="2.6.9" />
<dependency org="org.springframework" name="spring-beans" rev="2.0" />
<dependency org="org.springframework" name="spring-context" rev="2.0" />
<dependency org="org.springframework" name="spring-core" rev="2.0" />
<!-- test dependencies -->
<dependency org="org.easymock" name="easymock" rev="2.2" conf="test->default" />
<dependency org="junit" name="junit" rev="3.8.1" conf="test->default" />
<dependency org="log4j" name="log4j" rev="1.2.13" conf="test->default"/>
</dependencies>
</ivy-module>

77
spring-binding/pom.xml Normal file
View File

@@ -0,0 +1,77 @@
<?xml version="1.0"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>spring-binding</artifactId>
<name>Spring Binding</name>
<version>1.0.1-SNAPSHOT</version>
<description>Spring Data Binding Framework</description>
<url>http://www.springframework.org</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<connection>scm:svn:https://svn.sourceforge.net/svnroot/springframework/spring-projects</connection>
<developerConnection>scm:svn:https://svn.sourceforge.net/svnroot/springframework/spring-projects</developerConnection>
<tag>1.0</tag>
<url>http://svn.sourceforge.net/viewcvs.cgi/springframework/spring-projects</url>
</scm>
<organization>
<name>Spring Framework</name>
<url>http://www.springframework.org/</url>
</organization>
<dependencies>
<!-- External Dependencies -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.0.4</version>
</dependency>
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>2.6.9</version>
</dependency>
<!-- Spring Dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>2.0</version>
</dependency>
<!-- Runtime Dependencies -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- Test Dependencies -->
<dependency>
<groupId>easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,11 @@
# properties defined in this file are overridable by a local build.properties in this project dir
# The location of the common build system
common.build.dir=${basedir}/../../common-build
project.base.version=1.0.1
#project.version=${project.base.version}
#ivy.status=release
javac.source=1.3
javac.target=1.3

View File

@@ -0,0 +1,33 @@
# $Header$
# Contains filterable project settings. Setting placeholders in filterable project text
# files will be replaced with these values when the 'statics' build target is run.
#
# You may add static settings directly to this source file in the format:
# setting=value e.g MY_SETTING=myvalue
# This is appropriate usage if you know the setting value will never change.
#
# At build time this source file is copied to the ${target.dir} where additional
# dynamic settings may be appended using the <propertyfile> task. Use this approach
# when a setting value depends on the build or the local user's environment.
#
# An example of this approach is shown below:
#
# build.xml
# <target name="build.prepare" depends="common-targets.build.prepare">
# <!-- Append additional local settings that are applicable to this project -->
# <propertyfile file="${target.filter.file}">
# <!-- key=the name of the setting
# value=the property in your build.properties file that has the local setting value -->
# <entry key="MY_LOCAL_SETTING" value="${my.local.setting}" />
# </propertyfile>
# </target>
#
# This allows for dynamic replacement values that are sourced from local properties files to facilitate
# local user settings.
#
# To refer to filterable settings within project source files like config files, JSPs, or
# other text files use the standard ant placeholder format:
# @SETTING_NAME@ e.g, @MY_SETTING@ and @MY_LOCAL_SETTING@
#
# Your settings:

View File

@@ -0,0 +1,17 @@
log4j.rootCategory=WARN, stdout, logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=@TEST_RESULTS_DIR@/@PROJECT_NAME@.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files
log4j.appender.logfile.MaxBackupIndex=3
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
#Pattern to output : date priority [category] - <message>line_separator
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - <%m>%n
log4j.category.org.springframework.binding=DEBUG

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import org.springframework.util.Assert;
/**
* Iterator that combines multiple other iterators. This is a simple implementation
* that just maintains a list of iterators which are invoked in sequence untill
* all iterators are exhausted.
*
* @author Erwin Vervaet
*/
public class CompositeIterator implements Iterator {
private List iterators = new LinkedList();
private boolean inUse = false;
/**
* Create a new composite iterator. Add iterators using the {@link #add(Iterator)} method.
*/
public CompositeIterator() {
}
/**
* Add given iterator to this composite.
*/
public void add(Iterator iterator) {
Assert.state(!inUse, "You can no longer add iterator to a composite iterator that's already in use");
if (iterators.contains(iterator)) {
throw new IllegalArgumentException("You cannot add the same iterator twice");
}
iterators.add(iterator);
}
public boolean hasNext() {
inUse = true;
for (Iterator it = iterators.iterator(); it.hasNext(); ) {
if (((Iterator)it.next()).hasNext()) {
return true;
}
}
return false;
}
public Object next() {
inUse = true;
for (Iterator it = iterators.iterator(); it.hasNext(); ) {
Iterator iterator = (Iterator)it.next();
if (iterator.hasNext()) {
return iterator.next();
}
}
throw new NoSuchElementException("Exhaused all iterators");
}
public void remove() {
throw new UnsupportedOperationException("Remove is not supported");
}
}

View File

@@ -0,0 +1,463 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.collection;
import java.util.Collection;
import java.util.Map;
import org.springframework.util.Assert;
/**
* A simple, generic decorator for getting attributes out of a map. May be
* instantiated directly or used as a base class as a convenience.
*
* @author Keith Donald
*/
public class MapAccessor implements MapAdaptable {
/**
* The target map.
*/
private Map map;
/**
* Creates a new attribute map accessor.
* @param map the map
*/
public MapAccessor(Map map) {
Assert.notNull(map, "The map to decorate is required");
this.map = map;
}
// implementing MapAdaptable
public Map asMap() {
return map;
}
/**
* Returns a value in the map, returning the defaultValue if no value was
* found.
* @param key the key
* @param defaultValue the default
* @return the attribute value
*/
public Object get(Object key, Object defaultValue) {
if (!map.containsKey(key)) {
return defaultValue;
}
return map.get(key);
}
/**
* Returns a value in the map, asserting it is of the required type if
* present and returning <code>null</code> if not found.
* @param key the key
* @param requiredType the required type
* @return the value
* @throws IllegalArgumentException if the key is present but the value is
* not of the required type
*/
public Object get(Object key, Class requiredType) throws IllegalArgumentException {
return get(key, requiredType, null);
}
/**
* Returns a value in the map of the specified type, returning the
* defaultValue if no value is found.
* @param key the key
* @param requiredType the required type
* @param defaultValue the default
* @return the attribute value
* @throws IllegalArgumentException if the key is present but the value is
* not of the required type
*/
public Object get(Object key, Class requiredType, Object defaultValue) {
if (!map.containsKey(key)) {
return defaultValue;
}
return assertKeyValueOfType(key, requiredType);
}
/**
* Returns a value in the map, throwing an exception if the attribute is not
* present and of the correct type.
* @param key the key
* @return the value
*/
public Object getRequired(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return map.get(key);
}
/**
* Returns an value in the map, asserting it is present and of the required
* type.
* @param key the key
* @param requiredType the required type
* @return the value
*/
public Object getRequired(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
return assertKeyValueOfType(key, requiredType);
}
/**
* Returns a string value in the map, returning <code>null</code> if no
* value was found.
* @param key the key
* @return the string value
* @throws IllegalArgumentException if the key is present but the value is
* not a string
*/
public String getString(Object key) throws IllegalArgumentException {
return getString(key, null);
}
/**
* Returns a string value in the map, returning the defaultValue if no value
* was found.
* @param key the key
* @param defaultValue the default
* @return the string value
* @throws IllegalArgumentException if the key is present but the value is
* not a string
*/
public String getString(Object key, String defaultValue) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return defaultValue;
}
return (String)assertKeyValueOfType(key, String.class);
}
/**
* Returns a string value in the map, throwing an exception if the attribute
* is not present and of the correct type.
* @param key the key
* @return the string value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a string
*/
public String getRequiredString(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return (String)assertKeyValueOfType(key, String.class);
}
/**
* Returns a collection value in the map, returning <code>null</code> if
* no value was found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is present but the value is
* not a collection
*/
public Collection getCollection(Object key) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return null;
}
return (Collection)assertKeyValueOfType(key, Collection.class);
}
/**
* Returns a collection value in the map, asserting it is of the required
* type if present and returning <code>null</code> if not found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is present but the value is
* not a collection
*/
public Collection getCollection(Object key, Class requiredType) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return null;
}
assertAssignableTo(Collection.class, requiredType);
return (Collection)assertKeyValueOfType(key, requiredType);
}
/**
* Returns a collection value in the map, throwing an exception if not
* found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a collection
*/
public Collection getRequiredCollection(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return (Collection)assertKeyValueOfType(key, Collection.class);
}
/**
* Returns a collection value in the map, asserting it is of the required
* type if present and throwing an exception if not found.
* @param key the key
* @return the collection value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a collection of the required type
*/
public Collection getRequiredCollection(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
assertAssignableTo(Collection.class, requiredType);
return (Collection)assertKeyValueOfType(key, requiredType);
}
/**
* Returns a array value in the map, asserting it is of the required type if
* present and returning <code>null</code> if not found.
* @param key the key
* @return the array value
* @throws IllegalArgumentException if the key is present but the value is
* not an array of the required type
*/
public Object[] getArray(Object key, Class requiredType) throws IllegalArgumentException {
assertAssignableTo(Object[].class, requiredType);
if (!map.containsKey(key)) {
return null;
}
return (Object[])assertKeyValueOfType(key, requiredType);
}
/**
* Returns an array value in the map, asserting it is of the required type
* if present and throwing an exception if not found.
* @param key the key
* @return the array value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a array of the required type
*/
public Object[] getRequiredArray(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
assertAssignableTo(Object[].class, requiredType);
return (Object[])assertKeyValueOfType(key, requiredType);
}
/**
* Returns a number value in the map that is of the specified type,
* returning <code>null</code> if no value was found.
* @param key the key
* @param requiredType the required number type
* @return the numbervalue
* @throws IllegalArgumentException if the key is present but the value is
* not a number of the required type
*/
public Number getNumber(Object key, Class requiredType) throws IllegalArgumentException {
return getNumber(key, requiredType, null);
}
/**
* Returns a number attribute value in the map of the specified type,
* returning the defaultValue if no value was found.
* @param key the attribute name
* @return the number value
* @param defaultValue the default
* @throws IllegalArgumentException if the key is present but the value is
* not a number of the required type
*/
public Number getNumber(Object key, Class requiredType, Number defaultValue) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return defaultValue;
}
assertAssignableTo(Number.class, requiredType);
return (Number)assertKeyValueOfType(key, requiredType);
}
/**
* Returns a number value in the map, throwing an exception if the attribute
* is not present and of the correct type.
* @param key the key
* @return the number value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a number of the required type
*/
public Number getRequiredNumber(Object key, Class requiredType) throws IllegalArgumentException {
assertContainsKey(key);
return (Number)assertKeyValueOfType(key, requiredType);
}
/**
* Returns an integer value in the map, returning <code>null</code> if no
* value was found.
* @param key the key
* @return the integer value
* @throws IllegalArgumentException if the key is present but the value is
* not an integer
*/
public Integer getInteger(Object key) throws IllegalArgumentException {
return getInteger(key, null);
}
/**
* Returns an integer value in the map, returning the defaultValue if no
* value was found.
* @param key the key
* @param defaultValue the default
* @return the integer value
* @throws IllegalArgumentException if the key is present but the value is
* not an integer
*/
public Integer getInteger(Object key, Integer defaultValue) throws IllegalArgumentException {
return (Integer)getNumber(key, Integer.class, defaultValue);
}
/**
* Returns an integer value in the map, throwing an exception if the value
* is not present and of the correct type.
* @param key the attribute name
* @return the integer attribute value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not an integer
*/
public Integer getRequiredInteger(Object key) throws IllegalArgumentException {
return (Integer)getRequiredNumber(key, Integer.class);
}
/**
* Returns a long value in the map, returning <code>null</code> if no
* value was found.
* @param key the key
* @return the long value
* @throws IllegalArgumentException if the key is present but not a long
*/
public Long getLong(Object key) throws IllegalArgumentException {
return getLong(key, null);
}
/**
* Returns a long value in the map, returning the defaultValue if no value
* was found.
* @param key the key
* @param defaultValue the default
* @return the long attribute value
* @throws IllegalArgumentException if the key is present but the value is
* not a long
*/
public Long getLong(Object key, Long defaultValue) throws IllegalArgumentException {
return (Long)getNumber(key, Long.class, defaultValue);
}
/**
* Returns a long value in the map, throwing an exception if the value is
* not present and of the correct type.
* @param key the key
* @return the long attribute value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a long
*/
public Long getRequiredLong(Object key) throws IllegalArgumentException {
return (Long)getRequiredNumber(key, Long.class);
}
/**
* Returns a boolean value in the map, returning <code>null</code> if no
* value was found.
* @param key the key
* @return the boolean value
* @throws IllegalArgumentException if the key is present but the value is
* not a boolean
*/
public Boolean getBoolean(Object key) throws IllegalArgumentException {
return getBoolean(key, null);
}
/**
* Returns a boolean value in the map, returning the defaultValue if no
* value was found.
* @param key the key
* @param defaultValue the default
* @return the boolean value
* @throws IllegalArgumentException if the key is present but the value is
* not a boolean
*/
public Boolean getBoolean(Object key, Boolean defaultValue) throws IllegalArgumentException {
if (!map.containsKey(key)) {
return defaultValue;
}
return (Boolean)assertKeyValueOfType(key, Boolean.class);
}
/**
* Returns a boolean value in the map, throwing an exception if the value is
* not present and of the correct type.
* @param key the attribute
* @return the boolean value
* @throws IllegalArgumentException if the key is not present or present but
* the value is not a boolean
*/
public Boolean getRequiredBoolean(Object key) throws IllegalArgumentException {
assertContainsKey(key);
return (Boolean)assertKeyValueOfType(key, Boolean.class);
}
/**
* Asserts that the attribute is present in the attribute map.
* @param key the key
* @throws IllegalArgumentException if the key is not present
*/
public void assertContainsKey(Object key) throws IllegalArgumentException {
if (!map.containsKey(key)) {
throw new IllegalArgumentException("Required attribute '" + key
+ "' is not present in map; attributes present are [" + asMap() + "]");
}
}
/**
* Indicates if the attribute is present in the attribute map and of the
* required type.
* @param key the attribute name
* @return true if present and of the required type, false if not present.
*/
public boolean containsKey(Object key, Class requiredType) throws IllegalArgumentException {
if (map.containsKey(key)) {
assertKeyValueOfType(key, requiredType);
return true;
}
else {
return false;
}
}
/**
* Assert that value of the mak key is of the required type.
* @param key the attribute name
* @param requiredType the required attribute value type
* @return the attribute value
*/
public Object assertKeyValueOfType(Object key, Class requiredType) {
return assertKeyValueInstanceOf(key, map.get(key), requiredType);
}
/**
* Assert that the key value is an instance of the required type.
* @param key the key
* @param value the value
* @param requiredType the required type
* @return the value
*/
public Object assertKeyValueInstanceOf(Object key, Object value, Class requiredType) {
Assert.notNull(requiredType, "The required type to assert is required");
if (!requiredType.isInstance(value)) {
throw new IllegalArgumentException("Map key '" + key + "' has value [" + value
+ "] that is not of expected type [" + requiredType + "], instead it is of type ["
+ (value != null ? value.getClass().getName() : "null") + "]");
}
return value;
}
private void assertAssignableTo(Class clazz, Class requiredType) {
Assert.isTrue(clazz.isAssignableFrom(requiredType), "The provided required type must be assignable to ["
+ clazz + "]");
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.collection;
import java.util.Map;
/**
* An object whose contents are capable of being exposed as an unmodifiable map.
*
* @author Keith Donald
*/
public interface MapAdaptable {
/**
* Returns this object's contents as a {@link Map}. The returned map may or
* may not be modifiable depending on this implementation.
* <p>
* Warning: this operation may be called frequently; if so care should be
* taken so that the map contents (if calculated) be cached as appropriate.
* @return the object's contents as a map
*/
public Map asMap();
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 extends Map {
/**
* 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
*/
public Object getMutex();
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
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 implements SharedMap, Serializable {
/**
* The wrapped, target map.
*/
private Map map;
/**
* Creates a new shared map decorator.
* @param map the map that is shared by multiple threads, to be synced
*/
public SharedMapDecorator(Map 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 entrySet() {
return map.entrySet();
}
public Object get(Object key) {
return map.get(key);
}
public boolean isEmpty() {
return map.isEmpty();
}
public Set keySet() {
return map.keySet();
}
public Object put(Object key, Object value) {
return map.put(key, value);
}
public void putAll(Map map) {
this.map.putAll(map);
}
public Object remove(Object key) {
return map.remove(key);
}
public int size() {
return map.size();
}
public Collection 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

@@ -0,0 +1,285 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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 implements Map {
private Set keySet;
private Collection values;
private Set entrySet;
// implementing Map
public void clear() {
for (Iterator it = getAttributeNames(); it.hasNext();) {
removeAttribute((String)it.next());
}
}
public boolean containsKey(Object key) {
return getAttribute(key.toString()) != null;
}
public boolean containsValue(Object value) {
if (value == null) {
return false;
}
for (Iterator it = getAttributeNames(); it.hasNext();) {
Object aValue = getAttribute((String)it.next());
if (value.equals(aValue)) {
return true;
}
}
return false;
}
public Set entrySet() {
return (entrySet != null) ? entrySet : (entrySet = new EntrySet());
}
public Object get(Object key) {
return getAttribute(key.toString());
}
public boolean isEmpty() {
return !getAttributeNames().hasNext();
}
public Set keySet() {
return (keySet != null) ? keySet : (keySet = new KeySet());
}
public Object put(Object key, Object value) {
String stringKey = String.valueOf(key);
Object previousValue = getAttribute(stringKey);
setAttribute(stringKey, value);
return previousValue;
}
public void putAll(Map map) {
for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
Entry entry = (Entry)it.next();
setAttribute(entry.getKey().toString(), entry.getValue());
}
}
public Object remove(Object key) {
String stringKey = key.toString();
Object retval = getAttribute(stringKey);
removeAttribute(stringKey);
return retval;
}
public int size() {
int size = 0;
for (Iterator it = getAttributeNames(); it.hasNext();) {
size++;
it.next();
}
return size;
}
public Collection 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 Object 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, Object 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 getAttributeNames();
// internal helper classes
private abstract class AbstractSet extends java.util.AbstractSet {
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 {
public Iterator 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 class KeyIterator implements Iterator {
protected final Iterator it = getAttributeNames();
protected Object 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();
}
public Object next() {
return currentKey = it.next();
}
}
private class Values extends AbstractSet {
public Iterator 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 it = iterator(); it.hasNext();) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
return false;
}
}
private class ValuesIterator extends KeyIterator {
public Object next() {
super.next();
return StringKeyedMapAdapter.this.get(currentKey);
}
}
private class EntrySet extends AbstractSet {
public Iterator iterator() {
return new EntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Entry)) {
return false;
}
Entry entry = (Entry)o;
Object key = entry.getKey();
Object value = entry.getValue();
if (key == null || value == null) {
return false;
}
return value.equals(StringKeyedMapAdapter.this.get(key));
}
public boolean remove(Object o) {
if (!(o instanceof Entry)) {
return false;
}
Entry entry = (Entry)o;
Object key = entry.getKey();
Object value = entry.getValue();
if (key == null || value == null || !value.equals(StringKeyedMapAdapter.this.get(key))) {
return false;
}
return StringKeyedMapAdapter.this.remove(((Entry)o).getKey()) != null;
}
}
private class EntryIterator extends KeyIterator {
public Object next() {
super.next();
return new EntrySetEntry(currentKey);
}
}
private class EntrySetEntry implements Entry {
private final Object currentKey;
public EntrySetEntry(Object currentKey) {
this.currentKey = currentKey;
}
public Object getKey() {
return currentKey;
}
public Object getValue() {
return StringKeyedMapAdapter.this.get(currentKey);
}
public Object setValue(Object value) {
return StringKeyedMapAdapter.this.put(currentKey, value);
}
}
}

View File

@@ -0,0 +1,7 @@
<html>
<body>
<p>
Collection related classes usable by other packages and systems.
</p>
</body>
</html>

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert;
/**
* A context object with two main responsibities:
* <ol>
* <li>Exposing information to a converter to influence
* a type conversion attempt.
* <li>Providing operations for recording progress or
* errors during the type conversion process.
* </ol>
* Empty for now; subclasses may define their own custom context behavior
* accessible by a converter with a downcast.
*
* @author Keith Donald
*/
public interface ConversionContext {
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert;
import org.springframework.core.NestedRuntimeException;
/**
* Base class for exceptions thrown by the type conversion system.
*
* @author Keith Donald
*/
public class ConversionException extends NestedRuntimeException {
/**
* The source type we tried to convert from
*/
private Class sourceClass;
/**
* The value we tried to convert.
*/
private Object value;
/**
* The target type we tried to convert to.
*/
private Class targetClass;
/**
* Creates a new conversion exception.
* @param value the value we tried to convert
* @param targetClass the target type
*/
public ConversionException(Object value, Class targetClass) {
super("Unable to convert value '" + value + "' of type '" + (value != null ? value.getClass().getName() : null)
+ "' to class '" + targetClass.getName() + "'");
this.value = value;
this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
* @param value the value we tried to convert
* @param targetClass the target type
* @param cause underlying cause of this exception
*/
public ConversionException(Object value, Class targetClass, Throwable cause) {
super("Unable to convert value '" + value + "' of type '" + (value != null ? value.getClass().getName() : null)
+ "' to class '" + targetClass.getName() + "'", cause);
this.value = value;
this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
* @param value the value we tried to convert
* @param targetClass the target type
* @param message a descriptive message
* @param cause underlying cause of this exception
*/
public ConversionException(Object value, Class targetClass, String message, Throwable cause) {
super(message, cause);
this.value = value;
this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
* @param sourceClass the source type
* @param targetClass the target type
* @param message a descriptive message
*/
public ConversionException(Class sourceClass, Class targetClass, String message) {
super(message);
this.sourceClass = sourceClass;
this.value = null; // not available
this.targetClass = targetClass;
}
/**
* Creates a new conversion exception.
* @param sourceClass the source type
* @param message a descriptive message
*/
public ConversionException(Class sourceClass, String message) {
super(message);
this.sourceClass = sourceClass;
this.value = null; // not available
this.targetClass = null; // not available
}
/**
* Returns the source type.
*/
public Class getSourceClass() {
return sourceClass;
}
/**
* Returns the value we tried to convert.
*/
public Object getValue() {
return value;
}
/**
* Returns the target type.
*/
public Class getTargetClass() {
return targetClass;
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert;
import java.io.Serializable;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
/**
* A command object that is parameterized with the information necessary to
* perform a conversion of a source input to a target output.
* <p>
* Specifically, encapsulates knowledge about how to convert source objects to a
* specific target type using a specific converter.
*
* @author Keith Donald
*/
public class ConversionExecutor implements Serializable {
/**
* The source value type this executor will attempt to convert from.
*/
private final Class sourceClass;
/**
* The target value type this executor will attempt to convert to.
*/
private final Class targetClass;
/**
* The converter that will perform the conversion.
*/
private final Converter converter;
/**
* Creates a conversion executor.
* @param sourceClass the source type that the converter will convert from
* @param targetClass the target type that the converter will convert to
* @param converter the converter that will perform the conversion
*/
public ConversionExecutor(Class sourceClass, Class targetClass, Converter converter) {
Assert.notNull(sourceClass, "The source class is required");
Assert.notNull(targetClass, "The target class is required");
Assert.notNull(converter, "The converter is required");
this.sourceClass = sourceClass;
this.targetClass = targetClass;
this.converter = converter;
}
/**
* Returns the source class of conversions performed by this executor.
* @return the source class
*/
public Class getSourceClass() {
return sourceClass;
}
/**
* Returns the target class of conversions performed by this executor.
* @return the target class
*/
public Class getTargetClass() {
return targetClass;
}
/**
* Returns the converter that will perform the conversion.
* @return the converter
*/
public Converter getConverter() {
return converter;
}
/**
* Execute the conversion for the provided source object.
* @param source the source object to convert
*/
public Object execute(Object source) throws ConversionException {
return execute(source, null);
}
/**
* Execute the conversion for the provided source object.
* @param source the source object to convert
* @param context the conversion context, useful for influencing the
* behavior of the converter
*/
public Object execute(Object source, ConversionContext context) throws ConversionException {
if (source != null) {
Assert.isInstanceOf(sourceClass, source, "Not of source type: ");
}
return converter.convert(source, targetClass, context);
}
public boolean equals(Object o) {
if (!(o instanceof ConversionExecutor)) {
return false;
}
ConversionExecutor other = (ConversionExecutor)o;
return sourceClass.equals(other.sourceClass) && targetClass.equals(other.targetClass);
}
public int hashCode() {
return sourceClass.hashCode() + targetClass.hashCode();
}
public String toString() {
return new ToStringCreator(this).append("sourceClass", sourceClass).append("targetClass", targetClass)
.toString();
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert;
/**
* A service interface for retrieving type conversion executors. The returned
* command objects are thread-safe and may be safely cached for use by client
* code.
*
* @author Keith Donald
*/
public interface ConversionService {
/**
* Return a conversion executor command object capable of converting source
* objects of the specified <code>sourceClass</code> to instances of the
* <code>targetClass</code>.
* <p>
* The returned ConversionExecutor is thread-safe and may safely be cached
* for use in client code.
* @param sourceClass the source class to convert from
* @param targetClass the target class to convert to
* @return the executor that can execute instance conversion, never null
* @throws ConversionException an exception occured retrieving a converter
* for the source-to-target pair
*/
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
throws ConversionException;
/**
* Return a conversion executor command object capable of converting source
* objects of the specified <code>sourceClass</code> to target objects of
* the type associated with the specified alias.
* @param sourceClass the sourceClass
* @param targetAlias the target alias
* @return the conversion executor, or null if the alias cannot be found
* @throws ConversionException an exception occured retrieving a converter
* for the source-to-target pair
*/
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
throws ConversionException;
/**
* Return all conversion executors capable of converting source objects of
* the the specified <code>sourceClass</code>.
* @param sourceClass the source class to convert from
* @return the matching conversion executors
* @throws ConversionException an exception occured retrieving the converters
*/
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass)
throws ConversionException;
/**
* Return the class with the specified alias.
* @param alias the class alias
* @return the class, or null if not aliased
* @throws ConversionException when an error occurs looking up the class by alias
*/
public Class getClassByAlias(String alias) throws ConversionException;
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert;
/**
* A type converter converts objects from one type to another. They may support
* conversion of multiple source types to multiple target types.
* <p>
* Implementations of this interface are thread-safe.
*
* @author Keith Donald
*/
public interface Converter {
/**
* The source classes this converter can convert from.
* @return the supported source classes
*/
public Class[] getSourceClasses();
/**
* The target classes this converter can convert to.
* @return the supported target classes
*/
public Class[] getTargetClasses();
/**
* Convert the provided source object argument to an instance of the
* specified target class.
* @param source the source object to convert, its class must be one of the
* supported <code>sourceClasses</code>
* @param targetClass the target class to convert the source to, must be one
* of the supported <code>targetClasses</code>
* @param context an optional conversion context that may be used to
* influence the conversion process
* @return the converted object, an instance of the target type
* @throws ConversionException an exception occured during the conversion
*/
public Object convert(Object source, Class targetClass, ConversionContext context) throws ConversionException;
}

View File

@@ -0,0 +1,7 @@
<html>
<body>
<p>
Core services for converting objects from one type to another.
</p>
</body>
</html>

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.binding.convert.ConversionException;
import org.springframework.binding.convert.Converter;
/**
* Base class for converters provided as a convenience to implementors.
*
* @author Keith Donald
*/
public abstract class AbstractConverter implements Converter {
/**
* Convenience convert method that converts the provided source to the first
* target object supported by this converter. Useful when a converter only
* supports conversion to a single target.
* @param source the source to convert
* @return the converted object
* @throws ConversionException an exception occured converting the source
* value
*/
public Object convert(Object source) throws ConversionException {
return convert(source, getTargetClasses()[0], null);
}
/**
* Convenience convert method that converts the provided source to the
* target class specified with an empty conversion context.
* @param source the source to convert
* @param targetClass the target class to convert the source to, must be one
* of the supported <code>targetClasses</code>
* @return the converted object
* @throws ConversionException an exception occured converting the source
* value
*/
public Object convert(Object source, Class targetClass) throws ConversionException {
return convert(source, targetClass, null);
}
/**
* Convenience convert method that converts the provided source to the first
* target object supported by this converter. Useful when a converter only
* supports conversion to a single target.
* @param source the source to convert
* @param context the conversion context, useful for influencing the
* behavior of the converter
* @return the converted object
* @throws ConversionException an exception occured converting the source
* value
*/
public Object convert(Object source, ConversionContext context) throws ConversionException {
return convert(source, getTargetClasses()[0], context);
}
public Object convert(Object source, Class targetClass, ConversionContext context) throws ConversionException {
try {
return doConvert(source, targetClass, context);
}
catch (ConversionException e) {
throw e;
}
catch (Throwable e) {
// wrap in a ConversionException
if (targetClass == null) {
targetClass = getTargetClasses()[0];
}
throw new ConversionException(source, targetClass, e);
}
}
/**
* Template method subclasses should override to actually perform the type
* conversion.
* @param source the source to convert from
* @param targetClass the target type to convert to
* @param context an optional conversion context that may be used to
* influence the conversion process, could be null
* @return the converted source value
* @throws Exception an exception occured, will be wrapped in a conversion
* exception if necessary
*/
protected abstract Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception;
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.format.FormatterFactory;
/**
* A converter that delegates to a formatter to perform the conversion.
* Formatters are typically not thread safe, so we use a FormatterFactory that
* is expected to provide us with thread-safe instances as necessary.
*
* @author Keith Donald
*/
public abstract class AbstractFormattingConverter extends AbstractConverter {
/**
* The formatter factory.
*/
private FormatterFactory formatterFactory;
/**
* Creates a new converter that delegates to a formatter.
* @param formatterFactory the factory to use
*/
protected AbstractFormattingConverter(FormatterFactory formatterFactory) {
setFormatterFactory(formatterFactory);
}
protected FormatterFactory getFormatterFactory() {
return formatterFactory;
}
public void setFormatterFactory(FormatterFactory formatterSource) {
this.formatterFactory = formatterSource;
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.springframework.binding.convert.ConversionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.util.Assert;
/**
* A conversion service that delegates to an ordered chain of other conversion
* services. The first correct reply received from a conversion service in
* the chain is returned to the caller.
*
* @author Erwin Vervaet
*/
public class CompositeConversionService implements ConversionService {
private ConversionService[] chain;
/**
* Create a new composite conversion service.
* @param conversionServices the conversion services in the chain
*/
public CompositeConversionService(ConversionService[] conversionServices) {
Assert.notNull(conversionServices, "The conversion services chain is required");
this.chain = conversionServices;
}
/**
* Returns the conversion services in the chain managed by this
* composite conversion service.
*/
public ConversionService[] getConversionServices() {
return chain;
}
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass)
throws ConversionException {
for (int i = 0; i < chain.length; i++) {
try {
return chain[i].getConversionExecutor(sourceClass, targetClass);
}
catch (ConversionException e) {
// ignore and try the next conversion service in the chain
}
}
throw new ConversionException(sourceClass, targetClass,
"No converter registered to convert from sourceClass '" + sourceClass +
"' to target class '" + targetClass + "'");
}
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String targetAlias)
throws ConversionException {
boolean exceptionThrown = false;
for (int i = 0; i < chain.length; i++) {
try {
ConversionExecutor res = chain[i].getConversionExecutorByTargetAlias(sourceClass, targetAlias);
if (res != null) {
return res;
}
}
catch (ConversionException e) {
exceptionThrown = true;
}
}
if (exceptionThrown) {
throw new ConversionException(sourceClass,
"No converter registered to convert from sourceClass '" + sourceClass +
"' to aliased target type '" + targetAlias + "'");
}
else {
// alias was not recognized by any conversion service in the chain
return null;
}
}
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass)
throws ConversionException {
Set executors = new HashSet();
for (int i = 0; i < chain.length; i++) {
executors.addAll(Arrays.asList(chain[i].getConversionExecutorsForSource(sourceClass)));
}
return (ConversionExecutor[])executors.toArray(new ConversionExecutor[executors.size()]);
}
public Class getClassByAlias(String alias) throws ConversionException {
for (int i = 0; i < chain.length; i++) {
try {
Class res = chain[i].getClassByAlias(alias);
if (res != null) {
return res;
}
}
catch (ConversionException e) {
// ignore and try the next conversion service in the chain
}
}
return null;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionService;
/**
* Marker interface that denotes an object has a dependency on a conversion
* service that is expected to be fulfilled.
*
* @author Keith Donald
*/
public interface ConversionServiceAware {
/**
* Set the conversion service this object should be made aware of (as it
* presumably depends on it).
*
* @param conversionService the conversion service
*/
public void setConversionService(ConversionService conversionService);
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.expression.Expression;
/**
* Base class for converters that use other converters to convert things, thus
* they are conversion-service aware.
*
* @author Keith Donald
*/
public abstract class ConversionServiceAwareConverter extends AbstractConverter implements ConversionServiceAware {
/**
* The conversion service this converter is aware of.
*/
private ConversionService conversionService;
/**
* Default constructor, expectes to conversion service to be injected
* using {@link #setConversionService(ConversionService)}.
*/
protected ConversionServiceAwareConverter() {
}
/**
* Create a converter using given conversion service.
*/
protected ConversionServiceAwareConverter(ConversionService conversionService) {
setConversionService(conversionService);
}
/**
* Returns the conversion service used.
*/
public ConversionService getConversionService() {
if (conversionService == null) {
throw new IllegalStateException("Conversion service not yet set: set it first before calling this method");
}
return conversionService;
}
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
/**
* Returns a conversion executor capable of converting string objects to the
* specified target class.
* @param targetClass the target class
* @return the conversion executor, never null
*/
protected ConversionExecutor fromStringTo(Class targetClass) {
return getConversionService().getConversionExecutor(String.class, targetClass);
}
/**
* Returns a conversion executor capable of converting string objects to the
* target class aliased by the provided alias.
* @param targetAlias the target class alias, e.g "long" or "float"
* @return the conversion executor, or <code>null</code> if no suitable
* converter exists for alias
*/
protected ConversionExecutor fromStringToAliased(String targetAlias) {
return getConversionService().getConversionExecutorByTargetAlias(String.class, targetAlias);
}
/**
* Returns a conversion executor capable of converting objects from one
* class to another.
* @param sourceClass the source class to convert from
* @param targetClass the target class to convert to
* @return the conversion executor, never null
*/
protected ConversionExecutor converterFor(Class sourceClass, Class targetClass) {
return getConversionService().getConversionExecutor(sourceClass, targetClass);
}
/**
* Helper that parsers the given expression string into an expression, using
* the installed String-&gt;Expression converter.
* @param expressionString the expression string to parse
* @return the parsed, evaluatable expression
*/
protected Expression parseExpression(String expressionString) {
return (Expression)fromStringTo(Expression.class).execute(expressionString);
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import java.beans.PropertyEditorSupport;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.util.Assert;
/**
* Adapts a Converter to the PropertyEditor interface.
* <p>
* Note: with a converter, only forward conversion from-string-to-value is
* supported. Value-to-string conversion is not supported. If you need this
* capability, use a Formatter with a FormatterPropertyEditor adapter.
*
* @see org.springframework.binding.format.Formatter
* @see org.springframework.binding.format.support.FormatterPropertyEditor
*
* @author Keith Donald
*/
public class ConverterPropertyEditorAdapter extends PropertyEditorSupport {
private ConversionExecutor conversionExecutor;
/**
* Adapt given conversion executor to the PropertyEditor contract.
*/
public ConverterPropertyEditorAdapter(ConversionExecutor conversionExecutor) {
Assert.notNull(conversionExecutor, "A conversion executor is required");
Assert.isTrue(conversionExecutor.getSourceClass().equals(String.class),
"A string conversion executor is required");
this.conversionExecutor = conversionExecutor;
}
/**
* Returns the type strings will be converted to.
*/
public Class getTargetClass() {
return conversionExecutor.getTargetClass();
}
public void setAsText(String text) throws IllegalArgumentException {
setValue(conversionExecutor.execute(text));
}
public String getAsText() {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.util.Assert;
/**
* Registers all 'from string' converters known to a conversion service with
* a Spring bean factory.
* <p>
* Acts as bean factory post processor, registering property editor adapters for
* each supported conversion with a <code>java.lang.String sourceClass</code>.
* This makes for very convenient use with the Spring container.
*
* @author Keith Donald
*/
public class CustomConverterConfigurer implements BeanFactoryPostProcessor, InitializingBean {
private ConversionService conversionService;
/**
* Create a new configurer.
* @param conversionService the conversion service to take converters from
*/
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
}
public void afterPropertiesSet() throws Exception {
Assert.notNull(conversionService, "The conversion service is required");
}
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
ConversionExecutor[] executors = conversionService.getConversionExecutorsForSource(String.class);
for (int i = 0; i < executors.length; i++) {
ConverterPropertyEditorAdapter editor = new ConverterPropertyEditorAdapter(executors[i]);
beanFactory.registerCustomEditor(editor.getTargetClass(), editor);
}
}
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.springframework.binding.format.support.SimpleFormatterFactory;
import org.springframework.core.enums.LabeledEnum;
/**
* Default, local implementation of a conversion service. Will automatically
* register <i>from string</i> converters for a number of standard Java
* types like Class, Number, Boolean and so on.
*
* @author Keith Donald
*/
public class DefaultConversionService extends GenericConversionService {
/**
* Creates a new default conversion service, installing the default
* converters.
*/
public DefaultConversionService() {
addDefaultConverters();
}
/**
* Add all default converters to the conversion service.
*/
protected void addDefaultConverters() {
addConverter(new TextToClass());
addConverter(new TextToNumber(new SimpleFormatterFactory()));
addConverter(new TextToBoolean());
addConverter(new TextToLabeledEnum());
addDefaultAlias(String.class);
addDefaultAlias(Short.class);
addDefaultAlias(Integer.class);
addAlias("int", Integer.class);
addDefaultAlias(Byte.class);
addDefaultAlias(Long.class);
addDefaultAlias(Float.class);
addDefaultAlias(Double.class);
addDefaultAlias(BigInteger.class);
addDefaultAlias(BigDecimal.class);
addDefaultAlias(Boolean.class);
addDefaultAlias(Class.class);
addDefaultAlias(LabeledEnum.class);
}
}

View File

@@ -0,0 +1,300 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import org.springframework.binding.convert.ConversionException;
import org.springframework.binding.convert.ConversionExecutor;
import org.springframework.binding.convert.ConversionService;
import org.springframework.binding.convert.Converter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Base implementation of a conversion service. Initially empty, e.g. no converters
* are registered by default.
*
* @author Keith Donald
*/
public class GenericConversionService implements ConversionService {
/**
* An indexed map of converters. Each entry key is a source class that can
* be converted from, and each entry value is a map of target classes that
* can be convertered to, ultimately mapping to a specific converter that
* can perform the source->target conversion.
*/
private Map sourceClassConverters = new HashMap();
/**
* A map of string aliases to convertible classes. Allows lookup of
* converters by alias.
*/
private Map aliasMap = new HashMap();
/**
* An optional parent conversion service.
*/
private ConversionService parent;
/**
* Returns the parent of this conversion service. Could be null.
*/
public ConversionService getParent() {
return parent;
}
/**
* Set the parent of this conversion service. This is optional.
*/
public void setParent(ConversionService parent) {
this.parent = parent;
}
/**
* Add given converter to this conversion service. If the converter is
* {@link ConversionServiceAware}, it will get the conversion service
* injected.
*/
public void addConverter(Converter converter) {
Class[] sourceClasses = converter.getSourceClasses();
Class[] targetClasses = converter.getTargetClasses();
for (int i = 0; i < sourceClasses.length; i++) {
Class sourceClass = sourceClasses[i];
Map sourceMap = (Map)sourceClassConverters.get(sourceClass);
if (sourceMap == null) {
sourceMap = new HashMap();
sourceClassConverters.put(sourceClass, sourceMap);
}
for (int j = 0; j < targetClasses.length; j++) {
Class targetClass = targetClasses[j];
sourceMap.put(targetClass, converter);
}
}
if (converter instanceof ConversionServiceAware) {
((ConversionServiceAware)converter).setConversionService(this);
}
}
/**
* Add all given converters. If the converters are
* {@link ConversionServiceAware}, they will get the conversion service
* injected.
*/
public void addConverters(Converter[] converters) {
for (int i = 0; i < converters.length; i++) {
addConverter(converters[i]);
}
}
/**
* Add given converter with an alias to the conversion service. If the
* converter is {@link ConversionServiceAware}, it will get the conversion
* service injected.
*/
public void addConverter(Converter converter, String alias) {
aliasMap.put(alias, converter);
addConverter(converter);
}
/**
* Add an alias for given target type.
*/
public void addAlias(String alias, Class targetType) {
aliasMap.put(alias, targetType);
}
/**
* Generate a conventions based alias for given target type. For instance,
* "java.lang.Boolean" will get the "boolean" alias.
*/
public void addDefaultAlias(Class targetType) {
addAlias(StringUtils.uncapitalize(ClassUtils.getShortName(targetType)), targetType);
}
public ConversionExecutor getConversionExecutor(Class sourceClass, Class targetClass) throws ConversionException {
Assert.notNull(sourceClass, "The source class to convert from is required");
Assert.notNull(targetClass, "The target class to convert to is required");
if (this.sourceClassConverters == null || this.sourceClassConverters.isEmpty()) {
throw new IllegalStateException("No converters have been added to this service's registry");
}
if (sourceClass.equals(targetClass)) {
return new ConversionExecutor(sourceClass, targetClass, new NoOpConverter(sourceClass, targetClass));
}
Map sourceTargetConverters = findConvertersForSource(sourceClass);
Converter converter = findTargetConverter(sourceTargetConverters, targetClass);
if (converter != null) {
// we found a converter
return new ConversionExecutor(sourceClass, targetClass, converter);
}
else {
if (parent != null) {
// try the parent
return parent.getConversionExecutor(sourceClass, targetClass);
}
else {
throw new ConversionException(sourceClass, targetClass,
"No converter registered to convert from sourceClass '" + sourceClass +
"' to target class '" + targetClass + "'");
}
}
}
public ConversionExecutor getConversionExecutorByTargetAlias(Class sourceClass, String alias)
throws IllegalArgumentException {
Assert.notNull(sourceClass, "The source class to convert from is required");
Assert.hasText(alias, "The target alias is required and must either be a type alias (e.g 'boolean') "
+ "or a generic converter alias (e.g. 'bean') ");
Object targetType = aliasMap.get(alias);
if (targetType == null) {
if (parent != null) {
// try the parent
return parent.getConversionExecutorByTargetAlias(sourceClass, alias);
}
else {
// not aliased
return null;
}
}
else if (targetType instanceof Class) {
return getConversionExecutor(sourceClass, (Class)targetType);
}
else {
Assert.isInstanceOf(Converter.class, targetType, "Not a converter: ");
Converter conv = (Converter)targetType;
return new ConversionExecutor(sourceClass, Object.class, conv);
}
}
public ConversionExecutor[] getConversionExecutorsForSource(Class sourceClass) {
Assert.notNull(sourceClass, "The source class to convert from is required");
Map sourceTargetConverters = findConvertersForSource(sourceClass);
if (sourceTargetConverters.isEmpty()) {
if (parent != null) {
// use the parent
return parent.getConversionExecutorsForSource(sourceClass);
}
else {
// no converters for source class
return new ConversionExecutor[0];
}
}
else {
Set executors = new HashSet();
if (parent != null) {
executors.addAll(Arrays.asList(parent.getConversionExecutorsForSource(sourceClass)));
}
Iterator it = sourceTargetConverters.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry)it.next();
executors.add(new ConversionExecutor(sourceClass, (Class)entry.getKey(), (Converter)entry.getValue()));
}
return (ConversionExecutor[])executors.toArray(new ConversionExecutor[executors.size()]);
}
}
public Class getClassByAlias(String alias) {
Assert.hasText(alias, "The alias is required and must be a type alias (e.g 'boolean')");
Object clazz = aliasMap.get(alias);
if (clazz != null) {
Assert.isInstanceOf(Class.class, clazz, "Not a Class alias '" + alias + "': ");
return (Class)clazz;
}
else {
if (parent != null) {
// try parent service
return parent.getClassByAlias(alias);
}
else {
// alias does not index a class, return null
return null;
}
}
}
// internal helpers
private Map findConvertersForSource(Class sourceClass) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(sourceClass);
while (!classQueue.isEmpty()) {
sourceClass = (Class)classQueue.removeLast();
Map sourceTargetConverters = (Map)sourceClassConverters.get(sourceClass);
if (sourceTargetConverters != null && !sourceTargetConverters.isEmpty()) {
return sourceTargetConverters;
}
if (!sourceClass.isInterface() && (sourceClass.getSuperclass() != null)) {
classQueue.addFirst(sourceClass.getSuperclass());
}
// queue up source class's implemented interfaces.
Class[] interfaces = sourceClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
}
}
return Collections.EMPTY_MAP;
}
private Converter findTargetConverter(Map sourceTargetConverters, Class targetClass) {
LinkedList classQueue = new LinkedList();
classQueue.addFirst(targetClass);
while (!classQueue.isEmpty()) {
targetClass = (Class)classQueue.removeLast();
Converter converter = (Converter)sourceTargetConverters.get(targetClass);
if (converter != null) {
return converter;
}
if (!targetClass.isInterface() && (targetClass.getSuperclass() != null)) {
classQueue.addFirst(targetClass.getSuperclass());
}
// queue up target class's implemented interfaces.
Class[] interfaces = targetClass.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
classQueue.addFirst(interfaces[i]);
}
}
return null;
}
// subclassing support
/**
* Returns an indexed map of converters. Each entry key is a source class that
* can be converted from, and each entry value is a map of target classes that
* can be convertered to, ultimately mapping to a specific converter that can
* perform the source->target conversion.
*/
protected Map getSourceClassConverters() {
return sourceClassConverters;
}
/**
* Returns a map of known aliases. Each entry key is a String alias and the
* associated value is either a target class or a converter.
*/
protected Map getAliasMap() {
return aliasMap;
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionContext;
/**
* Package private converter that is a "no op".
*
* @author Keith Donald
*/
class NoOpConverter extends AbstractConverter {
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;
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
return source;
}
public Class[] getSourceClasses() {
return new Class[] { sourceClass };
}
public Class[] getTargetClasses() {
return new Class[] { targetClass };
}
}

View File

@@ -0,0 +1,100 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.util.StringUtils;
/**
* Converts a textual representation of a boolean object to a <code>Boolean</code>
* instance.
*
* @author Keith Donald
*/
public class TextToBoolean extends AbstractConverter {
private static final String VALUE_TRUE = "true";
private static final String VALUE_FALSE = "false";
private static final String VALUE_ON = "on";
private static final String VALUE_OFF = "off";
private static final String VALUE_YES = "yes";
private static final String VALUE_NO = "no";
private static final String VALUE_1 = "1";
private static final String VALUE_0 = "0";
private String trueString;
private String falseString;
/**
* Default constructor. No special true or false strings are considered.
*/
public TextToBoolean() {
this(null, null);
}
/**
* Create a text to boolean converter. Take given <i>special</i> string representations
* of true and false into account.
* @param trueString special true string to consider
* @param falseString special false string to consider
*/
public TextToBoolean(String trueString, String falseString) {
this.trueString = trueString;
this.falseString = falseString;
}
public Class[] getSourceClasses() {
return new Class[] { String.class };
}
public Class[] getTargetClasses() {
return new Class[] { Boolean.class };
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String text = (String)source;
if (!StringUtils.hasText(text)) {
return null;
}
else if (this.trueString != null && text.equalsIgnoreCase(this.trueString)) {
return Boolean.TRUE;
}
else if (this.falseString != null && text.equalsIgnoreCase(this.falseString)) {
return Boolean.FALSE;
}
else if (this.trueString == null
&& (text.equalsIgnoreCase(VALUE_TRUE) || text.equalsIgnoreCase(VALUE_ON)
|| text.equalsIgnoreCase(VALUE_YES) || text.equals(VALUE_1))) {
return Boolean.TRUE;
}
else if (this.falseString == null
&& (text.equalsIgnoreCase(VALUE_FALSE) || text.equalsIgnoreCase(VALUE_OFF)
|| text.equalsIgnoreCase(VALUE_NO) || text.equals(VALUE_0))) {
return Boolean.FALSE;
}
else {
throw new IllegalArgumentException("Invalid boolean value [" + text + "]");
}
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* Converts a textual representation of a class object to a <code>Class</code>
* instance.
*
* @author Keith Donald
*/
public class TextToClass extends ConversionServiceAwareConverter {
private static final String ALIAS_PREFIX = "type:";
private static final String CLASS_PREFIX = "class:";
public Class[] getSourceClasses() {
return new Class[] { String.class };
}
public Class[] getTargetClasses() {
return new Class[] { Class.class };
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String text = (String)source;
if (StringUtils.hasText(text)) {
String classNameOrAlias = text.trim();
if (classNameOrAlias.startsWith(CLASS_PREFIX)) {
return ClassUtils.forName(text.substring(CLASS_PREFIX.length()));
}
else if (classNameOrAlias.startsWith(ALIAS_PREFIX)) {
String alias = text.substring(ALIAS_PREFIX.length());
Class clazz = getConversionService().getClassByAlias(alias);
Assert.notNull(clazz, "No class found associated with type alias '" + alias + "'");
return clazz;
}
else {
// try first an aliased based lookup
if (getConversionService() != null) {
Class aliasedClass = getConversionService().getClassByAlias(text);
if (aliasedClass != null) {
return aliasedClass;
}
}
// treat as a class name
return ClassUtils.forName(classNameOrAlias);
}
}
else {
return null;
}
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.binding.expression.Expression;
import org.springframework.binding.expression.ExpressionParser;
import org.springframework.binding.expression.SettableExpression;
import org.springframework.binding.expression.support.StaticExpression;
import org.springframework.util.Assert;
/**
* Converter that converts a String into an Expression object.
*
* @see org.springframework.binding.expression.Expression
* @see org.springframework.binding.expression.SettableExpression
*
* @author Erwin Vervaet
*/
public class TextToExpression extends AbstractConverter {
/**
* The expression string parser.
*/
private ExpressionParser expressionParser;
/**
* Creates a new string-to-expression converter.
* @param expressionParser the expression string parser
*/
public TextToExpression(ExpressionParser expressionParser) {
Assert.notNull(expressionParser, "The expression parser is required");
this.expressionParser = expressionParser;
}
/**
* Returns the expression parser used by this converter.
*/
public ExpressionParser getExpressionParser() {
return expressionParser;
}
public Class[] getSourceClasses() {
return new Class[] { String.class };
}
public Class[] getTargetClasses() {
return new Class[] { Expression.class, SettableExpression.class };
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
String expressionString = (String)source;
if (getExpressionParser().isDelimitedExpression(expressionString)) {
return getExpressionParser().parseExpression((String)source);
}
else {
return new StaticExpression(expressionString);
}
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.binding.format.support.LabeledEnumFormatter;
import org.springframework.core.enums.LabeledEnum;
/**
* Converter that converts textual representations of enum
* instances to a specific instance of <code>LabeledEnum</code>.
*
* @author Keith Donald
*/
public class TextToLabeledEnum extends AbstractConverter {
private LabeledEnumFormatter labeledEnumFormatter = new LabeledEnumFormatter();
public Class[] getSourceClasses() {
return new Class[] { String.class };
}
public Class[] getTargetClasses() {
return new Class[] { LabeledEnum.class };
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
return labeledEnumFormatter.parseValue((String)source, targetClass);
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.convert.support;
import java.math.BigDecimal;
import java.math.BigInteger;
import org.springframework.binding.convert.ConversionContext;
import org.springframework.binding.format.FormatterFactory;
import org.springframework.binding.format.support.SimpleFormatterFactory;
/**
* Converts textual representations of numbers to a <code>Number</code>
* specialization. Delegates to a synchronized formatter to parse text strings.
*
* @author Keith Donald
*/
public class TextToNumber extends AbstractFormattingConverter {
/**
* Default constructor that uses a {@link SimpleFormatterFactory}.
*/
public TextToNumber() {
super(new SimpleFormatterFactory());
}
/**
* Create a string to number converter using given formatter factory.
* @param formatterFactory the factory to use
*/
public TextToNumber(FormatterFactory formatterFactory) {
super(formatterFactory);
}
public Class[] getSourceClasses() {
return new Class[] { String.class };
}
public Class[] getTargetClasses() {
return new Class[] { Integer.class, Short.class, Byte.class, Long.class, Float.class, Double.class,
BigInteger.class, BigDecimal.class };
}
protected Object doConvert(Object source, Class targetClass, ConversionContext context) throws Exception {
return getFormatterFactory().getNumberFormatter(targetClass).parseValue((String)source, targetClass);
}
}

View File

@@ -0,0 +1,7 @@
<html>
<body>
<p>
Supporting type converter implementations that are generically applicable and frequently used.
</p>
</body>
</html>

View File

@@ -0,0 +1,85 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.expression;
import java.io.Serializable;
import org.springframework.core.style.ToStringCreator;
/**
* A simple holder for information about an evaluation attempt.
*
* @author Keith Donald
*/
public class EvaluationAttempt implements Serializable {
/**
* The expression that attempted to evaluate.
*/
private Expression expression;
/**
* The target object being evaluated.
*/
private Object target;
/**
* The evaluation context.
*/
private EvaluationContext context;
/**
* Create an evaluation attempt.
* @param expression the expression that failed to evaluate
* @param target the target of the expression
* @param context the context attributes that might have affected evaluation behavior
*/
public EvaluationAttempt(Expression expression, Object target, EvaluationContext context) {
this.expression = expression;
this.target = target;
this.context = context;
}
/**
* Returns the expression that attempted to evaluate.
*/
public Expression getExpression() {
return expression;
}
/**
* Returns the target object upon which evaluation was attempted.
*/
public Object getTarget() {
return target;
}
/**
* Returns context attributes that may have influenced the evaluation process.
*/
public EvaluationContext getContext() {
return context;
}
public String toString() {
return createToString(new ToStringCreator(this)).toString();
}
protected ToStringCreator createToString(ToStringCreator creator) {
return creator.append("expression", expression).append("target", target).append("context",
context);
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.expression;
import java.util.Map;
/**
* A context object with two main responsibities:
* <ol>
* <li>Exposing information to an expression to influence
* an evaluation attempt.
* <li>Providing operations for recording progress or
* errors during the expression evaluation process.
* </ol>
*
* @author Keith Donald
*/
public interface EvaluationContext {
/**
* Returns a map of attributes that can be used to influence expression evaluation.
* @return the evaluation attributes
*/
public Map getAttributes();
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.expression;
import org.springframework.core.NestedRuntimeException;
/**
* Indicates an expression evaluation failed.
*
* @author Keith Donald
*/
public class EvaluationException extends NestedRuntimeException {
/**
* The evaluation attempt that failed.
*/
private EvaluationAttempt evaluationAttempt;
/**
* Creates a new evaluation exception.
* @param evaluationAttempt the evaluation attempt that failed
* @param cause the underlying cause of this exception
*/
public EvaluationException(EvaluationAttempt evaluationAttempt, Throwable cause) {
super("Expression " + evaluationAttempt
+ " failed - make sure the expression is evaluatable on the target object", cause);
this.evaluationAttempt = evaluationAttempt;
}
/**
* Returns the evaluation attempt that failed.
*/
public EvaluationAttempt getEvaluationAttempt() {
return evaluationAttempt;
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2002-2006 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.expression;
/**
* Evaluates a single parsed expression on the provided input object in the
* specified context. This provides a common abstraction for expression
* evaluation independent of any language like OGNL or Spring's BeanWrapper.
*
* @author Keith Donald
*/
public interface Expression {
/**
* Evaluate the expression encapsulated by this evaluator against the
* provided target object and return the result of the evaluation.
* @param target the target of the expression
* @param context the expression evaluation context
* @return the evaluation result
* @throws EvaluationException an exception occured during evaluation
*/
public Object evaluate(Object target, EvaluationContext context) throws EvaluationException;
}

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