[jboss-svn-commits] JBoss PortletSwap SVN: r111 - in portlets/src/framework: . spring-portlet-sample spring-portlet-sample/WEB-INF spring-portlet-sample/WEB-INF/context spring-portlet-sample/WEB-INF/context/portlet spring-portlet-sample/WEB-INF/dtd spring-portlet-sample/WEB-INF/jsp spring-portlet-sample/WEB-INF/lib spring-portlet-sample/WEB-INF/src spring-portlet-sample/WEB-INF/src/org spring-portlet-sample/WEB-INF/src/org/springframework spring-portlet-sample/WEB-INF/src/org/springframework/web spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test spring-portlet-sample/WEB-INF/tags spring-portlet-sample/WEB-INF/tags/html spring-portlet-sample/build spring-portlet-sample/images spring-portlet-sample/lib

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Tue Jul 25 13:46:59 EDT 2006


Author: roy.russo at jboss.com
Date: 2006-07-25 13:42:17 -0400 (Tue, 25 Jul 2006)
New Revision: 111

Added:
   portlets/src/framework/spring-portlet-sample/
   portlets/src/framework/spring-portlet-sample/.classpath
   portlets/src/framework/spring-portlet-sample/.project
   portlets/src/framework/spring-portlet-sample/.tomcatplugin
   portlets/src/framework/spring-portlet-sample/JBOSS_README.txt
   portlets/src/framework/spring-portlet-sample/WEB-INF/
   portlets/src/framework/spring-portlet-sample/WEB-INF/books.properties
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/applicationContext.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/books.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/exceptions.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/helloworld.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/mode.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/redirect.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/upload.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/dtd/
   portlets/src/framework/spring-portlet-sample/WEB-INF/dtd/spring-beans.dtd
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookAdd.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookEdit.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookView.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksHelp.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksView.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/defError.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/edit.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/exceptions.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/help.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/include.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAuthorized.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAvailable.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/redirect.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/upload.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/view.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-fileupload.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-io.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-logging.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/jstl.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/log4j.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-aop.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-beans.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-context.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-core.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-dao.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-mock.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-portlet.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-web.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-webmvc.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/lib/standard.jar
   portlets/src/framework/spring-portlet-sample/WEB-INF/portlet-instances.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/portlet.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/springportlet-object.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/log4j.properties
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages.properties
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages_de.properties
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Book.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookAddController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookDeleteController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookEditController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookIncrementController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookService.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookValidator.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookViewController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BooksController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/ExceptionsController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/HelloWorldPortlet.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/PortletNameInterceptor.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectCommand.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Upload.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/UploadController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/AllTests.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestBookViewController.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestCase.java
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/c.tld
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fmt.tld
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fn.tld
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/attributes.tag
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/errors.tag
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/imagesPath.tag
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/include.jsp
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/input.tag
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/rootPath.tag
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/textarea.tag
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/portlet.tld
   portlets/src/framework/spring-portlet-sample/WEB-INF/tags/spring.tld
   portlets/src/framework/spring-portlet-sample/WEB-INF/web.dist.xml
   portlets/src/framework/spring-portlet-sample/WEB-INF/web.xml
   portlets/src/framework/spring-portlet-sample/build.xml
   portlets/src/framework/spring-portlet-sample/build/
   portlets/src/framework/spring-portlet-sample/build/spring-portlet-sample.war
   portlets/src/framework/spring-portlet-sample/build/spring-portlet-sample.zip
   portlets/src/framework/spring-portlet-sample/images/
   portlets/src/framework/spring-portlet-sample/images/decrease.png
   portlets/src/framework/spring-portlet-sample/images/delete.png
   portlets/src/framework/spring-portlet-sample/images/edit.png
   portlets/src/framework/spring-portlet-sample/images/increase.png
   portlets/src/framework/spring-portlet-sample/images/new.png
   portlets/src/framework/spring-portlet-sample/lib/
   portlets/src/framework/spring-portlet-sample/lib/junit.jar
   portlets/src/framework/spring-portlet-sample/lib/portlet-api.jar
   portlets/src/framework/spring-portlet-sample/readme.txt
Log:


Added: portlets/src/framework/spring-portlet-sample/.classpath
===================================================================
--- portlets/src/framework/spring-portlet-sample/.classpath	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/.classpath	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="var" path="TOMCAT_HOME/common/lib/servlet-api.jar"/>
+	<classpathentry kind="var" path="TOMCAT_HOME/common/lib/jasper-runtime.jar"/>
+	<classpathentry kind="var" path="TOMCAT_HOME/common/lib/jsp-api.jar"/>
+	<classpathentry kind="src" path="WEB-INF/src"/>
+	<classpathentry kind="lib" path="lib/portlet-api.jar"/>
+	<classpathentry kind="lib" path="lib/junit.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/commons-logging.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-aop.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-beans.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-context.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-core.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-dao.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-mock.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-portlet.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-web.jar"/>
+	<classpathentry kind="lib" path="WEB-INF/lib/spring-webmvc.jar"/>
+	<classpathentry kind="output" path="WEB-INF/classes"/>
+</classpath>

Added: portlets/src/framework/spring-portlet-sample/.project
===================================================================
--- portlets/src/framework/spring-portlet-sample/.project	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/.project	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>spring-portlet-sample</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>
+		<nature>com.sysdeo.eclipse.tomcat.tomcatnature</nature>
+	</natures>
+</projectDescription>

Added: portlets/src/framework/spring-portlet-sample/.tomcatplugin
===================================================================
--- portlets/src/framework/spring-portlet-sample/.tomcatplugin	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/.tomcatplugin	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<tomcatProjectProperties>
+    <rootDir>/</rootDir>
+    <exportSource>false</exportSource>
+    <reloadable>true</reloadable>
+    <redirectLogger>false</redirectLogger>
+    <updateXml>true</updateXml>
+    <warLocation></warLocation>
+    <extraInfo></extraInfo>
+    <webPath>/spring-portlet-sample</webPath>
+</tomcatProjectProperties>

Added: portlets/src/framework/spring-portlet-sample/JBOSS_README.txt
===================================================================
--- portlets/src/framework/spring-portlet-sample/JBOSS_README.txt	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/JBOSS_README.txt	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,5 @@
+These portlets were taken from the Spring MVC Portlet project page at: http://opensource.atlassian.com/confluence/spring/display/JSR168/Home
+, and adapted for use in JBoss Portal.
+
+To deploy:
+- run 'ant build' and deploy the build/spring-portlet-sample.war in JBoss AS.
\ No newline at end of file


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF
___________________________________________________________________
Name: svn:ignore
   + classes


Added: portlets/src/framework/spring-portlet-sample/WEB-INF/books.properties
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/books.properties	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/books.properties	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1 @@
+books.initBooks=4
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/applicationContext.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/applicationContext.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/applicationContext.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../dtd/spring-beans.dtd">
+
+<beans>
+
+	<!-- Message source for this context, loaded from localized "messages_xx" files -->
+	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
+		<property name="basenames">
+			<list>
+				<value>messages</value>
+			</list>
+		</property>										
+	</bean>
+
+	<!-- Default View Resolver -->
+	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
+		<property name="cache" value="false"/>
+		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
+		<property name="prefix" value="/WEB-INF/jsp/"/>
+		<property name="suffix" value=".jsp"/>
+	</bean>
+
+	<!-- Abstract Default Exception Handler Bean -->
+    <bean id="defaultExceptionHandlerTemplate" class="org.springframework.web.portlet.handler.SimpleMappingExceptionResolver" abstract="true">
+		<property name="defaultErrorView" value="defError"/>
+		<property name="exceptionMappings">
+			<props>
+				<prop key="javax.portlet.PortletSecurityException">notAuthorized</prop>
+				<prop key="javax.portlet.UnavailableException">notAvailable</prop>
+			</props>
+		</property>  
+	</bean>
+
+	<bean id="portletNameInterceptor" class="org.springframework.web.portlet.sample.PortletNameInterceptor"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/books.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/books.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/books.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../../dtd/spring-beans.dtd">
+<beans>
+
+	<!-- Property Configurer  -->
+	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+		<property name="locations">
+			<list>
+				<value>WEB-INF/books.properties</value>
+			</list>
+		</property>
+	</bean>
+
+	<!-- Services -->
+
+	<bean id="bookService" class="org.springframework.web.portlet.sample.BookService">
+		<property name="initBooks" value="${books.initBooks}"/>
+	</bean>
+	
+	<!-- Validators -->
+
+	<bean id="bookValidator" class="org.springframework.web.portlet.sample.BookValidator"/>
+
+	<!-- Controllers -->
+
+	<bean id="booksControllerTemplate" abstract="true">
+		<property name="bookService"><ref bean="bookService"/></property>
+	</bean>
+
+	<bean id="booksController" class="org.springframework.web.portlet.sample.BooksController" parent="booksControllerTemplate"/>
+
+	<bean id="bookIncrementController" class="org.springframework.web.portlet.sample.BookIncrementController" parent="booksControllerTemplate"/>
+
+    <bean id="bookViewController" class="org.springframework.web.portlet.sample.BookViewController" parent="booksControllerTemplate"/>
+
+    <bean id="bookEditController" class="org.springframework.web.portlet.sample.BookEditController" parent="booksControllerTemplate">
+		<property name="sessionForm" value="true"/>
+		<property name="commandName" value="book"/>
+		<property name="commandClass" value="org.springframework.web.portlet.sample.Book"/>
+		<property name="formView" value="bookEdit"/>
+		<property name="validator"><ref bean="bookValidator"/></property> 
+    </bean>
+
+    <bean id="bookAddController" class="org.springframework.web.portlet.sample.BookAddController" parent="booksControllerTemplate">
+		<property name="sessionForm" value="true"/>
+		<property name="commandName" value="book"/>
+		<property name="commandClass" value="org.springframework.web.portlet.sample.Book"/>
+		<property name="pageAttribute" value="page"/>
+		<property name="pages" value="bookAdd,bookAdd,bookAdd,bookAdd,bookAdd"/>
+		<property name="validator"><ref bean="bookValidator"/></property> 
+    </bean>
+
+	<bean id="bookDeleteController" class="org.springframework.web.portlet.sample.BookDeleteController" parent="booksControllerTemplate"/>
+
+	<bean id="booksHelpController" class="org.springframework.web.portlet.mvc.ParameterizableViewController">
+		<property name="viewName" value="booksHelp"/>
+	</bean>
+
+	<!-- Handler Mapping -->
+	
+	<bean id="parameterMappingInterceptor" class="org.springframework.web.portlet.handler.ParameterMappingInterceptor"/>
+
+	<bean id="portletModeParameterHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping">
+        <property name="order" value="10"/>
+		<property name="interceptors">
+			<list>
+				<ref bean="parameterMappingInterceptor"/>
+			</list>
+		</property>
+		<property name="portletModeParameterMap">
+			<map>
+				<entry key="view">
+					<map>
+						<entry key="books"><ref bean="booksController"/></entry>
+						<entry key="incrementBook"><ref bean="bookIncrementController"/></entry>
+						<entry key="viewBook"><ref bean="bookViewController"/></entry>
+						<entry key="editBook"><ref bean="bookEditController"/></entry>
+						<entry key="deleteBook"><ref bean="bookDeleteController"/></entry>
+						<entry key="addBook"><ref bean="bookAddController"/></entry>
+					</map>
+				</entry>
+			</map>
+		</property>
+	</bean>
+
+	<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
+        <property name="order" value="20"/>
+		<property name="portletModeMap">
+			<map>
+				<entry key="view"><ref bean="booksController"/></entry>
+				<entry key="help"><ref bean="booksHelpController"/></entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Exceptions Handler -->
+
+	<bean id="defaultExceptionHandler" parent="defaultExceptionHandlerTemplate"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/exceptions.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/exceptions.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/exceptions.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../../dtd/spring-beans.dtd">
+<beans>
+
+	<!-- Controllers -->
+
+	<bean id="sampleExceptionsController" class="org.springframework.web.portlet.sample.ExceptionsController"/>
+
+	<!-- Handler Mapping -->
+	
+	<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
+		<property name="portletModeMap">
+			<map>
+				<entry key="view"><ref bean="sampleExceptionsController"/></entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Exceptions Handler -->
+
+	<bean id="defaultExceptionHandler" parent="defaultExceptionHandlerTemplate"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/helloworld.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/helloworld.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/helloworld.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../../dtd/spring-beans.dtd">
+<beans>
+
+	<!-- Reused Portlet -->
+
+	<bean id="helloWorldPortlet" class="org.springframework.web.portlet.mvc.PortletWrappingController">
+		<property name="portletClass">
+			<value>org.springframework.web.portlet.sample.HelloWorldPortlet</value>
+		</property>
+		<property name="useSharedPortletConfig">
+			<value>false</value>
+		</property>
+		<property name="portletName">
+			<value>wrapped-hello-world</value>
+		</property>
+		<property name="initParameters">
+			<props>
+				<prop key="HarryPotter">The magic property</prop>
+				<prop key="JerrySeinfeld">The funny property</prop>
+			</props>
+		</property>
+	</bean>
+	
+	<!-- Alternate method to reuse portlet - simpler, but no ability to rename or set init parameters
+	<bean id="simplePortletHandlerAdapter" class="org.springframework.web.portlet.handler.SimplePortletHandlerAdapter"/>
+	<bean id="simplePortletPostProcessor" class="org.springframework.web.portlet.handler.SimplePortletPostProcessor"/>
+	<bean id="helloWorldPortlet" class="org.springframework.web.portlet.sample.HelloWorldPortlet"/>
+	-->
+
+	<!-- Handler Mapping -->
+	
+	<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
+		<property name="portletModeMap">
+			<map>
+				<entry key="view"><ref bean="helloWorldPortlet"/></entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Exceptions Handler -->
+
+	<bean id="defaultExceptionHandler" parent="defaultExceptionHandlerTemplate"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/mode.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/mode.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/mode.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../../dtd/spring-beans.dtd">
+<beans>
+
+	<!-- Controllers -->
+
+	<bean id="modeNameViewController" class="org.springframework.web.portlet.mvc.PortletModeNameViewController"/>
+
+	<!-- Handler Mapping -->
+	
+	<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
+		<property name="interceptors">
+			<list>
+				<ref bean="portletNameInterceptor"/>
+			</list>
+		</property>
+		<property name="portletModeMap">
+			<map>
+				<entry key="view"><ref bean="modeNameViewController"/></entry>
+				<entry key="edit"><ref bean="modeNameViewController"/></entry>
+				<entry key="help"><ref bean="modeNameViewController"/></entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Exceptions Handler -->
+
+	<bean id="defaultExceptionHandler" parent="defaultExceptionHandlerTemplate"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/redirect.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/redirect.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/redirect.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../../dtd/spring-beans.dtd">
+<beans>
+
+	<!-- Controllers -->
+
+    <bean id="redirectController" class="org.springframework.web.portlet.sample.RedirectController">
+		<property name="sessionForm" value="true"/>
+		<property name="commandName" value="redirect"/>
+		<property name="commandClass" value="org.springframework.web.portlet.sample.RedirectCommand"/>
+		<property name="formView" value="redirect"/>
+    </bean>
+
+	<!-- Handler Mapping -->
+	
+	<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
+		<property name="portletModeMap">
+			<map>
+				<entry key="view"><ref bean="redirectController"/></entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Exceptions Handler -->
+
+	<bean id="defaultExceptionHandler" parent="defaultExceptionHandlerTemplate"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/upload.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/upload.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/context/portlet/upload.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "../../dtd/spring-beans.dtd">
+<beans>
+
+	<bean id="portletMultipartResolver" class="org.springframework.web.portlet.multipart.CommonsPortletMultipartResolver">
+		<property name="maxUploadSize">
+			<value>2048</value>
+		</property>
+	</bean>
+
+	<!-- Controllers -->
+
+    <bean id="uploadController" class="org.springframework.web.portlet.sample.UploadController">
+		<property name="sessionForm" value="true"/>
+		<property name="commandName" value="upload"/>
+		<property name="commandClass" value="org.springframework.web.portlet.sample.Upload"/>
+		<property name="formView" value="upload"/>
+		<property name="successView" value="upload"/>
+    </bean>
+
+	<!-- Handler Mapping -->
+	
+	<bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
+		<property name="portletModeMap">
+			<map>
+				<entry key="view"><ref bean="uploadController"/></entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Exceptions Handler -->
+
+	<bean id="defaultExceptionHandler" parent="defaultExceptionHandlerTemplate"/>
+
+</beans>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/dtd/spring-beans.dtd
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/dtd/spring-beans.dtd	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/dtd/spring-beans.dtd	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,650 @@
+<!--
+	Spring XML Beans DTD
+	Authors: Rod Johnson, Juergen Hoeller, Alef Arendsen, Colin Sampaleanu, Rob Harrop
+
+	This defines a simple and consistent way of creating a namespace
+	of JavaBeans objects, managed by a Spring BeanFactory, read by
+	XmlBeanDefinitionReader (with DefaultXmlBeanDefinitionParser).
+
+	This document type is used by most Spring functionality, including
+	web application contexts, which are based on bean factories.
+
+	Each "bean" element in this document defines a JavaBean.
+	Typically the bean class is specified, along with JavaBean properties
+	and/or constructor arguments.
+
+	Bean instances can be "singletons" (shared instances) or "prototypes"
+	(independent instances). Further scopes are supposed to be built on top
+	of the core BeanFactory infrastructure and are therefore not part of it.
+
+	References among beans are supported, i.e. setting a JavaBean property
+	or a constructor argument to refer to another bean in the same factory
+	(or an ancestor factory).
+
+	As alternative to bean references, "inner bean definitions" can be used.
+	Singleton flags of such inner bean definitions are effectively ignored:
+	Inner beans are typically anonymous prototypes.
+
+	There is also support for lists, sets, maps, and java.util.Properties
+	as bean property types or constructor argument types.
+
+	As the format is simple, a DTD is sufficient, and there's no need
+	for a schema at this point.
+
+	XML documents that conform to this DTD should declare the following doctype:
+
+	<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
+		"http://www.springframework.org/dtd/spring-beans.dtd">
+-->
+
+
+<!--
+	The document root. A document can contain bean definitions only,
+	imports only, or a mixture of both (typically with imports first).
+-->
+<!ELEMENT beans (
+	description?,
+	(import | alias | bean)*
+)>
+
+<!--
+	Default values for all bean definitions. Can be overridden at
+	the "bean" level. See those attribute definitions for details.
+-->
+<!ATTLIST beans default-lazy-init (true | false) "false">
+<!ATTLIST beans default-autowire (no | byName | byType | constructor | autodetect) "no">
+<!ATTLIST beans default-dependency-check (none | objects | simple | all) "none">
+<!ATTLIST beans default-init-method CDATA #IMPLIED>
+<!ATTLIST beans default-destroy-method CDATA #IMPLIED>
+<!ATTLIST beans default-merge (true | false) "false">
+
+<!--
+	Element containing informative text describing the purpose of the enclosing
+	element. Always optional.
+	Used primarily for user documentation of XML bean definition documents.
+-->
+<!ELEMENT description (#PCDATA)>
+
+
+<!--
+	Specifies an XML bean definition resource to import.
+-->
+<!ELEMENT import EMPTY>
+
+<!--
+	The relative resource location of the XML bean definition file to import,
+	for example "myImport.xml" or "includes/myImport.xml" or "../myImport.xml".
+-->
+<!ATTLIST import resource CDATA #REQUIRED>
+
+
+<!--
+	Defines an alias for a bean, which can reside in a different definition file.
+-->
+<!ELEMENT alias EMPTY>
+
+<!--
+	The name of the bean to define an alias for.
+-->
+<!ATTLIST alias name CDATA #REQUIRED>
+
+<!--
+	The alias name to define for the bean.
+-->
+<!ATTLIST alias alias CDATA #REQUIRED>
+
+<!--
+  Allows for arbitrary metadata to be attached to a bean definition.
+-->
+<!ELEMENT meta EMPTY>
+
+<!--
+  Specifies the key name of the metdata parameter being defined
+-->
+<!ATTLIST meta key CDATA #REQUIRED>
+
+<!--
+  Specifies the value of the metadata parameter being defined as a String
+-->
+<!ATTLIST meta value CDATA #REQUIRED>
+
+<!--
+	Defines a single (usually named) bean.
+
+	A bean definition may contain nested tags for constructor arguments,
+	property values, lookup methods, and replaced methods. Mixing constructor
+	injection and setter injection on the same bean is explicitly supported.
+-->
+<!ELEMENT bean (
+	description?,
+	(meta | constructor-arg | property | lookup-method | replaced-method)*
+)>
+
+<!--
+	Beans can be identified by an id, to enable reference checking.
+
+	There are constraints on a valid XML id: if you want to reference your bean
+	in Java code using a name that's illegal as an XML id, use the optional
+	"name" attribute. If neither is given, the bean class name is used as id
+	(with an appended counter like "#2" if there is already a bean with that name).
+-->
+<!ATTLIST bean id ID #IMPLIED>
+
+<!--
+	Optional. Can be used to create one or more aliases illegal in an id.
+	Multiple aliases can be separated by any number of spaces, commas, or
+	semi-colons (or indeed any mixture of the three).
+-->
+<!ATTLIST bean name CDATA #IMPLIED>
+
+<!--
+	Each bean definition must specify the fully qualified name of the class,
+	except if it pure serves as parent for child bean definitions.
+-->
+<!ATTLIST bean class CDATA #IMPLIED>
+
+<!--
+	Optionally specify a parent bean definition.
+
+	Will use the bean class of the parent if none specified, but can
+	also override it. In the latter case, the child bean class must be
+	compatible with the parent, i.e. accept the parent's property values
+	and constructor argument values, if any.
+
+	A child bean definition will inherit constructor argument values,
+	property values and method overrides from the parent, with the option
+	to add new values. If init method, destroy method, factory bean and/or factory
+	method are specified, they will override the corresponding parent settings.
+
+	The remaining settings will always be taken from the child definition:
+	depends on, autowire mode, dependency check, singleton, lazy init.
+-->
+<!ATTLIST bean parent CDATA #IMPLIED>
+
+<!--
+	Is this bean "abstract", i.e. not meant to be instantiated itself but
+	rather just serving as parent for concrete child bean definitions.
+	Default is "false". Specify "true" to tell the bean factory to not try to
+	instantiate that particular bean in any case.
+
+	Note: This attribute will not be inherited by child bean definitions.
+	Hence, it needs to be specified per concrete bean definition.
+-->
+<!ATTLIST bean abstract (true | false) "false">
+
+<!--
+	Is this bean a "singleton" (one shared instance, which will
+	be returned by all calls to getBean() with the id),
+	or a "prototype" (independent instance resulting from each call to
+	getBean(). Default is singleton.
+
+	Singletons are most commonly used, and are ideal for multi-threaded
+	service objects.
+
+	Note: This attribute will not be inherited by child bean definitions.
+	Hence, it needs to be specified per concrete bean definition.
+-->
+<!ATTLIST bean singleton (true | false) "true">
+
+<!--
+	If this bean should be lazily initialized.
+	If false, it will get instantiated on startup by bean factories
+	that perform eager initialization of singletons.
+
+
+	Note: This attribute will not be inherited by child bean definitions.
+	Hence, it needs to be specified per concrete bean definition.
+-->
+<!ATTLIST bean lazy-init (true | false | default) "default">
+
+<!--
+  Indicates whether or not this bean should be considered when looking
+  for candidates to satisfy another beans autowiring requirements.
+-->
+<!ATTLIST bean autowire-candidate (true | false) "true">
+
+<!--
+	Optional attribute controlling whether to "autowire" bean properties.
+	This is an automagical process in which bean references don't need to be coded
+	explicitly in the XML bean definition file, but Spring works out dependencies.
+
+	There are 5 modes:
+
+	1. "no"
+	The traditional Spring default. No automagical wiring. Bean references
+	must be defined in the XML file via the <ref> element. We recommend this
+	in most cases as it makes documentation more explicit.
+
+	2. "byName"
+	Autowiring by property name. If a bean of class Cat exposes a dog property,
+	Spring will try to set this to the value of the bean "dog" in the current factory.
+	If there is no matching bean by name, nothing special happens;
+	use dependency-check="objects" to raise an error in that case.
+
+	3. "byType"
+	Autowiring if there is exactly one bean of the property type in the bean factory.
+	If there is more than one, a fatal error is raised, and you can't use byType
+	autowiring for that bean. If there is none, nothing special happens;
+	use dependency-check="objects" to raise an error in that case.
+
+	4. "constructor"
+	Analogous to "byType" for constructor arguments. If there isn't exactly one bean
+	of the constructor argument type in the bean factory, a fatal error is raised.
+
+	5. "autodetect"
+	Chooses "constructor" or "byType" through introspection of the bean class.
+	If a default constructor is found, "byType" gets applied.
+
+	The latter two are similar to PicoContainer and make bean factories simple to
+	configure for small namespaces, but doesn't work as well as standard Spring
+	behaviour for bigger applications.
+
+	Note that explicit dependencies, i.e. "property" and "constructor-arg" elements,
+	always override autowiring. Autowire behavior can be combined with dependency
+	checking, which will be performed after all autowiring has been completed.
+
+	Note: This attribute will not be inherited by child bean definitions.
+	Hence, it needs to be specified per concrete bean definition.
+-->
+<!ATTLIST bean autowire (no | byName | byType | constructor | autodetect | default) "default">
+
+<!--
+	Optional attribute controlling whether to check whether all this
+	beans dependencies, expressed in its properties, are satisfied.
+	Default is no dependency checking.
+
+	"simple" type dependency checking includes primitives and String
+	"object" includes collaborators (other beans in the factory)
+	"all" includes both types of dependency checking
+
+	Note: This attribute will not be inherited by child bean definitions.
+	Hence, it needs to be specified per concrete bean definition.
+-->
+<!ATTLIST bean dependency-check (none | objects | simple | all | default) "default">
+
+<!--
+	The names of the beans that this bean depends on being initialized.
+	The bean factory will guarantee that these beans get initialized before.
+
+	Note that dependencies are normally expressed through bean properties or
+	constructor arguments. This property should just be necessary for other kinds
+	of dependencies like statics (*ugh*) or database preparation on startup.
+
+	Note: This attribute will not be inherited by child bean definitions.
+	Hence, it needs to be specified per concrete bean definition.
+-->
+<!ATTLIST bean depends-on CDATA #IMPLIED>
+
+<!--
+	Optional attribute for the name of the custom initialization method
+	to invoke after setting bean properties. The method must have no arguments,
+	but may throw any exception.
+-->
+<!ATTLIST bean init-method CDATA #IMPLIED>
+
+<!--
+	Optional attribute for the name of the custom destroy method to invoke
+	on bean factory shutdown. The method must have no arguments,
+	but may throw any exception. Note: Only invoked on singleton beans!
+-->
+<!ATTLIST bean destroy-method CDATA #IMPLIED>
+
+<!--
+	Optional attribute specifying the name of a factory method to use to
+	create this object. Use constructor-arg elements to specify arguments
+	to the factory method, if it takes arguments. Autowiring does not apply
+	to factory methods.
+
+	If the "class" attribute is present, the factory method will be a static
+	method on the class specified by the "class" attribute on this bean
+	definition. Often this will be the same class as that of the constructed
+	object - for example, when the factory method is used as an alternative
+	to a constructor. However, it may be on a different class. In that case,
+	the created object will *not* be of the class specified in the "class"
+	attribute. This is analogous to FactoryBean behavior.
+
+	If the "factory-bean" attribute is present, the "class" attribute is not
+	used, and the factory method will be an instance method on the object
+	returned from a getBean call with the specified bean name. The factory
+	bean may be defined as a singleton or a prototype.
+
+	The factory method can have any number of arguments. Autowiring is not
+	supported. Use indexed constructor-arg elements in conjunction with the
+	factory-method attribute.
+
+	Setter Injection can be used in conjunction with a factory method.
+	Method Injection cannot, as the factory method returns an instance,
+	which will be used when the container creates the bean.
+-->
+<!ATTLIST bean factory-method CDATA #IMPLIED>
+
+<!--
+	Alternative to class attribute for factory-method usage.
+	If this is specified, no class attribute should be used.
+	This should be set to the name of a bean in the current or
+	ancestor factories that contains the relevant factory method.
+	This allows the factory itself to be configured using Dependency
+	Injection, and an instance (rather than static) method to be used.
+-->
+<!ATTLIST bean factory-bean CDATA #IMPLIED>
+
+<!--
+	Bean definitions can specify zero or more constructor arguments.
+	This is an alternative to "autowire constructor".
+	Arguments correspond to either a specific index of the constructor argument
+	list or are supposed to be matched generically by type.
+
+	Note: A single generic argument value will just be used once, rather than
+	potentially matched multiple times (as of Spring 1.1).
+
+	constructor-arg elements are also used in conjunction with the factory-method
+	element to construct beans using static or instance factory methods.
+-->
+<!ELEMENT constructor-arg (
+	description?,
+	(bean | ref | idref | value | null | list | set | map | props)?
+)>
+
+<!--
+	The constructor-arg tag can have an optional index attribute,
+	to specify the exact index in the constructor argument list. Only needed
+	to avoid ambiguities, e.g. in case of 2 arguments of the same type.
+-->
+<!ATTLIST constructor-arg index CDATA #IMPLIED>
+
+<!--
+	The constructor-arg tag can have an optional type attribute,
+	to specify the exact type of the constructor argument. Only needed
+	to avoid ambiguities, e.g. in case of 2 single argument constructors
+	that can both be converted from a String.
+-->
+<!ATTLIST constructor-arg type CDATA #IMPLIED>
+
+<!--
+  A short-cut alternative to a child element "ref bean=".
+-->
+<!ATTLIST constructor-arg ref CDATA #IMPLIED>
+
+<!--
+  A short-cut alternative to a child element "value".
+-->
+<!ATTLIST constructor-arg value CDATA #IMPLIED>
+
+
+<!--
+	Bean definitions can have zero or more properties.
+	Property elements correspond to JavaBean setter methods exposed
+	by the bean classes. Spring supports primitives, references to other
+	beans in the same or related factories, lists, maps and properties.
+-->
+<!ELEMENT property (
+	description?, meta*,
+	(bean | ref | idref | value | null | list | set | map | props)?
+)>
+
+<!--
+	The property name attribute is the name of the JavaBean property.
+	This follows JavaBean conventions: a name of "age" would correspond
+	to setAge()/optional getAge() methods.
+-->
+<!ATTLIST property name CDATA #REQUIRED>
+
+<!--
+  A short-cut alternative to a child element "ref bean=".
+-->
+<!ATTLIST property ref CDATA #IMPLIED>
+
+<!--
+  A short-cut alternative to a child element "value".
+-->
+<!ATTLIST property value CDATA #IMPLIED>
+
+
+<!--
+	A lookup method causes the IoC container to override the given method and return
+	the bean with the name given in the bean attribute. This is a form of Method Injection.
+	It's particularly useful as an alternative to implementing the BeanFactoryAware
+	interface, in order to be able to make getBean() calls for non-singleton instances
+	at runtime. In this case, Method Injection is a less invasive alternative.
+-->
+<!ELEMENT lookup-method EMPTY>
+
+<!--
+	Name of a lookup method. This method should take no arguments.
+-->
+<!ATTLIST lookup-method name CDATA #IMPLIED>
+
+<!--
+	Name of the bean in the current or ancestor factories that the lookup method
+	should resolve to. Often this bean will be a prototype, in which case the
+	lookup method will return a distinct instance on every invocation. This
+	is useful for single-threaded objects.
+-->
+<!ATTLIST lookup-method bean CDATA #IMPLIED>
+
+
+<!--
+	Similar to the lookup method mechanism, the replaced-method element is used to control
+	IoC container method overriding: Method Injection. This mechanism allows the overriding
+	of a method with arbitrary code.
+-->
+<!ELEMENT replaced-method (
+	(arg-type)*
+)>
+
+<!--
+	Name of the method whose implementation should be replaced by the IoC container.
+	If this method is not overloaded, there's no need to use arg-type subelements.
+	If this method is overloaded, arg-type subelements must be used for all
+	override definitions for the method.
+-->
+<!ATTLIST replaced-method name CDATA #IMPLIED>
+
+<!--
+	Bean name of an implementation of the MethodReplacer interface
+	in the current or ancestor factories. This may be a singleton or prototype
+	bean. If it's a prototype, a new instance will be used for each method replacement.
+	Singleton usage is the norm.
+-->
+<!ATTLIST replaced-method replacer CDATA #IMPLIED>
+
+<!--
+	Subelement of replaced-method identifying an argument for a replaced method
+	in the event of method overloading.
+-->
+<!ELEMENT arg-type (#PCDATA)>
+
+<!--
+	Specification of the type of an overloaded method argument as a String.
+	For convenience, this may be a substring of the FQN. E.g. all the
+	following would match "java.lang.String":
+	- java.lang.String
+	- String
+	- Str
+
+	As the number of arguments will be checked also, this convenience can often
+	be used to save typing.
+-->
+<!ATTLIST arg-type match CDATA #IMPLIED>
+
+
+<!--
+	Defines a reference to another bean in this factory or an external
+	factory (parent or included factory).
+-->
+<!ELEMENT ref EMPTY>
+
+<!--
+	References must specify a name of the target bean.
+	The "bean" attribute can reference any name from any bean in the context,
+	to be checked at runtime.
+	Local references, using the "local" attribute, have to use bean ids;
+	they can be checked by this DTD, thus should be preferred for references
+	within the same bean factory XML file.
+-->
+<!ATTLIST ref bean CDATA #IMPLIED>
+<!ATTLIST ref local IDREF #IMPLIED>
+<!ATTLIST ref parent CDATA #IMPLIED>
+
+
+<!--
+	Defines a string property value, which must also be the id of another
+	bean in this factory or an external factory (parent or included factory).
+	While a regular 'value' element could instead be used for the same effect,
+	using idref in this case allows validation of local bean ids by the xml
+	parser, and name completion by helper tools.
+-->
+<!ELEMENT idref EMPTY>
+
+<!--
+	ID refs must specify a name of the target bean.
+	The "bean" attribute can reference any name from any bean in the context,
+	potentially to be checked at runtime by bean factory implementations.
+	Local references, using the "local" attribute, have to use bean ids;
+	they can be checked by this DTD, thus should be preferred for references
+	within the same bean factory XML file.
+-->
+<!ATTLIST idref bean CDATA #IMPLIED>
+<!ATTLIST idref local IDREF #IMPLIED>
+
+
+<!--
+	Contains a string representation of a property value.
+	The property may be a string, or may be converted to the
+	required type using the JavaBeans PropertyEditor
+	machinery. This makes it possible for application developers
+	to write custom PropertyEditor implementations that can
+	convert strings to objects.
+
+	Note that this is recommended for simple objects only.
+	Configure more complex objects by populating JavaBean
+	properties with references to other beans.
+-->
+<!ELEMENT value (#PCDATA)>
+
+<!--
+	The value tag can have an optional type attribute, to specify the
+	exact type that the value should be converted to. Only needed
+	if the type of the target property or constructor argument is
+	too generic: for example, in case of a collection element.
+-->
+<!ATTLIST value type CDATA #IMPLIED>
+
+<!--
+	Denotes a Java null value. Necessary because an empty "value" tag
+	will resolve to an empty String, which will not be resolved to a
+	null value unless a special PropertyEditor does so.
+-->
+<!ELEMENT null (#PCDATA)>
+
+
+<!--
+	A list can contain multiple inner bean, ref, collection, or value elements.
+	Java lists are untyped, pending generics support in Java 1.5,
+	although references will be strongly typed.
+	A list can also map to an array type. The necessary conversion
+	is automatically performed by the BeanFactory.
+-->
+<!ELEMENT list (
+	(bean | ref | idref | value | null | list | set | map | props)*
+)>
+
+<!-- Enable/disable merging for collections when using parent/child beans -->
+<!ATTLIST list merge (true | false | default) "default">
+
+<!-- Specify the default Java type for nested values -->
+<!ATTLIST list value-type CDATA #IMPLIED>
+
+<!--
+	A set can contain multiple inner bean, ref, collection, or value elements.
+	Java sets are untyped, pending generics support in Java 1.5,
+	although references will be strongly typed.
+-->
+<!ELEMENT set (
+	(bean | ref | idref | value | null | list | set | map | props)*
+)>
+
+<!-- Enable/disable merging for collections when using parent/child beans -->
+<!ATTLIST set merge (true | false | default) "default">
+
+<!-- Specify the default Java type for nested values -->
+<!ATTLIST set value-type CDATA #IMPLIED>
+
+<!--
+	A Spring map is a mapping from a string key to object.
+	Maps may be empty.
+-->
+<!ELEMENT map (
+	(entry)*
+)>
+
+<!-- Enable/disable merging for collections when using parent/child beans -->
+<!ATTLIST map merge (true | false | default) "default">
+
+<!-- Specify the default Java type for nested entry keys -->
+<!ATTLIST map key-type CDATA #IMPLIED>
+
+<!-- Specify the default Java type for nested entry values -->
+<!ATTLIST map value-type CDATA #IMPLIED>
+
+<!--
+	A map entry can be an inner bean, ref, value, or collection.
+	The key of the entry is given by the "key" attribute or child element.
+-->
+<!ELEMENT entry (
+  key?,
+	(bean | ref | idref | value | null | list | set | map | props)?
+)>
+
+<!--
+	Each map element must specify its key as attribute or as child element.
+	A key attribute is always a String value.
+-->
+<!ATTLIST entry key CDATA #IMPLIED>
+
+<!--
+  A short-cut alternative to a "key" element with a "ref bean=" child element.
+-->
+<!ATTLIST entry key-ref CDATA #IMPLIED>
+
+<!--
+  A short-cut alternative to a child element "value".
+-->
+<!ATTLIST entry value CDATA #IMPLIED>
+
+<!--
+  A short-cut alternative to a child element "ref bean=".
+-->
+<!ATTLIST entry value-ref CDATA #IMPLIED>
+
+<!--
+	A key element can contain an inner bean, ref, value, or collection.
+-->
+<!ELEMENT key (
+	(bean | ref | idref | value | null | list | set | map | props)
+)>
+
+
+<!--
+	Props elements differ from map elements in that values must be strings.
+	Props may be empty.
+-->
+<!ELEMENT props (
+	(prop)*
+)>
+
+<!-- Enable/disable merging for collections when using parent/child beans -->
+<!ATTLIST props merge (true | false | default) "default">
+
+<!--
+	Element content is the string value of the property.
+	Note that whitespace is trimmed off to avoid unwanted whitespace
+	caused by typical XML formatting.
+-->
+<!ELEMENT prop (#PCDATA)>
+
+<!--
+	Each property element must specify its key.
+-->
+<!ATTLIST prop key CDATA #REQUIRED>
+

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookAdd.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookAdd.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookAdd.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,50 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<c:set var="page" value="${empty page ? 0 : page}"/>
+<c:set var="nextPage" value="${page == 4 ? null : page + 1}"/>
+<c:set var="prevPage" value="${page == 0 ? null : page - 1}"/>
+
+<h1>Add New Book</h1>
+
+<html:errors path="book" fields="true"/>
+
+<form method="post" action="<portlet:actionURL>
+			<portlet:param name="action" value="addBook"/>
+			<portlet:param name="_page" value="${page}"/>
+		</portlet:actionURL>">
+	<table border="0" cellpadding="4">
+		<tr>
+			<c:choose> 
+				<c:when test="${page == 0}" > 
+					<th>Author</th>
+					<td><html:input path="book.author" size="30" maxlength="80"/></td>
+				</c:when> 
+				<c:when test="${page == 1}" > 
+					<th>Title</th>
+					<td><html:input path="book.title" size="30" maxlength="80"/></td>
+				</c:when> 
+				<c:when test="${page == 2}" > 
+					<th>Description</th>
+					<td><html:textarea path="book.description" rows="10" cols="80"/></td>
+				</c:when> 
+				<c:when test="${page == 3}" > 
+					<th>Availability Date</th>
+					<td><html:input path="book.availability" size="30" maxlength="30"/></td>
+				</c:when> 
+				<c:when test="${page == 4}" > 
+					<th>Count</th>
+					<td><html:input path="book.count" size="30" maxlength="30"/></td>
+				</c:when> 
+			</c:choose>  
+		<tr>
+			<th colspan="2">
+				<input type="submit" name="_target${nextPage}" ${empty nextPage ? "disabled" : ""} value="Next"/>
+				<input type="submit" name="_finish" value="Finish"/>
+				<input type="submit" name="_target${prevPage}" ${empty prevPage ? "disabled" : ""} value="Previous"/>
+				<input type="submit" name="_cancel" value="Cancel"/>
+			</th>
+		</tr>
+	</table>
+</form>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookEdit.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookEdit.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookEdit.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,40 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>${book.key == null ? 'Add New Book' : 'Edit Book Details'}</h1>
+
+<html:errors path="book" fields="true"/>
+
+<form method="post" action="<portlet:actionURL>
+			<portlet:param name="action" value="editBook"/>
+			<portlet:param name="book" value="${book.key}"/>
+		</portlet:actionURL>">
+	<table border="0" cellpadding="4">
+		<tr>
+			<th>Author</th>
+			<td><html:input path="book.author" size="30" maxlength="80"/></td>
+		</tr>
+		<tr>
+			<th>Title</th>
+			<td><html:input path="book.title" size="30" maxlength="80"/></td>
+		</tr>
+		<tr>
+			<th>Description</th>
+			<td><html:textarea path="book.description" rows="10" cols="80"/></td>
+		</tr>
+		<tr>
+			<th>Availability Date</th>
+			<td><html:input path="book.availability" size="30" maxlength="30"/></td>
+		</tr>
+		<tr>
+			<th>Count</th>
+			<td><html:input path="book.count" size="30" maxlength="30"/></td>
+		</tr>
+		<tr>
+			<th colspan="2">
+				<button type="submit">${book.key == null ? 'Add' : 'Save'}</button>
+			</th>
+		</tr>
+	</table>
+</form>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookView.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookView.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/bookView.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,34 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>Book Details</h1>
+
+<table border="0" cellpadding="4">
+	<tr>
+		<th>Author</th>
+		<td>${book.author}</td>
+	</tr>
+	<tr>
+		<th>Title</th>
+		<td>${book.title}</td>
+	</tr>
+	<tr>
+		<th>Description</th>
+		<td>${book.description}</td>
+	</tr>
+	<tr>
+		<th>Availability Date</th>
+		<td><fmt:formatDate value="${book.availability}" dateStyle="full" /></td>
+	</tr>
+	<tr>
+		<th>Count</th>
+		<td>${book.count}</td>
+	</tr>
+</table>
+
+<p style="text-align:center;">- 
+	<a href="<portlet:renderURL>
+			<portlet:param name="action" value="editBook"/>
+			<portlet:param name="book" value="${book.key}"/>
+		</portlet:renderURL>"><spring:message code="button.edit"/></a> - 
+	<a href="<portlet:renderURL portletMode="view"/>"><spring:message code="button.home"/></a>
+-</p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksHelp.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksHelp.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksHelp.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,12 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>Books Portlet</h1>
+
+<p>This portlet is an example of a slightly more complicated portlet
+that use multiple pages within various modes.  You can view the list
+of books, edit a given book, delete a given book, and add new books.</p>
+
+<p>You can also go into 'edit' mode and select your favorite books
+and then these will be displayed first when in view mode.</p>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksView.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksView.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/booksView.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,44 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>Book Inventory</h1>
+
+<table border="0" cellpadding="4">
+	<tr><th>Author</th><th>Title</th><th>Count</th><th></th></tr>
+	<c:forEach items="${model.books}" var="book">
+		<tr>
+			<td>${book.author}</td>
+			<td><a href="<portlet:renderURL>
+						<portlet:param name="action" value="viewBook"/>
+						<portlet:param name="book" value="${book.key}"/>
+					</portlet:renderURL>">${book.title}</a></td>
+			<td align="right">${book.count}</td>
+			<td>
+				<a href="<portlet:actionURL>
+						<portlet:param name="action" value="incrementBook"/>
+						<portlet:param name="book" value="${book.key}"/>
+						<portlet:param name="increment" value="1"/>
+					</portlet:actionURL>"><img title="Increase Count" src="<html:imagesPath/>increase.png" border=0 /></a>
+				<a href="<portlet:actionURL>
+						<portlet:param name="action" value="incrementBook"/>
+						<portlet:param name="book" value="${book.key}"/>
+						<portlet:param name="increment" value="-1"/>
+					</portlet:actionURL>"><img title="Decrease Count" src="<html:imagesPath/>decrease.png" border=0 /></a>
+				<a href="<portlet:renderURL>
+						<portlet:param name="action" value="editBook"/>
+						<portlet:param name="book" value="${book.key}"/>
+					</portlet:renderURL>"><img title="Edit Book Details" src="<html:imagesPath/>edit.png" border=0 /></a>
+				<a href="<portlet:actionURL>
+						<portlet:param name="action" value="deleteBook"/>
+						<portlet:param name="book" value="${book.key}"/>
+					</portlet:actionURL>"><img title="Delete Book" src="<html:imagesPath/>delete.png" border=0 /></a>
+			</td>
+		</tr>
+	</c:forEach>
+		<tr>
+			<td colspan="4">
+				<a href="<portlet:renderURL>
+						<portlet:param name="action" value="addBook"/>
+					</portlet:renderURL>"><img title="Add New Book" src="<html:imagesPath/>new.png" border=0 /> Add New Book</a>
+			</td>
+		</tr>
+</table>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/defError.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/defError.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/defError.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,10 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1><spring:message code="exception.generalError.title"/></h1>
+
+<p>${exception.localizedMessage == null ? exception : exception.localizedMessage }<br/>
+<spring:message code="exception.contactAdmin"/></p>
+
+<p>${exception.class}</p>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/edit.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/edit.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/edit.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,19 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>Edit Mode</h1>
+
+<p>This portlet simply displays a different view depending on the 
+mode of the portlet.</p>
+
+<p>You can switch modes using the controls in your portal.  You can also
+experiment with the URLs below for changing mode and window state.</p>
+
+<h2>Portlet URLs</h2>
+<ul>
+	<li><a href="<portlet:renderURL portletMode="view" />">View Mode</a>
+	<li><a href="<portlet:renderURL portletMode="edit" />">Edit Mode</a>
+	<li><a href="<portlet:renderURL portletMode="help" />">Help Mode</a>
+	<li><a href="<portlet:renderURL windowState="normal" />">Normal State</a>
+	<li><a href="<portlet:renderURL windowState="maximized" />">Maximized State</a>
+	<li><a href="<portlet:renderURL windowState="minimized" />">Minimized State</a>
+</ul>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/exceptions.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/exceptions.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/exceptions.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,25 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+<portlet:defineObjects/>
+	
+<h1><spring:message code="portlet.exceptions.title"/></h1>
+
+<p>Locale: [${renderRequest.locale}]</p>
+
+<p><spring:message code="portlet.exceptions.message"/></p>
+<ul>
+	<c:forEach items="${model.exceptions}" var="exName">
+		<li><a href="<portlet:renderURL>
+				<portlet:param name="throw" value="${exName}"/>
+			</portlet:renderURL>">${exName}</a></li>
+	</c:forEach>
+</ul>
+
+<p>You can also cause an exception in this portlet by switching to edit or help mode
+because no handler has been mapped for those modes, even though they are declared as
+valid in the portlet.xml file.<p>
+
+<p>Here is an <a href="<portlet:actionURL/>">ActionURL</a> for an
+AbstractController that does not implement the action phase.  This will both 
+test the default implementation of handleActionRequestInternal (which should
+throw an exception) and the DispatcherPortlet facility for forwarding an 
+exception during the action phase to the render phase.</p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/help.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/help.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/help.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,19 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>Help Mode</h1>
+
+<p>This portlet simply displays a different view depending on the 
+mode of the portlet.</p>
+
+<p>You can switch modes using the controls in your portal.  You can also
+experiment with the URLs below for changing mode and window state.</p>
+
+<h2>Portlet URLs</h2>
+<ul>
+	<li><a href="<portlet:renderURL portletMode="view" />">View Mode</a>
+	<li><a href="<portlet:renderURL portletMode="edit" />">Edit Mode</a>
+	<li><a href="<portlet:renderURL portletMode="help" />">Help Mode</a>
+	<li><a href="<portlet:renderURL windowState="normal" />">Normal State</a>
+	<li><a href="<portlet:renderURL windowState="maximized" />">Maximized State</a>
+	<li><a href="<portlet:renderURL windowState="minimized" />">Minimized State</a>
+</ul>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/include.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/include.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/include.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,10 @@
+<%@ page contentType="text/html" isELIgnored="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="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+
+<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>
+<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
+
+<%@ taglib prefix="html" tagdir="/WEB-INF/tags/html" %>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAuthorized.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAuthorized.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAuthorized.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,9 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1><spring:message code="exception.notAuthorized.title"/></h1>
+
+<p><spring:message code="exception.notAuthorized.message"/><br>
+
+<spring:message code="exception.contactAdmin"/></p>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAvailable.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAvailable.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/notAvailable.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,9 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1><spring:message code="exception.notAvailable.title"/></h1>
+
+<p><spring:message code="exception.notAvailable.message"/><br>
+
+<spring:message code="exception.contactAdmin"/></p>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/redirect.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/redirect.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/redirect.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,23 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>Enter a URL for Redirection</h1>
+
+<form method="post" action="<portlet:actionURL/>">
+	<table border="0" cellpadding="4">
+		<tr>
+			<th>URL</th>
+			<td><html:input path="redirect.url" size="30" maxlength="80"/></td>
+		</tr>
+		<tr>
+			<th colspan="2">
+				<button type="submit">Go</button>
+			</th>
+		</tr>
+	</table>
+</form>
+
+<spring:hasBindErrors name="redirect">
+	<p style="color:#A00000">Please fix all errors!</p>
+</spring:hasBindErrors>
+
+<p style="text-align:center;"><a href="<portlet:renderURL portletMode="view"/>">- <spring:message code="button.home"/> -</a></p>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/upload.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/upload.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/upload.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,14 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+<portlet:defineObjects/>
+
+<h1>File Upload</h1>
+
+<p> Please upload a small text file (under 2KB) and the contents will be displayed back to you.</p>
+
+<form method="post" action="<portlet:actionURL/>" enctype="multipart/form-data">
+	<input type="file" name="file"/><br/>
+	<button type="submit">Go</button>
+</form>
+
+<p>Content:</p>
+<pre>${fn:escapeXml(param["upload"])}</pre>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/view.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/view.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/jsp/view.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,19 @@
+<%@ include file="/WEB-INF/jsp/include.jsp" %>
+
+<h1>View Mode</h1>
+
+<p>This portlet simply displays a different view depending on the 
+mode of the portlet.</p>
+
+<p>You can switch modes using the controls in your portal.  You can also
+experiment with the URLs below for changing mode and window state.</p>
+
+<h2>Portlet URLs</h2>
+<ul>
+	<li><a href="<portlet:renderURL portletMode="view" />">View Mode</a>
+	<li><a href="<portlet:renderURL portletMode="edit" />">Edit Mode</a>
+	<li><a href="<portlet:renderURL portletMode="help" />">Help Mode</a>
+	<li><a href="<portlet:renderURL windowState="normal" />">Normal State</a>
+	<li><a href="<portlet:renderURL windowState="maximized" />">Maximized State</a>
+	<li><a href="<portlet:renderURL windowState="minimized" />">Minimized State</a>
+</ul>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-fileupload.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-fileupload.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-io.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-io.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-logging.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/commons-logging.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/jstl.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/jstl.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/log4j.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/log4j.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-aop.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-aop.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-beans.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-beans.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-context.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-context.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-core.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-core.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-dao.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-dao.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-mock.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-mock.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-portlet.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-portlet.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-web.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-web.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-webmvc.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/spring-webmvc.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/standard.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/WEB-INF/lib/standard.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/portlet-instances.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/portlet-instances.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/portlet-instances.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,39 @@
+<?xml version="1.0" standalone="yes"?>
+<deployments>
+   <deployment>
+      <instance>
+         <instance-id>ModePortletInstance</instance-id>
+         <portlet-ref>mode</portlet-ref>
+      </instance>
+   </deployment>
+      <deployment>
+      <instance>
+         <instance-id>ExceptionsPortletInstance</instance-id>
+         <portlet-ref>exceptions</portlet-ref>
+      </instance>
+   </deployment>
+      <deployment>
+      <instance>
+         <instance-id>BooksPortletInstance</instance-id>
+         <portlet-ref>books</portlet-ref>
+      </instance>
+   </deployment>
+      <deployment>
+      <instance>
+         <instance-id>RedirectPortletInstance</instance-id>
+         <portlet-ref>redirect</portlet-ref>
+      </instance>
+   </deployment>
+      <deployment>
+      <instance>
+         <instance-id>UploadPortletInstance</instance-id>
+         <portlet-ref>upload</portlet-ref>
+      </instance>
+   </deployment>
+      <deployment>
+      <instance>
+         <instance-id>SpringHellowWorldPortletInstance</instance-id>
+         <portlet-ref>helloworld</portlet-ref>
+      </instance>
+   </deployment>
+</deployments>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/portlet.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/portlet.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/portlet.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd
+	                    http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"
+	version="1.0">
+
+    <portlet>
+        <portlet-name>mode</portlet-name>
+        <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
+		<init-param>
+			<name>contextConfigLocation</name>
+			<value>/WEB-INF/context/portlet/mode.xml</value>
+		</init-param>
+        <supports>
+            <mime-type>text/html</mime-type>
+            <portlet-mode>view</portlet-mode>
+            <portlet-mode>edit</portlet-mode>
+            <portlet-mode>help</portlet-mode>
+        </supports>
+        <portlet-info>
+            <title>Mode Name View</title>
+        </portlet-info>      
+    </portlet>
+
+    <portlet>
+        <portlet-name>exceptions</portlet-name>
+        <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
+		<init-param>
+			<name>contextConfigLocation</name>
+			<value>/WEB-INF/context/portlet/exceptions.xml</value>
+		</init-param>
+        <supports>
+            <mime-type>text/html</mime-type>
+            <portlet-mode>view</portlet-mode>
+            <portlet-mode>edit</portlet-mode>
+            <portlet-mode>help</portlet-mode>
+        </supports>
+        <portlet-info>
+            <title>Test Exceptions</title>
+        </portlet-info>      
+    </portlet>
+
+    <portlet>
+        <portlet-name>books</portlet-name>
+        <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
+		<init-param>
+			<name>contextConfigLocation</name>
+			<value>/WEB-INF/context/portlet/books.xml</value>
+		</init-param>
+        <supports>
+            <mime-type>text/html</mime-type>
+            <portlet-mode>view</portlet-mode>
+            <portlet-mode>help</portlet-mode>
+        </supports>
+        <portlet-info>
+            <title>Books</title>
+        </portlet-info>      
+    </portlet>
+
+    <portlet>
+        <portlet-name>redirect</portlet-name>
+        <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
+		<init-param>
+			<name>contextConfigLocation</name>
+			<value>/WEB-INF/context/portlet/redirect.xml</value>
+		</init-param>
+        <supports>
+            <mime-type>text/html</mime-type>
+            <portlet-mode>view</portlet-mode>
+        </supports>
+        <portlet-info>
+            <title>Redirect</title>
+        </portlet-info>      
+    </portlet>
+
+    <portlet>
+        <portlet-name>upload</portlet-name>
+        <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
+		<init-param>
+			<name>contextConfigLocation</name>
+			<value>/WEB-INF/context/portlet/upload.xml</value>
+		</init-param>
+        <supports>
+            <mime-type>text/html</mime-type>
+            <portlet-mode>view</portlet-mode>
+        </supports>
+        <portlet-info>
+            <title>Upload</title>
+        </portlet-info>      
+    </portlet>
+
+    <portlet>
+        <portlet-name>helloworld</portlet-name>
+        <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
+		<init-param>
+			<name>contextConfigLocation</name>
+			<value>/WEB-INF/context/portlet/helloworld.xml</value>
+		</init-param>
+        <supports>
+            <mime-type>text/html</mime-type>
+            <portlet-mode>view</portlet-mode>
+        </supports>
+        <portlet-info>
+            <title>Hello World</title>
+        </portlet-info>      
+    </portlet>
+
+    <user-attribute>
+        <name>user.login.id</name>
+    </user-attribute>
+    <user-attribute>
+        <name>user.name</name>
+    </user-attribute>
+    <user-attribute>
+        <name>user.name.full</name>
+    </user-attribute>
+    
+</portlet-app>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/springportlet-object.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/springportlet-object.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/springportlet-object.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<deployments>
+   <deployment>
+      <if-exists>overwrite</if-exists>
+      <parent-ref>default</parent-ref>
+      <page>
+         <page-name>Spring MVC</page-name>
+         <window>
+            <window-name>ModePortletWindow</window-name>
+            <instance-ref>ModePortletInstance</instance-ref>
+            <region>left</region>
+            <height>2</height>
+         </window>
+         <window>
+            <window-name>ExceptionsPortletWindow</window-name>
+            <instance-ref>ExceptionsPortletInstance</instance-ref>
+            <region>center</region>
+            <height>2</height>
+         </window>
+         <window>
+            <window-name>BooksPortletWindow</window-name>
+            <instance-ref>BooksPortletInstance</instance-ref>
+            <region>center</region>
+            <height>0</height>
+         </window>
+         <window>
+            <window-name>RedirectPortletWindow</window-name>
+            <instance-ref>RedirectPortletInstance</instance-ref>
+            <region>left</region>
+            <height>1</height>
+         </window>
+         <window>
+            <window-name>UploadPortletWindow</window-name>
+            <instance-ref>UploadPortletInstance</instance-ref>
+            <region>center</region>
+            <height>1</height>
+         </window>
+         <window>
+            <window-name>SpringHellowWorldPortletWindow</window-name>
+            <instance-ref>SpringHellowWorldPortletInstance</instance-ref>
+            <region>left</region>
+            <height>0</height>
+         </window>
+      </page>
+   </deployment>
+</deployments>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/log4j.properties
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/log4j.properties	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/log4j.properties	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,17 @@
+#log4j.debug=TRUE
+
+#log4j.rootLogger=FATAL, stdout
+#log4j.rootLogger=ERROR, stdout
+log4j.rootLogger=WARN, stdout
+#log4j.rootLogger=INFO, stdout
+#log4j.rootLogger=DEBUG, stdout
+
+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
+
+# spring portlet mvc classes
+log4j.logger.org.springframework.web.portlet=DEBUG
+
+# spring portlet mvc sample classes
+log4j.logger.org.springframework.web.portlet.sample=DEBUG

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages.properties
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages.properties	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages.properties	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,23 @@
+
+required=Required
+required.java.util.Date=A date of the form 'MM/dd/yyyy' is required
+
+typeMismatch=Invalid Data Entry
+typeMismatch.java.lang.Integer=Must be a number
+typeMismatch.java.util.Date=Must be of the form 'MM/dd/yyyy'
+
+button.home=Home
+button.edit=Edit
+
+exception.generalError.title=General Error
+
+exception.notAuthorized.title=Access Not Permitted
+exception.notAuthorized.message=You do not have permission to access this area.
+
+exception.notAvailable.title=Resource Not Available
+exception.notAvailable.message=That resource is not available.
+
+exception.contactAdmin=Please contact your System Administrator for assistance.
+
+portlet.exceptions.title=Sample Exceptions
+portlet.exceptions.message=This portlet lets you see what uncaught exceptions will look like in your portlet.  Select one of the exceptions below in order to throw it.

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages_de.properties
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages_de.properties	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/messages_de.properties	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,15 @@
+
+# Apologies to those fluent in German -- these translations are straight from BabelFish and are only for demonstration purposes.
+
+exception.generalError.title=Allgemeine Störung
+
+exception.notAuthorized.title=Zugang Nicht Die Erlaubnis Gehabt
+exception.notAuthorized.message=Sie haben nicht Erlaubnis, diesen Bereich zugänglich zu machen.
+
+exception.notAvailable.title=Hilfsmittel Nicht Vorhanden
+exception.notAvailable.message=Dieses Hilfsmittel ist nicht vorhanden.
+
+exception.contactAdmin=Treten Sie bitte mit Ihrem Systemverwalter für Unterstützung in Verbindung.
+
+portlet.exceptions.title=Beispielausnahmen
+portlet.exceptions.message=Dieses portlet läßt Sie sehen, welche uncaught Ausnahmen wie in Ihrem portlet aussehen. Wählen Sie eine der Ausnahmen unten vor, um sie zu werfen.

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Book.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Book.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Book.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,124 @@
+package org.springframework.web.portlet.sample;
+
+import java.io.Serializable;
+import java.lang.Comparable;
+import java.util.Date;
+
+public class Book implements Comparable, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer key;
+    private String author;
+    private String title;
+    private String description;
+    private Date availability;
+    private Integer count;
+
+	private int hashCode = Integer.MIN_VALUE;
+	
+	public Book() {
+        super();
+    }
+    
+	public Book(String author, String title, Integer count) {
+        super();
+        setAuthor(author);
+        setTitle(title);
+        setCount(count);
+    }
+    
+    public Book(String author, String title, int count) {
+        this(author, title, new Integer(count));
+    }
+    
+    public synchronized String getAuthor() {
+        return author;
+    }
+
+    public synchronized void setAuthor(String author) {
+        if (author == null) throw new NullPointerException("author may not be null");
+        this.author = author;
+        this.hashCode = Integer.MIN_VALUE;
+    }
+
+    public synchronized String getTitle() {
+        return title;
+    }
+
+    public synchronized void setTitle(String title) {
+        if (title == null) throw new NullPointerException("title may not be null");
+        this.title = title;
+        this.hashCode = Integer.MIN_VALUE;
+    }
+
+    public synchronized String getDescription() {
+        return description;
+    }
+
+    public synchronized void setDescription(String description) {
+        this.description = description;
+    }
+
+    public Date getAvailability() {
+        return availability;
+    }
+    
+    public void setAvailability(Date availability) {
+        this.availability = availability;
+    }
+    
+    public synchronized Integer getCount() {
+        return count;
+    }
+
+    public synchronized void setCount(Integer count) {
+        this.count = count;
+    }
+
+    public synchronized Integer getKey() {
+        return key;
+    }
+
+    public synchronized void setKey(Integer key) {
+        this.key = key;
+    }
+
+    public synchronized void incrementCount(Integer increment) {
+        int count = this.count.intValue() + increment.intValue();
+        if (count < 0) count = 0;
+        this.count = new Integer(count);
+    }
+
+    public int compareTo(Object obj) {
+        if (obj == null) throw new NullPointerException("Cannot compare to null object");
+        if (!(obj instanceof Book)) throw new ClassCastException("Can only compare to class" + this.getClass().getName());
+        if (this.author == null || this.title == null) throw new NullPointerException("This object is not initialized yet");
+        if (this.equals(obj)) return 0;
+        Book book = (Book)obj;
+        int res = getAuthor().compareTo(book.getAuthor());
+        if (res != 0) return res;
+        return getTitle().compareTo(book.getTitle());
+    }
+
+    public boolean equals(Object obj) {
+        if (obj == null) return false;
+        if (!(obj instanceof Book)) return false;
+        if (this.author == null || this.title == null) return false;
+        Book book = (Book)obj;
+        return (this.author.equals(book.getAuthor()) &&
+                 this.title.equals(book.getTitle()));
+    }
+    
+    public int hashCode() {
+		if (Integer.MIN_VALUE == this.hashCode) {
+			String hashStr = this.getClass().getName() + ":" + this.toString();
+			this.hashCode = hashStr.hashCode();
+		}
+		return this.hashCode;
+    }
+
+    public String toString() {
+        return this.author + ":" + this.title;
+    }
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookAddController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookAddController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookAddController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,83 @@
+package org.springframework.web.portlet.sample;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletRequest;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.beans.propertyeditors.CustomDateEditor;
+import org.springframework.validation.BindException;
+import org.springframework.validation.Errors;
+import org.springframework.web.portlet.bind.PortletRequestDataBinder;
+import org.springframework.web.portlet.mvc.AbstractWizardFormController;
+import org.springframework.web.portlet.ModelAndView;
+
+class BookAddController extends AbstractWizardFormController {
+
+    private BookService bookService;
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.bookService == null)
+            throw new IllegalArgumentException("A BookService is required");
+    }
+
+    protected void processFinish(
+            ActionRequest request, ActionResponse response,
+            Object command, BindException errors)
+    		throws Exception {
+		bookService.addBook((Book)command);
+		response.setRenderParameter("action","books");
+    }
+
+    protected void processCancel(
+            ActionRequest request, ActionResponse response,
+            Object command, BindException errors)
+            throws Exception {
+		response.setRenderParameter("action","books");
+    }
+
+    protected void validatePage(
+            Object command, Errors errors, int page, boolean finish) {
+        if (finish) {
+            this.getValidator().validate(command, errors);
+            return;
+        }
+		Book book = (Book)command;
+		BookValidator bookValidator = (BookValidator)getValidator();
+		//errors.setNestedPath("book");
+		switch (page) {
+			case 0: bookValidator.validateAuthor(book, errors);	break;
+			case 1: bookValidator.validateTitle(book, errors); break;
+			case 2: bookValidator.validateDescription(book, errors); break;
+			case 3: bookValidator.validateAvailability(book, errors); break;
+			case 4: bookValidator.validateCount(book, errors); break;
+		}
+		//errors.setNestedPath("");
+    }
+
+    protected void initBinder(PortletRequest request, PortletRequestDataBinder binder)
+			throws Exception {
+	    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
+	    binder.registerCustomEditor(Date.class, null, new	CustomDateEditor(dateFormat, true));
+	    binder.setAllowedFields(new String[] {"author","title","description","availability","count"});
+    }
+
+	protected ModelAndView renderInvalidSubmit(RenderRequest request, RenderResponse response)
+			throws Exception {
+	    return null;
+	}
+
+	protected void handleInvalidSubmit(ActionRequest request, ActionResponse response)
+			throws Exception {
+	    response.setRenderParameter("action","books");
+	}
+
+	public void setBookService(BookService bookService) {
+	    this.bookService = bookService;
+	}
+
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookDeleteController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookDeleteController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookDeleteController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,30 @@
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.web.portlet.mvc.AbstractController;
+
+
+public class BookDeleteController extends AbstractController implements InitializingBean {
+
+    private BookService bookService;
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.bookService == null)
+            throw new IllegalArgumentException("A BookService is required");
+    }
+
+	public void handleActionRequestInternal(ActionRequest request, ActionResponse response) throws Exception {
+	    // get the id and delete it
+	    Integer id = new Integer(request.getParameter("book"));
+		bookService.deleteBook(id);
+		// change mapping parameter to go to the default view
+		response.setRenderParameter("action","books");
+	}
+
+	public void setBookService(BookService bookService) {
+	    this.bookService = bookService;
+	}
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookEditController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookEditController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookEditController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,84 @@
+package org.springframework.web.portlet.sample;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletRequest;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.propertyeditors.CustomDateEditor;
+import org.springframework.validation.BindException;
+import org.springframework.web.portlet.bind.PortletRequestDataBinder;
+import org.springframework.web.portlet.mvc.SimpleFormController;
+import org.springframework.web.portlet.ModelAndView;
+
+public class BookEditController extends SimpleFormController implements InitializingBean {
+
+    private BookService bookService;
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.bookService == null)
+            throw new IllegalArgumentException("A BookService is required");
+    }
+
+	public void onSubmitAction(ActionRequest request, ActionResponse response,
+			Object command,	BindException errors) throws Exception {
+		
+		Book book = (Book) command;
+	    Integer key;
+
+    	try {
+    	    key = new Integer(request.getParameter("book"));
+    	} catch (NumberFormatException ex) {
+    	    key = null;
+    	}
+		
+		if (key == null) {
+			bookService.addBook(book);
+		} else {
+			bookService.saveBook(book);
+		}
+
+		response.setRenderParameter("action","books");
+	}
+	
+    protected Object formBackingObject(PortletRequest request)
+    		throws Exception {
+
+    	Book book;
+
+    	try {
+    	    Integer key = new Integer(request.getParameter("book"));
+    	    book = bookService.getBook(key);
+    	} catch (NumberFormatException ex) {
+        	book = new Book();
+    	}
+    	
+		return book;
+	}
+    
+	protected void initBinder(PortletRequest request, PortletRequestDataBinder binder)
+			throws Exception {
+	    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
+	    binder.registerCustomEditor(Date.class, null, new	CustomDateEditor(dateFormat, true));
+	    binder.setAllowedFields(new String[] {"author","title","description","availability","count"});
+	}
+
+	protected ModelAndView renderInvalidSubmit(RenderRequest request, RenderResponse response)
+			throws Exception {
+	    return null;
+	}
+	
+	protected void handleInvalidSubmit(ActionRequest request, ActionResponse response)
+			throws Exception {
+		response.setRenderParameter("action","books");
+	}
+
+	public void setBookService(BookService bookService) {
+	    this.bookService = bookService;
+	}
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookIncrementController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookIncrementController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookIncrementController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,33 @@
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.web.portlet.mvc.AbstractController;
+
+
+public class BookIncrementController extends AbstractController implements InitializingBean {
+
+    private BookService bookService;
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.bookService == null)
+            throw new IllegalArgumentException("A BookService is required");
+    }
+
+	public void handleActionRequestInternal(ActionRequest request, ActionResponse response) throws Exception {
+	    // get the id and delete it
+	    Integer id = new Integer(request.getParameter("book"));
+	    Integer increment = new Integer(request.getParameter("increment"));
+		Book book = bookService.getBook(id);
+		book.incrementCount(increment);
+        bookService.saveBook(book);
+		// change action parameter to go to default view
+		response.setRenderParameter("action","books");
+	}
+
+	public void setBookService(BookService bookService) {
+	    this.bookService = bookService;
+	}
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookService.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookService.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookService.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,93 @@
+package org.springframework.web.portlet.sample;
+
+import java.util.Collections;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.support.ApplicationObjectSupport;
+
+public class BookService extends ApplicationObjectSupport {
+
+    private SortedMap books = Collections.synchronizedSortedMap(new TreeMap());
+
+    private int initBooks = -1;
+    
+	public void initApplicationContext() throws BeansException {
+        if (initBooks < 0 || initBooks > 0)
+            addBook("Neal Stephenson", "Snow Crash", 50);
+        if (initBooks < 0 || initBooks > 1)
+            addBook("William Gibson", "Neuromancer", 92);
+        if (initBooks < 0 || initBooks > 2)
+            addBook("Bruce Bethke", "Headcrash", 12);
+        if (initBooks < 0 || initBooks > 3)
+            addBook("Eric S. Nylund", "Signal To Noise", 44);
+        if (initBooks < 0 || initBooks > 4)
+            addBook("Noman", "Shouldn't See This Book", 10);
+	}
+
+    public Book getBook (Integer key) {
+        synchronized (books) {
+            return (Book)this.books.get(key);
+        }
+    }
+    
+    public Book getBook (int key) {
+        return getBook(new Integer(key));
+    }
+    
+    public SortedSet getAllBooks () {
+        synchronized (books) {
+            return (SortedSet) new TreeSet(this.books.values());
+        }
+    }
+    
+    public int addBook (Book book) {
+        int key;
+        synchronized (books) {
+            if (books.isEmpty()) key = 1;
+            else key = ((Integer)books.lastKey()).intValue() + 1;
+            Integer keyObj = new Integer(key);
+            book.setKey(keyObj);
+            this.books.put(keyObj, book);
+        }
+        return key;
+    }
+
+    public int addBook (String author, String title, Integer count) {
+        Book book = new Book(author, title, count);
+        return addBook(book);
+    }
+
+    public int addBook (String author, String title, int count) {
+        Book book = new Book(author, title, count);
+        return addBook(book);
+    }
+
+    public void saveBook (Book book) {
+        synchronized (books) {
+            this.books.put(book.getKey(),book);
+        }
+    }
+
+    public void deleteBook (Integer key) {
+        synchronized (books) {
+            this.books.remove(key);
+        }
+    }
+
+    public void deleteBook (Book book) {
+        deleteBook(book.getKey());
+    }
+
+    public void deleteBook (int key) {
+        deleteBook(new Integer(key));
+    }
+
+    public void setInitBooks(int initBooks) {
+        this.initBooks = initBooks;
+    }
+    
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookValidator.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookValidator.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookValidator.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,40 @@
+package org.springframework.web.portlet.sample;
+
+import org.springframework.validation.Errors;
+import org.springframework.validation.ValidationUtils;
+import org.springframework.validation.Validator;
+
+public class BookValidator implements Validator {
+
+    public boolean supports(Class clazz) {
+        return Book.class.isAssignableFrom(clazz);
+    }
+
+    public void validate(Object obj, Errors errors) {
+        Book book = (Book)obj;
+        validateAuthor(book, errors);
+        validateTitle(book, errors);
+        validateDescription(book, errors);
+        validateAvailability(book, errors);
+        validateCount(book, errors);
+    }
+
+	public void validateAuthor(Book book, Errors errors) {
+		ValidationUtils.rejectIfEmpty(errors, "author", "AUTHOR_REQUIRED", "Author is required.");
+	}
+
+	public void validateTitle(Book book, Errors errors) {
+		ValidationUtils.rejectIfEmpty(errors, "title", "TITLE_REQUIRED", "Title is required.");
+	}
+
+	public void validateDescription(Book book, Errors errors) {
+	}
+    
+	public void validateAvailability(Book book, Errors errors) {
+	}
+    
+	public void validateCount(Book book, Errors errors) {
+		ValidationUtils.rejectIfEmpty(errors, "count", "COUNT_REQUIRED", "Current count is required.");
+	}
+    
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookViewController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookViewController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BookViewController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,28 @@
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.web.portlet.mvc.AbstractController;
+import org.springframework.web.portlet.ModelAndView;
+
+public class BookViewController extends AbstractController implements InitializingBean {
+
+    private BookService bookService;
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.bookService == null)
+            throw new IllegalArgumentException("A BookService is required");
+    }
+    
+	public ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception {
+	    // get the id and display it
+	    Integer id = new Integer(request.getParameter("book"));
+        return new ModelAndView("bookView", "book", bookService.getBook(id));
+	}
+
+    public void setBookService(BookService bookService) {
+        this.bookService = bookService;
+    }
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BooksController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BooksController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/BooksController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,32 @@
+package org.springframework.web.portlet.sample;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.web.portlet.mvc.AbstractController;
+import org.springframework.web.portlet.ModelAndView;
+
+public class BooksController extends AbstractController implements InitializingBean {
+
+    private BookService bookService;
+    
+    public void afterPropertiesSet() throws Exception {
+        if (this.bookService == null)
+            throw new IllegalArgumentException("A BookService is required");
+    }
+    
+	public ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception {
+    
+		Map model = new HashMap();
+		model.put("books", bookService.getAllBooks());
+        return new ModelAndView("booksView", "model", model);
+	}
+
+    public void setBookService(BookService bookService) {
+        this.bookService = bookService;
+    }
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/ExceptionsController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/ExceptionsController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/ExceptionsController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,42 @@
+package org.springframework.web.portlet.sample;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.portlet.PortletException;
+import javax.portlet.PortletSecurityException;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.web.portlet.mvc.AbstractController;
+import org.springframework.web.portlet.ModelAndView;
+
+public class ExceptionsController extends AbstractController {
+
+    private final static String THROW_PARAMETER = "throw";
+    
+	public ModelAndView handleRenderRequestInternal(RenderRequest request, RenderResponse response) throws Exception {
+
+		String throwme = request.getParameter(THROW_PARAMETER);
+
+		// build map of throwable exceptions
+		Map exceptions = new HashMap();
+		exceptions.put(PortletException.class.getName(),
+		        new PortletException("This is a test"));
+		exceptions.put(PortletSecurityException.class.getName(),
+		        new PortletSecurityException("This is a test"));
+
+		// see if we have been asked to throw something
+		if (throwme != null) {
+		    Exception ex = (Exception)exceptions.get(throwme);
+		    if (ex != null)
+		        throw ex;
+		}
+
+		// didn't throw anything -- build model and view
+		Map model = new HashMap();
+		model.put("exceptions", exceptions.keySet());
+        return new ModelAndView("exceptions", "model", model);
+	}
+
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/HelloWorldPortlet.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/HelloWorldPortlet.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/HelloWorldPortlet.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,31 @@
+
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.GenericPortlet;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+import javax.portlet.PortletException;
+import java.io.PrintWriter;
+import java.io.IOException;
+import java.util.Enumeration;
+
+public class HelloWorldPortlet extends GenericPortlet {
+
+    public void doView(RenderRequest request, RenderResponse response)
+    	throws PortletException, IOException {
+        System.out.println("Entering HelloWorldPortlet.doView");
+        response.setContentType("text/html");
+        PrintWriter out = response.getWriter();
+        out.println("<h1>Hello World</h1>");
+        out.println("<p>This portlet demonstrates how to delegate to "+
+                "an existing JSR-168 portlet via a HandlerAdapter</p>");
+        out.println("<p>Portlet Name: " + this.getPortletName() + "</p>");
+        out.println("<p>Init Parameters:</p><ul>");
+        for (Enumeration e = this.getInitParameterNames(); e.hasMoreElements();) {
+            String name = (String)e.nextElement();
+            out.println("<li>" + name + " = " + this.getInitParameter(name) + "</li>");
+        }
+        out.println("</ul>");
+    }
+
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/PortletNameInterceptor.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/PortletNameInterceptor.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/PortletNameInterceptor.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,39 @@
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.PortletContext;
+import javax.portlet.PortletRequest;
+import javax.portlet.PortletResponse;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.web.portlet.HandlerInterceptor;
+import org.springframework.web.portlet.ModelAndView;
+import org.springframework.web.portlet.context.PortletApplicationObjectSupport;
+import org.springframework.web.portlet.context.PortletContextAware;
+
+public class PortletNameInterceptor extends PortletApplicationObjectSupport
+        implements HandlerInterceptor, PortletContextAware {
+
+    PortletContext portletContext;
+    
+	public void setPortletConfig(PortletContext portletContext) {
+        this.portletContext = portletContext;
+    }
+
+	public boolean preHandle(PortletRequest request, PortletResponse response, Object handler)
+			throws Exception {
+        logger.info("portletContextName : " +(portletContext == null ? "<no PortletContext!>" : portletContext.getPortletContextName()));
+        return true;
+	}
+
+	public void postHandle(
+			RenderRequest request, RenderResponse response, Object handler, ModelAndView modelAndView)
+			throws Exception {
+	}
+
+	public void afterCompletion(
+			PortletRequest request, PortletResponse response, Object handler, Exception ex)
+			throws Exception {
+	}
+
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectCommand.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectCommand.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectCommand.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,33 @@
+package org.springframework.web.portlet.sample;
+
+import java.io.Serializable;
+import java.net.URL;
+
+public class RedirectCommand implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private URL url = null;
+	
+	public RedirectCommand() {
+        super();
+    }
+    
+	public RedirectCommand(URL url) {
+        super();
+        setUrl(url);
+    }
+    
+    public synchronized URL getUrl() {
+        return this.url;
+    }
+
+    public synchronized void setUrl(URL url) {
+        this.url = url;
+    }
+
+    public String toString() {
+        if (url == null) return null;
+        return this.url.toString();
+    }
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/RedirectController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,22 @@
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.validation.BindException;
+import org.springframework.web.portlet.mvc.SimpleFormController;
+
+public class RedirectController extends SimpleFormController implements InitializingBean {
+
+    public void afterPropertiesSet() throws Exception {
+        this.setRedirectAction(true);
+    }
+    
+	public void onSubmitAction(ActionRequest request, ActionResponse response,
+			Object command,	BindException errors) throws Exception {
+	    RedirectCommand redirect = (RedirectCommand)command;
+	    response.sendRedirect(redirect.toString());
+	}
+	
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Upload.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Upload.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/Upload.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,28 @@
+package org.springframework.web.portlet.sample;
+
+import java.io.Serializable;
+
+public class Upload implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private byte[] file;
+
+	public Upload() {
+        super();
+    }
+    
+	public Upload(byte[] file) {
+        super();
+        setFile(file);
+    }
+    
+    public void setFile(byte[] file) {
+        this.file = file;
+    }
+    
+    public byte[] getFile() {
+        return file;
+    }
+    
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/UploadController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/UploadController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/UploadController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,64 @@
+package org.springframework.web.portlet.sample;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequest;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.springframework.validation.BindException;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
+import org.springframework.web.portlet.ModelAndView;
+import org.springframework.web.portlet.bind.PortletRequestDataBinder;
+import org.springframework.web.portlet.multipart.MultipartActionRequest;
+import org.springframework.web.portlet.mvc.SimpleFormController;
+
+
+public class UploadController extends SimpleFormController {
+
+    public void onSubmitAction(ActionRequest request, ActionResponse response,
+            Object command, BindException errors) throws Exception {
+
+        if (request instanceof MultipartActionRequest) {
+            MultipartActionRequest multipartRequest = (MultipartActionRequest) request;
+            MultipartFile multipartFile = multipartRequest.getFile("file");
+            if (multipartFile != null) {
+                logger.info("isEmpty: " + multipartFile.isEmpty());
+                logger.info("contentType: " + multipartFile.getContentType());
+                logger.info("name: " + multipartFile.getName());
+                logger.info("size: " + multipartFile.getSize());
+                logger.info("originalFilename: " + multipartFile.getOriginalFilename());
+                if (!"text/plain".equals(multipartFile.getContentType())) {
+                    throw new PortletException("File is of type '" + 
+                            multipartFile.getContentType() + 
+                            "', not 'text/plain'");
+                }
+                logger.info("content: " + multipartFile.getBytes().toString());
+            } else {
+                logger.info("MultipartFile returned NULL");
+            }
+        }
+        
+        Upload upload = (Upload)command;
+        if (upload != null) {
+            byte[] file = upload.getFile();
+            if (file != null) {
+                String uploadString = new String(file);
+                response.setRenderParameter("upload",uploadString);
+            }
+        }
+    }
+
+    protected ModelAndView onSubmitRender(RenderRequest request, RenderResponse response,
+            Object command, BindException errors) throws Exception {
+        return this.showNewForm(request, response);
+    }
+
+    protected void initBinder(PortletRequest request, PortletRequestDataBinder binder) throws Exception {
+        binder.registerCustomEditor(byte[].class, new ByteArrayMultipartFileEditor());
+        //binder.registerCustomEditor(String.class, new StringMultipartFileEditor());
+    }
+
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/AllTests.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/AllTests.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/AllTests.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,19 @@
+package org.springframework.web.portlet.sample.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AllTests {
+
+	public static Test suite() {
+		
+		TestSuite suite = new TestSuite("Test for org.springframework.web.portlet.sample");
+		
+		//$JUnit-BEGIN$
+		suite.addTestSuite(TestBookViewController.class);
+		//$JUnit-END$
+		
+		return suite;
+		
+	}
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestBookViewController.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestBookViewController.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestBookViewController.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,39 @@
+package org.springframework.web.portlet.sample.test;
+
+import java.util.Map;
+
+import org.springframework.mock.web.portlet.MockRenderRequest;
+import org.springframework.mock.web.portlet.MockRenderResponse;
+import org.springframework.web.portlet.sample.Book;
+import org.springframework.web.portlet.sample.BookViewController;
+import org.springframework.web.portlet.ModelAndView;
+
+public class TestBookViewController extends TestCase {
+
+    public void testBookViewController() throws Exception {
+
+        BookViewController controller = (BookViewController)booksPortletContext.getBean("bookViewController");
+
+    	MockRenderRequest request = new MockRenderRequest();
+    	MockRenderResponse response = new MockRenderResponse();
+
+    	request.addParameter("book", "1");
+    	
+		ModelAndView mav = controller.handleRenderRequest(request, response);
+		assertNotNull(mav);
+		
+		logger.info("view: " + mav.getViewName());
+		
+		Map model = mav.getModel();
+
+		assertTrue(model.containsKey("book"));
+		Book book = (Book)model.get("book");
+
+		logger.info("book.author: " + book.getAuthor());
+		logger.info("book.title: " + book.getTitle());
+		logger.info("book.description: " + book.getDescription());
+		logger.info("book.count: " + book.getCount());
+        
+    }
+    
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestCase.java
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestCase.java	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/src/org/springframework/web/portlet/sample/test/TestCase.java	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,26 @@
+package org.springframework.web.portlet.sample.test;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.FileSystemXmlApplicationContext;
+
+public abstract class TestCase extends junit.framework.TestCase {
+
+	protected final Log logger = LogFactory.getLog(getClass());
+	
+	protected static final ApplicationContext appContext;
+	protected static final ApplicationContext booksPortletContext;
+
+    static {
+        try {
+    		appContext = new FileSystemXmlApplicationContext(
+    		        new String[]{"WEB-INF/context/applicationContext.xml"});
+    		booksPortletContext = new FileSystemXmlApplicationContext(
+    		        new String[]{"WEB-INF/context/portlet/books.xml"}, appContext);
+        } catch (Throwable ex) {
+            throw new ExceptionInInitializerError(ex);
+        }
+    }
+
+}

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/c.tld
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/c.tld	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/c.tld	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,563 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<taglib 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-jsptaglibrary_2_0.xsd"
+    version="2.0">
+    
+  <description>JSTL 1.1 core library</description>
+  <display-name>JSTL core</display-name>
+  <tlib-version>1.1</tlib-version>
+  <short-name>c</short-name>
+  <uri>http://java.sun.com/jsp/jstl/core</uri>
+
+  <validator>
+    <description>
+        Provides core validation features for JSTL tags.
+    </description>
+    <validator-class>
+        org.apache.taglibs.standard.tlv.JstlCoreTLV
+    </validator-class>
+  </validator>
+
+  <tag>
+    <description>
+        Catches any Throwable that occurs in its body and optionally
+        exposes it.
+    </description>
+    <name>catch</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.CatchTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+exception thrown from a nested action. The type of the
+scoped variable is the type of the exception thrown.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	Simple conditional tag that establishes a context for
+	mutually exclusive conditional operations, marked by
+	&lt;when&gt; and &lt;otherwise&gt;
+    </description>
+    <name>choose</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.ChooseTag</tag-class>
+    <body-content>JSP</body-content>
+  </tag>
+
+  <tag>
+    <description>
+	Simple conditional tag, which evalutes its body if the
+	supplied condition is true and optionally exposes a Boolean
+	scripting variable representing the evaluation of this condition
+    </description>
+    <name>if</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The test condition that determines whether or
+not the body content should be processed.
+        </description>
+        <name>test</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+	<type>boolean</type>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+resulting value of the test condition. The type
+of the scoped variable is Boolean.        
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Retrieves an absolute or relative URL and exposes its contents
+        to either the page, a String in 'var', or a Reader in 'varReader'.
+    </description>
+    <name>import</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ImportTag</tag-class>
+    <tei-class>org.apache.taglibs.standard.tei.ImportTEI</tei-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The URL of the resource to import.
+        </description>
+        <name>url</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+resource's content. The type of the scoped
+variable is String.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+resource's content. The type of the scoped
+variable is Reader.
+        </description>
+        <name>varReader</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the context when accessing a relative
+URL resource that belongs to a foreign
+context.
+        </description>
+        <name>context</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Character encoding of the content at the input
+resource.
+        </description>
+        <name>charEncoding</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	The basic iteration tag, accepting many different
+        collection types and supporting subsetting and other
+        functionality
+    </description>
+    <name>forEach</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ForEachTag</tag-class>
+    <tei-class>org.apache.taglibs.standard.tei.ForEachTEI</tei-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Collection of items to iterate over.
+        </description>
+	<name>items</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>java.lang.Object</type>
+    </attribute>
+    <attribute>
+        <description>
+If items specified:
+Iteration begins at the item located at the
+specified index. First item of the collection has
+index 0.
+If items not specified:
+Iteration begins with index set at the value
+specified.
+        </description>
+	<name>begin</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+If items specified:
+Iteration ends at the item located at the
+specified index (inclusive).
+If items not specified:
+Iteration ends when index reaches the value
+specified.
+        </description>
+	<name>end</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration will only process every step items of
+the collection, starting with the first one.
+        </description>
+	<name>step</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+current item of the iteration. This scoped
+variable has nested visibility. Its type depends
+on the object of the underlying collection.
+        </description>
+	<name>var</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+status of the iteration. Object exported is of type
+javax.servlet.jsp.jstl.core.LoopTagStatus. This scoped variable has nested
+visibility.
+        </description>
+	<name>varStatus</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	Iterates over tokens, separated by the supplied delimeters
+    </description>
+    <name>forTokens</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ForTokensTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+String of tokens to iterate over.
+        </description>
+	<name>items</name>
+	<required>true</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>java.lang.String</type>
+    </attribute>
+    <attribute>
+        <description>
+The set of delimiters (the characters that
+separate the tokens in the string).
+        </description>
+	<name>delims</name>
+	<required>true</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>java.lang.String</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration begins at the token located at the
+specified index. First token has index 0.
+        </description>
+	<name>begin</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration ends at the token located at the
+specified index (inclusive).
+        </description>
+	<name>end</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Iteration will only process every step tokens
+of the string, starting with the first one.
+        </description>
+	<name>step</name>
+	<required>false</required>
+	<rtexprvalue>true</rtexprvalue>
+	<type>int</type>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+current item of the iteration. This scoped
+variable has nested visibility.
+        </description>
+	<name>var</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+status of the iteration. Object exported is of
+type
+javax.servlet.jsp.jstl.core.LoopTag
+Status. This scoped variable has nested
+visibility.
+        </description>
+	<name>varStatus</name>
+	<required>false</required>
+	<rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Like &lt;%= ... &gt;, but for expressions.
+    </description> 
+    <name>out</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.OutTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Expression to be evaluated.
+        </description>
+        <name>value</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Default value if the resulting value is null.
+        </description>
+        <name>default</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Determines whether characters &lt;,&gt;,&amp;,'," in the
+resulting string should be converted to their
+corresponding character entity codes. Default value is
+true.
+        </description>
+        <name>escapeXml</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+
+  <tag>
+    <description>
+        Subtag of &lt;choose&gt; that follows &lt;when&gt; tags
+        and runs only if all of the prior conditions evaluated to
+        'false'
+    </description>
+    <name>otherwise</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.OtherwiseTag</tag-class>
+    <body-content>JSP</body-content>
+  </tag>
+
+  <tag>
+    <description>
+        Adds a parameter to a containing 'import' tag's URL.
+    </description>
+    <name>param</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.ParamTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the query string parameter.
+        </description>
+        <name>name</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Value of the parameter.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Redirects to a new URL.
+    </description>
+    <name>redirect</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.RedirectTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The URL of the resource to redirect to.
+        </description>
+        <name>url</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the context when redirecting to a relative URL
+resource that belongs to a foreign context.
+        </description>
+        <name>context</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Removes a scoped variable (from a particular scope, if specified).
+    </description>
+    <name>remove</name>
+    <tag-class>org.apache.taglibs.standard.tag.common.core.RemoveTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+Name of the scoped variable to be removed.
+        </description>
+        <name>var</name>
+        <required>true</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+ <tag>
+    <description>
+        Sets the result of an expression evaluation in a 'scope'
+    </description>
+    <name>set</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.SetTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the exported scoped variable to hold the value
+specified in the action. The type of the scoped variable is
+whatever type the value expression evaluates to.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Expression to be evaluated.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Target object whose property will be set. Must evaluate to
+a JavaBeans object with setter property property, or to a
+java.util.Map object.
+        </description>
+        <name>target</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the property to be set in the target object.
+        </description>
+        <name>property</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Creates a URL with optional query parameters.
+    </description>
+    <name>url</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.UrlTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Name of the exported scoped variable for the
+processed url. The type of the scoped variable is
+String.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope for var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+URL to be processed.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the context when specifying a relative URL
+resource that belongs to a foreign context.
+        </description>
+        <name>context</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+	Subtag of &lt;choose&gt; that includes its body if its
+	condition evalutes to 'true'
+    </description>
+    <name>when</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.core.WhenTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The test condition that determines whether or not the
+body content should be processed.
+        </description>
+        <name>test</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+	<type>boolean</type>
+    </attribute>
+  </tag>
+
+</taglib>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fmt.tld
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fmt.tld	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fmt.tld	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,671 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<taglib 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-jsptaglibrary_2_0.xsd"
+    version="2.0">
+    
+  <description>JSTL 1.1 i18n-capable formatting library</description>
+  <display-name>JSTL fmt</display-name>
+  <tlib-version>1.1</tlib-version>
+  <short-name>fmt</short-name>
+  <uri>http://java.sun.com/jsp/jstl/fmt</uri>
+
+  <validator>
+    <description>
+        Provides core validation features for JSTL tags.
+    </description>
+    <validator-class>
+        org.apache.taglibs.standard.tlv.JstlFmtTLV
+    </validator-class>
+  </validator>
+
+  <tag>
+    <description>
+        Sets the request character encoding
+    </description>
+    <name>requestEncoding</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.RequestEncodingTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+Name of character encoding to be applied when
+decoding request parameters.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Stores the given locale in the locale configuration variable
+    </description>
+    <name>setLocale</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.SetLocaleTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+A String value is interpreted as the
+printable representation of a locale, which
+must contain a two-letter (lower-case)
+language code (as defined by ISO-639),
+and may contain a two-letter (upper-case)
+country code (as defined by ISO-3166).
+Language and country codes must be
+separated by hyphen (-) or underscore
+(_).        
+	</description>
+        <name>value</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Vendor- or browser-specific variant.
+See the java.util.Locale javadocs for
+more information on variants.
+        </description>
+        <name>variant</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of the locale configuration variable.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Specifies the time zone for any time formatting or parsing actions
+        nested in its body
+    </description>
+    <name>timeZone</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.TimeZoneTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+The time zone. A String value is interpreted as
+a time zone ID. This may be one of the time zone
+IDs supported by the Java platform (such as
+"America/Los_Angeles") or a custom time zone
+ID (such as "GMT-8"). See
+java.util.TimeZone for more information on
+supported time zone formats.
+        </description>
+        <name>value</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Stores the given time zone in the time zone configuration variable
+    </description>
+    <name>setTimeZone</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.SetTimeZoneTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+The time zone. A String value is interpreted as
+a time zone ID. This may be one of the time zone
+IDs supported by the Java platform (such as
+"America/Los_Angeles") or a custom time zone
+ID (such as "GMT-8"). See java.util.TimeZone for
+more information on supported time zone
+formats.
+        </description>
+        <name>value</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable which
+stores the time zone of type
+java.util.TimeZone.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var or the time zone configuration
+variable.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Loads a resource bundle to be used by its tag body
+    </description>
+    <name>bundle</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.BundleTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Resource bundle base name. This is the bundle's
+fully-qualified resource name, which has the same
+form as a fully-qualified class name, that is, it uses
+"." as the package component separator and does not
+have any file type (such as ".class" or ".properties")
+suffix.
+        </description>
+        <name>basename</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Prefix to be prepended to the value of the message
+key of any nested &lt;fmt:message&gt; action.
+        </description>
+        <name>prefix</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Loads a resource bundle and stores it in the named scoped variable or
+        the bundle configuration variable
+    </description>
+    <name>setBundle</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.SetBundleTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+Resource bundle base name. This is the bundle's
+fully-qualified resource name, which has the same
+form as a fully-qualified class name, that is, it uses
+"." as the package component separator and does not
+have any file type (such as ".class" or ".properties")
+suffix.
+        </description>
+        <name>basename</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable which stores
+the i18n localization context of type
+javax.servlet.jsp.jstl.fmt.LocalizationC
+ontext.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var or the localization context
+configuration variable.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Maps key to localized message and performs parametric replacement
+    </description>
+    <name>message</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.MessageTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Message key to be looked up.
+        </description>
+        <name>key</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Localization context in whose resource
+bundle the message key is looked up.
+        </description>
+        <name>bundle</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable
+which stores the localized message.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Supplies an argument for parametric replacement to a containing
+        &lt;message&gt; tag
+    </description>
+    <name>param</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.ParamTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Argument used for parametric replacement.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Formats a numeric value as a number, currency, or percentage
+    </description>
+    <name>formatNumber</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.FormatNumberTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Numeric value to be formatted.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Specifies whether the value is to be
+formatted as number, currency, or
+percentage.
+        </description>
+        <name>type</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Custom formatting pattern.
+        </description>
+        <name>pattern</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+ISO 4217 currency code. Applied only
+when formatting currencies (i.e. if type is
+equal to "currency"); ignored otherwise.
+        </description>
+        <name>currencyCode</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Currency symbol. Applied only when
+formatting currencies (i.e. if type is equal
+to "currency"); ignored otherwise.
+        </description>
+        <name>currencySymbol</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Specifies whether the formatted output
+will contain any grouping separators.
+        </description>
+        <name>groupingUsed</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Maximum number of digits in the integer
+portion of the formatted output.
+        </description>
+        <name>maxIntegerDigits</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Minimum number of digits in the integer
+portion of the formatted output.
+        </description>
+        <name>minIntegerDigits</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Maximum number of digits in the
+fractional portion of the formatted output.
+        </description>
+        <name>maxFractionDigits</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Minimum number of digits in the
+fractional portion of the formatted output.
+        </description>
+        <name>minFractionDigits</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable
+which stores the formatted result as a
+String.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Parses the string representation of a number, currency, or percentage
+    </description>
+    <name>parseNumber</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.ParseNumberTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+String to be parsed.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Specifies whether the string in the value
+attribute should be parsed as a number,
+currency, or percentage.
+        </description>
+        <name>type</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Custom formatting pattern that determines
+how the string in the value attribute is to be
+parsed.
+        </description>
+        <name>pattern</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Locale whose default formatting pattern (for
+numbers, currencies, or percentages,
+respectively) is to be used during the parse
+operation, or to which the pattern specified
+via the pattern attribute (if present) is
+applied.
+        </description>
+        <name>parseLocale</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Specifies whether just the integer portion of
+the given value should be parsed.
+        </description>
+        <name>integerOnly</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable which
+stores the parsed result (of type
+java.lang.Number).
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Formats a date and/or time using the supplied styles and pattern
+    </description>
+    <name>formatDate</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.FormatDateTag</tag-class>
+    <body-content>empty</body-content>
+    <attribute>
+        <description>
+Date and/or time to be formatted.
+        </description>
+        <name>value</name>
+        <required>true</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Specifies whether the time, the date, or both
+the time and date components of the given
+date are to be formatted. 
+        </description>
+        <name>type</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Predefined formatting style for dates. Follows
+the semantics defined in class
+java.text.DateFormat. Applied only
+when formatting a date or both a date and
+time (i.e. if type is missing or is equal to
+"date" or "both"); ignored otherwise.
+        </description>
+        <name>dateStyle</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Predefined formatting style for times. Follows
+the semantics defined in class
+java.text.DateFormat. Applied only
+when formatting a time or both a date and
+time (i.e. if type is equal to "time" or "both");
+ignored otherwise.
+        </description>
+        <name>timeStyle</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Custom formatting style for dates and times.
+        </description>
+        <name>pattern</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Time zone in which to represent the formatted
+time.
+        </description>
+        <name>timeZone</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable which
+stores the formatted result as a String.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+  <tag>
+    <description>
+        Parses the string representation of a date and/or time
+    </description>
+    <name>parseDate</name>
+    <tag-class>org.apache.taglibs.standard.tag.rt.fmt.ParseDateTag</tag-class>
+    <body-content>JSP</body-content>
+    <attribute>
+        <description>
+Date string to be parsed.
+        </description>
+        <name>value</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Specifies whether the date string in the
+value attribute is supposed to contain a
+time, a date, or both.
+        </description>
+        <name>type</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Predefined formatting style for days
+which determines how the date
+component of the date string is to be
+parsed. Applied only when formatting a
+date or both a date and time (i.e. if type
+is missing or is equal to "date" or "both");
+ignored otherwise.
+        </description>
+        <name>dateStyle</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Predefined formatting styles for times
+which determines how the time
+component in the date string is to be
+parsed. Applied only when formatting a
+time or both a date and time (i.e. if type
+is equal to "time" or "both"); ignored
+otherwise.
+        </description>
+        <name>timeStyle</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Custom formatting pattern which
+determines how the date string is to be
+parsed.
+        </description>
+        <name>pattern</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Time zone in which to interpret any time
+information in the date string.
+        </description>
+        <name>timeZone</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Locale whose predefined formatting styles
+for dates and times are to be used during
+the parse operation, or to which the
+pattern specified via the pattern
+attribute (if present) is applied.
+        </description>
+        <name>parseLocale</name>
+        <required>false</required>
+        <rtexprvalue>true</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Name of the exported scoped variable in
+which the parsing result (of type
+java.util.Date) is stored.
+        </description>
+        <name>var</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+    <attribute>
+        <description>
+Scope of var.
+        </description>
+        <name>scope</name>
+        <required>false</required>
+        <rtexprvalue>false</rtexprvalue>
+    </attribute>
+  </tag>
+
+</taglib>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fn.tld
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fn.tld	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/fn.tld	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<taglib 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-jsptaglibrary_2_0.xsd"
+  version="2.0">
+    
+  <description>JSTL 1.1 functions library</description>
+  <display-name>JSTL functions</display-name>
+  <tlib-version>1.1</tlib-version>
+  <short-name>fn</short-name>
+  <uri>http://java.sun.com/jsp/jstl/functions</uri>
+
+  <function>
+    <description>
+      Tests if an input string contains the specified substring.
+    </description>
+    <name>contains</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>boolean contains(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      &lt;c:if test="${fn:contains(name, searchString)}">
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Tests if an input string contains the specified substring in a case insensitive way.
+    </description>
+    <name>containsIgnoreCase</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>boolean containsIgnoreCase(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      &lt;c:if test="${fn:containsIgnoreCase(name, searchString)}">
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Tests if an input string ends with the specified suffix.
+    </description>
+    <name>endsWith</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>boolean endsWith(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      &lt;c:if test="${fn:endsWith(filename, ".txt")}">
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Escapes characters that could be interpreted as XML markup.
+    </description>
+    <name>escapeXml</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String escapeXml(java.lang.String)</function-signature>
+    <example>
+      ${fn:escapeXml(param:info)}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Returns the index withing a string of the first occurrence of a specified substring.
+    </description>
+    <name>indexOf</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>int indexOf(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      ${fn:indexOf(name, "-")}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Joins all elements of an array into a string.
+    </description>
+    <name>join</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String join(java.lang.String[], java.lang.String)</function-signature>
+    <example>
+      ${fn:join(array, ";")}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Returns the number of items in a collection, or the number of characters in a string.
+    </description>
+    <name>length</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>int length(java.lang.Object)</function-signature>
+    <example>
+      You have ${fn:length(shoppingCart.products)} in your shopping cart.
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Returns a string resulting from replacing in an input string all occurrences
+      of a "before" string into an "after" substring.
+    </description>
+    <name>replace</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String replace(java.lang.String, java.lang.String, java.lang.String)</function-signature>
+    <example>
+      ${fn:replace(text, "-", "&#149;")}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Splits a string into an array of substrings.
+    </description>
+    <name>split</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String[] split(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      ${fn:split(customerNames, ";")}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Tests if an input string starts with the specified prefix.
+    </description>
+    <name>startsWith</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>boolean startsWith(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      &lt;c:if test="${fn:startsWith(product.id, "100-")}">
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Returns a subset of a string.
+    </description>
+    <name>substring</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String substring(java.lang.String, int, int)</function-signature>
+    <example>
+      P.O. Box: ${fn:substring(zip, 6, -1)}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Returns a subset of a string following a specific substring.
+    </description>
+    <name>substringAfter</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String substringAfter(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      P.O. Box: ${fn:substringAfter(zip, "-")}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Returns a subset of a string before a specific substring.
+    </description>
+    <name>substringBefore</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String substringBefore(java.lang.String, java.lang.String)</function-signature>
+    <example>
+      Zip (without P.O. Box): ${fn:substringBefore(zip, "-")}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Converts all of the characters of a string to lower case.
+    </description>
+    <name>toLowerCase</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String toLowerCase(java.lang.String)</function-signature>
+    <example>
+      Product name: ${fn.toLowerCase(product.name)}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Converts all of the characters of a string to upper case.
+    </description>
+    <name>toUpperCase</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String toUpperCase(java.lang.String)</function-signature>
+    <example>
+      Product name: ${fn.UpperCase(product.name)}
+    </example>
+  </function>
+
+  <function>
+    <description>
+      Removes white spaces from both ends of a string.
+    </description>
+    <name>trim</name>
+    <function-class>org.apache.taglibs.standard.functions.Functions</function-class>
+    <function-signature>java.lang.String trim(java.lang.String)</function-signature>
+    <example>
+      Name: ${fn.trim(name)}
+    </example>  
+  </function>
+
+</taglib>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/attributes.tag
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/attributes.tag	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/attributes.tag	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,31 @@
+<%--
+	- attributes
+	-
+	- Expose a string of HTML attributes from the given map of attributes.
+	- Dynamic attributes specified will be added to the string if they do
+	- not already exist in the map. This tag exposes a variable with the
+	- name specified in the 'var' attribute.
+	-
+	- @param var the variable in which the string attributes will be exposed.
+	-     (required)
+	- @param attributeMap a map of attributes to convert to a string of
+	-     name/value pairs.
+	--%>
+<%@ tag dynamic-attributes="attributes" isELIgnored="false" %>
+<%@ include file="include.jsp" %>
+<%@ attribute name="var" required="true" rtexprvalue="false" %>
+<%@ attribute name="attributeMap" type="java.util.Map" %>
+<%@ variable name-from-attribute="var" alias="attrString" declare="false" %>
+<c:forEach var="attr" items="${attributeMap}">
+	<c:set var="attrString">
+	    <c:out escapeXml="false" value="${attrString} ${attr.key}=\""/><c:out value="${attr.value}"/><c:out escapeXml="false" value="\""/>
+	</c:set>
+</c:forEach>
+<c:forEach var="attr" items="${attributes}">
+	<c:if test="${empty attributeMap[attr.key]}">
+		<c:set var="attrString">
+	    	<c:out escapeXml="false" value="${attrString} ${attr.key}=\""/><c:out value="${attr.value}"/><c:out escapeXml="false" value="\""/>
+		</c:set>
+	</c:if>
+</c:forEach>
+<jsp:doBody />
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/errors.tag
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/errors.tag	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/errors.tag	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,34 @@
+<%--
+	- errors
+	- 
+	- Output a list of errors for the command or bean specified in the
+	- 'path' attribute. The markup enclosing each error message can be
+	- customized by editing this tag file directly.
+	-
+	- @param path the name of the field to bind to (required)
+	- @param fields whether the individual fields should also be checked,
+	-     specifically '${path}.*' (optional)
+	--%>
+<%@ tag dynamic-attributes="attributes" isELIgnored="false" body-content="empty" %>
+<%@ include file="include.jsp" %>
+<%@ attribute name="path" required="true" %>
+<%@ attribute name="fields" required="false"%>
+<spring:hasBindErrors name="${path}">
+	<div style="color:#A00000">
+		<p>Please correct the following errors:</p>
+		<ul class="errors">
+			<spring:bind path="${path}">
+				<c:forEach items="${status.errorMessages}" var="error">
+					<li><c:out value="${error}"/></li>
+				</c:forEach>
+			</spring:bind>
+			<c:if test="${fields}">
+				<spring:bind path="${path}.*">
+					<c:forEach items="${status.errorMessages}" var="error">
+						<li><c:out value="${error}"/></li>
+					</c:forEach>
+				</spring:bind>
+			</c:if>
+		<ul>
+	</div>
+</spring:hasBindErrors>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/imagesPath.tag
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/imagesPath.tag	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/imagesPath.tag	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1 @@
+<%@ tag isELIgnored="false" body-content="empty"  %>${pageContext.request.contextPath}/images/
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/include.jsp
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/include.jsp	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/include.jsp	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,6 @@
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>
+<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
+<%@ taglib prefix="html" tagdir="/WEB-INF/tags/html" %>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/input.tag
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/input.tag	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/input.tag	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,24 @@
+<%--
+	- input
+	- 
+	- Display an input field (default type="text") and bind it to the attribute
+	- of a command or bean. If name and/or value attributes are specified,
+	- they will be used instead of status.expression and/or status.value
+	- respectively. A type attribute may also be used to override the
+	- input tag type (the default is text).
+	- Accepts dynamic attributes.
+	-
+	- @param path the name of the field to bind to (required)
+	- @param type use this attribute to override the input type (i.e. hidden).
+	- @param name use this attribute to override the input name
+	- @param value use this attribute to override the input value
+	--%>
+<%@ tag dynamic-attributes="attributes" isELIgnored="false" body-content="empty" %>
+<%@ include file="include.jsp" %>
+<%@ attribute name="path" required="true" %>
+<spring:bind path="${path}">
+	<html:attributes var="attrString" attributeMap="${attributes}" type="text" name="${status.expression}" value="${status.value}">
+		<input ${attrString} />
+	</html:attributes>
+	<span style="color:#A00000">${status.errorMessage}</span>
+</spring:bind>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/rootPath.tag
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/rootPath.tag	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/rootPath.tag	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1 @@
+<%@ tag isELIgnored="false" body-content="empty" %>${pageContext.request.contextPath}/
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/textarea.tag
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/textarea.tag	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/html/textarea.tag	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,27 @@
+<%--
+	- textarea
+	- 
+	- Display an html textarea and bind it to the attribute of a command or
+	- bean. The var attribute specifies a variable that may be used to place
+	- the value in the body of the tag.
+	- Accepts dynamic attributes.
+	-
+	- @param path the name of the field to bind to (required)
+	- @param clear set to "true" to override the value with a blank value.
+	--%>
+<%@ tag dynamic-attributes="attributes" isELIgnored="false" %>
+<%@ include file="include.jsp" %>
+<%@ attribute name="path" required="true" %>
+<%@ attribute name="clear" %>
+<spring:bind path="${path}">
+	<html:attributes var="attrString" attributeMap="${attributes}" name="${status.expression}">
+		<c:if test="${clear != \"true\"}">
+			<jsp:doBody var="value" />
+			<c:if test="${empty value}">
+				<c:set var="value" value="${status.value}" />
+			</c:if>
+		</c:if>
+		<textarea ${attrString}>${value}</textarea>
+	</html:attributes>
+	<span style="color:#A00000">${status.errorMessage}</span>
+</spring:bind>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/portlet.tld
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/portlet.tld	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/portlet.tld	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE taglib PUBLIC
+  "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
+  "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
+<!-- 
+Copyright 2004 The Apache Software Foundation
+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.
+-->
+<taglib>
+    <tlibversion>1.0</tlibversion>
+    <jspversion>1.1</jspversion>
+    <shortname>portlet</shortname>
+    <uri>http://java.sun.com/portlet</uri>
+    <tag>
+        <name>defineObjects</name>
+        <tagclass>org.apache.pluto.tags.DefineObjectsTag</tagclass>
+        <teiclass>org.apache.pluto.tags.DefineObjectsTag$TEI</teiclass>
+        <bodycontent>empty</bodycontent>
+    </tag>
+    <tag>
+        <name>param</name>
+        <tagclass>org.apache.pluto.tags.ParamTag</tagclass>
+        <bodycontent>empty</bodycontent>
+        <attribute>
+            <name>name</name>
+            <required>true</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>value</name>
+            <required>true</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+    </tag>
+    <tag>
+        <name>actionURL</name>
+        <tagclass>org.apache.pluto.tags.ActionURLTag</tagclass>
+        <teiclass>org.apache.pluto.tags.BasicURLTag$TEI</teiclass>
+        <bodycontent>JSP</bodycontent>
+        <attribute>
+            <name>windowState</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>portletMode</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>secure</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>var</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+    </tag>
+    <tag>
+        <name>renderURL</name>
+        <tagclass>org.apache.pluto.tags.RenderURLTag</tagclass>
+        <teiclass>org.apache.pluto.tags.BasicURLTag$TEI</teiclass>
+        <bodycontent>JSP</bodycontent>
+        <attribute>
+            <name>windowState</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>portletMode</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>secure</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+        <attribute>
+            <name>var</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+        </attribute>
+    </tag>
+    <tag>
+        <name>namespace</name>
+        <tagclass>org.apache.pluto.tags.NamespaceTag</tagclass>
+        <bodycontent>empty</bodycontent>
+    </tag>
+</taglib>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/tags/spring.tld
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/tags/spring.tld	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/tags/spring.tld	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,323 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
+
+<taglib>
+
+	<tlib-version>1.1.2</tlib-version>
+
+	<jsp-version>1.2</jsp-version>
+
+	<short-name>Spring</short-name>
+
+	<uri>http://www.springframework.org/tags</uri>
+
+	<description>Spring Framework JSP Tag Library. Authors: Rod Johnson, Juergen Hoeller</description>
+
+
+	<tag>
+
+		<name>htmlEscape</name>
+		<tag-class>org.springframework.web.servlet.tags.HtmlEscapeTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Sets default HTML escape value for the current page.
+			Overrides a "defaultHtmlEscape" context-param in web.xml, if any.
+		</description>
+
+		<attribute>
+			<name>defaultHtmlEscape</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>escapeBody</name>
+		<tag-class>org.springframework.web.servlet.tags.EscapeBodyTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Escapes its enclosed body content, applying HTML escaping and/or JavaScript escaping.
+			The HTML escaping flag participates in a page-wide or application-wide setting
+			(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+		</description>
+
+		<attribute>
+			<name>htmlEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>javaScriptEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>message</name>
+		<tag-class>org.springframework.web.servlet.tags.MessageTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Retrieves the message with the given code, or text if code isn't resolvable.
+			The HTML escaping flag participates in a page-wide or application-wide setting
+			(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+		</description>
+
+		<attribute>
+			<name>message</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>code</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>arguments</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>argumentSeparator</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>text</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>var</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>scope</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>htmlEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>javaScriptEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>theme</name>
+		<tag-class>org.springframework.web.servlet.tags.ThemeTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Retrieves the theme message with the given code, or text if code isn't resolvable.
+			The HTML escaping flag participates in a page-wide or application-wide setting
+			(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+		</description>
+
+		<attribute>
+			<name>code</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>arguments</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>text</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>var</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>scope</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>htmlEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>javaScriptEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>hasBindErrors</name>
+		<tag-class>org.springframework.web.servlet.tags.BindErrorsTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Provides Errors instance in case of bind errors.
+			The HTML escaping flag participates in a page-wide or application-wide setting
+			(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+		</description>
+
+		<variable>
+			<name-given>errors</name-given>
+			<variable-class>org.springframework.validation.Errors</variable-class>
+		</variable>
+
+		<attribute>
+			<name>name</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>htmlEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>nestedPath</name>
+		<tag-class>org.springframework.web.servlet.tags.NestedPathTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Sets a nested path to be used by the bind tag's path.
+		</description>
+
+		<variable>
+			<name-given>nestedPath</name-given>
+			<variable-class>java.lang.String</variable-class>
+		</variable>
+
+		<attribute>
+			<name>path</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>bind</name>
+		<tag-class>org.springframework.web.servlet.tags.BindTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Provides BindStatus object for the given bind path.
+			The HTML escaping flag participates in a page-wide or application-wide setting
+			(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+		</description>
+
+		<variable>
+			<name-given>status</name-given>
+			<variable-class>org.springframework.web.servlet.support.BindStatus</variable-class>
+		</variable>
+
+		<attribute>
+			<name>path</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>ignoreNestedPath</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>htmlEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+
+	<tag>
+
+		<name>transform</name>
+		<tag-class>org.springframework.web.servlet.tags.TransformTag</tag-class>
+		<body-content>JSP</body-content>
+
+		<description>
+			Provides transformation of variables to Strings, using an appropriate
+			custom PropertyEditor from BindTag (can only be used inside BindTag).
+			The HTML escaping flag participates in a page-wide or application-wide setting
+			(i.e. by HtmlEscapeTag or a "defaultHtmlEscape" context-param in web.xml).
+		</description>
+
+		<attribute>
+			<name>value</name>
+			<required>true</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>var</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>scope</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+		<attribute>
+			<name>htmlEscape</name>
+			<required>false</required>
+			<rtexprvalue>true</rtexprvalue>
+		</attribute>
+
+	</tag>
+
+</taglib>

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/web.dist.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/web.dist.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/web.dist.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+                         "http://java.sun.com/dtd/web-app_2_3.dtd">
+                         
+<web-app>
+
+	<display-name>Spring Portlet MVC Sample Application</display-name>
+
+	<context-param>
+		<param-name>webAppRootKey</param-name>
+		<param-value>org.springframework.web.portlet.sample</param-value>
+	</context-param>
+
+    <context-param>
+        <param-name>log4jConfigLocation</param-name>
+        <param-value>/WEB-INF/classes/log4j.properties</param-value>
+    </context-param>
+	
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>/WEB-INF/context/applicationContext.xml</param-value>
+	</context-param>
+
+	<listener>
+		<listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
+	</listener>
+
+    <listener>
+        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
+    </listener>
+
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+
+	<servlet>
+		<servlet-name>ViewRendererServlet</servlet-name>
+		<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>ViewRendererServlet</servlet-name>
+		<url-pattern>/WEB-INF/servlet/view</url-pattern>
+	</servlet-mapping>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
+        <taglib-location>/WEB-INF/tags/c.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
+        <taglib-location>/WEB-INF/tags/fmt.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/jsp/jstl/functions</taglib-uri>
+        <taglib-location>/WEB-INF/tags/fn.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://www.springframework.org/tags</taglib-uri>
+        <taglib-location>/WEB-INF/tags/spring.tld</taglib-location>
+    </taglib>
+
+</web-app>
\ No newline at end of file

Added: portlets/src/framework/spring-portlet-sample/WEB-INF/web.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/WEB-INF/web.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/WEB-INF/web.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,192 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+                         "http://java.sun.com/dtd/web-app_2_3.dtd">
+                         
+<web-app>
+
+	<display-name>Spring Portlet MVC Sample Application</display-name>
+
+    <context-param>
+        <param-name>log4jConfigLocation</param-name>
+        <param-value>/WEB-INF/classes/log4j.properties</param-value>
+    </context-param>
+	
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+		<param-value>/WEB-INF/context/applicationContext.xml</param-value>
+	</context-param>
+
+    <listener>
+        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
+    </listener>
+
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+
+	<servlet>
+		<servlet-name>ViewRendererServlet</servlet-name>
+		<servlet-class>org.springframework.web.servlet.ViewRendererServlet</servlet-class>
+		<load-on-startup>1</load-on-startup>
+	</servlet>
+
+    <servlet>
+        <servlet-name>mode</servlet-name>
+        <display-name>mode Wrapper</display-name>
+        <description>Automated generated Portlet Wrapper</description>
+        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
+        <init-param>
+            <param-name>portlet-guid</param-name>
+            <param-value>spring-portlet-sample.mode</param-value>
+        </init-param>
+        <init-param>
+            <param-name>portlet-class</param-name>
+            <param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
+        </init-param>
+		<init-param>
+			<param-name>contextConfigLocation</param-name>
+			<param-value>/WEB-INF/context/portlet/mode.xml</param-value>
+		</init-param>
+    </servlet>
+    
+    <servlet>
+        <servlet-name>exceptions</servlet-name>
+        <display-name>exceptions Wrapper</display-name>
+        <description>Automated generated Portlet Wrapper</description>
+        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
+        <init-param>
+            <param-name>portlet-guid</param-name>
+            <param-value>spring-portlet-sample.exceptions</param-value>
+        </init-param>
+        <init-param>
+            <param-name>portlet-class</param-name>
+            <param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
+        </init-param>
+		<init-param>
+			<param-name>contextConfigLocation</param-name>
+			<param-value>/WEB-INF/context/portlet/exceptions.xml</param-value>
+		</init-param>
+    </servlet>
+    
+    <servlet>
+        <servlet-name>books</servlet-name>
+        <display-name>books Wrapper</display-name>
+        <description>Automated generated Portlet Wrapper</description>
+        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
+        <init-param>
+            <param-name>portlet-class</param-name>
+            <param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
+        </init-param>
+        <init-param>
+            <param-name>portlet-guid</param-name>
+            <param-value>spring-portlet-sample.books</param-value>
+        </init-param>
+    </servlet>
+    
+    <servlet>
+        <servlet-name>redirect</servlet-name>
+        <display-name>redirect Wrapper</display-name>
+        <description>Automated generated Portlet Wrapper</description>
+        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
+        <init-param>
+            <param-name>portlet-class</param-name>
+            <param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
+        </init-param>
+        <init-param>
+            <param-name>portlet-guid</param-name>
+            <param-value>spring-portlet-sample.redirect</param-value>
+        </init-param>
+    </servlet>
+    
+    <servlet>
+        <servlet-name>upload</servlet-name>
+        <display-name>upload Wrapper</display-name>
+        <description>Automated generated Portlet Wrapper</description>
+        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
+        <init-param>
+            <param-name>portlet-class</param-name>
+            <param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
+        </init-param>
+        <init-param>
+            <param-name>portlet-guid</param-name>
+            <param-value>spring-portlet-sample.upload</param-value>
+        </init-param>
+    </servlet>
+    
+    <servlet>
+        <servlet-name>helloworld</servlet-name>
+        <display-name>helloworld Wrapper</display-name>
+        <description>Automated generated Portlet Wrapper</description>
+        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
+        <init-param>
+            <param-name>portlet-class</param-name>
+            <param-value>org.springframework.web.portlet.DispatcherPortlet</param-value>
+        </init-param>
+        <init-param>
+            <param-name>portlet-guid</param-name>
+            <param-value>spring-portlet-sample.helloworld</param-value>
+        </init-param>
+    </servlet>
+    
+	<servlet-mapping>
+		<servlet-name>ViewRendererServlet</servlet-name>
+		<url-pattern>/WEB-INF/servlet/view</url-pattern>
+	</servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>mode</servlet-name>
+        <url-pattern>/mode/*</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>exceptions</servlet-name>
+        <url-pattern>/exceptions/*</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>books</servlet-name>
+        <url-pattern>/books/*</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>redirect</servlet-name>
+        <url-pattern>/redirect/*</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>helloworld</servlet-name>
+        <url-pattern>/helloworld/*</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>upload</servlet-name>
+        <url-pattern>/upload/*</url-pattern>
+    </servlet-mapping>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
+        <taglib-location>/WEB-INF/tags/c.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri>
+        <taglib-location>/WEB-INF/tags/fmt.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/jsp/jstl/functions</taglib-uri>
+        <taglib-location>/WEB-INF/tags/fn.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://www.springframework.org/tags</taglib-uri>
+        <taglib-location>/WEB-INF/tags/spring.tld</taglib-location>
+    </taglib>
+
+    <taglib>
+        <taglib-uri>http://java.sun.com/portlet</taglib-uri>
+        <taglib-location>/WEB-INF/tags/portlet.tld</taglib-location>
+    </taglib>
+
+</web-app>

Added: portlets/src/framework/spring-portlet-sample/build/spring-portlet-sample.war
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/build/spring-portlet-sample.war
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/build/spring-portlet-sample.zip
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/build/spring-portlet-sample.zip
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/build.xml
===================================================================
--- portlets/src/framework/spring-portlet-sample/build.xml	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/build.xml	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+
+<project name = "spring-portlet-sample" default="build" basedir=".">
+
+	<property name="compiler" value="modern"/>
+	<property name="fork" value="no"/>
+	<property name="verbose" value="no"/>
+	<property name="debug" value="on"/>
+	<property name="optimize" value="on"/>
+	<property name="deprecation" value="on"/>
+	<property name="target" value="1.3"/>
+	<property name="source" value="1.3"/>
+
+	<property environment="env"/> 
+  
+	<!--property name="spring.dist.dir" value="../spring/dist"/-->
+	<property name="spring.dist.dir" value="../spring-framework-2.0-m4/dist"/>
+
+    <property name="webinf.dir" value="WEB-INF"/>
+	
+	<property name="src.dir" value="${webinf.dir}/src"/>
+	<property name="lib.dir" value="lib"/>
+	<property name="build.dir" value="build"/>
+	<property name="work.dir" value="work"/>
+	
+    <property name="webinf.classes.dir" value="${webinf.dir}/classes"/>
+    <property name="webinf.lib.dir" value="${webinf.dir}/lib"/>
+    <property name="webinf.dtd.dir" value="${webinf.dir}/dtd"/>
+    <property name="webinf.tags.dir" value="${webinf.dir}/tags"/>
+	
+    <property name="web.xml" value="${webinf.dir}/web.xml"/>
+    <property name="web.dist.xml" value="${webinf.dir}/web.dist.xml"/>
+
+    <property name="portlet.tld" value="${webinf.tags.dir}/portlet.tld"/>
+	
+	<fileset id="spring.libs" dir="${spring.dist.dir}">
+		<include name="modules/spring-aop.jar"/>
+		<include name="modules/spring-beans.jar"/>
+		<include name="modules/spring-context.jar"/>
+		<include name="modules/spring-core.jar"/>
+		<include name="modules/spring-dao.jar"/>
+		<include name="modules/spring-web.jar"/>
+		<include name="modules/spring-webmvc.jar"/>
+		<include name="extmodules/spring-mock.jar"/>
+		<include name="extmodules/spring-portlet.jar"/>
+	</fileset>
+
+	<fileset id="spring.dtds" dir="${spring.dist.dir}">
+		<include name="spring-beans.dtd"/>
+	</fileset>
+
+	<fileset id="spring.tlds" dir="${spring.dist.dir}">
+		<include name="spring.tld"/>
+	</fileset>
+
+	<fileset id="api.libs" dir="${lib.dir}">
+		<include name="*.jar"/>
+	</fileset>
+
+	<fileset id="webapp.libs" dir="${webinf.lib.dir}">
+		<include name="*.jar"/>
+	</fileset>
+
+	<path id="class.path">
+		<pathelement path="${webinf.classes.dir}"/>
+		<fileset refid="webapp.libs"/>
+		<fileset refid="api.libs"/>
+	</path>
+
+	<pathconvert pathsep=":" property="class.path" refid="class.path"/>
+
+	<fileset id="war.files" dir=".">
+		<include name="${webinf.dir}/**"/>
+		<exclude name="${web.xml}"/>
+		<exclude name="${web.dist.xml}"/>
+		<exclude name="${portlet.tld}"/>
+		<include name="images/**"/>
+	</fileset>
+
+	<!-- target to get lib files from spring build -->
+	<target name="getlibs">
+		<copy todir="${webinf.lib.dir}" overwrite="true"
+		      preservelastmodified="true" flatten="true">
+			<fileset refid="spring.libs"/>
+		</copy>
+		<copy todir="${webinf.dtd.dir}" overwrite="true"
+		      preservelastmodified="true" flatten="true">
+			<fileset refid="spring.dtds"/>
+		</copy>
+		<copy todir="${webinf.tags.dir}" overwrite="true"
+		      preservelastmodified="true" flatten="true">
+			<fileset refid="spring.tlds"/>
+		</copy>
+	</target>
+
+	<!-- target to copy lib files to the webapp -->
+	<target name="copylibs" depends="getlibs">
+		<mkdir dir="${webinf.lib.dir}"/>
+		<copy todir="${webinf.lib.dir}"
+		      preservelastmodified="true" flatten="true">
+			<fileset refid="webapp.libs"/>
+		</copy>
+	</target>
+
+	<!-- target to build all the source into the classes directory -->		
+	<target name="compile">
+		<mkdir dir="${webinf.classes.dir}"/>
+        <javac srcdir="${src.dir}" destdir="${webinf.classes.dir}"
+		       fork="${fork}" verbose="${verbose}" deprecation="${deprecation}"
+		       debug="${debug}" optimize="${optimize}"
+		       compiler="${compiler}" target="${target}" source="${source}">
+			<classpath refid="class.path"/>
+        </javac>
+		<copy todir="${webinf.classes.dir}" preservelastmodified="true">
+			<fileset dir="${src.dir}">
+				<include name="**/*.properties"/>
+			</fileset>
+		</copy>
+	</target>
+
+	<!-- target to build everything -->
+	<target name="build" depends="clean,compile">
+	    <mkdir dir="${build.dir}"/>
+		<war destfile="${build.dir}/spring-portlet-sample.war" webxml="${web.dist.xml}">
+			<fileset refid="war.files"/>
+	    </war>
+	    <zip destfile="${build.dir}/spring-portlet-sample.zip">
+			<zipfileset dir="." prefix="" includes="readme.txt"/>
+			<zipfileset dir="${build.dir}" prefix="" includes="spring-portlet-sample.war"/>
+	    </zip>
+	</target>
+		
+	<!-- target to clean up all files created by various tasks -->
+	<target name="clean">
+		<delete quiet="true" includeemptydirs="true">
+			<fileset dir="${webinf.classes.dir}" includes="**/*"/>
+			<fileset dir="${build.dir}"/>
+			<fileset dir="${work.dir}"/>
+		</delete>
+	</target>
+
+</project>

Added: portlets/src/framework/spring-portlet-sample/images/decrease.png
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/images/decrease.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/images/delete.png
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/images/delete.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/images/edit.png
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/images/edit.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/images/increase.png
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/images/increase.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/images/new.png
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/images/new.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/lib/junit.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/lib/junit.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/lib/portlet-api.jar
===================================================================
(Binary files differ)


Property changes on: portlets/src/framework/spring-portlet-sample/lib/portlet-api.jar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: portlets/src/framework/spring-portlet-sample/readme.txt
===================================================================
--- portlets/src/framework/spring-portlet-sample/readme.txt	2006-07-25 16:13:18 UTC (rev 110)
+++ portlets/src/framework/spring-portlet-sample/readme.txt	2006-07-25 17:42:17 UTC (rev 111)
@@ -0,0 +1,89 @@
+
+OVERVIEW
+
+This is a sample web application that contains six JSR-168 portlets developed 
+using the Spring Portlet MVC framework.  The sample portlets are:
+
+"Mode Name View" - A simple portlet that just use the Spring framework to render 
+    JSP views that correspond to the Portlet Mode.  No customer Java code is 
+    used in this portlet at all -- just JSP and Spring beans configurations.
+
+"Test Exceptions" - This portlet demonstrates the handling of uncaught 
+    exceptions and how they can be caught by Spring and mapped to predefined
+    views for that exception condition.  There is also a basic demonstration
+    of localization into English & German as part of this portlet.
+
+"Books" - A more complex portlet that provides a small application to keep an 
+    inventory of books.  This portlet demonstrates usage of multiple custom 
+    controllers within a single portlet mode and demonstrates usage of a 
+    service within Spring that is not specific to the portlet framework.
+
+"Redirect" - A simple form that demonstrates redirection out of the portal.
+
+"Upload" - A portlet that demonstrates multipart file uploads.
+
+"Hello World" - A simple portlet that demonstrates integrating pre-existing
+    portlets within Spring in order to apply mappings, interceptors, or
+    exception handling.
+
+
+NOTES
+
+This sample application is intended for a Servlet 2.3 / JSP 2.0 capable 
+container such as Tomcat 5.x.  It has not been tested with any other servlet 
+containers.
+
+There are a number of required libraries included in the WEB-INF/lib directory 
+of this webapp.  Be aware that having duplicate libraries in any of the other 
+class-loaders can create serious problems.  Depending on your portal, you may 
+well already have some of these libraries in a shared class-loader.  Be sure to 
+move/delete any duplicate libraries out of this webapp or bad things may happen.
+
+This sample does use JSP 2.0 and JSTL 1.1.  It will not work properly on
+servlet containers that will not support these.  If you are porting the samples
+to an older container, be sure to remove the relevant taglib entries from the
+web.xml file, convert all the jsp files to an earlier spec, and change the 
+viewClass attribute of the viewResolver from JstlView to something else or
+remove it entirely.
+
+This webapp cannot be simple dropped into a servlet container and used as-is.
+You must go through some kind of deployment process specific to your portal
+platform.  The deployment process usually consists of the following two changes
+to the webapp:
+
+1. The web.xml file needs to be modified.  This is necessary so that your 
+   portlet-container webapp can issue cross-context requests into the portlet
+   webapp.  This generally involves some kind of well-defined servlet from the
+   portlet-container itself.  This may be a wrapper servlet for each portlet
+   or a single servlet for access to the entire webapp.
+
+2. A 'portlet.tld' file needs to be provided.  Either via a jar file in the
+   classloader (for Servlet 2.4 containers) or an actual file in the WEB-INF
+   directory.  The contents of this file define the standard JSR-168 JSP tags
+   and the classes that implement them.  The implementation of the tags is a 
+   part of the portlet-container's responsibilities and your webapp needs direct
+   access to them, so this definition is specific to the given portlet-container.
+
+This is the basic set of changes required to deploy a portlet webapp to work 
+with any portlet-container webapp.  However, a given portlet-container may 
+require additional changes, such as entire jar files that must be placed in WEB-
+INF/lib or additional xml files that must be placed into WEB-INF.  They also 
+usually require some kind of configuration on the side of the portlet-container 
+webapp to "register" your portlets -- these will be entirely unique to the 
+portlet-container.
+
+Many portal platforms have an "automatic" deployment process that will
+make the necessary modifications to the webapp for you.  Make sure you
+carefully review the resulting web.xml file after it is deployed.  Some
+of these deployment tools will mangle listeners or the ViewRenderServlet 
+and break the example.  It is generally safer to learn how to deploy the webapp 
+yourself and do it by hand or with a custom ant script.
+
+
+CONTACT
+
+If you have any questions or problems with this sample, please email me at 
+jlewis at unicon.net and I will try to help you get it working.  Thanks for 
+trying out the Spring Portlet MVC Framework!
+
+- John Lewis




More information about the jboss-svn-commits mailing list